This complete error message is...
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
...implies that the desired element was not visible within the HTML DOM while the WebDriver instance was trying to find it.
ElementNotVisibleException
ElementNotVisibleException is thrown to indicate that although an element is present on the DOM Tree, it is not visible, and so is not able to be interacted with. It is a runtime exception and have the following hierarchy:
java.lang.RuntimeException
org.openqa.selenium.WebDriverException
org.openqa.selenium.InvalidElementStateException
org.openqa.selenium.ElementNotInteractableException
org.openqa.selenium.ElementNotVisibleException
Field Summary
The fields of this exception are inherited from class org.openqa.selenium.WebDriverException and are as follows:
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
Reason
One possitive take away from ElementNotVisibleException is the fact that the WebElement is present within the HTML and this exception is commonly encountered when trying to click()
or read
an attribute of an element that is hidden from view.
Solution
As ElementNotVisibleException ensures that the WebElement is present within the HTML so the solution ahead would be two folds as per the next steps as detailed below:
If you next step is to read any attribute of the desired element, then you need to induce WebDriverWait in-conjunction with ExpectedConditions clause set to visibilityOfElementLocated as follows:
//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");
If you next step is to invoke click()
on the desired element, then you need to induce WebDriverWait in-conjunction with ExpectedConditions clause set to elementToBeClickable as follows:
//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();
This usecase
The desired element is an Angular element so you need to induce WebDriverWait for the element to be clickable and you can use either of the following solutions:
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();
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…