Protractor - ScriptTimeoutError: тайм-аут асинхронного скрипта: результат не был получен в течение 20 секунд

Я новичок в Protractor и пытаюсь запустить свой сценарий.

describe('Navigator homepage', function() {
it('should proceed to login', function() {
browser.get('url');
})
it('Clicks the proceed button',function() {
const proceedButton = element(by.id('auth-login-page-button'));

proceedButton.click();
});
});

Но всякий раз, когда я запускаю его, браузер открывается и переходит на веб-сайт, а затем ждет 20 секунд, и я получаю сообщение об ошибке: ScriptTimeoutError: asynchronous script timeout: result was not received in 20 seconds. Элемент явно присутствует, и его можно щелкнуть, но не транспортиром. Я делаю что-то неправильно? Файл конфигурации выглядит так:

// An example configuration file.
exports.config = {
  directConnect: true,

  // Capabilities to be passed to the webdriver instance.
  capabilities: {
    'browserName': 'chrome'
  },

  // Framework to use. Jasmine is recommended.
  framework: 'jasmine',

  // Spec patterns are relative to the current working directory when
  // protractor is called.
  specs: ['login_spec.js'],

  allScriptsTimeout: 20000,
  getPageTimeout: 15000,
  framework: 'jasmine',
  jasmineNodeOpts: {
    isVerbose: false,
    showColors: true,
    includeStackTrace: false,
    defaultTimeoutInterval: 40000
  }
  };

person Mateusz    schedule 02.10.2017    source источник


Ответы (2)


Учитывая ваше добавленное сообщение об ошибке (см. Комментарий), причиной кажется непрерывный опрос $timeout, который позволяет обещанию не выполняться в течение неопределенного времени и, следовательно, приводит к асинхронному таймауту транспортира (подробности здесь).

решение

Правильное решение - избегать использования $timeout и использовать вместо него $interval. Таким образом, транспортир может оставаться ответственным за ControlFlow, управляя вашими асинхронными задачами. Так что это своего рода программная ошибка, а не ошибка транспортира.

ваше сообщение об ошибке:

Failed: Timed out waiting for asynchronous Angular tasks to finish after 20 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeo‌​uts.md#waiting-for-a‌​ngular While waiting for element with locator - Locator: By(css selector, md-raised md-primary md-button md-ink-ripple). *The following tasks were pending: - $timeout: function (){return _this.getVersion()}*

Временное решение

Не очень приятный обходной путь - отключить часть waitForAngular в Protractor, установив browser.waitForAngularEnabled(false); (либо в beforeEach, либо непосредственно в spec.

Однако это также означает, что нужно вручную позаботиться о controlFlow в рамках самих тестовых спецификаций. Это требует использования большого количества .then() и ExpectedConditions, теряя одно из основных преимуществ транспортира.

Возможности отладки

Проверьте описания здесь для потенциальных причины и обходные пути. В частности, попробуйте также browser.waitForAngularEnabled(false); исключить проблемы с угловым транспортиром.

Если вы не можете найти причину, это может быть проблема со сроками (маловероятно, но на этом этапе стоит изучить).

Вы можете попробовать добавить сообщения журнала, чтобы сузить эффективный порядок выполнения:

describe('Navigator homepage', function() {
    it('should proceed to login', function() {
    browser.get('url').then(function(){
        console.log("Page is fully loaded");
        });
    });
    it('Clicks the proceed button',function() {
        console.log("Start 2nd Test");
        const proceedButton = element(by.id('auth-login-page-button'));
        proceedButton.click();
    });
});

Или вы помещаете действия в один и тот же тестовый пример, используя then() для их синхронного выполнения:

describe('Navigator homepage', function() {
    it('should proceed to login', function() {
    browser.get('url').then(function(){
        const proceedButton = element(by.id('auth-login-page-button'));
        proceedButton.click();
    });
});

Открыть главную страницу в onPrepare

Одно приятное замечание: если вы всегда сначала загружаете домашнюю страницу, просто поместите ее в onPrepare-часть вашего conf.js, и она всегда будет выполняться один раз перед запуском ваших тестов:

onPrepare: function () {
    browser.driver.manage().window().maximize();
    browser.get('url');
},
person Ernst Zwingli    schedule 02.10.2017
comment
Спасибо, попробовал все эти варианты, когда я вставляю waitForAngular = false, появляется ошибка Failed: Timed out waiting for asynchronous Angular tasks to finish after 20 seconds. This may be because the current page is not an Angular application. Please see the FAQ for more details: https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular While waiting for element with locator - Locator: By(css selector, md-raised md-primary md-button md-ink-ripple). The following tasks were pending: - $timeout: function (){return _this.getVersion()} - person Mateusz; 03.10.2017
comment
Похоже, ваш ответ содержится в сообщении об ошибке: The following tasks were pending: - $timeout: function (){return _this.getVersion()} Итак, установлен тайм-аут $, который не разрешен. Дополнительные сведения см. Здесь: github.com/angular/protractor/issues/169 и здесь: github.com/angular/protractor/blob/master/docs/ Не могли бы вы (или ваш разработчик) заменить $timeout на $interval на странице, которую вы тестируете ... или, может быть, просто позаботитесь о том, чтобы this.getVersion() в конечном итоге разрешился? - person Ernst Zwingli; 03.10.2017
comment
ой ... Я видел, что вводил ошибку для waitForAngular. Правильный синтаксис для этого: browser.waitForAngularEnabled(false); Я отредактирую свой ответ для этого. - person Ernst Zwingli; 03.10.2017
comment
Изменен на browser.waitForAngularEnabled(false);, и теперь я получаю Failed: No element found using locator: By(css selector, *[id="auth-login-page-button"]) до полной загрузки веб-страницы. - person Mateusz; 03.10.2017
comment
Да, когда вы устанавливаете browser.waitForAngularEnabled(false);, вы теряете одно из основных преимуществ Protractor: теперь вам нужно самостоятельно управлять своим controlFlow, поскольку Protractor не ждет выполнения обещаний Angular. Если вы выберете browser.get('url').then(function(){ const proceedButton = element(by.id('auth-login-page-button')); proceedButton.click(); });, он будет работать в вашем случае. Но вам нужно знать, как использовать .then() и ExpectedConditions, если вам нужно продолжить с browser.waitForAngularEnabled(false);. Лучше всего заменить $timeout вашими разработчиками - person Ernst Zwingli; 03.10.2017
comment
Хорошо спасибо. Попросит их сделать это. Спасибо за помощь. - person Mateusz; 03.10.2017
comment
Я отредактировал свой ответ, чтобы дополнить его нашими выводами и решением. Будьте любезны и отметьте это как правильный ответ (если считаете, что он правильный). - person Ernst Zwingli; 03.10.2017

У меня была аналогичная проблема, я решил ее включив игнорировать синхронизацию

browser.ignoreSynchronization = true
person Beyar    schedule 21.01.2019
comment
Это устранило проблему для меня! - person Maximilian; 01.02.2019
comment
классно! Через 3 дня попытки разных решений это сработало. Публикация моего onPrepare в conf.ts здесь: onPrepare: () = ›{let globals = require ('protractor'); пусть браузер = globals.browser; browser.manage (). Window (). maximize (); browser.manage (). timeouts (). implicitlyWait (10000); browser.ignoreSynchronization = true; } - person Bruno Carvalho; 04.05.2019