Selenium:元素无法滚动到视图中

17

嗨,我遇到了以下错误。 我无法点击屏幕截图中买家按钮。 我已尝试等待和睡眠功能,但无法解决这个问题。 有人能帮我吗?

请问有人能帮我吗: 检查元素代码为

代码是:

driver.findElement(By.name("login")).click();  //Click on login button
    System.out.println("hello world-----4");

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {

        e.printStackTrace();
    }   
    System.out.println("hello world-----5");
    WebElement element = driver.findElement(By.xpath("//*
[@id=\"modeuser\"]/div/ul/li[3]"));
    ((JavascriptExecutor) 
driver).executeScript("arguments[0].scrollIntoView(true);", element);
    element.click();                                                                                    
//Click on usertype



Error:

Exception in thread "main" 
org.openqa.selenium.ElementNotInteractableException: Element <li 
class="buyer_border changeusermode "> could not be scrolled into view
Build info: version: '3.9.0', revision: '698b3178f0', time: '2018-02-
05T14:56:13.134Z'
System info: host: 'CLAVAX-PC-93', ip: '192.168.2.122', os.name: 'Windows 
10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_161'
Driver info: org.openqa.selenium.firefox.FirefoxDriver
Capabilities {acceptInsecureCerts: true, browserName: firefox, 
browserVersion: 58.0.2, javascriptEnabled: true, moz:accessibilityChecks: 
false, moz:headless: false, moz:processID: 14260, moz:profile: 
C:\Users\Rahul\AppData\Loca..., moz:webdriverClick: true, pageLoadStrategy: 
normal, platform: XP, platformName: XP, platformVersion: 10.0, rotatable: 
false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}}


HTML is :

<div class="right hide-on-med-and-down head_right_mar" id="modeuser">
               <!--  <div class="toggleWrapper">
                  <input class="dn" type="checkbox" id="dn" value="1"/>
                  <label class="toggle" for="dn"><span class="toggle__handler"></span></label>
                </div> -->

                <div class="right_toggle">
                                            <ul>
                        <li data-get="seller" class="changeusermode active">
                            <span>Seller</span>
                                                                <span class="nav_span">On</span>

                        </li>


                        <li class="mid_toggle">  
                            <div class="switch">
                            <label>

                              <input class="changeusermode_btn" type="checkbox" data-on="Yes" data-off="No">
                              <span class="lever"></span>
                            </label>
                          </div>
                        </li>


                        <li data-get="buyer" class="buyer_border changeusermode ">
                            <span>Buyer</span>

                                <span class="nav_span">Off</span>                                     

                        </li>
                    </ul>
                </div>


            </div>

请发布HTML代码。它是否嵌入在iframe中?您尝试过将焦点放在它上面吗?您能否单击其父元素?可能是elementnotinteractableexception的重复问题。 - lloyd
已发布...您现在可以检查。 - RAHUL
可能是如何解决Selenium webdriver中的ElementNotInteractableException?的重复问题。 - undetected Selenium
9个回答

19
首先,请确认元素在你的框架内

如果不在,你需要切换到正确的框架才能点击该元素:


driver.switchTo().frame(driver.findElement(By.name("iframeWithElement")));

此外,在单击不同的UI元素时,您可以采取一些步骤来提高其稳定性:

  • 显式地等待其在DOM中的存在
  • 滚动到元素视图中
  • 检查是否可点击

这有助于稳定性吗?

WebDriverWait wait = new WebDriverWait(driver, 3);
JavascriptExecutor js = ((JavascriptExecutor) driver);

//presence in DOM
wait.until(ExpectedConditions.presenceOfElement(By.id("ID")));

//scrolling
WebElement element = driver.findElement(By.id("ID")));  
js.executeScript("arguments[0].scrollIntoView(true);", element);

//clickable
wait.until(ExpectedConditions.elementToBeClickable(By.id("ID")));

例如,假设我正在处理该网站,我会使用:


Wait.until(ExpectedConditions.presenceOfElement(By.class("article-feed-title")));

4

不要使用scrollToView,直接点击该元素即可。

driver.execute_script("arguments[0].click();", element)

4

4
您可以尝试这个版本,它会滚动到元素的x、y位置:
public static void scrollIntoView(WebElement ele) {
    ((JavascriptExecutor)driver).executeScript(String.format("window.scrollTo(%s,%s)", ele.getLocation().x, ele.getLocation().y);
}

2
这对我很有效。但是我必须强调测试代码的可读性非常重要。String.format("window.scrollTo(%s,%s)", ele.getLocation().x, ele.getLocation().y) 是表示JS脚本的更好的方式。 - st0ve
感谢您的建议和点赞,我们很高兴地接受了您的编辑。 - Bill Hileman

2

我在Firefox中遇到了同样的问题(在Chrome和Opera中它工作正常)。尝试将JavascriptExecutor更改为Actions:

Actions action = new Actions(driver);
action.moveToElement(element).click().perform();

2

我在Firefox中遇到了类似的问题,但是(第一次点击Hover菜单时,它能够启用主要元素,然后我点击子元素,但第二次尝试点击另一个子元素时,出现错误)。 错误:“无法将元素滚动到视图中”。 我在另一个窗口中打开了下一个子菜单,这对我有用。

WebElement element = driver.findElement(By.xpath("//div[2]/ul/li[3]/a"));
WebDriverWait wait = new WebDriverWait(driver, 30); //here, wait time is 20 sec
wait.until(ExpectedConditions.visibilityOf(element)); //this will wait for element to be visible for 20 seconds
element.click(); //now it clicks on element
Thread.sleep(8000);
driver.findElement(By.xpath("//li[3]/ul/li/a")).click();

if(driver.getTitle().equals("Invoice Search")) {

test4.log(LogStatus.PASS, "Navigated to Invoice Search Page");
}

0
如果有人仍然遇到这个问题,我通过在无头模式下设置窗口大小来解决它。在Java中,可以这样做:driver.manage().window().setSize(new Dimension(5120, 2880));

0

我知道这个问题期望得到一个Java的答案,但我希望这个评论能够通过这个Python解释帮助理解这个错误的一个可能来源。

所以,我也遇到了这个问题。我成功地解决了它,基于这些评论 https://dev59.com/IlMI5IYBdhLWcg3wfrls#56361554

https://dev59.com/11UM5IYBdhLWcg3wSetQ#51789111

我对这个问题的补充是,如果出现这个问题,您可能需要检查一下您的CSS。在我的情况下,事实证明我尝试点击的元素在一个.css文件中的位置是(x: -9999, y: 538)。难怪它无法在视图中滚动。

此外,如果您使用以下内容进行点击操作,这种CSS错误很可能会引发异常。

from selenium.webdriver.common.action_chains import ActionChains

# ...

tc = self.browser.find_element(*self.TC_CHECKBOX)
ActionChains(self.browser).move_to_element(tc).click(tc).perform()

-1

我遇到了同样的问题(但是在NodeJS中,而不是Java)。

我在MacOS上使用了Firefox驱动程序。

问题是:Firefox在MacOS上很慢。因此,它仍在启动并忽略了第一个测试命令。当它打算点击一个按钮时,那个按钮实际上并不存在。

如何解决我的问题?

在测试任何内容之前,我编写了这个睡眠函数:

const sleep = (waitTimeInMs) => new Promise(resolve => setTimeout(resolve, waitTimeInMs))

我使用以下命令执行它:

await driver.get('http://localhost:8080/webapp/')
await sleep(5000)
// tests after that

替代选项:

sleep(5000).then(() => {
  // tests here
});

这段时间足够 Firefox 启动并正确接收测试命令。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接