Protractor浏览器等待在Angular中不适用于element(by())。

4
这段代码为什么会失败(未找到元素)的原因是什么?
   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中自动添加,但已经有很多相关的问题(这里那里相关问题...),不幸的是没有明确的答案。

2个回答

6

这两者之间有一个不太明显的区别。但是webdriver 文档对此非常清楚。

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

isPresent() - 返回一个Promise。browser.wait()不会/不能重复评估Promises(!)。browser.wait()将在Promise解析后立即继续,而不管其返回true还是false。

如果您想使用isPresent(),可以将其包装在函数中。这使webdriver可以反复调用它。

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

完全按照您的期望工作。


4
这两个语句并不完全等价。我创建了一个类似以下的简单页面。
<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 实际上等待对象出现,而之前的方法没有。

这是因为控制流会使 isPresent 被执行并返回 true/false 的 Promise 返回值给等待命令。而 visibilityOf 会返回一个函数,等待命令可以通过反复调用该函数来检查。

您可以通过在测试中添加以下内容进行验证。

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

same的输出结果为:
function
object

所以你以下两个语句相同的假设是错误的,这就是为什么你用第一个语句得不到正确结果的原因。
browser.wait(element(by.tagName('myComponent')).isPresent(), 10000, 'timeout');
browser.wait(eC.visibilityOf(element(by.tagName('myComponent'))), 10000, 'timeout');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接