Cypress: Find plain text element under a span with other html element - selenium

How can we find the text element in the html DOM below. I need to get the text "Hello World1", "Hello World2", "Hello World3". I tried getting all span element with "class1" and called text() method but it's not returning the Hello world text.
Edit: I need a solution to iterate through the Hello World texts and compare it against an another text passed to a function and find the containing span element and click on it.
<div>
<span class="class1">
<span class="class2">
"Text1"
</span>
"Hello World 1"
</span>
<span class="class1">
<span class="class2">
"Text2"
</span>
"Hello World 2"
</span>
<span class="class1">
<span class="class2">
"Text3"
</span>
"Hello World 3"
</span>
</div>

You can directly use the text and add a visible assertion like this:
cy.contains('Hello World 1').should('be.visible')
cy.contains('Hello World 2').should('be.visible')
cy.contains('Hello World 3').should('be.visible')

Related

xpath: find element by text between tags

We can find element by inner text, for example:
<span>
<div>
Example Text
</div>
<div>
Other Text
</div>
</span>
In this case we can use follow xpath: //span/div[contains(text(), 'Example')]
But how can I found element when the text exist out of the tag?
For example:
<span>
<div id="1">
...........
</div>
Example Text
<div id="2">
......
</div>
Other Text
</span>
And shat if, I haven't id on the div tags, and I can't use order?
<span>
...........
<div>
...........
</div>
Example Text
<div>
......
</div>
Other Text
</span>
You can use xpath axes to select siblings.
//text()[contains(.,"Example")]//preceding-sibling::div[1]
You can use this XPath
//span[contains(text(),'Example Text')]//div[#id='1']
For the first div.
The same for the second div
//span[contains(text(),'Example Text')]//div[#id='2']
Generally, in this case the "Example Text" text is contained by the parent span element.
So you can locate the parent span according to this text and then drill down to the child div.

How can I find out what number in <ul> some <li> element is? In Selenium

I have a < ul > with unknown number of < li > elements. Each < li > has some text and also a button. How can I identify which < li > contains the text I'm looking for, in order to click the button in that same < li >?
<ul>
<li class="ot-queryitem row-fluid">
<div class="ot-queryitem__info ot-queryitem__info--left span7">
<span class="ot-queryitem__name">Äänikysely (Voice Activity and Participation Profile)</span>
</div>
<div class="ot-queryitem__info ot-queryitem__info--center span3"></div>
<div class="ot-queryitem__info ot-queryitem__info--right span2">
<button class="ot-button ot-button--undefined pull-right ot-queryitem__button">
<i class="icon-pencil fa ot-icon ot-icon--default" style="margin-right: 8px;"></i>
<span>Täytä</span>
</button>
<span class="ot-queryitem__logo"></span></div></li>
<li class="ot-queryitem row-fluid">
<div class="ot-queryitem__info ot-queryitem__info--left span7">
<span class="ot-queryitem__name">Nikotiiniriippuvuustesti</span>
</div>
<div class="ot-queryitem__info ot-queryitem__info--center span3"></div>
<div class="ot-queryitem__info ot-queryitem__info--right span2">
<button class="ot-button ot-button--undefined pull-right ot-queryitem__button">
<i class="icon-pencil fa ot-icon ot-icon--default" style="margin-right: 8px;"></i>
<span>Täytä</span>
</button>
<span class="ot-queryitem__logo"></span></div></li>
//span[text()='Nikotiiniriippuvuustesti'] will give you a <span> with the given text
/ancestor::li axis will give you the parent <li> tag
/descendant::button axis will give you the <button> you're looking for
Putting everything together:
//span[text()='Nikotiiniriippuvuustesti']/ancestor::li/descendant::button
Demo:
References:
XPath Tutorial
XPath Axes
XPath Operators & Functions
Try the following xpath.
xpath: //ul//li[contains(.,'Nikotiiniriippuvuustesti')]//button
OR
xpath: //ul//li[contains(.,'Äänikysely')]//button
However You can pass this Nikotiiniriippuvuustesti or Äänikysely as string variable in robotframework.Hope this helps.
Both the element with the text and the button are child elements under each <li>. You need to go up the html tree from the text and then look for a button under a sibling element
//div[span[contains(., 'Äänikysely')]]/following-sibling::div/button
To identify li tag which contains text you looking for as -
${YOUR_TEXT} Nikotiiniriippuvuustesti
## this keyword will give first matching element
${elements}= Get WebElement xpath://span[contains(text(),'${YOUR_TEXT}')]/ancestor::li
### wait for element to be present on page
Wait Until Page Contains Element ${elements}
## now click on button inside li tag found in above lines
Click Button xpath://span[contains(text(),'${YOUR_TEXT}')]/ancestor::li//button
note: locators are taken from the html sample you provided
You don't have to count the number of <li> within the <ul>.
To click on the respective button according to the text e.g. Äänikysely, Nikotiiniriippuvuustesti etc you can use the following solution:
To click for Äänikysely:
Click Button xpath://div[contains(#class, 'ot-queryitem__info--left')]/span[contains(.,'Äänikysely')]//following::button[#class='ot-button ot-button--undefined pull-right ot-queryitem__button']//span[text()='Täytä']
To click for Nikotiiniriippuvuustesti:
Click Button xpath://div[contains(#class, 'ot-queryitem__info--left')]/span[contains(.,'Nikotiiniriippuvuustesti')]//following::button[#class='ot-button ot-button--undefined pull-right ot-queryitem__button']//span[text()='Täytä']

