最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Protractor browser.wait doesn't work with element(by()) on Angular - Stack Overflow

programmeradmin5浏览0评论

For what reason(s) could this code fail (no element found)...

   element(by.id('loginButton')).click(); // triggers route change
   browser.wait(element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');
   element(by.tagName('myComponent')).click();

...while this code works ?

   element(by.id('loginButton')).click(); // triggers route change
   const eC = protractor.ExpectedConditions;
   browser.wait(eC.visibilityOf(element(by.tagName('myComponent'))), 10000, 'timeout');
   element(by.tagName('myComponent')).click();

I'm working with Angular 5.2.5, Protractor 5.3.0 and Jasmine 2.8.0.

May be related: I could also have asked why I need to add a browser.wait() while element(by()) is supposed to be automatically added in the ControlFlow by Protractor, but there are already lots of related questions (here, here, there, there,...), with no clear answer unfortunately.

For what reason(s) could this code fail (no element found)...

   element(by.id('loginButton')).click(); // triggers route change
   browser.wait(element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');
   element(by.tagName('myComponent')).click();

...while this code works ?

   element(by.id('loginButton')).click(); // triggers route change
   const eC = protractor.ExpectedConditions;
   browser.wait(eC.visibilityOf(element(by.tagName('myComponent'))), 10000, 'timeout');
   element(by.tagName('myComponent')).click();

I'm working with Angular 5.2.5, Protractor 5.3.0 and Jasmine 2.8.0.

May be related: I could also have asked why I need to add a browser.wait() while element(by()) is supposed to be automatically added in the ControlFlow by Protractor, but there are already lots of related questions (here, here, there, there,...), with no clear answer unfortunately.

Share Improve this question edited Mar 21, 2018 at 7:21 Tarun Lalwani 147k11 gold badges213 silver badges276 bronze badges asked Mar 14, 2018 at 11:09 ThCollignonThCollignon 1,2143 gold badges17 silver badges40 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6 +50

There is a not-so obvious difference between the two . But the webdriver docs are clear about this.

eC.visibilityOf(...) - Returns a function. browser.wait() repeatedly evaluates functions until they return true.

isPresent() - Returns a promise. browser.wait() does not / cannot repeatedly evalute promises(!) browser.wait() will continue immediately when the promise resolves , regardless of whether it returns true or false.

If you want to use isPresent() you can wrap it in a function. This allows webdriver to call it over and over.

 browser.wait(() => element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');

Works exactly as you expect.

The two statements are not equivalent as such. I created a simple page like below

<html>
    <body>
        <div id="first_name">Tarun</div>
        <script type="text/javascript">
            var div = document.createElement('div');
            div.innerText = 'lalwani';
            div.id = 'last_name';
            setTimeout( () => document.body.appendChild(div),  3000);
        </script>
    </body>
</html>

And a simple test like below

describe('angularjs homepage todo list', function() {
    it('should add a todo', async function() {
        browser.waitForAngularEnabled(false);

        browser.get('http://0.0.0.0:8000');

        const eC = protractor.ExpectedConditions;

        browser.wait(element(by.id('last_name')).isPresent(), 10000, 'timeout');
    });
});

When you run you will find the output is

Started
...
1 spec, 0 failures
Finished in 0.617 seconds

Now if you change the code to

describe('angularjs homepage todo list', function() {
    it('should add a todo', async function() {
        browser.waitForAngularEnabled(false);

        browser.get('http://0.0.0.0:8000');

        const eC = protractor.ExpectedConditions;

        browser.wait(eC.visibilityOf(element(by.id('last_name'))), 10000, 'timeout');

    });
});

The output of the same is below

Started
...
1 spec, 0 failures
Finished in 3.398 seconds

As you can see the visibilityOf actually waited for the object to appear while the previous one didn't.

This is because the controlFlow will make isPresent get executed and return the promise returning value of true/false to the wait. While visibilityOf will return a function that the wait can check by calling again and again.

You can verify this by adding below in the test

console.log(typeof eC.visibilityOf(element(by.id('last_name'))))
console.log(typeof element(by.id('last_name')))

The output of same is

function
object

So the assumption your below two statements are same is wrong and that is why you don't get the correct results with the first one

browser.wait(element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');
browser.wait(eC.visibilityOf(element(by.tagName('myComponent'))), 10000, 'timeout');
发布评论

评论列表(0)

  1. 暂无评论