当两个按钮之一被显示以单击它时,为两个按钮添加条件?

时间:2019-06-06 16:22:08

标签: javascript selenium protractor

我对if(.isDisplayed())else if(.isDisplayed())else条件有疑问。

isDisplayed()函数在这种情况下不起作用,即使powderRinseStartButton不在DOM中,它也总是在第一个if块进入。

if (powderRinseStartButton != null && powderRinseStartButton.isDisplayed() && powderRinseStartButton.ispresent()) {
  powderRinseStartButton.click();
} else if (brewerRinseStartButton != null && brewerRinseStartButton.isDisplayed() && brewerRinseStartButton.ispresent()) {
  brewerRinseStartButton.click();
} else {
  fn.click();
}

如果我输入第一段或第二段代码,效果很好

browser.wait(() => {
      return brewerRinseStartButton.isDisplayed().then(() => {
      browser.wait(EC.visibilityOf(brewerRinseStartButton), delay).then(() =>
      {
          browser.wait(EC.elementToBeClickable(brewerRinseStartButton), delay).then(() =>
          {
              expect(EC.elementToBeClickable(brewerRinseStartButton)).toBeTruthy();

                brewerRinseStartButton.click().then(() =>
                {
                   browser.wait(EC.visibilityOf(maintenanceText), 240000,
                                               'The Maintenance Text should be visible within 240s');
                   expect(maintenanceText.isDisplayed()).toBeTruthy();
               });
           });
       });
    });

  // return powderRinseStartButton.isDisplayed().then(() => 
  // {
  //     browser.wait(EC.visibilityOf(powderRinseStartButton), delay).then(() =>
  //     {
  //         browser.wait(EC.elementToBeClickable(powderRinseStartButton), delay).then(() =>
  //         {
  //             expect(EC.elementToBeClickable(powderRinseStartButton)).toBeTruthy();

  //              powderRinseStartButton.click().then(() =>
  //              {
  //                  browser.wait(EC.visibilityOf(maintenanceText), 240000,
  //                                              'The Maintenance Text should be visible within 240s');
  //                  expect(maintenanceText.isDisplayed()).toBeTruthy();
  //              });
  //          });
  //      });
  //  });

}, 5000)
  .then(() => {
    console.log('return true')
    return true;
  }, () => {
    console.log('false');
    browser.wait(EC.visibilityOf(fn), delay).then(() => {
      browser.wait(EC.elementToBeClickable(fn), delay).then(() => {
        expect(EC.elementToBeClickable(fn)).toBeTruthy();
        fn.click();
      });
    });
  });

如果要显示brewerRinseStartButton而不是单击brewerRinseStartButton,我想做一个条件,否则如果要显示powderRinseStartButton而不是单击powderRinseStartButton则可以。

我解决了这个问题。 isDisplayed() @返回 一个承诺,将通过此元素当前在页面上是否可见来解决。 等待所有诺言得到解决,或者等待任何诺言被拒绝。

       let failHandler = ()=>
        {
            browser.wait(EC.visibilityOf(fn), delay).then(() =>
            {
                browser.wait(EC.elementToBeClickable(fn), delay).then(() =>
                {
                    expect(fn.isDisplayed()).toBeTruthy();
                    expect(EC.elementToBeClickable(fn)).toBeTruthy();
                    fn.click();
                });
            }); 
        };



        brewerRinseStartButton.isDisplayed().then(()=>
        {                               
            fnBrewer();

        },()=>
        {
            powderRinseStartButton.isDisplayed().then(()=>
            {                                  
                fnPowder();
            },()=>
            { 
                failHandler();
            });
        });

5 个答案:

答案 0 :(得分:0)

IsDisplayed()函数返回Promise,因此有两种处理方法。您还尝试过在返回promise对象时使用它,然后执行操作。 第二种方法是使用async / await处理承诺的最正确,最干净的方法

