Транспарант проверяет непостоянство прохождения/неудачи для приложения 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