I am trying to click a link that is on a dropdown menu. This dropdown menu appears when I hover over a button. Right now, my test crashes with a MoveTargetOutOfBoundsException
, which happens when I try to hover the button. When I open the page in my browser, I have no trouble finding or hovering over the button, as it doesn't seem to be outside of the viewport by any means.
The code I use to hover the button is:
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");
}
}
Then, the test waits for the dropdown menu to appear and loops through the available options to find the desired one, and finally clicks it:
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");
}
Now, when I comment out a.moveToElement(button).build().perform();
, run the test and move the mouse to the button myself in order to display the dropdown menu, the test is terminated instead by the Assert.fail()
call. This means that the test does find a list of links, since dataItems.size() == 0
evaluates to false, but it is unable to find the desired link on the dropdown menu. I have added a print method to print the text of all the links on the dropdown menu that appears:
private void printDataItems() {
for (WebElement item: dataItemsText) {
System.out.println(item.getText());
}
}
but that just prints 5 empty Strings
.
When I look for the elements that contain the link texts on the dropdown menu in devTools with the selector div[class='dataitems'] a span
, it lists all the links and highlights the link texts like it should, but it doesn't work when I try it with Selenium.
The text nodes look like this:
I have manually checked all my locators, and they are all correct, so I don't know what I'm doing wrong here. I should note that I run into this issue with chromedriver (96) and edgedriver (95), but not with geckodriver (94). When I run this test with geckodriver, the test script correctly hovers the button, prints out all the available links on the dropdown menu and clicks the link. Any ideas?
Edit: As requested, here are the locators for the WebElements that I refer to in my question:
@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;
And the stacktrace of the MoveTargetOutOfBoundsException (I'm assuming it is this):
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)
Edit: solved
I contacted our frontend dev, and they asked to try it on the production environment. It worked there, and after some searching I noticed that the containing element that I was trying to interact with had zoom: 90%
. I ran my test, paused it and set the element zoom
to 100% in devTools, and continued execution; everything worked again.
I did some digging, and apparently this is a known thing: link