Как я могу подождать условия?
Я новичок в транспортире, и я пытаюсь выполнить тест e2e.
Я не знаю, правильно ли это сделать, но...
Страница, которую я хочу проверить, не является полной страницей angular, поэтому... У меня проблемы.
В моей первой спецификации я:
describe('should open contact page', function() {
var ptor = protractor.getInstance();
beforeEach(function(){
var Login = require('./util/Login');
new Login(ptor);
});
Я создал этот класс Login, но после входа в систему я хочу открыть страницу контакта, но транспортир немедленно попытается найти элемент до того, как страница будет полностью загружена.
Я пытался использовать:
browser.driver.wait(function() {
expect(browser.findElement(by.xpath("//a[@href='#/contacts']")).isDisplayed());
ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});
Но он не работает... он всегда пытается найти элемент до загрузки страницы.
Я тоже пробовал:
browser.driver.wait(function() {
expect(ptor.isElementPresent(by.xpath("//a[@href='#/contacts']")));
ptor.findElement(by.xpath("//a[@href='#/contacts']")).click();
});
Я могу сделать это с помощью browser.sleep();
, но я не думаю, что это хороший вариант. Есть идеи? В моем классе входа у меня есть:
ptor.ignoreSynchronization = true;
Как я могу ждать этого @href='#/contacts
, прежде чем транспортир попытается щелкнуть по нему?
Ответы
Ответ 1
У меня была та же самая проблема, с которой вы сталкивались в течение длительного времени при использовании транспортира. В моем тестировании e2e я запускаю приложение angular, а затем перейду в часть angular, а затем вернусь к части angular. Сделал все сложно. Ключ должен понимать promises и как они работают. Вот некоторые примеры моего кода реального мира в действующем тесте e2e. Надеясь, что это дает вам представление о том, как структурировать ваши тесты. Вероятно, некоторые плохие практики в этом коде, пожалуйста, не стесняйтесь улучшать это, но я знаю, что это работает, может быть, не лучший способ.
Чтобы перейти к angular, я использую
var ptor;
var events = require('events');
var eventEmitter = new events.EventEmitter();
var secondClick = require('./second-click');
beforeEach(function () {
browser.driver.get('http://localhost:8080/');
},10000);
it("should start the test", function () {
describe("starting", function () {
it("should find the link and start the test", function(){
var elementToFind = by.linkText('Start'); //what element we are looking for
browser.driver.isElementPresent(elementToFind).then(function(isPresent){
expect(isPresent).toBe(true); //the test, kind of redundant but it helps pass or fail
browser.driver.findElement(elementToFind).then(function(start){
start.click().then(function(){ //once we've found the element and its on the page click it!! :)
ptor = protractor.getInstance(); //pass down protractor and the events to other files so we can emit events
secondClick(eventEmitter, ptor); //this is your callback to keep going on to other actions or test in another file
});
});
});
});
});
},60000);
В angular этот код работает
describe("type in a message ", function(){
it("should find and type in a random message", function(){
var elementToFind = by.css('form textarea.limited');
browser.driver.isElementPresent(elementToFind).then(function(isPresent){
element(elementToFind).sendKeys(randomSentence).then(function(){
console.log("typed in random message");
continueOn();
});
});
});
},15000);
После выхода из angular
browser.driver.wait(function(){
console.log("polling for a firstName to appear");
return browser.driver.isElementPresent(by.name('firstName')).then(function(el){
return el === true;
});
}).
then(function(){
somefunctionToExecute()
});
Надеюсь, что дает некоторые рекомендации и поможет вам!
Ответ 2
Транспортир 1.7.0
также представил новую функцию: ожидаемые условия.
Есть несколько предопределенных условий для явного ожидания. Если вы хотите дождаться появления элемента:
var EC = protractor.ExpectedConditions;
var e = element(by.id('xyz'));
browser.wait(EC.presenceOf(e), 10000);
expect(e.isPresent()).toBeTruthy();
Смотрите также:
Ответ 3
Наконец-то узнаю...
var waitLoading = by.css('#loading.loader-state-hidden');
browser.wait(function() {
return ptor.isElementPresent(waitLoading);
}, 8000);
expect(ptor.isElementPresent(waitLoading)).toBeTruthy();
var openContact = by.xpath("//a[@href='#/contacts']");
element(openContact).click();
С помощью этого транспортира можно дождаться этого элемента, пока страница загрузки не исчезнет.
Спасибо за тех, кто пытался помочь XD.
Ответ 4
browser.driver.wait(function() {
return browser.driver.isElementPresent(by.xpath("//a[@href='#/contacts']"));
});
Это работает и для меня (без параметра таймаута).
для получения дополнительной информации см. http://angular.github.io/protractor/#/api?view=webdriver.WebDriver.prototype.wait
Ответ 5
Благодаря вышеприведенным ответам это было мое упрощенное и обновленное использование
function waitFor (selector) {
return browser.wait(function () {
return browser.isElementPresent(by.css(selector));
}, 50000);
}
Ответ 6
Вы пытались поместить ng-app
в тег <html>
(если эта часть кода находится под вашим контролем)? Это решило множество проблем синхронизации инициализации для меня.
Ответ 7
Лучший способ использовать условия ожидания в транспортире, который помогает отображать правильное сообщение об ошибке для конкретного элемента в случае неудачного теста
const EC = ExpectedConditions;
const ele = element(by.xpath(your xpath));
return browser.wait(EC.visibilityOf(ele),9000,'element not found').then(() => {
ele.click();
});
Ответ 8
Я удивлен, что никто не добавил это решение. В основном, если вы используете модальные диалоги, вы часто получаете элемент видимым и доступным для щелчка, но не активируемым из-за модального диалога перед ним. Это происходит потому, что транспортир движется быстрее, чем угловой, и готов щелкнуть следующий элемент, пока угловой все еще закрывает модальное.
Я предлагаю использовать
public async clickElementBug(elementLocator: Locator) {
const elem = await element(elementLocator);
await browser.wait(
async function() {
try {
await elem.click();
return true;
} catch (error) {
return false;
}
},
this.TIMEOUT_MILLIS,
'Clicking of element failed: ' + elem
);
}