Асинхронная / ожидающая логика в тестах транспортира не обнаруживает элемент страницы - PullRequest
0 голосов
/ 11 января 2019

Я новичок в написании тестов e2e в транспортире. Я начал использовать async await в тестах транспортира и добавил также ожидание браузера. Ниже мой код. Проблема menuBtn никогда не найдена транспортиром и время ожидания истекло. Я пытался использовать ожидаемые условия видимости и присутствия. но они все висят там и никогда не решаются. Я думал, что я даю неправильный локатор. Однако при использовании $ x ('xPath в строке 3') он обнаруживает его на веб-странице. Может ли кто-нибудь, пожалуйста, помочь в этом.

async menuNav(title, pageElement) {
    browser.sleep(3000);
    // browser.waitForAngular();
    const menuBtn = element(by.xpath('.//mat-icon[@id="' + pageElement + '"]'));

    console.log('menu btn: ', menuBtn.locator());
    await browser.wait(() => {
        return browser.isElementPresent(menuBtn);
    }, 3000);

    await menuBtn[0].click();
    const  menuTitle = element(by.xpath('.//*[contains(text(),\''  + title + '\')]'));
    browser.sleep(3000);
    menuTitle.isPresent().then(result => {
        expect(result).toBe(true);
        console.log('inside is present');
        console.log(title);
    });

}

Вот так выглядит HTML

<div *ngFor="let item of items"
    class="item"
    placement="right"
    container="body"
    containerClass="sidebar-tooltip">

    <mat-icon class="icon" [id]="item.id" [svgIcon]="item.icon"></mat-icon>
  </div>

Основываясь на комментариях @Gunderson и @SimonN, я добавил await перед локаторами элементов. Но я подумал, что это просто определения, так как я не использую локаторы транспортира, такие как findByElement. Однако я изменил код, и он по-прежнему блокируется в menuBtn.click, и теперь мой код:

async menuNav(title, pageElement) {
    browser.sleep(3000)
    const menuBtn = await element(by.xpath('.//mat-icon[@id="' + pageElement + '"]'));

    browser.wait(() => {
        return browser.isElementPresent(menuBtn);
    }, 3000);

    return menuBtn.isPresent().then(elementAvailable =>  {
        browser.wait(this.EC.elementToBeClickable(menuBtn), 3000).then(async () => {
            await menuBtn.click();
            const menuTitle = await element(by.xpath('.//*[contains(text(),\''  + title + '")]'));
            return browser.wait(this.EC.presenceOf(menuTitle), 3000).then(() => {
                return true;
            });
        });
    }).catch(error => {
        console.log('error: ', error);
    });

}

Ответы [ 2 ]

0 голосов
/ 11 января 2019

@ yong прав в своих комментариях, вы пропускаете await в разных местах. Он должен быть перед всеми функциями транспортира, включая локаторы. Тебе не нужно спать, но я пока оставлю их там:

async menuNav(title, pageElement) {
    await browser.sleep(3000);  <-- missed await here
    const menuBtn = await element(by.xpath('.//mat-icon[@id="' + pageElement + '"]')); <-- missed await here

    await menuBtn[0].click(); <-- this isn't an ElementArray, so not sure why [0] is there
    const  menuTitle = await element(by.xpath('.//*[contains(text(),\''  + title + '\')]')); <-- missed await here
    await browser.sleep(3000); <-- missed await here
    // no need to use .then() here either
    expect(await menuTitle.isPresent()).toBe(true);
}
0 голосов
/ 11 января 2019

Я думаю, что использование цепочек async / await и обещаний на самом деле не слишком хорошо работает вместе, так что это может вызвать у вас несколько проблем (хотя это и не та проблема, с которой вы столкнулись. Вот что я бы попытался решить вашу проблему. Попробуйте это:

    async menuNav(title, pageElement) {
const menuBtn = element(by.xpath('.//mat-icon[@id="' + pageElement + '"]'));
console.log('menu btn: ', menuBtn.locator());

await menuBtn.click();
const  menuTitle = element(by.xpath('.//*[contains(text(),\''  + title + '\')]'));
browser.sleep(3000);
menuTitle.isPresent().then(result => {
    expect(result).toBe(true);
    console.log('inside is present');
    console.log(title);
});

}

Если есть несколько элементов с идентификатором item.id, я бы сделал это:

    async menuNav(title, pageElement) {
const menuBtn = element.all(by.xpath('.//mat-icon[@id="' + pageElement + '"]'));
console.log('menu btn: ', menuBtn.locator());

await menuBtn[0].click();
const  menuTitle = element(by.xpath('.//*[contains(text(),\''  + title + '\')]'));
browser.sleep(3000);
menuTitle.isPresent().then(result => {
    expect(result).toBe(true);
    console.log('inside is present');
    console.log(title);
});
...