Транспарант проверяет непостоянство прохождения/неудачи для приложения AngularJS

Тесты My Protractor e2e несовместимы и не проходят.

Кажется, это может быть связано с асинхронным javascript, как описано здесь: Транспортир: как дождаться завершения страницы после нажатия кнопки?.

Однако здесь он упомянул, что тесты Protractor автоматически выполняются последовательно/синхронно: https://github.com/angular/protractor/issues/909

Мой тест script:

describe('Login', function() {

  var ptor;

  beforeEach(function() {
    browser.get('https://127.0.0.1:8443');
    ptor = protractor.getInstance();
    element(by.id('splash')).click();
    browser.ignoreSynchronization = true;  // <-- to proceed beyond splash screen
  });

  describe('with correct email and password', function() {

    beforeEach(function() {
        element(by.id('email')).sendKeys('[email protected]');
        element(by.id('password')).sendKeys('adminpassword');
        element(by.id('loginButton')).click();
    });

    afterEach(function() {
        ptor.findElement(by.id('logout')).then(function(elem) {
            elem.click();
        });
    });

    it('does not show alert', function() {  // <-- sometimes passes, sometimes fails
        expect(browser.isElementPresent(by.css('.alert-danger'))).toBe(false);
    });

    it('changes route to /admin', function() {  // <-- sometimes passes, sometimes fails
        expect(browser.getCurrentUrl()).toMatch(/\/admin/);
    });
  });
});

В двух тестах выше, либо оба теста пройдут, либо один/оба теста не сработают с этими сообщениями:

Failures:

1) Login with correct email and password does not show alert
Message:
  NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...

или

Failures:

1) Login with correct email and password changes route to /admin
Message:
  NoSuchElementError: no such element
...
==== async task ====
WebDriver.findElement(By.id("logout"))
...

Мысли/помощь очень ценятся.

Ответы

Ответ 1

Мне удалось решить проблему на основе следующего:

Как упоминалось в комментарии Nguyen Vu Hoang к исходному вопросу, я тестирую чистое приложение Angular с тем, что, на мой взгляд, является чистым Транспортером (нет вызовов веб-администратора), Я знаю, что ptor.ignoreSynchronization = true в этом случае не требуется, но по какой-то причине тесты не будут выполняться при нажатии кнопки без этой настройки.

Моя новая спецификация:

describe('Login', function() {

  var ptor;

  beforeEach(function() {
    ptor = protractor.getInstance();
    ptor.ignoreSynchronization = true;
    ptor.waitForAngular();
    ptor.get('https://127.0.0.1:8443');
    ptor.findElement(by.id('splash')).then(function(elem) {
        elem.click();
    });
  });

  describe('with correct email and password', function() {

    beforeEach(function() {
        ptor.findElement(by.id('email')).then(function(elem) {
            elem.sendKeys('[email protected]');
        });

        ptor.findElement(by.id('password')).then(function(elem) {
            elem.sendKeys('adminpassword');
        });

        ptor.findElement(by.id('loginButton')).then(function(elem) {
            elem.click();
        });
    });

    afterEach(function() {
        ptor.findElement(by.id('logout')).then(function(elem) {
            elem.click();
        });
    });

    it('does not show alert', function() {
        expect(ptor.isElementPresent(by.css('.alert-danger'))).toBe(false);
    });

    it('changes route to /admin', function() {
        expect(ptor.getCurrentUrl()).toMatch(/\/admin/);
    });
  });
});

Ответ 2

Существует еще один способ сделать ваши тесты более стабильными: Явные ожидания и ожидаемые условия docs).

Я нашел использование ожидаемых условий особенно полезными при тестировании с не-w500 > страницами или angular приложениями, в которых задействовано много анимаций.

Например, вы можете дождаться щелчка элемента перед кликом:

var EC = protractor.ExpectedConditions;
var link = element(by.id("mylink"));

browser.wait(EC.elementToBeClickable(link), "10000", "The link is still not clickable");
link.click();

Существуют также другие встроенные ожидаемые условия, такие как:

  • presenseOf()
  • visibilityOf()
  • alertIsPresent()
  • textToBePresentInElementValue()
  • и т.д.

И, легко написать пользовательское ожидаемое условие, пример использования:

Вы также можете объединить ожидаемые условия с помощью and, or и not, например:

var urlChanged = function() {
  return browser.getCurrentUrl().then(function(url) {
    return url != 'http://www.angularjs.org';
  });
};

// condition to wait for url to change, title to contain 'foo', and $('abc') element to contain text 'bar'
var condition = EC.and(urlChanged, EC.titleContains('foo'), EC.textToBePresentInElement($('abc'), 'bar'));
$('navButton').click();
browser.wait(condition, 5000); //wait for condition to be true.

Ответ 3

browser.ignoreSynchronization = true; имеет глобальный эффект для всех ваших тестов. вам может потребоваться вернуть значение false, поэтому транспортир ждет завершения angular отображения страницы. например в или перед вашей второй функцией beforeEach