通过WebElement列表循环的索引超出范围

时间:2018-03-29 16:13:12

标签: java selenium selenium-webdriver

我正在尝试将web元素值设置为0或null。基本上我想清除web元素的值,以便它可以存储另一个元素。目前我得到堆栈跟踪信息说:java.lang.IndexOutOfBoundsException:Index:1,Size:1。我知道这意味着有一个值仍然存在,需要先将其清除才能再次使用。 / p>

基本上我正在尝试这样做 1获取列表元素值 2循环 3清除价值 4重复步骤1 -3直到条件为真,我打破循环。

我的代码如下。它有效,但只有一次。

 for (int x = 0; x < 100; x++) {

 String PreviewStatus = "//table[@id='cppProcessInfoTable_rows_table']//tr[@id='cppProcessInfoTable_row_0']/td[starts-with(@id,'cppProcessInfoTable_row_0_cell_2')]";
 List < WebElement > Status = driver.findElements(By.xpath(PreviewStatus));
 WebElement status = Status.get(x);
 String pstatus = status.getText().trim();


 String Status1 = "Completed";
 String Status2 = "Sucessfull";
 String Status3 = "Payroll Delayed";
 String Status4 = "Error";

 WebElement CalcPreviewPayroll = driver.findElement(By.xpath("//*[contains(@id,'cppBatch_title')]"));

 if (CalcPreviewPayroll.isDisplayed() && pstatus.equals(Status1) || pstatus.equals(Status2) || pstatus.equals(Status3) || pstatus.equals(Status4)) {
  PS_OBJ_CycleData.Close(driver).click();
  break;
 }

 if (!CalcPreviewPayroll.isDisplayed()) {
  break;
 }
 System.out.println("\n" + "status " + pstatus);
 Status = null;

}       }

3 个答案:

答案 0 :(得分:1)

由于存在大量相互矛盾的信息,您需要更好地解释您尝试完成的内容:

  • Java.lang.IndexOutOfBoundsException: Index: 1, Size: 1表示你有一个只有一个数组的数组(大小:1),但是你试图访问数组之外​​的东西(索引:1,但是java是0索引的,所以在一件事情中数组唯一的索引是0)。
  • 您的PreviewStatus xpath似乎非常具体:'cppProcessInfoTable_row_0_cell_2'。这让我觉得你只得到一个特定的单元格,所以你只会有一个1索引数组。 xpath应该足够通用以获得一系列单元格。
  • 你有一个固定的for循环 - 0到100.根据IndexOutOfBounds错误,一直有100件事要做。它应该是一个基于您要查找的条件是否存在的循环(例如,数组的.size()
  • 在循环内部,您将创建一个WebElements数组。通常,您只希望在循环外部执行此操作,并且如前一个项目符号所述,专门循环到数组的大小。例外情况是,您执行的.click()会刷新屏幕。但那是一场完全不同的球赛。
  • 没有真正的理由将循环中的变量归零或归零,因为每次使用新值重新声明变量时都会如此。

一般流程应该是这样的:

  • 获取一系列webelements
  • 启动数组循环(foreach)
  • 存储webelement的文本文本
  • 如果&#39; cppBatch_title&#39;没有显示,突破循环
  • 如果&#39; cppBatch_title&#39;显示,与已知值比较。
    • 如果已知,请单击某些内容并退出循环
    • 如果未知,请打印文本值

我仍然不认为这是你真正想要的,但它是你目前正在尝试的更清晰的版本。

答案 1 :(得分:1)

您的错误消息确切地说明了什么是错的。你正在做一个findElements,它返回一个web元素数组。它在错误消息中说返回的大小是一。你试图循环100次。在第一次迭代(零)之后,它尝试获取第一个元素,该元素不存在。您应该始终检查返回的数组的大小(),并将其用作计数器限制。

答案 2 :(得分:1)

我要重申我认为你的问题。如果我误解了某些事情你就必须纠正我。

您希望等到特定表格单元格包含以下值之一:“已完成”,“成功”,“工资延迟”,“错误”,然后执行某些操作。

将来,如果您开始解释您在单词(而不是代码)中尝试的内容,然后使用您尝试的代码以及代码中的错误/问题,那将是最好的。它将帮助读者了解是否还有其他/更好的方法来修复您的代码。

下面的代码一直等到单元格包含一个所需的字符串。如果那不是真的,它将抛出超时异常。

// store the status strings in a List (makes comparisons easier)
List<String> statuses = Arrays.asList("Completed", "Successful", "Payroll Delayed", "Error");
// define the locator (not required but since it is so long, it makes later lines more readable)
By statusLocator = By.xpath("//table[@id='cppProcessInfoTable_rows_table']//tr[@id='cppProcessInfoTable_row_0']/td[starts-with(@id,'cppProcessInfoTable_row_0_cell_2')]");
// custom wait... wait for the text in the element to be one of the supplied statuses
new WebDriverWait(driver, 10).until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver driver) {
            try {
              status = driver.findElement(statusLocator, driver).getText();
              return statuses.stream().anyMatch(str -> str.trim().equals(status));
            } catch (Exception e) {
              return false;
            }
          }
    });
// if we got here, the element contained a desired status
PS_OBJ_CycleData.Close(driver).click();