繁体   English   中英

量角器browser.wait不适用于Angular上的element(by())

[英]Protractor browser.wait doesn't work with element(by()) on Angular

出于什么原因,此代码可能失败( 未找到任何元素 )......

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

...这段代码有效吗?

   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();

我正在使用Angular 5.2.5,Protractor 5.3.0和Jasmine 2.8.0。

可能是相关的 :我也可以问为什么我需要添加一个browser.wait()element(by())应该由Protractor自动添加到ControlFlow中,但是已经有很多相关的问题( 这里在这里 ,...),没有明确的答案很遗憾。

这两个陈述不等同于此。 我创建了一个简单的页面,如下所示

<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>

以及如下的简单测试

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');
    });
});

当你运行时,你会发现输出是

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

现在,如果您将代码更改为

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');

    });
});

它的输出如下

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

正如您所看到的, visibilityOf实际上等待对象出现而前一个对象没有出现。

这是因为controlFlow将使isPresent得到执行,并将返回值true或false的promise返回给wait。 虽然visibilityOf将返回一个wait可以通过反复调用来检查的函数。

您可以通过在测试中添加以下内容来验证这一点

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

它的输出是

function
object

因此,下面两个语句相同的假设是错误的,这就是为什么你没有得到第一个正确的结果

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

两者之间存在着不那么明显的区别。 但是webdriver 文档对此很清楚。

eC.visibilityOf(...) - 返回一个函数 browser.wait()重复计算函数,直到它们返回true。

isPresent() - 返回一个promise browser.wait()没有/不能重复评估promises(!),当promise解析时,browser.wait()将立即继续,无论它是返回true还是false。

如果要使用isPresent(),可以将其包装在函数中 这允许webdriver一遍又一遍地调用它。

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

完全按照您的预期工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM