[英]Protractor browser.wait doesn't work with element(by()) on Angular
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. 我正在使用Angular 5.2.5,Protractor 5.3.0和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. 可能是相关的 :我也可以问为什么我需要添加一个
browser.wait()
而element(by())
应该由Protractor自动添加到ControlFlow中,但是已经有很多相关的问题( 这里 , 在这里 , 有 , 有 ,...),没有明确的答案很遗憾。
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. 正如您所看到的,
visibilityOf
实际上等待对象出现而前一个对象没有出现。
This is because the controlFlow will make isPresent
get executed and return the promise returning value of true/false to the wait. 这是因为controlFlow将使
isPresent
得到执行,并将返回值true或false的promise返回给wait。 While visibilityOf
will return a function that the wait
can check by calling again and again. 虽然
visibilityOf
将返回一个wait
可以通过反复调用来检查的函数。
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');
There is a not-so obvious difference between the two . 两者之间存在着不那么明显的区别。 But the webdriver docs are clear about this.
但是webdriver 文档对此很清楚。
eC.visibilityOf(...)
- Returns a function . eC.visibilityOf(...)
- 返回一个函数 。 browser.wait() repeatedly evaluates functions until they return true. browser.wait()重复计算函数,直到它们返回true。
isPresent()
- Returns a promise . isPresent()
- 返回一个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. browser.wait()没有/不能重复评估promises(!),当promise解析时,browser.wait()将立即继续,无论它是返回true还是false。
If you want to use isPresent() you can wrap it in a function . 如果要使用isPresent(),可以将其包装在函数中 。 This allows webdriver to call it over and over.
这允许webdriver一遍又一遍地调用它。
browser.wait(() => element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');
Works exactly as you expect. 完全按照您的预期工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.