0

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?

Peter Penzov
  • 1,126
  • 134
  • 430
  • 808

2 Answers2

1

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 however within your code trials you considered it as a .

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

Update

For the element within parent1:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//parent1//button[@id="source-lp.select-lp.button"]"))).click();

For the element within parent2:

new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//parent2//button[@id="source-lp.select-lp.button"]"))).click();
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Thank you for the provided solution. However I found one issue: I have multiple components which hold inner components with same id. Example: `//parent1/componet//button[@id="source-lp.select-lp.button"]"` and `//parent2/componet2//button[@id="source-lp.select-lp.button"]"` What are the available options here? – Peter Penzov Jan 15 '22 at 00:27
  • @PeterPenzov Checkout the answer update and let me know the status. – undetected Selenium Jan 15 '22 at 13:19
-1

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.

JeffC
  • 22,180
  • 5
  • 32
  • 55
  • I got error `org.openqa.selenium.ElementNotInteractableException: element not interactable` – Peter Penzov Jan 14 '22 at 09:10
  • The code you have provided doesn't interact with any elements so I can't really comment on why you're getting that error. If you need help, you should create a new question that contains the relevant code and HTML as well as the error message, etc. – JeffC Jan 14 '22 at 14:52
  • `ElementNotInteractableException` means that the element you've located and are trying to interact with is probably hidden or somehow otherwise not interactable. I would suggest you check your locator and make sure that you are finding the element you are intending to find. – JeffC Jan 14 '22 at 14:54