【问题标题】:Protractor not finding element量角器找不到元素
【发布时间】:2015-11-03 05:05:35
【问题描述】:

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

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: No element found using locator: By.id("login-username")。请注意,这个元素 不是 我实际上试图点击的那个元素,这是奇怪的一部分。

【问题讨论】:

  • 你能展示你的html吗?
  • 为什么需要将ignoreSynchronization设置为true?你如何引导角度以及ng-app 的定义位置?谢谢
  • @alecxe:我还没弄清楚为什么我需要 ignoreSynchronization!否则它永远不会同步。我知道这可能与 http 调用(没有任何调用)或 $timeout 有关。我也无法追踪其中任何一个,但我不太确定,因为除了检查代码库之外,我不知道有任何方法可以找到它。 ng-app 是在 html 元素上定义的。

标签: angularjs protractor


【解决方案1】:

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


一旦将此标志设置为False,您就可以取消不必要的 browser.sleep()。

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

我建议你试试:

  1. 使用承诺、异步/等待或回调处理所有异步事件。
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;在进行下一步之前确保您的异步事件已完成。如果您需要对此了解更多信息,请在下面发表评论,否则我将严格按照您提出的问题回答。 问吧!

【讨论】:

    【解决方案2】:

    你必须等到你的元素完全出现,使用:

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

    或者您想验证使用的选择器是否正确,方法是使用 GoogleChrome 控制台键入:document.querySelector('Your CSS Selector')。

    【讨论】:

      【解决方案3】:

      您可以尝试以下方法:

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

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

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-09-08
          • 1970-01-01
          • 1970-01-01
          • 2022-01-18
          • 1970-01-01
          • 2019-05-28
          相关资源
          最近更新 更多