【问题标题】:Failed: Wait timed out after 30009ms失败:等待 30009 毫秒后超时
【发布时间】:2017-10-12 18:10:59
【问题描述】:

config.js

exports.config = {
framework: 'jasmine',
seleniumAddress: 'http://localhost:4444/wd/hub',

specs: [
    'Login.js',
    'FeatureList.js',
    'NewApplicationRegistration.js',
    'ApplicationRegistrationManagement.js',
    'RegistrationStatus.js',
],
baseUrl: 'http://localhost:3000',
multiCapabilities: [{
    'browserName': 'chrome'
},
    // {
    //     'browserName': 'firefox'
    // }, 
    // {
    //     'browserName': 'internet explorer'
    // }
],
jasmineNodeOpts: {
    onComplete: null,
    isVerbose: false,
    showColors: true,
    includeStackTrace: true,
    defaultTimeoutInterval: 3000000
},
allScriptsTimeout: 11000,
rootElement: 'html',
onPrepare: function () {
    browser.ignoreSynchronization = true;
    browser.driver.manage().window();
},
};

第一个规范文件

'use strict'

describe('Application Registration Page', function () {

beforeEach(function () {
    browser.waitForAngular();
    browser.get('/register');
});

// Login
it('Test for Login', function () {
    expect(element(by.xpath('/html/body/admin-app-root/layout/div[1]/div/ng-component/div/form/div/table/tbody/tr[1]/th/label')));
    var EC = protractor.ExpectedConditions;
    var username = element(by.id('login-username'));
    browser.wait(EC.visibilityOf(username), 30000);
    username.sendKeys('sss');

    expect(element(by.xpath('/html/body/admin-app-root/layout/div[1]/div/ng-component/div/form/div/table/tbody/tr[2]/th/label')));
    var EC = protractor.ExpectedConditions;
    var password = element(by.id('login-password'));
    browser.wait(EC.visibilityOf(password), 30000);
    password.sendKeys('sss');

    browser.driver.sleep(1000);

    element(by.xpath('/html/body/admin-app-root/layout/div[1]/div/ng-component/div/form/div/table/tbody/tr[3]/td/button')).click().then(function (username, password) {
        if (username, password) {
            browser.navigateTo('http://localhost:3000/register/core/feature-list');
        } else {
            expect(browser.isElementPresent(element(by.xpath('/html/body/admin-app-root/layout/div[1]/div/ng-component/div/form/div/table/tbody/tr[1]/td/b'))));
        }
    });
});
});

第二规范

'use strict'