Xpath for div with span having a css class get its sibling anchor link

I want all div's anchor link whose span having css class ='block-diff-neutral'
<div class="file-info" xpath="1">
<span class="diffstat tooltipped tooltipped-e" aria-label="0 ">
<span class="block-diff-deleted"></span>
<span class="block-diff-deleted"></span>
<span class="block-diff-neutral" style=""></span>
<span class="block-diff-neutral"></span>
<span class="block-diff-neutral"></span>
</span>
someText
</div>
<div class="file-info" xpath="1">
<span class="diffstat tooltipped tooltipped-e" aria-label="0 ">
<span class="block-diff-deleted"></span>
<span class="block-diff-deleted"></span>
</span>
someText2
</div>
Here div contains 2 subtags i.e. span and a
if span contains a css class as 'block-diff-neutral' only then get the a tag's title attribute => xpath with this condition is required
Expected output is => someText or file1
Your markup looks invalid (it's missing some closing tags) and it looks over convoluted in places (multi-layered <span> tags).
However this should do what you want if I've understood your requirements correctly.
//div[#class="file-info"][./descendant-or-self::span[#class="block-diff-neutral"]]/a
if the span with a missing closing tag is actually a parent of the anchor this would be better:
//div[#class="file-info"][./descendant-or-self::span[#class="block-diff-neutral"]]/descendant-or-self::a
This will find a div with a class of file-info that has a descendent <span> element with the class block-diff-neutral and then find the anchor inside that div element.
To get the title attribute out of the WebElement you would find with this XPath you will need to use .getAttribute("title")
Try the following Xpath.
//span[#class='block-diff-neutral']/parent::span/parent::div/a
Or use following sibling
//span[#class='block-diff-neutral']/parent::span/following-sibling::a
If you are using python use following code and use any of the xpath locator above.
driver.find_element_by_xpath("//span[#class='block-diff-neutral']/parent::span/parent::div/a").text
driver.find_element_by_xpath("//span[#class='block-diff-neutral']/parent::span/parent::div/a").get_attribute("title")
If you are using java try below code and any locator mentioned above.
driver.findElement(By.xpath("//span[#class='block-diff-neutral']/parent::span/following-sibling::a").getText()
driver.findElement(By.xpath("//span[#class='block-diff-neutral']/parent::span/following-sibling::a").getAttribute('title')

Selenium XPath of preceding element

I have a scenario wherein the html tags are generated dynamically through ajax as shown below
<div>
<span class="rptName">QLMS</span>
<span id="button_id_91">//generated dynamically
<span id="button_span_right_91">
<span id="button_91"/>
</span>
</span>
<span class="rptName">QLRS</span>
<span id="button_id_92">//generated dynamically
<span id="button_span_right_92">
<span id="button_92"/>
</span>
</span>
</div>
The span elements are generated dynamically, in such scenarios how do we get the xpath based on the text search(QLMS,QLRS present in span).
I need to do an click event on the
<span id="button_92" or "91"/>
Please let me know how to achieve in such scenario.
Seems pretty tricky. Using following-sibling should help. I am also filtering out the span with the partial id right. Try this:
//span[contains(text(),'QLRS')]/following-sibling::span//span[not(contains(#id,'right'))]

xpath not finding text inside <div><span>

.//*[contains(text(), "Apply")]
<input type="hidden" value="false" name="needsValidation"/>
<input type="hidden" value="false" name="fullValidationPerformed"/>
<div class="loadingBox hidden">
<div class="paneContent">
<div class="topButtons">
<div class="rightSide">
<div id="saveChangesButton" class="majorButton">
<div>
<div>
<div>
<span class="hidden"/>
Apply Changes
<span class="down"/>
</div>
</div>
</div>
</div>
</div>
Why is it that the xpath string I created doesn't find "Apply" here? It appears that my xpath statement only fails when the text I want to find is inside a "span" tag inside a "div" tag like this.
Can someone help me understand what I'm missing here please?
The reason that contains(text(), 'Apply') does not work is that the element has several text nodes, and the contains function in XPath 1.0 ignores all but the first. (XPath 2.0 would give you an error if there is more than one).
If you want to get an element whose string value contains 'Apply' without also returning its ancestors, the simplest way is to get the last element containing this string:
(//*[contains(., 'Apply')])[last()]