Selenium web driver getting the text from the for attribute of a label using Ruby - ruby

I have seen some examples of how to do this in Javascript or python, but am looking for how to find the text of the for attribute on a label. e.g.
<label for="thisIsTheTextNeeded">LabelText</label>
<input type="checkbox" id=thisIsTheTextNeeded">
We want to pick up the text from the for attribute on the label element. Then use that text as the id to find the checkbox.
The .NET solution might look like:
textWeNeed = selenium.getAttribute("//label[text()='LabelText']/#for");
I tried this in Ruby:
textWeNeed =
#browser.find_element("xpath//label[text()='LabelText']/#for")
and get the error:
expected "xpath//label[text()=input_value]/#for":String to respond to #shift (ArgumentError)
Any ideas?

Here is how I fixed it. Thanks for all the help!
element = #browser.find_element(:xpath=>"//label[text()=\'#{input_value}\']")
attrValue = element.attribute('for') listElement =
#browser.find_element(:id=>"#{attrValue}")

You should use the attribute method to get the value of the attribute. See the doc
element = #browser.find_element(:xpath, "//label[text()='LabelText']")
attrValue = element.attribute("for")
According to OP's comment and provided html I think the element needs some explicit wait
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
element = wait.until { #browser.find_element(:xpath => "//label[contains(text(),'My list name')]") }
attrValue = element.attribute("for")

find_element function requires Hash to search with xpath.
correct way is here,
textWeNeed =
#browser.find_element(xpath: "xpath//label[text()='LabelText']/#for")
below is wrong way(your code).
textWeNeed =
#browser.find_element("xpath//label[text()='LabelText']/#for")

I found in Ruby when looking for Strings best to use is :find: instead of :find_element:
textWeNeed =
#browser.find("xpath//label[text()='LabelText']/#for")
when presented with the error: "String to respond to #shift"

Related

Capture selected value from list using webdriver and Ruby

I'm using selenium webdriver with ruby. I've written a script that will fill in a form. One field is a dropdown list. What I would like to do is capture the value I selected in the list.
For example: If I had a list of cars and I selected Honda I would like to capture the value in the field (Honda) and place it in a variable for me to use later.
I hope I'm making sense.
You can use below code select list items:
cars_select = driver.find_element(:id=> "cars_list")
//use id of your dropdownlist
options = cars_select.find_elements(:tag_name=>"option")
options.each do |el|
if (el.value == "Honda")
el.select()
var selected_car = el.value;
break
end
end
If you are selecting from dropdown with:
browser.select_list(id: 'some_id').option(text: 'some_value').select
Then you can store that value in a variable, like below:
var1=browser.select_list(id: 'some_id').option(text: 'some_value').value
Hope this will work. If not, then provide your dropdown part html, and explain more. I am using watir-webdriver, try if this work for selenium-webdriver.

has_css? will not find a present id

I am writing a finder for pages with various but finite id's
#field = ['name1', 'name2']
def fieldfind
#field.each do |elem|
out = elem if page.has_css?(elem)
end
end
HTML
<input type='text' id = 'name1'>
For whatever reason, I cannot find name1. I tried find_field? and elem.to_s, but to no avail. Any ideas?
As Baldrick mentioned, the css locator is not right. However, after correcting that, you would still get a problem with the #field.each. This is going to return an array - not an element or the css of the field that exists.
If you want an element that matches one of the css in #field, try:
#field = ['#name2', '#name1']
def fieldfind
matching_css = #field.find{ |elem| page.has_css?(elem) }
page.find(matching_css)
end
Or if you just want the matching css-locator:
#field = ['#name2', '#name1']
def fieldfind
#field.find{ |elem| page.has_css?(elem) }
end
You missing #, the css selector to find element by id. It should be:
#field = ['#name1', '#name2']
...
You can use:
page.find(:css, "input[id=name1]")
If that works, go ahead and dynamically add the variable to your code.
I'm suggesting you try to find an element first (rather than just improving your existing each block) is perhaps your session object is pointed towards the wrong window or frame.

Selenium WebDriver findElement(By.xpath()) not working for me

I've been through the xpath tutorials and checked many other posts, hence I'm not sure what I'm missing. I'm simply trying to find the following element by xpath:
<input class="t-TextBox" type="email" test-id="test-username"/>
I've tried many things, such as:
element = findElement(By.xpath("//[#test-id='test-username']"));
The error is Expression is not a legal expression.
I'm using Firefox on MacBook
Any suggestion would be greatly appreciated.
element = findElement(By.xpath("//*[#test-id='test-username']"));
element = findElement(By.xpath("//input[#test-id='test-username']"));
(*) - means any tag name.
You should add the tag name in the xpath, like:
element = findElement(By.xpath("//input[#test-id='test-username']");
your syntax is completely wrong....you need to give findelement to the driver
i.e your code will be :
WebDriver driver = new FirefoxDriver();
WebeElement element ;
element = driver.findElement(By.xpath("//[#test-id='test-username']");
// your xpath is: "//[#test-id='test-username']"
i suggest try this :"//*[#test-id='test-username']"
You missed the closing parenthesis at the end:
element = findElement(By.xpath("//[#test-id='test-username']"));
Just need to add * at the beginning of xpath and closing bracket at last.
element = findElement(By.xpath("//*[#test-id='test-username']"));
You can use contains too:
element = findElement(By.xpath("//input[contains (#test-id,"test-username")]");
You haven't specified what kind of html element you are trying to do an absolute xpath search on. In your case, it's the input element.
Try this:
element = findElement(By.xpath("//input[#class='t-TextBox' and #type='email' and #test-
id='test-username']");
Correct Xpath syntax is like:
//tagname[#value='name']
So you should write something like this:
findElement(By.xpath("//input[#test-id='test-username']"));

Clear input field and enter new info using Watir? (Ruby, Watir)

Pretty positive you have to use .clear, or maybe not as it doesn't seem to be working for me, maybe i'm just implementing it wrong I'm unsure.
Example:
browser.div(:id => "formLib1").clear.type("input", "hi")
Can anyone tell me how to simply clear a field then enter in a new string?
Assuming we are talking about a text field (ie you are not trying to clear/input a div tag), the .set() and .value= methods automatically clear the text field before inputting the value.
So one of the following would work:
browser.text_field(:id, 'yourid').set('hi')
browser.text_field(:id, 'yourid').value = 'hi'
Note that it is usually preferred to use .set since .value= does not fire events.
I had a similar issue, and, for some reason, .set() and .value= were not available/working for the element.
The element was a Watir::Input:
browser.input(:id => "formLib1").to_subtype.clear
after clearing the field I was able to enter text.
browser.input(:id => "formLib1").send_keys "hi"
I had a similar issue, and, for some reason, .set() and .value= were not available for the element.
The element was a Watir::HTMLElement:
[2] pry(#<Object>)> field.class
=> Watir::HTMLElement
field.methods.grep /^(set|clear)$/
=> []
I resorted to sending the backspace key until the value of the field was "":
count = 0
while field.value != "" && count < 50
field.send_keys(:backspace)
count += 1
end
field.send_keys "hi"

Selenium Webdriver + Ruby regex: Can I use regex with find_element?

I am trying to click an element that changes per each order like so
edit_div_123
edit_div_124
edit_div_xxx
xxx = any three numbers
I have tried using regex like so:
#driver.find_element(:css, "#edit_order_#{\d*} > div.submit > button[name=\"commit\"]").click
#driver.find_element(:xpath, "//*[(#id = "edit_order_#{\d*}")]//button").click
Is this possible? Any other ways of doing this?
You cannot use Regexp, like the other answers have indicated.
Instead, you can use a nifty CSS Selector trick:
#driver.find_element(:css, "[id^=\"edit_order_\"] > div.submit > button[name=\"commit\"]").click
Using:
^= indicates to find the element with the value beginning with your criteria.
*= says the criteria should be found anywhere within the element's value
$= indicates to find the element with with your criteria at the end of the value.
~= allows you to find the element based on a single criteria when the actual value has multiple space-seperated list of values.
Take a look at http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/ for some more info on other neat CSS tricks you should add to your utility belt!
You have no provided any html fragment that you are working on. Hence my answer is just based on the limited inputs provided your question.
I don't think WebDriver APIs support regex for locating elements. However, you can achieve what you want using just plain XPath as follows:
//*[starts-with(#id, 'edit_div_')]//button
Explanation: Above xpath will try to search all <button> nodes present under all elements whose id attribute starts with string edit_div_
In short, you can use starts-with() xpath function in order to match element with id format as edit_div_ followed by any number of characters
No, you can not.
But you should do something like this:
function hasClass(element, className) {
var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
return re.test(element.className);
}
This worked for me
#driver.find_element(:xpath, "//a[contains(#href, 'person')]").click

Resources