量角器测试中的异步/等待逻辑未检测到页面元素

时间:2019-01-11 00:42:18

标签: angular selenium jasmine protractor e2e-testing

我不熟悉在量角器中编写e2e测试。 我开始在量角器测试中使用异步等待,并且还添加了浏览器等待。下面是我的代码。 量角器从未发现menuBtn问题,并且超时。我尝试使用visilityOf和presentOfOf的ExpectedCOnditions。但他们都死在那里,从未解决。 我以为我给出了错误的定位器。但是,当使用$ x('xPath on line 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 :(得分:2)

@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);
}

答案 1 :(得分:0)

我认为使用async / await和promise链不能很好地协同工作,因此可能会引起一些问题(尽管不是您要面对的确切问题。这是我将尝试解决的问题。尝试这个:

    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);
});

}

如果有多个id为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);
});