0

I'm trying to check that a list of elements from a column on a webpage are in descending order. I come from a Java background so I'm still trying to figure out why this wont work. To my knowledge when it hits that final expect, isDescending should be properly set, but instead it never changes from what I initialize it as.

I've put print statements in the loop previously and everything is working fine in there.

I did some digging and it probably has to do with either it running the expect at the bottom before it finishes the loop, or isDescending is not actually getting set properly for some reason.

I tried a number of things like setTimeout and others but nothing fixed the issue.

Here is the below code, looking for any suggestions or link to pages where I can research more.

    function checkIfDescending(){
        // Will hold list of webelements that each have one account number
        const accountNumbersDescending = pa_search.account_no_column_elements();
        let previousDescendingValue = '';
        let isDescending = true;
        accountNumbersDescending.each((accountNumberElement) => {
            accountNumberElement.getText().then((text) => {
                if (previousDescendingValue !== '') {
                    if (!(text >= previousDescendingValue)) {
                        isDescending = false;
                    }
                }
                previousDescendingValue = text;
            });
        });
        expect(isDescending).toBe(true);
    }

As a final note, if I put the expect within the if statement, it properly works. Problem is that it then will run several times if there is a failure early on.

canpan14
  • 1,181
  • 1
  • 14
  • 36
  • The expect runs prior to your setting it even if it is prior in the sequential order it is not in the execution order. – Mark Schultheiss Jul 19 '17 at 14:02
  • Yeah that's what I'm seeing after trying more things. Which is why I went to look up how to fix those types of things in javascript/typescript. No luck so far. – canpan14 Jul 19 '17 at 14:04
  • You will need to put the `expect` in some kind of event handler that you execute once all your loops are done and trigger that somehow. i.e. promises or some such - avoid `settimeout` as that just presents code that will fail under some condition - and be hard to diagnose – Mark Schultheiss Jul 19 '17 at 14:07
  • After reading through promises I believe I'm kind of already using with the 'then' syntax. So basically the event handler would have to only trigger when the loop is done. But then I reach the same problem where if I had a way to know when the loop is done, I would already have the expect sitting there. – canpan14 Jul 19 '17 at 14:09
  • 1
    Chain it? after the `then` outside the `each` - since each instance may change the value. OR just trigger it once, with false and abort further loops... – Mark Schultheiss Jul 19 '17 at 14:11
  • By chain it do you mean do .each(stuff I'm already doing).then(expect isDescending is true) ? Looks like that worked. I'll post is as a solution below. Might not technically be the right thing to do but it passes for now! – canpan14 Jul 19 '17 at 14:17
  • If `getText()` only returns elements text you shouldn't need a promise for that and can do this synchronously – charlietfl Jul 19 '17 at 14:20
  • The reason I had a promise around it was because getText() actually returns a promise itself. So you can't compare a promise against a string which is what I needed to do below. There also isn't anything that I saw built into expect to compare strings being less than or greater than each other. The strings I'm comparing are not in numeric format. They are like '12-234-56'. – canpan14 Jul 19 '17 at 14:23
  • But what is source of those strings? If it is from the dom you don't need to return a promise and thus could do this synchronously without over complicating it – charlietfl Jul 19 '17 at 14:24
  • Source of the strings are web page elements. I thought I had to use getText()? If there is a way to just return the string right away I'd be glad to use it instead in this case. – canpan14 Jul 19 '17 at 14:26
  • Oh getText() is from working with protractor and webelements. – canpan14 Jul 19 '17 at 14:41

2 Answers2

0

Thanks to Mark Schultheiss for leading me to this answer. I'm not 100% it's the right way to do things but it probably passes/fails now.

    function checkIfDescending(){
        const accountNumbersDescending = pa_search.account_no_column_elements();
        let previousDescendingValue = '';
        let isDescending = true;
        accountNumbersDescending.each((accountNumberElement) => {
            accountNumberElement.getText().then((text) => {
                if (previousDescendingValue !== '') {
                    if (!(text >= previousDescendingValue)) {
                        isDescending = false;

                    }
                }
                previousDescendingValue = text;
            })
        }).then(() => {
            expect(isDescending).toBe(true);
        });
    }
canpan14
  • 1,181
  • 1
  • 14
  • 36
0

You can take a look at chai-increasing plugin.

You need to store values in an array or a promise and make an expect assertion.

Kacper
  • 1,201
  • 1
  • 9
  • 21
  • That's a really cool plugin. I'll check it out and recommend it. Storing them in an array will be easy. – canpan14 Jul 19 '17 at 14:32