org.openqa.selenium.ElementNotVisibleException:通过SeleniumWebDriver和Java单击复选框时,元素当前不可见

时间:2018-10-09 12:17:40

标签: java selenium xpath css-selectors webdriverwait

我必须选中以下HTML代码段中包含的复选框。 该复选框包含在输入标签中

<div formarrayname="entityTypes" fxlayout="" fxlayoutgap="10px" class="ng-untouched ng-pristine ng-valid ng-star-inserted" style="flex-direction: row; box-sizing: border-box; display: flex;">
                  <div class="form-row ng-untouched ng-pristine ng-valid" fxlayout="row" fxlayoutgap="10px" style="flex-direction: row; box-sizing: border-box; display: flex;">
                    <app-checkbox formcontrolname="isSelected" _nghost-c26="" class="ng-untouched ng-pristine ng-valid"><div _ngcontent-c26="" class="checkbox-wrapper">

  <span _ngcontent-c26="" class="tix-checkbox" fxlayout="row" fxlayoutalign="start center" style="flex-direction: row; box-sizing: border-box; display: flex; max-height: 100%; place-content: center flex-start; align-items: center;">
    <!---->
    <input _ngcontent-c26="" type="checkbox" name="undefined" class="ng-star-inserted" style="" xpath="1">
  
      Funder
      <label _ngcontent-c26=""></label>
  </span>
  
  <!---->

  <!---->

</div>
</app-checkbox>
                  </div>
                </div>

我尝试了各种方法来识别它并选择它,但是它从不可见。 我已经将复选框标签的文本打印到控制台,因此无法理解为什么复选框本身不可见。 以下Java代码成功打印了标签,但未单击复选框并抛出错误元素不可见。

//print text of input box
WebElement labelFunder = driver.findElement(By.xpath("//div[@fxflex='50']//div[3]//div[1]//app-checkbox[1]//div[1]//span[1]//input[1]"));
String textFunderLabel2 = labelFunder.getAttribute("innerText").toString();
System.out.println(textFunderLabel);
labelFunder.click();

我尝试了不同的等待,但是也没有成功。

//select the funder checkbox
//driver.findElement(By.xpath("//div[@fxflex='50']//div[3]//div[1]//app-checkbox[1]//div[1]//span[1]//input[@type='checkbox']")).click();
//WebDriverWait wait = new WebDriverWait(driver, 30);
//WebElement checkbox = wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html[1]/body[1]/app-root[1]/main[1]/section[1]/div[2]/app-company-detail[1]/div[2]/form[1]/md-tab-group[1]/div[1]/md-tab-body[1]/div[1]/div[1]/div[2]/div[1]/div[2]/div[3]/div[1]/app-checkbox[1]/div[1]/span[1]/input[1]")));
//checkbox.click();

有人可以在这里向我指出正确的方向

谢谢。

2 个答案:

答案 0 :(得分:2)

此完整的错误消息是...

Exception in thread "main" org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with Command duration or timeout: 2.05 seconds

...表示在 WebDriver 实例试图查找时,HTML DOM中所需的元素不可见


ElementNotVisibleException

抛出

ElementNotVisibleException来表示尽管DOM Tree上存在一个元素,但该元素不可见,因此无法进行交互。这是一个运行时异常,具有以下层次结构:

java.lang.RuntimeException
    org.openqa.selenium.WebDriverException
        org.openqa.selenium.InvalidElementStateException
            org.openqa.selenium.ElementNotInteractableException
                org.openqa.selenium.ElementNotVisibleException

字段摘要

此异常的字段继承自org.openqa.selenium类。WebDriverException如下:

Modifier and Type                        Field and Description
---------------------------------        ---------------------
protected static java.lang.String        BASE_SUPPORT_URL 
static java.lang.String                  DRIVER_INFO 
static java.lang.String                  SESSION_ID 

原因

ElementNotVisibleException 的一个可能原因是 WebElement 在HTML中存在,并且在尝试click()read是从视图中隐藏的元素的属性。


解决方案

由于 ElementNotVisibleException 确保 WebElement 在HTML中存在,因此按照下面的详细步骤,前面的解决方案将是两方面的下方:

  • 如果下一步是读取所需元素的任何属性,则需要将WebDriverWait子句设置为{ {3}}如下:

    //using id attribute
    new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.id("element_id"))).getAttribute("innerHTML");
    //using linkText attribute          
    new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.linkText("element_linkText"))).getAttribute("innerHTML");
    //using cssSelector     
    new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("element_cssSelector"))).getAttribute("innerHTML");
    //using xpath           
    new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("element_xpath"))).getAttribute("innerHTML");
    
  • 如果下一步是在所需元素上调用 click() ,那么您需要将ExpectedConditionsvisibilityOfElementLocated子句结合使用设置为WebDriverWait如下:

    //using id attribute
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.id("element_id"))).click();
    //using linkText attribute          
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.linkText("element_linkText"))).click();
    //using cssSelector     
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.cssSelector("element_cssSelector"))).click();
    //using xpath           
    new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(By.xpath("element_xpath"))).click();
    

此用例

所需元素是ExpectedConditions元素,因此您需要诱使 WebDriverWait 使元素可点击,并且可以使用以下任一解决方案:

  • cssSelector

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("span.tix-checkbox input.ng-star-inserted[name='undefined']"))).click();
    
  • xpath

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//span[@class='tix-checkbox']//input[@class='ng-star-inserted' and @name='undefined']"))).click();
    

答案 1 :(得分:1)

尝试使用javascript单击:

public void clickElementWithJS(By locator) {
    String jsClickCode = "arguments[0].scrollIntoView(true); arguments[0].click();";
    try {
        WebElement elementToClick = driver.findElement(locator);
        ((JavascriptExecutor) driver).executeScript(jsClickCode, elementToClick);
    } catch(Exception e) {
        System.out.println("Element could not be clicked.. "  + e.getMessage());
    }
}