0

如果动态发生任何错误,则错误消息会显示在站点上。就我而言,如果发生错误,会出现弹出窗口,我需要单击“确定”按钮。

问题是,使用所有 Selenium 技巧,我无法避免 NoSuchElementException 或“无法单击元素”异常。期望:如果出现错误弹出,点击确定,如果没有,继续跳过这些ifs。我正在遵循这种方法:

PageFactory 元素和方法。

@FindBy(id='locator')
List<WebElement> errorElement1;

@FindBy(id='locator2')
List<WebElement> errorElement2;

Usage:

if(errorElement1.size() > 0) {
errorElement1.get(0).click();
}

if(errorElement2.size() > 0) {
errorElement2.get(0).click();
}

问题是,如果我使用 errorElement1.isDisplayed 方法,我会得到 NosuchElementException。

我尝试了所有可以在这里找到的技巧,到目前为止没有成功。谢谢!

4

4 回答 4

0

如果你想检查一个元素的存在,我通常这样做的方式是做这样的事情:

try {
    errorElement1.get(0).click();
} catch (NoSuchElementException e) {
    // the element isn't present on the page, you can do something about it here
}
于 2018-03-08T19:58:34.320 回答
0

有几种方法可以处理这个问题。您可以编写一个click()方法来处理单击您当前正在使用的元素集合。

public void click(List<WebElement> e)
{
    if (!e.isEmpty())
    {
        e.get(0).click();
    }
}

你会像这样使用它

click(errorElement1);

您可以将其更改ListWebElement

@FindBy(id='locator')
WebElement errorElement1;

并使用类似的东西

public void click(WebElement e)
{
    try
    {
        e.click();
    }
    catch (Exception ex)
    {
        // catch and handle various exceptions
    }
}

你会这样称呼它

click(errorElement1);

处理这种情况的另一种方法是编写一个函数来检查每个错误元素并使用上述方法单击它click()

public void handleErrors()
{
    click(errorElement1);
    click(errorElement2);
}

所以你的脚本看起来像

// do some action
handleErrors();
// do another action

如何使用当前定位器检查错误是否存在

public boolean errorsExist()
{
    return !errorElement1.isEmpty() || !errorElement2.isEmpty();
}

您可以检查任一集合是否包含任何元素。如果有,则存在错误。如果您需要知道存在哪个错误,您可能希望将此函数分解为两个函数,一个用于每个错误元素。

于 2018-03-08T23:22:47.260 回答
0

仍然不完全确定您在寻找什么。所以我提到我的假设 -

  1. 连接的系统出现故障,但站点运行良好,对 UI 没有干扰。这意味着没有弹出窗口或模式警报。
  2. 这些消息出现在页面上的某些特定区域,不会妨碍任何页面功能。
  3. 当消息可见时,您希望验证消息并抛出异常以结束测试。这部分令人困惑,因为在原始帖子中您提到单击“确定”按钮。但是在评论中你提到了抛出和异常。
  4. 可能有多个系统,所以使用地图而不是页面对象来存储它们。

您需要将 webdriver 传递给ErrorChecker类,使用 pico 容器最简单的构造函数。如果你想改变它,你可以看看内部类。要包含新的系统消息,只需创建一个静态键并使用详细信息更新地图。

要调用此ErrorChecker代码,您需要将其放在 try catch 中以获取已检查的SystemFailureException.

