Как я могу подождать условия? - программирование
Подтвердить что ты не робот

Как я могу подождать условия?

Я новичок в транспортире, и я пытаюсь выполнить тест 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, прежде чем транспортир попытается щелкнуть по нему?

4b9b3361

Ответ 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.

Ответ 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
);

}