org.openqa.selenium.ElementNotInteractableException:键盘无法访问元素:向 Facebook 中的 FirstName 字段发送文本时

Posted

技术标签:

【中文标题】org.openqa.selenium.ElementNotInteractableException:键盘无法访问元素:向 Facebook 中的 FirstName 字段发送文本时【英文标题】:org.openqa.selenium.ElementNotInteractableException: Element is not reachable by keyboard: while sending text to FirstName field in Facebook 【发布时间】:2018-09-26 15:28:49 【问题描述】:

错误是:

Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: Element <div id="u_0_b" class="_5dbb"> is not reachable by keyboard

代码为:

System.setProperty("webdriver.gecko.driver","//Users//rozali//Documents//Selenium//geckodriver");
    WebDriver driver = new FirefoxDriver();
    driver.get("http://www.facebook.com");
    driver.manage().window().maximize();

    //entering first name
    driver.findElement(By.id("u_0_b")).click();
    driver.findElement(By.id("u_0_b")).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.id("u_0_t")).click();

【问题讨论】:

如您的错误所述,driver.findElement(By.id("u_0_b")).sendKeys("testing it ") 看起来无法交互。逐步浏览您的脚本,看看它是否正在显示和可访问。是否有元素覆盖它? 第一步显示同样的错误。我已经一一检查了每一行,但每次都可以看到相同的错误。 【参考方案1】:

ElementNotInteractableException:键盘无法访问元素

Element is not reachable by keyboard 简单来说意味着无法使用键盘访问该元素,这意味着您甚至不会与它进行物理交互。

原因

错误的背后可能有多种原因键盘无法访问元素,可能是以下任一原因:

元素被隐藏,因为现代以 javascript 为中心的 UI 样式总是隐藏丑陋的原始 html 输入字段。 hidden 属性可以通过以下任一方式实现: 一些其他元素的临时覆盖在所需元素上。 其他元素在所需元素上的永久覆盖。 存在属性,例如class="ng-hide"style="display: none"等 根据发送字符序列时的最佳实践,您不得尝试在任何&lt;p&gt;&lt;div&gt; 标签上调用click()sendKeys(),而是在所需的&lt;input&gt; 标签上调用click() Official locator strategies for the webdriver。

解决方案

有不同的方法来解决这个问题。

如果临时覆盖使用WebDriverWait与ExpectedConditions联合使用,以使所需的元素可见/可点击如下:

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();

永久覆盖使用JavascriptExecutor接口中的executeScript()方法如下:

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);

你会在Using JS to enter text, but if I input text in one text box, the value already entered is getting deleted找到详细的讨论

如果存在属性,例如class="ng-hide"style="display: none"等使用JavascriptExecutor接口中的executeScript()方法编辑和重置style="display: none"属性为style="display: block"如下:

import org.openqa.selenium.JavascriptExecutor;
((JavascriptExecutor) driver).executeScript("document.getElementById('ID').style.display='block';");

您将在Can't fill in the Hidden text area element找到详细讨论

参考文献

For input[type=file], should allow sendKeys even when display=none Special-casing file upload controls in keyboard-interactability check Element is not reachable by keyboard Input field with display: none is not interactable at all?

这个特殊问题

如果您查看 Facebook 登录页面的 HTML,应用程序包含 React Native 元素。因此,曾经在您的系统中以 id 表示为 u_0_b 的元素在您系统的下一次运行中可能不会以与 u_0_b 相同的 id 表示。因此,我们必须借助 Dynamic Locator Strategy。您可以使用以下代码块来执行您的预期步骤:

代码块:

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();

浏览器客户端:


更新

解决错误:

org.openqa.selenium.ElementNotInteractableException: Element is not reachable by keyboard

随着 Firefox 功能moz:webdriverClick 的可用性变得更加容易

moz:webdriverClick()