公共类错误检查器{

  //As you are using picocontainer create a constructor with the driver as argument.
  private WebDriver driver;

  private static final Map<String, ErrorMsg> errMap = new HashMap<>();

  private static final String SYSTEM_A_ID = "sysakey";
  private static final String SYSTEM_B_ID = "sysbkey";
  private static final String SYSTEM_C_ID = "sysckey";

  static {
      //First parameter - By for locating the message
      //Second paremeter - By for locating the OK button
      //Third parameter - Expected Message
      errMap.put(SYSTEM_A_ID, new ErrorMsg(By.id("ida"),By.xpath("xpa"), "ExpectedMsgA"));
      errMap.put(SYSTEM_B_ID, new ErrorMsg(By.id("idb"),By.xpath("xpb"), "ExpectedMsgB"));
      errMap.put(SYSTEM_C_ID, new ErrorMsg(By.id("idc"),By.xpath("xpc"), "ExpectedMsgC"));
  }

  public void verifyErrors() throws SystemFailureException{
      Set<String> keys = errMap.keySet();

      for(String key : keys) {
          ErrorMsg err = errMap.get(key);
          System.out.println(err);

          try {
              //If this fails with NoSuchElement(ie appropriate msg is missing) 
              //then control goes to catch.
              //Loops to next key or system.
              WebElement msgBox = driver.findElement(err.msgBy);

              //Reaches here then msg for failng system found
              String msg = msgBox.getText();

              //Verify if correct. If this is required to be done.
              Assert.assertEquals("Error message mismatch.", err.expectedMessage, msg);

              //Click to make it disappear. Though does not make sense as exception
              //be thrown to break process.
              driver.findElement(err.okbtnBy).click();

              //Throw the exception that systems are failing and break out of loop.
              throw new SystemFailureException(key + " gone kaput.");             

          } catch (NoSuchElementException e) {
              System.out.println("catch do nothing");
          }
      }
  }

  private static class ErrorMsg{
      public By msgBy; 
      public By okbtnBy;
      public String expectedMessage;

      public ErrorMsg(By msgBy, By okbtnBy, String expectedMessage) {
          this.msgBy = msgBy;
          this.okbtnBy = okbtnBy;
          this.expectedMessage = expectedMessage;
      }

      @Override
      public String toString() {
          return "ErrorMsg [msgBy=" + msgBy
                  + ", okbtnBy=" + okbtnBy
                  + ", expectedMessage=" + expectedMessage + "]";
      }

  }
}

自定义异常类。

public class SystemFailureException extends Exception {

  public SystemFailureException() {
  }

  public SystemFailureException(String message) {
      super(message);
  }

  public SystemFailureException(Throwable cause) {
      super(cause);
  }

  public SystemFailureException(String message, Throwable cause) {
      super(message, cause);
  }

}
于 2018-03-16T09:10:15.997 回答
0

与其将所有页面元素定义为列表,不如仅将实际上可能是列表的元素定义为列表,将其余的定义为 Web 元素。我所做的是在帮助文件中编写一个函数来检查是否存在通过首先专门检查空值定义的任何元素。该函数可能对您正在寻找的东西来说太过分了,但我将它用作包装器并简单地为我需要在页面对象类内部检查的元素定义一个函数,例如 okButtonIsDisplayed() 并在内部调用下面的包装器,传递定义的 web 元素,一个用于记录错误的描述性字符串,以及一个布尔值,用于确定元素 - 应该 - 是否因通过/失败原因而存在。

public static Boolean pomIsDisplayed(WebElement ele, String eleName, String passOrFail) {
    /*
     * This function returns true if the passed WebElement is displayed
     * 
     * @Param ele - The WebElement being tested
     * 
     * @Param eleName - The textual description of the WebElement for
     * logging purposes.
     * 
     * @Param passOrFail - "Pass" if log should show pass unless unexpected
     * exception occurs. "Fail" is the default if not specified and will log
     * a failure if not displayed.
     * 
     * Returns true - The WebElement is displayed false - The WebElement is
     * not displayed
     */
    String stsStart = " " + passOrFail + ": Element " + eleName;
    Boolean isDisplayed = false;
    String stsMsg = stsStart + " is NOT displayed";
    try {
        if (ele.equals(null))
            stsMsg = stsStart + " is NOT found";
        else if ("checkbox".equals(ele.getAttribute("type")) || "radio".equals(ele.getAttribute("type"))) {
            isDisplayed = true;
            stsMsg = " Pass: Element " + eleName + " is displayed";
        } else if (!ele.isDisplayed())
            stsMsg = stsStart + " is NOT displayed";
        else {
            isDisplayed = true;
            stsMsg = " Pass: Element " + eleName + " is displayed";
        }
    } catch (NoSuchElementException | NullPointerException e) {
        stsMsg = stsStart + " is NOT found. Cause: " + e.getCause();
    } catch (ElementNotVisibleException e1) {
        stsMsg = stsStart + " is NOT displayed. Cause: " + e1.getCause();
    } catch (Exception e2) {
        stsMsg = " Fail: Element " + eleName + " Exception error. Cause: " + e2.getCause();
    }
    addresult(stsMsg);
    return isDisplayed;
}
于 2018-03-08T20:38:36.180 回答