Protractor compare string numbers

2019-06-07 07:07发布

问题:

Today I've faced interesting problem of create test for pretty simple behavior: 'Most recent' sorting. All what test need to know:

  1. Every item have ID
  2. Previous ID is less then next in this case of sorting

Approach: writing ID in to attribute of item, getting that id from first item with getAttribute() and either way for second.

Problem: getAttribute() promise resulting with string value and Jasmine is not able to compare (from the box) string numbers.

I would like to find elegant way to compare them with toBeLessThan() instead of using chains of few .then() that will be finished with comparing that things.

Root of no-type-definition evil

Thanks guys <3

回答1:

You can create a helper function to convert string number to actual number, which will make use of Promises:

function toNumber(promiseOrValue) {

    // if it is not a promise, then convert a value
    if (!protractor.promise.isPromise(promiseOrValue)) {
        return parseInt(promiseOrValue, 10);
    }

    // if promise - convert result to number
    return promiseOrValue.then(function (stringNumber) {
        return parseInt(stringNumber, 10);
    });
}

And then use the result with .toBeLessThan, etc:

expect(toNumber(itemId)).toBeLessThan(toNumber(anotherItemId));


回答2:

I forgot of native nature of promises but tnx to Michael Radionov I've remembered what I want to do.

expect(first.then( r => Number(r) )).toBe(next.then( r => Number(r) ));

I guess this stroke looks simple.

UPDATE

ES6:

it('should test numbers', async function () {
    let first = Number(await $('#first').getText());
    let second = Number(await $('#second').getText());
    expect(first).toBeGreaterThan(second);
})


回答3:

One option to approach it with a custom jasmine matcher:

toBeSorted: function() {
    return {
        compare: function(actual) {
            var expected = actual.slice().sort(function (a, b) {
                return +a.localeCompare(+b);
            });

            return {
                pass: jasmine.matchersUtil.equals(actual, expected)
            };
        }
    };
},

Here the matcher takes an actual input array, integer-sort it and compare with the input array.

Usage:

expect(element.all(by.css(".myclass")).getAttribute("id")).toBeSorted();

Note that here we are calling getAttribute("id") on an ElementArrayFinder which would resolve into an array of id attribute values. expect() itself is patched to implicitly resolve promises.