Selenim chrome driver unable to locate nested <li> tags

Viewed 83

I'm trying to locate nested nl tag which I cannot get it from by.xpath query.

Here is my relevant line of code in java.

driver.findElement(By.xpath("//div[@id='navbarNav']/following-sibling::ul[1]/li[2]")).click();

` I want to match:

<a class="sub-nav-link style-scope app-shell active" href="#/trend-analysis/tag-search">Trend Analysis

Error:

Exception in thread "main" org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//div[@id='navbarNav']/following-sibling::ul[1]"}
  (Session info: headless chrome=85.0.4183.102)
For documentation on this error, please visit: http://seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:13:22.693Z'
System info: host: 'root', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-118-generic', java.version: '1.8.0_265'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 85.0.4183.102, chrome: {chromedriverVersion: 85.0.4183.87 (cd6713ebf92fa..., userDataDir: /tmp/.com.google.Chrome.qnBVf1}, goog:chromeOptions: {debuggerAddress: localhost:35357}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: 99a0f9193871a6e94151d885c331875d
*** Element info: {Using=xpath, value=//div[@id='navbarNav']/following-sibling::ul[1]}
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        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:548)
        at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:322)
        at org.openqa.selenium.remote.RemoteWebDriver.findElementByXPath(RemoteWebDriver.java:424)
        at org.openqa.selenium.By$ByXPath.findElement(By.java:353)
        at org.openqa.selenium.remote.RemoteWebDriver.findElement(RemoteWebDriver.java:314)
        at GettingStarted.main(GettingStarted.java:96)

Relevant HTML:

<div class="collapse navbar-collapse style-scope app-shell" id="navbarNav">
                <ul class="app-nav navbar-nav mr-auto style-scope app-shell">
                    <li class="nav-item style-scope app-shell">
                        <a class="nav-link p-3 px-4 style-scope app-shell" href="/#/dashboard">Dashboard</a>
                    </li>
                    <li class="nav-item style-scope app-shell">
                        <a class="nav-link py-3 px-4 style-scope app-shell active" href="/#/trend-analysis/tag-search">TrendAnalysis</a>
                        <ul class="sub-nav d-flex flex-row flex-nowrap list-unstyled style-scope app-shell">
                            <li class="sub-nav-item style-scope app-shell">
                                <a class="sub-nav-link style-scope app-shell active" href="#/trend-analysis/tag-search">
                                    Trend Analysis
                                </a>
                            </li>
                            <li class="sub-nav-item style-scope app-shell">
                                <a class="sub-nav-link style-scope app-shell" href="#/trend-analysis/value-based-search">
                                    Value-Based Search
                                </a>
                            </li>
                  .....

I have spend whole week fixing the issue but no avail, kindly help thanks.

I tested the code with

WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@id='navbarNav']/ul")));

driver.findElement(By.xpath("//div[@id='navbarNav']//li/a[contains(@href,'tag-search')]")).click();

Update:

Exception in thread "main" org.openqa.selenium.TimeoutException: Expected condition failed: waiting for element to be clickable: By.xpath: //div[@id='navbarNav']/ul (tried for 30 second(s) with 500 milliseconds interval)
Build info: version: '3.14.0', revision: 'aacccce0', time: '2018-08-02T20:13:22.693Z'
System info: host: 'root', ip: '127.0.1.1', os.name: 'Linux', os.arch: 'amd64', os.version: '4.15.0-118-generic', java.version: '1.8.0_265'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 85.0.4183.102, chrome: {chromedriverVersion: 85.0.4183.87 (cd6713ebf92fa..., userDataDir: /tmp/.com.google.Chrome.7m6LU4}, goog:chromeOptions: {debuggerAddress: localhost:38779}, javascriptEnabled: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: LINUX, platformName: LINUX, proxy: Proxy(), setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:virtualAuthenticators: true}
Session ID: 6e2d32881f709e2e0d727d8cc45813c4
        at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:113)
        at org.openqa.selenium.support.ui.FluentWait.until(FluentWait.java:283)
        at GettingStarted.main(GettingStarted.java:103)

Update 2:

when i run the code with just:

driver.findElement(By.xpath("//div[@id='navbarNav']//li/a[contains(@href,'tag-search')]")).click();

I get:

Exception in thread "main" org.openqa.selenium.ElementNotInteractableException: element not interactable
  (Session info: headless chrome=85.0.4183.102)
3 Answers

Add some wait before clicking on the element.

String myElement = "(//div[@id='navbarNav']//li/a[contains(@href,'tag-search')])[1]";    
WebDriverWait wait = new WebDriverWait(driver, 30);
 wait.until(ExpectedConditions.elementToBeClickable(By.xpath(myElement)));

or

wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(myElement)));

or

wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(myElement)));

You also need to target the correct anchor element using xpath.

driver.findElement(By.xpath(myElement)).click()

Check with Threads.sleep(10), that either with that time element is clickable or not, if element is not clickable it should be the xpath you are making is wrong.

But If it is clicking, Then Use 2 waits side by side Like This:

String myElement = "(//div[@id='navbarNav']//li/a[contains(@href,'tag-search')])[1]";    
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath(myElement)));
wait.until(ExpectedConditions.elementToBeClickable(By.xpath(myElement)));
driver.findElement(By.xpath(myElement)).click()

To click() on the element with text as Trend Analysis you can use either of the following Locator Strategies:

  • linkText:

    driver.findElement(By.linkText("Trend Analysis")).click();
    
  • partialLinkText:

    driver.findElement(By.partialLinkText("Trend Analysis")).click();
    
  • cssSelector:

    driver.findElement(By.cssSelector("div#navbarNav li.sub-nav-item.style-scope.app-shell>a[href$='tag-search']")).click();
    
  • xpath:

    driver.findElement(By.xpath("//div[@id='navbarNav']//li[@class='sub-nav-item style-scope app-shell']/a[contains(@href, 'tag-search')][contains(., 'Trend Analysis')]")).click();
    

Ideally, to click() on the element you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the following Locator Strategies:

  • linkText:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.linkText("Trend Analysis"))).click();
    
  • partialLinkText:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Trend Analysis"))).click();
    
  • cssSelector:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div#navbarNav li.sub-nav-item.style-scope.app-shell>a[href$='tag-search']"))).click();
    
  • xpath:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//div[@id='navbarNav']//li[@class='sub-nav-item style-scope app-shell']/a[contains(@href, 'tag-search')][contains(., 'Trend Analysis')]"))).click();
    
Related