量角器browser.wait不能在Angular上使用element(by())

时间:2018-03-14 11:09:08

标签: javascript angular webdriver protractor

这个代码失败的原因是什么(找不到元素)......

  $user_profile=collect(UserProfileItem::where('type', "age_group")->get()->toArray())->groupBy("age_group");

...这段代码有效吗?

 [
        'account-x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'account-x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]

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

可能是相关的:我也可能问过为什么我需要添加 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(); 应该由Protractor自动添加到ControlFlow中,但是那里已经有很多相关问题(hereheretherethere,...),遗憾的是没有明确答案。

2 个答案:

答案 0 :(得分: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实际上等待对象出现而前一个对象没有出现。

这是因为controlFlow将使isPresent执行并将promise返回值true或false返回到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');

答案 1 :(得分:4)

两者之间存在明显的差异。但是网络驱动程序docs对此很清楚。

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

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

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

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

完全按照您的预期工作。