ElementNotInteractableException: Element is not reachable by keyboard
Element is not reachable by keyboard
in plain words means that the element can’t be reached using the keyboard, which means you won't even physically interact with it.
Reason
There can be multiple reasons behind the error Element is not reachable by keyboard which can be either of the following:
- The element is hidden, as modern JavaScript-centric UI styles always keep the ugly raw HTML input field hidden. The
hidden
attribute could have been implemented through either of the following ways:
- A temporary overlay of some other element over the desired element.
- A permanent overlay of some other element over the desired element.
- Presence of attributes e.g.
class="ng-hide"
, style="display: none"
, etc
- As per best practices while sending character sequence, you must not attempt to invoke
click()
or sendKeys()
on any <p>
or <div>
tag; instead, invoke click()
on the desired <input>
tag following the Official locator strategies for the webdriver.
Solution
There are different approaches to address this issue.
import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.nsg-button"))).click();
import org.openqa.selenium.JavascriptExecutor;
String inputText = "Rozmeen";
WebElement myElement = driver.findElement(By.id("u_0_b"));
String js = "arguments[0].setAttribute('value','"+inputText+"')"
((JavascriptExecutor) driver).executeScript(js, myElement);
You will find a detailed discussion in Using JS to enter text, but if I input text in one text box, the value already entered is getting deleted.
- Incase presence of attributes e.g.
class="ng-hide"
, style="display: none"
, etc., use executeScript()
method from the JavascriptExecutor interface to edit and reset the style="display: none"
attribute to style="display: block"
as follows:
import org.openqa.selenium.JavascriptExecutor;
((JavascriptExecutor) driver).executeScript("document.getElementById('ID').style.display='block';");
You will find a detailed discussion in Can't fill in the Hidden text area element.
References
This particular issue
If you look into the HTML of Facebook login page, the application contains React Native elements. So an element once represented with id
as u_0_b in your system may not be represented by the same id
as u_0_b in the next run on your system. Hence, we have to take the help of Dynamic Locator Strategy. You can use the following code block to perform your intended steps:
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.facebook.com");
driver.findElement(By.xpath("//input[@name='firstname' and contains(@class,'inputtext')]")).sendKeys("testing it ");
//DOB
Select sel1 = new Select(driver.findElement(By.xpath(".//*[@id='month']")));
sel1.selectByIndex(4);
Select sel2 = new Select(driver.findElement(By.xpath(".//*[@id='day']")));
sel2.selectByValue("6");
Select sel3 = new Select(driver.findElement(By.xpath(".//*[@id='year']")));
sel3.selectByValue("2013");
//clicking sign up
driver.findElement(By.xpath("//button[@name='websubmit' and contains(.,'Sign Up')]")).click();
Update
Addressing the error:
org.openqa.selenium.ElementNotInteractableException: Element is not
reachable by keyboard
has become easier with the availability of Firefox capability moz:webdriverClick
moz:webdriverClick()
Through webdriverClick()
, you can pass a boolean value to indicate which kind of interactability checks to run when performing a click or sending keys to an element. For Firefoxen prior to v58.0, some legacy code as imported from an older version of FirefoxDriver was in use. With the availability of Firefox v58, the interactability checks as required by the WebDriver specification are enabled by default. This means that geckodriver will additionally check if an element is obscured by another when clicking and if an element is focusable for sending keys. Because of this change in behaviour, we are aware that some extra errors could be returned. In most cases, the test in question might have to be updated so it conforms with the new checks.
To temporarily disable the WebDriver conformant checks, use false
as value for this capability.
Note: This capability exists only temporarily, and it will be removed once the interactability checks have been stabilized.
driver.findElement(By.id("u_0_b")).sendKeys("testing it ")
looks like it's not interactable. Go through your script step by step and see if it's showing, and accessible. Is there an element overlaying it? – Marjorie