I'm using the "firepath" Firefox extension to test my xpaths.
Running this xpath:
driver.find_elements(:xpath, "//path/a[#class='anytext']").map{|el| el.text}
against this anchor:
<a class="anytext" href="/any/path/" title="Search for skill">text</a>
I received all elements on page as [string1, string2....]
With this xpath:
driver.find_elements(:xpath, "//path/a[#class='anytext and']").map{|el| el.text}
and this anchor:
<a class="anytext andmore" href="/any/path/" title="Search for skill" aria-describedby="tooltip">text</a>
I received array [" ", " ", ....] without text.
I understand that the problem is to do with "aria-describedby" but I dont know what to try next? I tried using different methods but not getting what I need.
There are multiple classes so try contains and and in your xpath instead:
driver.find_elements(:xpath, "//path/a[contains(#class, 'anytext') and contains(#class, 'and')]").map{|el| el.text}
Conversely you could search by css selectors:
driver.find_elements(:css, "path a.anytext.and").map{|el| el.text}
I solved the problem with firebug
This is hidden elements with attribute: 'innerHTML' or 'textContent'
i.e.:
driver.find_elements(:css, "path to elements").map{|el| el.attribute('textContent')}
Related
Given I have the following HTML structure:
<button aria-labelledby="ref-1" id="foo" onclick="convey(event)">action 2</button>
<div class="anotherElement">foobar</div>
<div id="ref-1" hidden>target 2</div>
I would like to fetch button by its aria-labelledby attribute. I tried the following options:
//*[#aria-labelledby=string(/div[#id="ref-1"]/#id)]
//*[#aria-labelledby = string(.//*[normalize-space() = "target 2"]/#id)]
//*[#aria-labelledby = .//*[normalize-space() = "target 2"]/#id]
But wasn't able to fetch the element. Anyone has an idea what the right xPath could be?
Edit: simply put: how do I fetch the button element if my only information is "target 2", and if both elements can be randomly located?
//button[#aria-labelledby='ref-1']
or
//button[#aria-labelledby=(//*/#id)]
or
//button[#aria-labelledby=(//*[contains(.,'target 2')]/#id)]
or
//button[#aria-labelledby=(//*[contains(text(),'target 2')]/#id)]
?
Since button and div are the same level siblings here you can use preceding-sibling XPath expression like this:
//div[text()='target 2']//preceding-sibling::button
pay attention with with your actual XML this will match 2 button elements.
To make more precise math I think we will need to be based on more details, not only the target 2 text
CSS/xpath selector to get the link text excluding the text in .muted.
I have html like this:
<a href="link">
Text
<span class="muted"> –text</span>
</a>
When I do getText(), I get the complete text like, Text-text. Is it possible to exclude the muted subclass text ?
Tried cssSelector = "a:not([span='muted'])" doesn't work.
xpath = "//a/node()[not(name()='span')][1]"
ERROR: The result of the xpath expression "//a/node()[not(name()='span')][1]" is: [objectText]. It should be an element.
AFAIK this cannot be done with CSS selector only. You can try to use JavaScriptExecutor to get required text.
As you didn't mention programming language you use I show you example on Python:
link = driver.find_element_by_css_selector('a[href="link"]')
driver.execute_script('return arguments[0].childNodes[0].nodeValue', link)
This will return just "Text" without " -text"
You cannot do this using Selenium WebDriver's API. You have to handle it in your code as follows:
// Get the entire link text
String linkText = driver.findElement(By.xpath("//a[#href='link']")).getText();
// Get the span text only
String spanText = driver.findElement(By.xpath("//a[#href='link']/span[#class='muted']")).getText();
// Replace the span text from link text and trim any whitespace
linkText.replace(spanText, "").trim();
I am trying to use Selenium. The problem is the following:
The doc structure:
<div class="jsSkills oSkills">
<a class="oTag oTagSmall oSkill" href="/contractors/skill/software-testing/" data-contractor="749244">software-testing</a>
<a class="oTag oTagSmall oSkill" href="/contractors/skill/software-qa-testing/" data-contractor="749244">software-qa-testing</a>
<a class="oTag oTagSmall oSkill" href="/contractors/skill/blog-writing/" data-contractor="749244">blog-writing</a>
</div>
I need to obtain all a's text to be in array like:
{"software-testing", "software-qa-testing", "blog-writing"}
I tried this:
contrSkill = driver.find_element(:xpath, "//div[contains(#class, 'jsSkills')]").text
puts contrSkill
but got this:
"software-testingsoftware-qa-testingblog-writing"
Please explain how to appropriately make an array.
You should get all of the link elements you want (using find_elements). Then you can iterate over each link and collect its text into an array (Ruby has a collect method that helps with this).
# Get all of the link elements within the div
skill_links = driver.find_elements(:xpath, "//div[contains(#class, 'jsSkills')]/a")
# Create an array of the text of each link
skill_text_array = skill_links.collect(&:text)
p skill_text_array
#=> ["software-testing", "software-qa-testing", "blog-writing"]
Is it possible to return a map of hidden links using watir? I have been trying to find some useful documentation, but have been most unsuccessful.
I need it to be generic enough to return any link thats hidden on page regardless of class, id, etc
style=display: none;
This currently returns me all visible links
full_list = #driver.links.map{|a| a.href}
i'd like to do something like (my syntax is probably way off):
hidden_list = #driver.hiddens.map{:style, a => 'display: none;'}
Please, please let me know if there is a way!
Thanks!
You could find all the links that are not visible? and collect their href attributes:
For example, given the following html:
asdf
<a style="display:none;" href="somewhere/invisible">asdf</a>
<a style="display:none;" href="somewhere/invisible2">asdf</a>
You can do:
hidden_list = #driver.links.find_all{ |a| !a.visible? }.collect(&:href)
#=> ["somewhere/invisible", "somewhere/invisible2"]
I'd like to use xquery (I believe) to output the text from the title attribute of an html element.
Example:
<div class="rating" title="1.0 stars">...</div>
I can use xpath to select the element, but it tries to output the info between the div tags. I think I need to use xquery to output the "1.0 stars" text from the title attribute.
There's gotta be a way to do this. My Google skills are proving ineffective in coming up with an answer.
Thanks.
XPath: //div[#class='rating']/#title
This will give you the title text for every div with a class of "rating".
Addendum (following from comments below):
If the class has other, additional text in it, in addition to "rating", then you can use something like this:
//div[contains(concat(' ', normalize-space(#class), ' '), ' rating ')]
(Hat tip to How can I match on an attribute that contains a certain string?).
You should use:
let $XML := <p><div class="rating" title="2.0 stars">sdfd</div><div class="rating" title="1.0 stars">sdfd</div></p>
for $title in $XML//#title
return
<p>{data($title)}</p>
to get output:
<p>2.0 stars</p>
<p>1.0 stars</p>