【问题标题】:org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: move target out of bounds using Selenium Chrome and java.version: '16.0.2'org.openqa.selenium.interactions.MoveTargetOutOfBoundsException:使用 Selenium Chrome 和 java.version 将目标移出边界:'16.0.2'
【发布时间】:2021-12-26 17:50:18
【问题描述】:

我正在尝试单击下拉菜单上的链接。当我将鼠标悬停在按钮上时,会出现此下拉菜单。现在,我的测试因MoveTargetOutOfBoundsException 而崩溃,当我尝试悬停按钮时会发生这种情况。当我在浏览器中打开页面时,我可以轻松找到或将鼠标悬停在按钮上,因为它似乎无论如何都不在视口之外。 我用来悬停按钮的代码是:

private void hoverButtonWaitDropDown(WebElement button) {
        a.moveToElement(button).build().perform();
        try {
            w.until(ExpectedConditions.visibilityOf(dropDownMenu));
        } catch (TimeoutException ex) {
            ExtentTestManager.log(logger, Level.WARN, "Dropdown menu failed to display");
        }
    }

然后,测试等待下拉菜单出现并循环通过可用选项来找到所需的选项,最后单击它:

public void clickContextSetting(String setting) {
        hoverButtonWaitDropDown(contextButton);
        if (dataItems.size() == 0) {
            ExtentTestManager.log(logger, Level.WARN, "There are no context settings on the dropdown menu");
            return;
        }
        for (WebElement con : dataItems) {
            if (con.findElement(By.tagName("span")).getText().trim().equalsIgnoreCase(setting)) {
                con.click();
                return;
            }
        }
        Assert.fail("Test aborted because context setting: " + setting + " is not present on the topbar dropdown menu");
    }

现在,当我注释掉 a.moveToElement(button).build().perform(); 时,我自己运行测试并将鼠标移动到按钮上以显示下拉菜单,测试被 Assert.fail() 调用终止。这意味着测试确实找到了链接列表,因为dataItems.size() == 0 评估为假,但无法在下拉菜单中找到所需的链接。我添加了一个打印方法来打印出现的下拉菜单上所有链接的文本:

private void printDataItems() {
        for (WebElement item: dataItemsText) {
            System.out.println(item.getText());
        }
    }

但这只会打印 5 个空的 Strings。 当我使用选择器div[class='dataitems'] a span 在 devTools 的下拉菜单中查找包含链接文本的元素时,它会列出所有链接并按应有的方式突出显示链接文本,但是当我尝试使用 Selenium 时它不起作用.

文本节点如下所示:

span

我已经手动检查了我所有的定位器,它们都是正确的,所以我不知道我在这里做错了什么。 我应该注意,我在 chromedriver (96) 和 edgedriver (95) 中遇到了这个问题,但在 geckodriver (94) 中没有。当我使用 geckodriver 运行此测试时,测试脚本正确地悬停在按钮上,打印出下拉菜单上的所有可用链接并单击该链接。有什么想法吗?

编辑: 根据要求,这里是我在问题中提到的 WebElements 的定位器:

@FindBy(css = "div[gadget-name='Topbar context btn']")
private WebElement contextButton;

@FindBy(css = "div[class^='dropdata']")
private WebElement dropDownMenu;

@FindBy(css = "div[class='dataitems'] a")
private List<WebElement> dataItems;

@FindBy(css = "div[class='dataitems'] a span")
private List<WebElement> dataItemsText;

还有 MoveTargetOutOfBoundsException 的堆栈跟踪(我假设是这样的):