通过webdriverClick(),您可以传递一个布尔值来指示在执行点击或向元素发送键时要运行哪种交互性检查。对于 v58.0 之前的 Firefoxen,一些从旧版本 FirefoxDriver 导入的遗留代码正在使用中。随着 Firefox v58 的推出,WebDriver specification 要求的可交互性检查默认启用。这意味着 geckodriver 将额外检查一个元素在单击时是否被另一个元素遮挡,以及一个元素是否可以聚焦以发送键。由于这种行为变化,我们知道可能会返回一些额外的错误。在大多数情况下,可能需要更新相关测试以符合新的检查。

要暂时禁用 WebDriver 一致性检查,请使用 false 作为此功能的值。

注意:此功能只是暂时存在,一旦交互性检查稳定,它将被移除。

【讨论】:

你好,请问chromedriver怎么样?我已经尝试过上面的 webdriver.until(ExpectedConditions.elementToBeClickable)、presentOfElement 等,但没有运气。我也试过 JS 视图。 也许禁用 CSS 会更容易? 临时或永久覆盖不会给您带来 ElementNotInteractableException。您将收到有关尝试单击 X 但 Y 元素挡住了的错误消息。此答案大部分不正确或包含误导性信息。 @JeffC 我认为你在这里有点困惑。我建议您看看 Browser Architecture 以及 CSS 的工作原理。这将消除您的基本疑问。如果您在这些主题或方向上需要进一步帮助,请告诉我。 不……一点也不困惑。当您设置此处描述的场景并亲自尝试时,您会发现它也不正确。【参考方案2】:

你可以试试这个代码

public class Rozmeen

    static WebDriver driver;
    static WebDriverWait wait;

    public static void main(String[] args) throws InterruptedException 
            System.setProperty("webdriver.gecko.driver", "F:\\Automation\\geckodriver.exe");
            driver = new FirefoxDriver();
            driver.manage().window().maximize();
            WebDriverWait wait = new WebDriverWait(driver, 40);
            driver.get("http://www.facebook.com");

            //entering first name
            wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.id("pagelet_bluebar"))));
            driver.findElement(By.name("firstname")).sendKeys("testing it ");

            //DOB
            selectFromDropDown(driver.findElement(By.name("birthday_day")), "4");
            selectFromDropDown(driver.findElement(By.name("birthday_month")), "Jun");
            selectFromDropDown(driver.findElement(By.name("birthday_year")), "2013");

            //clicking sign up
            wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.name("websubmit"))));
            driver.findElement(By.name("websubmit")).click();
        



        public static void selectFromDropDown(WebElement element , String Visibletext)
            Select select = new Select(element);
            select.selectByVisibleText(Visibletext);
        
  

试试这个代码,让我知道状态。

【讨论】:

我尝试使用等待命令,但仍然无法正常工作。【参考方案3】:

在一个用例中,我遇到了同样的问题:

Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: Element <div id="search"> is not reachable by keyboard

在发送键之前使用 id 来识别元素。比如:

driver.findElement(By.id("search")).sendKeys("...");

经过测试,我改用 CSS Selector 解决了这个问题:

driver.findElement(By.cssSelector("#search > input:nth-child(2)")).sendKeys("...");

因此,我强烈建议您使用不同的方法与元素进行交互,因为其他方法可以节省您解决问题的时间。

【讨论】:

【参考方案4】:

我遇到了类似的问题,在执行 click() 操作时,在按钮上显示 org.openqa.selenium.ElementNotInteractableException 异常。正如 DebanjanB 在他的回答中提到的,该元素无法通过键盘访问。 为了解决这个问题,将 click() 替换为 sendKeys(Keys.ENTER) 并点击按钮。

【讨论】:

否:按键盘键与单击鼠标按钮不同——这不是重点。仔细检查(模拟的)输入设备是否无关紧要! @AmigoJack 在我的例子中,模拟输入设备无关紧要,只需要调用 CTA。

以上是关于org.openqa.selenium.ElementNotInteractableException:键盘无法访问元素:向 Facebook 中的 FirstName 字段发送文本时的主要内容,如果未能解决你的问题,请参考以下文章