describe('Welcome to feature list', function () {

beforeEach(function () {
    browser.waitForAngular();
    browser.get('/register/core/feature-list');
});


describe('Header', function () {

    // Application Registration text
    it('Test for Application Registration text', function () {
        var EC = protractor.ExpectedConditions;
        var ar = element(by.xpath('/html/body/admin-app-root/layout/div[1]/c-header/nav/div/div[1]/a[2]'));
        browser.wait(EC.presenceOf(ar), 2000000);
        expect(ar.getAttribute('value')).toEqual('Application Registration');
    });


    it('Test for user name', function () {
        var EC = protractor.ExpectedConditions;
        var username = element(by.xpath('//*[@id="cox-navbar"]/ul/li[1]/a'));
        browser.wait(EC.visibilityOf(username), 2000);
        expect(username.isPresent()).toBe(true);
    });     
});

第一个规范脚本运行良好,但在运行第二个规范时出现错误

2000000 毫秒后等待超时

即使脚本超时非常大,它也会出错。它无法在给定的时间从浏览器中找到元素。

帮我找到解决办法。

【问题讨论】:

  • 您是否尝试过为该元素使用其他选择器?使用那种 xpath 有点糟糕,也许尝试使用 css 类、名称或 id ?
  • @Hikaryu,你我已经尝试了所有的期望,但我得到了同样的错误。但是我看到一件事,在运行第二规范时它只显示第一规范页面,我不确定它是否正在加载第二规范 browser.get 页面。

标签: protractor


【解决方案1】:

@amit 尝试在 beforeEach 中使用 promise,如下所示:

beforeEach(function () {
    browser.waitForAngular().then(funtion(){
      return browser.get('/register/core/feature-list');
    }).then(function(){
       console.log(browser.getCurrentUrl()) // ensure you are on correct url 
    })
});

它应该可以工作。

【讨论】:

  • 有什么错误吗?因为没有它我无能为力。如果您复制粘贴,那么它可能不起作用,因为我只是为了一个想法而写它
  • 我编写了该代码并尝试过,但遇到了同样的错误。
【解决方案2】:

简而言之,您的答案是:让您的量角器在不使用ignoreSynchronization 的情况下工作,以避免此类问题。我将在下面详细说明您的问题,从您特别提出的问题开始。

第二个规范超时的原因

EC.presencesOf() 隐式调用 waitForAngular read more about it here

因为您有 ignoreSynchronization = true 您对 waitForAngular 的调用超时(因为您忽略了 AngularSynchronization 量角器无法识别对象的存在)。因为你间接调用它会超时。

如果你在不知道后果的情况下使用ignoreSynchronization,那是没有意义的。使用它的原因非常有限。

没有ignoreSynchronization的第一个规范的问题

鉴于您的 XPath 查询,在我看来您的 Angular-Root-Element 不是 body,而是 admin-app-root。因此尝试将config.ts 中的rootElement: body 更改为rootElement: admin-app-root。 (作为一个可能的根本原因,为什么你的量角器不能很好地与你正在测试的 Angular 页面一起工作)。

配置调整后:如果您仍然遇到超时或缺少可测试性,请进一步check this answer

还为您的ar-元素减少您的timeout 2000000。我认为,如此长的超时几乎没有意义,因为之前应用了许多其他超时(web-timeout、jasmine-timeout、进一步的 webdriver-timeouts 等)。

更多建议和信息

  1. global.EC = protractor.ExpectedConditions; 放入conf.jsonPrepare: 部分,因此您不必将其添加到每个测试用例中。
  2. 在您的onPrepare: 部分添加一个带有承诺的步骤,否则您的测试可能会提前开始(请参阅this documentationa simple example here
  3. 避免使用 XPath 选择器,因为它们速度慢且难以维护(任何添加的 div 或移动的表单...基本上任何 UI 设计修改都可能让您的测试失败)。请改用 Angular-Model 或 CSS-Selectors (learn about it here)。
  4. 作为browser.get() 命令不会创建承诺,您应该在beforeEach 部分中添加browser.waitForAngular(),以确保您的测试仅在页面完全加载后开始。
  5. 仅使用ignoreSynchronization,如果您知道您测试需要它的特定情况。例如,如果您在加载过程中明确尝试验证某些内容,那么在处理异步任务时(即测试阻塞元素的外观)。 Learn about the purpose of ignoreSynchronization here
  6. 如果您的量角器无法与您的 Angular-Page 或您测试非 Angular-Page 同步,请使用 browser.waitForAngularEnabled(false)。如果你处理一个Angular页面,首先尝试调试Protractor无法同步的原因。 Learn about these possibilities here

【讨论】:

  • 从测试用例中删除 browser.wait(presenceOf()/visibilityOf()) 后,我收到错误消息,提示找不到使用定位器的元素。
  • 我刚刚看到,您在 conf.js 中设置了 ignoreSynchronization = true。有什么具体原因吗?因为这基本上告诉量角器不要等到加载页面。将该变量设置为 true 有相当具体的原因。阅读有关here 的更多信息。我现在更新了我的答案。
  • 如果我在 browser.ignoreSynchronization = true;然后我收到第一个规范的错误,还说等待超时错误。
  • 这听起来比另一个错误更好。正如我已经在我编辑的答案中所写的那样,check this answer 以查看您在调试超时方面的可能性。它还解释了很多上下文。
  • 我的规范文件对吗?因为第一个规范在 browser.ignoreSynchronization = true 下运行良好;如果我评论 browser.ignoreSynchronization = true 行,那么它会抛出“无法找到元素的测试能力”,但无论同步是真还是假,第二规范无论如何都会抛出“等待超时错误”;
猜你喜欢
  • 2017-02-02
  • 2017-12-30
  • 2016-02-17
  • 2019-09-16
  • 2015-01-05
  • 1970-01-01
  • 2015-11-03
  • 2018-12-22
  • 1970-01-01
相关资源
最近更新 更多