I want to click on button using partial css path:
Full xpath:
// /html/body/div[1]/div[2]/div/mat-dialog-container/mobileweb-outbound-pick-picking-dialog/mobileweb-outbound-pick-confirmation/div/div/div/mobileweb-client-area/div/div/div/div[2]/div/div[1]/mobileweb-action-button[1]/div/button
// //*[@id="source-lp.select-lp.button"]
I tried this Java Selenium web driver code:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(20));
WebElement until = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("//mat-dialog-container/mobileweb-outbound-pick-picking-dialog/mobileweb-outbound-pick-confirmation//*[@id=\"source-lp.select-lp.button\"]")));
But I get error:
org.openqa.selenium.TimeoutException: Expected condition failed: waiting for presence of element located by: By.cssSelector: //mat-dialog-container/mobileweb-outbound-pick-picking-dialog/mobileweb-outbound-pick-confirmation//*[@id="source-lp.select-lp.button"] (tried for 20 second(s) with 500 milliseconds interval)
at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:138)
at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:231)
at org.mobile.outbound.pick.picking.clusterpicking.ClusterPickingPickTest.buildEmptyClusterFromShipmentId(ClusterPickingPickTest.java:361)
at org.mobile.outbound.pick.picking.clusterpicking.ClusterPickingPickTest.Mobile_Web_Cluster_Picking_Pick_66732(ClusterPickingPickTest.java:176)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:133)
at org.testng.internal.TestInvoker.invokeMethod(TestInvoker.java:598)
at org.testng.internal.TestInvoker.invokeTestMethod(TestInvoker.java:173)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:46)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:824)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:146)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.testng.TestRunner.privateRun(TestRunner.java:794)
at org.testng.TestRunner.run(TestRunner.java:596)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:377)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:371)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:332)
at org.testng.SuiteRunner.run(SuiteRunner.java:276)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1212)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1134)
at org.testng.TestNG.runSuites(TestNG.java:1063)
at org.testng.TestNG.run(TestNG.java:1031)
at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)
Caused by: org.openqa.selenium.InvalidSelectorException: invalid selector: An invalid or illegal selector was specified
Do you know how I can fix this issue?
CodePudding user response:
The problem is that you've specified an XPath but used By.cssSelector().
Your second line should be
WebElement until = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//mat-dialog-container/mobileweb-outbound-pick-picking-dialog/mobileweb-outbound-pick-confirmation//*[@id=\"source-lp.select-lp.button\"]")));
Also note that the XPath you put in your question is not the same one you are using in the code you posted.
XPaths that start at //html, have that many levels, and/or use indices are very brittle (they break easily with even small changes to the page). You should spend some time learning how to handcraft locators to avoid this issue.
That giant XPath you have can be reduced down to just By.id("source-lp.select-lp.button") instead of an XPath. Always look for ids, names, and other attributes that are unique on the element before turning to a large XPath.
CodePudding user response:
You are seeing...
org.openqa.selenium.InvalidSelectorException: invalid selector: An invalid or illegal selector was specified
...as the Locator Strategy you have used is a qualified xpath however within your code trials you considered it as a css-selectors.
Further, as per your code trials assuming the element to be a button element with value of id attribute as source-lp.select-lp.button, you can use a relative locator and you can use either of the Locator Strategies:
xpath:
//button[@id="source-lp.select-lp.button"]cssSelector:
button[id="source-lp.select-lp.button"]
Ideally, to click() on any clickable element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:
cssSelector:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button[id="source-lp.select-lp.button"]"))).click();xpath:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@id="source-lp.select-lp.button"]"))).click();
