量角器没有找到元素

时间:2015-08-11 05:30:34

标签: angularjs protractor

在测试我的角度应用程序时,我无法让量角器按预期运行。我的spec文件如下所示:

describe('app login', function() {
   it('should allow admin user to log in', function() {
       browser.get('http://localhost:3008');

    //we can find the log in link
    expect(element(by.id('login-link')).getText()).toContain('Log in');

    //open login dialog
    element(by.id('login-link')).click();
    browser.ignoreSynchronization = true;
    browser.sleep(1000);

    //enter credentials
    element(by.id('login-username')).sendKeys('User1');
    element(by.id('login-password')).sendKeys('Password1');
    browser.sleep(1000);

    //log in
    var el = element(by.id('login-btn'));
    //WORKS IF BELOW LINE IS COMMENTED OUT 
    el.click();
    browser.sleep(1000);

    //display confirms login
    expect(element(by.id('user-display')).getText()).toContain('User1');

  });
});

请注意,我在开始时遇到同步错误,这就是我将ignoreSynchronization标志设置为true以及所有browser.sleeps的原因。

现在问题是:如果删除el.click()语句(以及最终期望调用),测试将会很好。但是,一旦包含该行,我就会得到 NoSuchElementError:找不到使用locator找到的元素:By.id(" login-username")。请注意,此元素不是我实际上想要点击的元素,这是奇怪的一部分。

4 个答案:

答案 0 :(得分:0)

您必须等到元素完全显示后才能使用:

browser.driver.wait(function() {
            return element(by.css(YourElement'/login-username)).isDisplayed().then(function(IsVisible) {
                return IsVisible;
            });
        }, 10000);

browser.driver.wait(function() {
            return element(by.css(YourElement'/login-username)).isPresent().then(function(IsVisible) {
                return IsVisible;
            });
        }, 10000);

或者您想通过键入以下内容来验证使用过的选择器是否正确,方法是输入:document.querySelector('您的CSS选择器')。

答案 1 :(得分:0)

您可以尝试以下操作:

    let EC: any = protractor.ExpectedConditions;
    return browser.wait(EC.visibilityOf($('#login-username')), 6000);

我在测试我的登录页面时遇到了同样的问题,其中量角器在渲染之前搜索元素。使用量角器的预期条件告诉框架在继续之前等待元素发生特定条件(当然是超时限制)。

答案 2 :(得分:0)

如果您的错误可能与测试窗口的显示大小相关联,您可能希望在启动测试时最大限度地提高驾驶员的可见性。

为此,您可以在protractor.conf.js文件中包含以下代码行:

onPrepare() {
    browser.driver.manage().window().maximize();
}

答案 3 :(得分:0)

首先让我将您的问题分为三部分。 让我们一次迈出一步:
1) ignoreSynchronization flag set to true :它指示量角器不要等待Angular承诺。当您i)测试围绕$ http或$ timeout解决ii)针对非角度站点的测试时,使用此方法。这些时候应该将ignoreSynchronization设置设置为true。问问自己,测试先决条件是否需要?通过上面的解释,我相信您可以将其设置为false并继续安全地进行测试。通过在不需要时将其设置为true,可以指示量角器在执行操作之前不要尝试与页面同步。这可能是有害的,因为量角器不会等到$ timeouts和$ http调用处理完毕后才出现,这可能导致测试变得不稳定。有关更多信息:https://github.com/angular/protractor/blob/9891d430aff477c5feb80ae01b48356866820132/lib/protractor.js#L158


将此标志设置为False后,就可以删除不必要的browser.sleep()。

2) Protractor not finding element :量角器未检测到元素的原因有多种:
-元素不适合显示窗口。
-元素不可见,但存在。
-异步任务未正确处理。
-另一个元素覆盖在另一个元素上

我建议您尝试: 1)使用promise,async / await或回调处理所有异步事件。

describe('app login', function() {
it('should allow admin user to log in', async() => {
   await browser.get('http://localhost:3008');

//we can find the log in link
expect(await element(by.id('login-link')).getText()).toContain('Log in');

//open login dialog
await element(by.id('login-link')).click();
//try putting this setting in your protractor.conf file instead of describe 
//block
//browser.ignoreSynchronization = false;

//enter credentials
await element(by.id('login-username')).sendKeys('User1');
await element(by.id('login-password')).sendKeys('Password1');

//log in
var el = element(by.id('login-btn'));
//WORKS IF BELOW LINE IS COMMENTED OUT 
await el.click();

//display confirms login
expect(await element(by.id('user-display')).getText()).toContain('User1');

}); });

有关如何更改代码的更多信息:https://jasmine.github.io/tutorials/async



3)过度使用browser.sleep(1000); :在您的代码中,使用sleep()使其易碎,并且如果系统运行速度低于系统运行速度有时会失败正常。通常在不可重现的情况下,这使测试失败易如反掌。因此,除非您想花费时间进行徒劳的调试,否则请停止使用它。

请改为使用以下等待策略:显式等待,waitforAngular;以确保您的异步事件已完成,然后再进行下一步。如果您需要更多有关此的信息,请在下面留下评论,否则,我将严格按照您所提出的问题保留此答案。 问吧!