async clickStartButton() {
     if(powderRinseStartButton != null && await 
      powderRinseStartButton.isDisplayed() && await 
    powderRinseStartButton.ispresent())
  {
       await   powderRinseStartButton.click();
    }
   else if(brewerRinseStartButton != null && await 
   brewerRinseStartButton.isDisplayed() && await 
    brewerRinseStartButton.ispresent())
     {
     await   brewerRinseStartButton.click();
    }
    else
   {
       await fn.click();
       {}
     }

注意:我已经用手机键盘输入了,所以请忽略代码标识

答案 1 :(得分:0)

我可能会尝试使用xpath定位器中提供的功能来做到这一点。逻辑是您提供一个单独的定位器,其中包含定位两个对象所需的定位器。如果找到第一个定位器,则将使用它,如果找到第二个定位器,则将使用它。如果都找不到,则可以使用ele.isDisplayed()检查并在其上运行else条件。

let requiredEle = element(by.xpath('//button[@class="locator1" or @class="locator2"]');

requiredEle.isDisplayed().then(function(wasDisplayed){
    if(wasDisplayed){
      requiredEle.click();
    } else {
      //Your else actions
    }
})
* not tested

我也建议使用 isPresent 代替isDisplayed,如果可以的话,如果元素不存在,则isDisplayed会引发异常,并且我不确定在上述if语句中该行为如何。

答案 2 :(得分:0)

在这种情况下,您可以尝试的一种方法是在此处使用.then().catch()承诺链,而不是其他情况。因此,在此之后,您尝试单击第一个元素按钮,而在catch()中,您不会拒绝或抛出错误,而是单击了第二个元素按钮。 因此,您可以在函数中返回以下内容:

return brewerRinseStartButton.isDisplayed()
  .then(() => brewerRinseStartButton.click())
  .catch(() => { 
    return powderRinseStartButton.isDisplayed()
     .then(() => powderRinseStartButton.click());
  });
Note: I've also used my mobile keypad for typing so please ignore the code identation. Also I assumed that first you want to try clicking (if found) on brewerRinseStartButton and then you want to try clicking on powderRinseStartButton.

答案 3 :(得分:0)

我尝试使用此代码。我希望这可以解决您的问题。我已经分别重构了WaitForElement代码,以便可以在两种情况下使用。

async WaitForElement(element, timeout = 30000) {
        try {
            await browser.wait(function () {
                return element.isDisplayed()
                    .then((isDisplayed) => isDisplayed, () => false);
            }, timeout);
            await browser.wait(function () {
                return element.isPresent()
                    .then((isPresent) => isPresent, () => false);
            }, timeout);
            return true;
        }
        catch (e) {
            console.log(e.message);
            return false;
        }
    }




async clickStartButton() {
        // powderRinseStartButton  = element(define locator)
        //brewerRinseStartButton =  element(define locator)

        if (await this.WaitForElement(this.powderRinseStartButton)) {
            await powderRinseStartButton.click();
        } else if (await this.WaitForElement(this.brewerRinseStartButton)) {
            await brewerRinseStartButton.click();
        } else {
            //await fn.click();
        }
    }

说明:

第一个element.isDisplayed()函数返回Promise对象,因此,如果将其置于If条件中,则它将始终返回true,这就是为什么它将始终通过第一个If循环的原因。

第二点是browser.wait理解是非,因此我们必须解析element.isDiplayed promise,以便它永远不会出现异常,并且我们可以等到超时。

答案 4 :(得分:0)

尝试以下方法。这绝对适合您。

const powderRinseStartButton= element(by.id('start_powder_rinse'); 
const brewerRinseStartButton = element(by.id('start_brewer_rinse');

if (await powderRinseStartButton.ispresent()) {
  await powderRinseStartButton.click();
} else if (await brewerRinseStartButton.ispresent()) {
  await brewerRinseStartButton.click();
} else {
 await fn.click();
}

如果按钮需要一些时间才能加载。尝试在sleep之前添加if

希望它对您有帮助。如果方法失败,请分享错误。