user9347168
user9347168

Reputation:

Selenium (Java) unable to find element by visible link text

I've gotten one of the more frustrating Selenium problems.

I've got a table on a page, where one of the elements have a link. The link is called "Send brev".

<td data-e2e-selector="sakHendelser" id="sakHendelser_0" class="ng-star-inserted">
  <saksnytt><!----><!----><!---->
   <div class="hb-tekst--ingenBryting ng-star-inserted">
    <!----><!----><!---->
     <button class="hb-knapp hb-knapp--lenke hb-knapp--alignTeks hb-knapp-lenke-nopadding ng-star-inserted" 
      data-e2e-selector="saksnytt-link">
        <i aria-hidden="true" class="fa fa-flag fa-envelope"></i>
        <span class="hb-knapp-tekst">Send brev </span></button> &nbsp;&nbsp;
        <!----><span aria-hidden="true" class="fa fa-info-circle ng-star-inserted" 
        id="reservert-info">
        </span><!----><!----><!----></div><!---->
</saksnytt></td>

This has worked before, and I haven't found a reason for why it's stopped working now. But no matter how I try to find it, Selenium responds with

 no such element: Unable to locate element: {"method":"xpath","selector":"//data-e2e-selector[contains(text(),'Send brev ')]"}

or similar-

I've tried the following:

Browser.Wait().until(presenceOfElementLocated(By.linkText(merknad + " ")));

This times out.

driver.findElement(By.linkText(merknad + " ")).click();
driver.findElement(By.partialLinkText(merknad + " ")).click();
driver.findElement(By.xpath("//data-e2e-selector[contains(text(),'" + "Send brev" +"')]"));    
driver.findElement(By.xpath("//id[contains(text(),'" + "Send brev" +"')]"));
data-e2e-selector="sakHendelser" id="sakHendelser

I've also tried adding a space after the "v" in the link text, with no luck.

How can Selenium not find an element that is clearly visible and interactable like this?

Since the code is generated in Angular, and is more or less dynamic, I cannot create a tag for this specific element either, so I'm left with trying to find it by text. Which I cannot get to work.

Any ideas?

I AM able to click it with this code:

driver.findElement(By.xpath("//*[@id='sakHendelser_0']/saksnytt/div/button/span")).click();

But I want to be able to send the link text to the method instead of hardcoding the xpath like that.

Upvotes: 0

Views: 221

Answers (4)

undetected Selenium
undetected Selenium

Reputation: 193068

You need to take care of a couple of things as follows:

  • By.linkText() and By.partialLinkText() works only for <a> tags, where as the desired element is within a <span> tag.
  • data-e2e-selector and id are attributes of an WebElement but you have tried to use them as tagName.
  • The text Send brev is with in a <span> tag.
  • So identify the element with text as Send brev and moving ahead to interact with it 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.hb-knapp.hb-knapp--lenke.hb-knapp--alignTeks.hb-knapp-lenke-nopadding.ng-star-inserted[data-e2e-selector='saksnytt-link'] span.hb-knapp-tekst"))).click();
    
  • xpath:

    new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[@class='hb-knapp hb-knapp--lenke hb-knapp--alignTeks hb-knapp-lenke-nopadding ng-star-inserted' and @data-e2e-selector='saksnytt-link']//span[@class='hb-knapp-tekst' and contains(., 'Send brev')]"))).click();
    

Upvotes: 0

JeffC
JeffC

Reputation: 25542

LinkText and PartialLinkText will only work with text inside an A tag. You don't have that given your HTML so this will not work. Your only option to locate an element given the contained text is to use XPath.

Upvotes: 1

Sooraj
Sooraj

Reputation: 585

Try using normalize-space with xpath:

//span[normalize-space(text())='Send brev']

Upvotes: 0

CEH
CEH

Reputation: 5909

The way you are using XPath by placing // before an attribute (such as //id or //data-e2e-selector) is not correct. These are element attributes, not tags.

The text Send brev is contained in a span element, so trying to locate it by querying on data-e2e-selector will not work -- that's also not a WebElement, it's an attribute on button.

Because you mention this item has some visible link text that you want to use as a parameter, I would query on only text and use a contains to work around any hidden whitespace:

driver.findElement(By.xpath("//span[contains(text(), 'Send brev')]")).click();

You can use link text as a parameter as such:

string linkText = "Send brev"
driver.findElement(By.xpath("//span[contains(text(), '" + linkText + "')]")).click();

You might have better luck clicking on the button itself though:

driver.findElement(By.xpath("//button[span[contains(text(), '" + linkText + "')]]")).click();

Upvotes: 0

Related Questions