Reputation:
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>
<!----><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
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.<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
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
Reputation: 585
Try using normalize-space with xpath:
//span[normalize-space(text())='Send brev']
Upvotes: 0
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