C# / Selenium - failing to find XPath text using contains()

I have and html element that I wish to click using Selenium:

<a class="epi-navigation-global_user_settings_shell_search " href="DatabaseJob.aspx?pluginId=20">
                                            Importer obligationsliste
                                        </a>

With the following xpath: /html/body/form/div[4]/div[1]/div/ul/li[2]/ul/li[19]/a

I attempt to click the element containing the text "Importer obligationsliste" by the following expression:

var obligationButton = By.XPath("//a[contains(text(), 'Importer')]");
wait.Until(ExpectedConditions.ElementToBeClickable(obligationButton)).Click();

Yet the element is never found. I've also tried the full string Importer obligationsliste to no avail. Any ideas why the element is not being found? I suspect it has to do with the whitespace around the text, but contains() should also be able to find substrings.

Upvotes: 0

Views: 810

Answers (2)

undetected Selenium
undetected Selenium

Reputation: 193108

The text Importer obligationsliste have a lot of leading and trailing whitespaces. So to Click() on the element you have to induce WebDriverWait for the desired ElementToBeClickable() and you can use either of the following Locator Strategies:

  • Using XPath with contains() for the text Importer obligationsliste:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a[contains(., 'Importer obligationsliste')]"))).Click();
    
  • Using XPath with normalize-space() for the text Importer obligationsliste:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a[normalize-space()='Importer obligationsliste']"))).Click();
    
  • Using XPath:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("//a[@class='epi-navigation-global_user_settings_shell_search ' and starts-with(@href, 'DatabaseJob')]"))).Click();
    
  • Using PartialLinkText:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.PartialLinkText("Importer obligationsliste"))).Click();
    
  • Using CssSelector:

    new WebDriverWait(driver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.CssSelector("a.epi-navigation-global_user_settings_shell_search[href^='DatabaseJob']"))).Click();
    

Upvotes: 1

Dazed
Dazed

Reputation: 1551

Please go to https://www.w3schools.com/xml/xpath_intro.asp and read about writing xpath. Grabbing paths from Chrome is the worst thing you can do. Those paths take longer to find and are extremely brittle. On dev change adding a div, ul or li and your path will break.

If it is not in an iframe, try these:

//a[contains(text(), 'Importer obligationsliste')]
//a[normalize-space()='Importer obligationsliste']

Upvotes: 0

Related Questions