2

This is the code of the demo store I want to test:

 <li class="level0 nav-2 parent">
      <a href="http://demo-store.seleniumacademy.com/men.html" 
               class="level0 has-children">Men</a> 
        <ul class="level0">
            <li class="level1 view-all">
               <a class="level1" href="http://demo- 
                         store.seleniumacademy.com/men.html">View All 
                         Men</a>
            </li>
               <li class="level1 nav-2-1 first"><a></a></li>
               <li class="level1 nav-2-2"><a href="http://demo- 
                          store.seleniumacademy.com/men/shirts.html" 
                          class="level1">text to get</a> 
               </li>
               <li class="level1 nav-2-3"><a></a></li>
         </ul>
    </li>

I want to get text of those subcategories so I can later click on specific category by using text inside of a link element. My code is:

public Subcategory openSubcategory (String subcategoryName){

    List<WebElement> subcategories = driver.findElements(By.cssSelector("a.level1"));

    for (WebElement element: subcategories) {
        if (element.getText().equals(subcategoryName)){
            element.click();
            break;
        }
    }
    return new Subcategory(driver);
}

But it won't go inside loop, probably because element.getText() is empty.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Maybe you are missing some delay / wait here? – Prophet Feb 15 '22 at 11:43
  • Try with https://api.jquery.com/text/ or https://api.jquery.com/html/ methods – Garci García Feb 15 '22 at 11:44
  • I tried to add wait but implicit wait get crossed out. Maybe I put wait on a wrong place. Where shoud it be? – Stefan Itic Feb 15 '22 at 11:49
  • @StefanItic I meant to put a delay, not implicit wait. Put it before the line where you collecting the elements. I.e. before `List subcategories = driver.findElements(By.cssSelector("a.level1"));` – Prophet Feb 15 '22 at 12:01
  • @Prophet Sorry but i'm newbie here, so I don't know how to add delay. I just know about implicit and explicit waits... Can you give me the code that I should implement inside, plese? – Stefan Itic Feb 15 '22 at 12:05
  • I mean something like `Thread.sleep(2000);` A simple, dummy pause. – Prophet Feb 15 '22 at 12:08
  • In case this will help we will be able to do this with explicit wait as well – Prophet Feb 15 '22 at 12:08
  • org.openqa.selenium.ElementNotInteractableException: element not interactable – Stefan Itic Feb 15 '22 at 12:11
  • http://demo-store.seleniumacademy.com/ This is the store where I want to click on MEN -> SHIRTS, I tried everything and after 4 days I'm here, looking for help... Maybe you can find something inside code that i didn't see, that's why I pasted link to the store. – Stefan Itic Feb 15 '22 at 12:15
  • @StefanItic debug your code and try using other queries to see if those go through(eg. `".level1"`). – Alias Cartellano Feb 15 '22 at 17:31
  • ((RemoteWebElement)element).id = Cannot find local variable 'element' – Stefan Itic Feb 15 '22 at 17:49

2 Answers2

1

element.getText() can be empty.

Try:

element.getAttribute("value");
// or
element.getAttribute("innerHTML");

Change your CSS to be:

"a[class*='level']";
// or
"a[]";

Debug the code and check if the element is not null

Tal Angel
  • 1,301
  • 3
  • 29
  • 63
1

To click on the WebElement with text as Shirts first you have to Mouse Hover the element with text as Men inducing WebDriverWait for the visibilityOfElementLocated and you can use the following locator strategies:

public Subcategory openSubcategory (String subcategoryName){

    WebElement menuMen = new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[contains(@class,'has-children') and text()='Men']")));
    new Actions(driver).moveToElement(menuMen).build().perform();
    List<WebElement> subcategories = driver.findElements(By.xpath("//a[contains(@class,'has-children') and text()='Men']//following::ul[1]//li/a"));
    for (WebElement element: subcategories) {
        if (element.getText().equals(subcategoryName)){
            element.click();
            break;
        }
    }
    return new Subcategory(driver);
}
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • 1
    OMG it's finally working!!!! Thank you sooo much!! Can you please explain to me how do you use xpath? I used it on a very simple way, but I don't understand everything you typed in xpath. – Stefan Itic Feb 16 '22 at 09:28
  • 1
    @StefanItic The element with text _**Men**_ has the _class_ _`level0 has-children`_ where as I considered only _`has-children`_ as I suspected _`level0`_ to be dynamic. Further the desired `
      ` element in just the following element which have a descendant `li -> a`
    – undetected Selenium Feb 16 '22 at 11:43