I have currently got a situation where I need to get all elements on a page, iterate through the elements 1 by 1 and within each element, I want to see if a certain other element exists.
To make it more clear, this is my loop:
${elements} = Get WebElements //li[#class='product-item--row js_item_root ']
FOR ${item} IN #{elements}
This is the part where I need to check within ${item} if the xpath exists:
//*[contains(text(), '${companyname}')]
END
So basically, I have 24 elements on my page which have the xpath
//li[#class='product-item--row js_item_root ']
I have 1 element on my page which can be located by xpath
//li[#class='product-item--row js_item_root ']//*[contains(text(), '${companyname}')]
And I want to know, within the 24 elements, which place the element is located which contains
//*[contains(text(), '${companyname}')]
Hoping someone can help!
Edit
This does not work:
Element should be visible ${item}//*[contains(text(), 'BargainsKing')]
And that's because:
Element with locator '<selenium.webdriver.remote.webelement.WebElement (session="4b40581d8835aac628e3a2032e355ee5", element="663438f7-76eb-4801-b255-021a865035dd")>//*[contains(text(), 'BargainsKing')]' not found.
Edit
I found the
${item.get_attribute('innerHTML')}
Now my next/final question is, can I look up an xpath within this innerHTML?
A solution is to count the number of elements and then get a FOR to cycle all elements
${count} Get Element Count XmlLocatorForAllElements
FOR ${i} IN RANGE 1 ${count}
${tmpElement} Get Element Count XmlLocator[${i}]/WithCompany
IF ${tmpElement} > ${0}
#element found
END
END
Could you please provide more detail about the selectors?
For now, I think you should try this:
You can check in the selector if there are any incremental values
if not then add a counter for each row
for selecting a specific column you can either go with the counter or the company name in Xpath
Related
I have a date picker on my website,
It contains a list of elements for each week
and then those include 7 elements for each day
2930311234
Now I'm trying to xpath find the last button with class "is-selected"
And I'd also like to go trough each week since I want the last possible date ( "is-selected" means avaible)
I've tried
.//div[#'available-dates-calendar']//table/?[last()='True']//button[last()='True']
But that gave me the first element...
For the last() condition to work, I think that you would have to use the spy to create a XPath query that finds all buttons.
When such a query is found, then you can use the last() condition to find the last in the list of items found.
Hope this helps.
I believe you can use the [-1] identifier to grab the last element. So, instead of [last()='True'], use [-1].
I'm trying to get the current position of a xpath match. Here is a real world example
on this page http://newyork.backpage.com/homes-for-sale/
running the following xpath matches the 8th listing counting from top
//div[contains(#class, 'cat 93893742')]
I want to somehow get the ad position using xpath which at the time of posting this question is "8". I tried using prececeding-sibling::div but I am getting unexpected results.
Anyway to achieve this with xpath?
I'm not sure wether current version of htmlunit supports XPath 2.0, but if so you can use below expression:
index-of(//div[starts-with(#class, "cat")], //div[#class='cat 93893742'])
This will return 10 - position in common list
If you want to get position in list for specific date (Thu. May. 11) you can try:
index-of(//div[normalize-space()="Thu. May. 11"]/following::div[starts-with(#class, "cat")],//div[normalize-space()="Thu. May. 11"]/following::div[#class='cat 93893742'])
which returns 8
Some description added in #har07 answer
I think this is what you required
count(//div[contains(#class, 'cat 93893742')]/preceding-sibling::div[starts-with(#class,'cat')])+1
Lets breakdown the whole
//div[contains(#class, 'cat 93893742')]
will match the required context node which have classname = cat 93893742
/preceding-sibling::div[starts-with(#class,'cat')]
Will match the all div element starts with classname=cat just before your context node
So if we keep all those in count() it will count all div tag just before the context node So add 1 to include count of context node as well
If you want to point that element by using index like calculated above then add this
//div[starts-with(#class,'cat')][count(//div[contains(#class, 'cat 93893742')]/preceding-sibling::div[starts-with(#class,'cat')])+1]
Equal to
//div[starts-with(#class,'cat')][10] // 10 in index number
Based on this and your previous question, maybe the following XPath is what you're looking for :
count(
//div[contains(#class, 'cat 93893742')]/preceding-sibling::div[contains(#class, 'cat ')]
)+1
I have a scenario where i am filling a search field with text 'A' and it returns a bunch of results. These results are always changing and i simply want to select the first 5 options. How is it possible to write an Xpath for this. I am trying to write an acceptance test using codecption
.//*[#id='js_search_table_filter'] - is the search table filter. I enter A with this below
$this->fillField($_sSelectSearchXPath,"A");
The xpath element when i click on the tick box option for the search results are like
.//*[#id='assign-9488'].
<label class="checkbox checked" for="assign-9488">
Note that the numbers vary and they are not in any chronological order.
I'm not sure if this is what you're after, but if you need the first 5 elements of a nodeset, you can suffix it with:
[position() <= 5]
Example:
<a>
<b>1</b>
<c>2</c>
<d>3</d>
<e>4</e>
<f>5</f>
<g>6</g>
</a>
If you want to get elements from b to f, you can run /a/*[position() <= 5].
I am not sure how codeception/php version works but in ruby (watir or pageobjectgem) you can identify all elements with a reqular expression or a partial match
the element would look like:
checkboxes(:your_element_name, :id => /assign/)
Notice the difference between checkbox and checkboxes which returns all checkboxes which have id containing assign.
In Java Webdriver, you have
driver.findElements(By.xpath("//checkbox[contains(#id,'assign')]"));
Both representatinos (ruby and java) return an array of elements where the Java solution is using xpath. The element you mentioned is a label, if you are looking for the checkbox, it is possibly a child element of this label and the xpath will be
//label[contains(#for,'assign')]/checkbox
Basically, you can use "contains" method in xpath to identify your element. You can then take the first five elements of the array.
I used this guys and tried to select all the tickboxes in the dropdown
(.//*[#type='checkbox'])[1]
I am trying to find XPath of an element which has no attribute. It can only be identified by its parent's attribute. However, the parent also does not have unique attribute.
Eg: //*[#id="btn"][1]/ul/li[2]/a/span
Here there are 2 elements with id=btn. How do i get the 2nd element. The above syntax gives me 1st element.. However if i use:
//*[#id="btn"][2]/ul/li[2]/a/span
I get an error message
"The xpath expression '//*[#id="btn"][2]/ul/li[2]/a/span' cannot be evaluated or does not result in a WebElement "
Try this, you select those two first, then use brackets around and index them.
(//*[#id="btn"]/ul/li[2]/a/span)[2]
By the way, it's not a good practice to have multiple elements sharing same ids, if you are the developer, may consider change them.
I have those two RxPaths which I need to be written in one expresion:
/td[2]/a[1]/tag[1]
and
/td[2]/a[1]
So basically I need to select path with 'tag' element if exists, if not than to select 'a' element.
something like:
if exist /td[2]/a[1]/tag[1] select /td[2]/a[1]/tag[1]
else select /td[2]/a[1]
Those elements need to have innertext attribute with some value in them, so I tried:
/td[2]/descendant::node()[#innertext!='']
but it won't work...
Also those elements are at the bottom of hierarchy so if is there any way to just select first element at lowest level.
I managed to solve this with an regex at the end of my Xpath expression.
/dom/body/div[#id='isc_0']/div/div[#id='isc_B']/div[#id='isc_C']/div[#id='isc_10']/div/div/iframe/body/table/tbody/tr/td[1]/a[#innertext='any uri item']/../../td[2]/*[#innertext~'[^ ]+']
Sorry for misunderstanding with problem...
Regards,
Vajda Vladimir
So basically I need to select path
with 'tag' element if exists, if not
than to select 'a' element. something
like:
if exist
/td[2]/a[1]/tag[1]
select
/td[2]/a[1]/tag[1]
else select
/td[2]/a[1]
I highly doubt that the top element of the document is a td. Don't use /td -- it means you want to select the top element of the document and this top element must be a td .
Also, /td[2] never selects anything, because a (wellformed) XML document has exactly one top element.
Use:
someParentElement/td[2]/a[1]/tag[1]
|
someParentElement/td[2]/a[1][not(someParentElement/td[2]/a[1]/tag[1])]
Those elements need to have innertext
attribute with some value in them
Use:
someParentElement/td[2][.//#innertext[normalize-space()]]/a[1]/tag[1]
|
someParentElement/td[2]
[.//#innertext[normalize-space()]]/a[1]
[not(someParentElement/td[2]
[.//#innertext[normalize-space()]]/a[1]/tag[1])]
Also those elements are at the bottom
of hierarchy so if is there any way to
just select first element at lowest
level.
This is not clear. Please, clarify.
All "leaf" elements can be selected using the following XPath expression:
//*[not(*)]
The elements selected don't have any children-elements, but may have other children (such as text-nodes, PIs, comments) and attributes.
Besides all those good advices from #Dimitre, I want to add that a parent will always come before (in document order) than a child, so you could use this XPath expression:
(/real-path-from-root/td[2]/a[1]
|
/real-path-from-root/td[2]/a[1]/tag[1])[last()]
You could do this without | union set operator in XPath 1.0, but it will end up very unreadable... Of course, in XPath 2.0 you could just do:
(/real-path-from-root/td[2]/a[1]/(.|tag[1]))[last()]