XPATH conditional exclusion - xpath

I have a html fragment that looks like the following;
<div class="sideBar">
<ul>
<li class="test testlist">
<div>test 1</div>
<ul>
<li class="test testlist"><div>sub test1</div></li>
<li class="test testlist"><div>sub test2</div></li>
</ul>
</li>
<li class="test testlist"><div>test 2</div></li>
</ul>
</div>
I need to get node list number two containing text "test 2", but when I try the following;
//div[contains(#class, 'sideBar')]//li[#class=\"test testlist\"])[2]//div
It returns node;
<li class="test testlist"><div>sub test2</div></li>
How would I go about returning node please;
<li class="test testlist"><div>test 2</div></li>
Many thanks,
C.

I'm not sure what the rule should be to get node with text "test 2".
First of all your xpath has a wrong parenthesis (copy past error):
//div[contains(#class, 'sideBar')]//li[#class=\"test testlist\"] -->)<-- [2]//div
There are two interpretation:
//div[contains(#class, 'sideBar')]//li[#class='test testlist'][2]//div"
Which will select all li (with class test testlis) descendant to the div which on second position to the parent.
Or:
(//div[contains(#class, 'sideBar')]//li[#class='test testlist'])[2]//div
Which will select the the second li (with class test testlis) of the three found.
Both is not what you like to have. Therefore try:
(//div[contains(#class, 'sideBar')]//li[#class='test testlist'][2])[2]//div
The second of the two on position two.
Or best(in my view):
//div[contains(#class, 'sideBar')]/ul/li[#class='test testlist'][2]//div"
The second li in the first direct child ul of the div .

Related

Cypress: How to get <li> only without its children <li>?

I'm recently using cypress and I want to get the array of list but I just want the to get <li> under the class "list" and not including the other children of <li>
I'm using
cy.get('.list >li')
but I'm also getting the children <li> under Home.
<ul class="list">
<li>Home</li>
<ul>
<li>Another One</li>
<li>Another Two</li>
</ul>
<li>Page</li>
<li>Hello</li>
<li>Hi</li>
</ul>
you have two ways to do this
get only li children of parent
cy.get('.list').children('li')
get children by level in dom
cy.get('.list > li')
.its('length')
.should('eq', 2)
You can also use the combination of selector and text using contains. In this way you will only get the intended li element.
cy.contains('li', 'Home')
You can do something like this as well:
cy.get('ul.list > li').each(($ele) => {
cy.log($ele.text()) //prints Home Page Hello Hi
})
Created a small POC from your HTML and this is what I got:

how can i click the value of li element of embedded li class(some-menu-item-optional-value)

I want to click the third value(embedded li element) given the below code snippet, any help?
some-menu-title-value
some-menu-item-default-value
some-menu-item-optional-value
Assuming that the element will always be the 2nd <li> element, you can use:
element.all(by.css('li')).get(1).click();
If there are other <li> elements on the page, you can refine the css selector like:
element.all(by.css('li.some-menu-items')).get(1).click();
Its hard to tell from the HTML provided, but if your elements are nested like so:
<div class="myClass"
<li class="myClass"
<li class="myClass"</li>
</li>
</div>
Then you could do element(by.css('div>li>li')).click(); to click the inner <li> element.

Select visible xpath in list

I am trying to get the error message off of a page from a site. The list contains several possible errors so i can't check by id; but I do know that the one with display:list-item is the one I want. This is my rule but doesn't seem to work, what is wrong with it? What I want returned is the error text in the element.
//*[#id='errors']/ul/li[contains(#style,'display:list-item')]
Example dom elements:
<div id="errors" class="some class" style="display: block;">
<div class="some other class"></div>
<div class="some other class 2">
<span class="displayError">Please correct the errors listed in red below:</span>
<ul>
<li style="display:none;" id="invalidId">Enter a valid id</li>
<li style="display:list-item;" id="genericError">Something bad happened</li>
<li style="display:none;" id="somethingBlah" ............ </li>
....
</ul>
</div>
The correct XPath should be:
//*[#id='errors']//ul/li[contains(#style,'display:list-item')]
After //*[#id='errors'] you need an extra /, because <ul> is not directly beneath it. Using // again scans all underlying elements for <ul>.
If you are capable to not use // it would be better and faster and less consuming.

Select elements which has certain descendent using Xpath

I want to Select all the LI elements which contain SPAN with id="liveDeal152_dealPrice" as descendents. How do i do this with xpath?
Here is a sample html
<ul>
<li id="liveDeal_152">
<p class="price">
<em>|
<span class="WebRupee">₹ </span>
<span id="liveDeal152_dealPrice">495 </span>
</p>
</li>
<li id="liveDeal_152">
<p class="price">
<em>|
<span class="WebRupee">₹ </span>
(price hidden)
</p>
</li>
</ul>
//li[.//span[#id = 'liveDeal152_dealPrice']] should do. Or more verbose but closer to your textual description //li[descendant::span[#id = 'liveDeal152_dealPrice']].
Use this
//li[.//span[#id="liveDeal152_dealPrice"]]
It selects
ALL <li> ELEMENTS
//li[ ]
THAT HAVE A <span> DESCENDANT
.//span[ ]
WITH id ATTRIBUTE EQUAL TO "liveDeal152_dealPrice"
#id="liveDeal152_dealPrice"
That said, it doesn't seem like a very wise element selection, mostly due to the dynamically looking id. If you're going to use it once, it's probably ok, but if you're using it, say, for testing and will reuse it many times, it might cause trouble. Are you sure this won't change when you change your website and/or database?
As a side note:
ul stands for "unordered list"
ol stands for "ordered list"
li stands for "list item"

How can I select the 6th option in the list?

<div id="suggestionlist">
<ol id="suggestionroot">
<li id="sugg_1">
<li id="sugg_2">
<li id="sugg_3">
<li id="sugg_4">
<li id="sugg_5">
<li id="sugg_6">
<li id="sugg_7">
<li id="sugg_8">
<li id="sugg_9">
<li id="sugg_10">
I have a search look ahead feature which I'm trying to automate. I'm trying to pick the 6th option in the list every time but I just can't seem to locate it! This is the nearest I've got but it's not working..
#Browser.div(:id, "suggestionlist").link(:index, 6).click
You should do some reading about HTML. <li> tag is not link, <a> tag is link.
So, to click <li id="sugg_6"> try this:
browser.li(:id => "sugg_6").click
To click a link inside the list item (not shown in your HTML but referenced in comments)
browser.li(:id => "sugg_6").link.click
(that presumes you want to click the first/only link inside the LI, otherwise you might need to specify an index value)
Did you try to access this element by XPath?
browser.find_elements_by_xpath("div[#id='suggestionlist'/li[6]").click

Resources