org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: move target out of bounds
  (Session info: chrome=95.0.4638.69)
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'
System info: host: 'DESKTOP-I6V1OLJ', ip: '192.168.2.8', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '16.0.2'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 95.0.4638.69, chrome: {chromedriverVersion: 95.0.4638.17 (a9d0719444d4b..., userDataDir: C:\Users\mb_vl\AppData\Loca...}, goog:chromeOptions: {debuggerAddress: localhost:59476}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: WINDOWS, platformName: WINDOWS, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:virtualAuthenticators: true}
Session ID: 6003d76fccdd4ddbed789b440fa9e6f7
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.createException(W3CHttpResponseCodec.java:187)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:122)
at org.openqa.selenium.remote.http.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:158)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:552)
at org.openqa.selenium.remote.RemoteWebDriver.perform(RemoteWebDriver.java:618)
at org.openqa.selenium.interactions.Actions$BuiltAction.perform(Actions.java:639)
at ObjectRepository.items.topbar_improved.hoverButtonWaitDropDown(topbar_improved.java:65)
at ObjectRepository.items.topbar_improved.clickContextSetting(topbar_improved.java:500)
at test_classes.general_scenarios.topbar_general.checkModal(topbar_general.java:50)
at test_classes.pages_local.local_test.topBar_clickLastLogins_modalIsDisplayed(local_test.java:102)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:132)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:599)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:174)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:822)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:147)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.testng.TestRunner.privateRun(TestRunner.java:764)
at org.testng.TestRunner.run(TestRunner.java:585)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:384)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:378)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:337)
at org.testng.SuiteRunner.run(SuiteRunner.java:286)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1218)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1140)
at org.testng.TestNG.runSuites(TestNG.java:1069)
at org.testng.TestNG.run(TestNG.java:1037)
at org.apache.maven.surefire.testng.TestNGExecutor.run(TestNGExecutor.java:284)
at org.apache.maven.surefire.testng.TestNGXmlTestSuite.execute(TestNGXmlTestSuite.java:75)
at org.apache.maven.surefire.testng.TestNGProvider.invoke(TestNGProvider.java:119)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:428)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:162)
at org.apache.maven.surefire.booter.ForkedBooter.run(ForkedBooter.java:562)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:548)

编辑:已解决

我联系了我们的前端开发人员,他们要求在生产环境中试用。它在那里工作,经过一番搜索,我注意到我试图与之交互的包含元素有zoom: 90%。我运行了我的测试,暂停它并在 devTools 中将元素 zoom 设置为 100%,然后继续执行;一切都再次奏效。 我做了一些挖掘,显然这是一个已知的事情:link

【问题讨论】:

  • 您应该显示定位“contextButton”、“dropDownMenu”、“dataItems”和“dataItemsText”的代码。 (您问题的第一部分将涉及“contextButton”......第二部分似乎仅与等待可见性有关(这可能还不够),并且可能仅在容器上用于跨度......)跨度>
  • 我已经用您要求的代码更新了我的问题。
  • MoveTargetOutOfBoundsException 的错误堆栈跟踪?
  • 我现在也添加了stacktrace。
  • 对于第二部分,您可能希望包含您尝试从中获取文本()的 标记之一的 HTML。您没有收到过时元素异常的事实表明那里还有另一个节点。或者,要进行故障排除,请检查: System.out.println(item.getAttribute('innerHTML'));

标签: java selenium selenium-chromedriver java-16 selenium-edgedriver


【解决方案1】:

此错误消息...

org.openqa.selenium.interactions.MoveTargetOutOfBoundsException: 

...暗示Selenium 无法专注于所需的元素,因为该元素超出了视口的范围。

您的主要问题是标识为 buttonWebElement 不在 Viewport 范围内,因此 Selenium 可以t 通过moveToElement() 方法将焦点移到所需元素上。


解决方案

一个简单的解决方案是使用scrollIntoView() 方法将所需元素带入视口,然后调用moveToElement() 方法,如下所示:

WebElement myElement = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOf(button));
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView();", myElement);
a.moveToElement(webElement).build().perform();

更新

保守的建议是将 java.version: '16.0.2' 替换为稳定的最新 JDK 8u311,因为之前我们在 Java 版本较高时遇到了以下 Selenium 问题:


参考文献

您可以在以下位置找到相关的详细讨论:

【讨论】:

  • moveToElement() 不是已经负责将项目滚动到视图中了吗?
  • 只有当元素可见并且在视口内时才会这样做。
  • 我假设在视口中的元素和我能够在屏幕上看到它之间存在差异?另外,我已经尝试过您的解决方案,但我仍然收到MoveTargetOutOfBoundsException
  • 查看更新的答案并让我知道状态
  • 来自docs:“将鼠标移动到元素的中间。元素滚动到视图中,并使用getClientRects计算其位置。”
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2019-02-06
  • 2013-12-09
  • 2014-04-23
相关资源
最近更新 更多