Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium-Webdriver: Get attributes after finding an element

I'm still rather new with the automation stuff, so this might sound like a stupid question. I did google search the hell out of it, before posting a question though :)

Anyways, here is the problem

I am automating tests on an Android device One of the tests is to verify that an item has been marked as 'Favorite' Code snippet of page is:

<li class = "resultItem isFavorite" data-index="2">
<div class="name" data-cis="4ced6feb-3b5c-415a-ae1c-0b8bca8e3c85" onclick="return true">f,f</div>
</li>

I can find the element in the list with el = @driver.find_element(:xpath, "//*[class='name' and text() ='f,f']"). I was hoping that el.class would show me resultItem isFavorite. Instead what i get is: Selenium:WebDriver::Element

If an item is not marked as favorite, the isFavorite flag isn't added in the field. I was hoping to use isFavorite to verify that an item is marked as favorite, but I can't seem to get it into a variable.

Any help would be appreciated.

Thanks,

Jeff

like image 205
Jeff Sanders Avatar asked Jan 12 '13 00:01

Jeff Sanders


3 Answers

What you really want here is something like the following:

# Note: Possibly incorrect Ruby code here. 
# Written from memory.
el = @driver.find_element(:xpath, "/your/xpath/here")
# Could also your el["class"]
element_class_attribute = el.attribute("class")

Ordinarily, using most attribute names like src (as in el.src) would give you a runtime error. However, it happens that class has a special meaning in Ruby, and every object has a class attribute, which is the Ruby class.

like image 66
JimEvans Avatar answered Oct 17 '22 10:10

JimEvans


I'm reading two questions here. First, the short, easy one.

Q: Now that I've found el, how do I access its class HTML attribute?

A: Use el.attribute('class'), or its short-hand el['class']. See Selenium::WebDriver::Element.attribute.

Now the longer one.

Q: How can I test that the item denoted by el is marked as a favorite?

A: See below.

To give a better answer, I would need more information about the composition of the page we're testing. I've made some basic assumptions:

  • The page has one or more li elements with class 'resultItem', some of which also have class 'isFavorite'.
  • Each of these li elements have one or more child elements, one of which is guaranteed to be a div with class 'name'.
  • Only one such child div will have text 'f,f'.

Broadly speaking, we have two ways to go about this.

  1. We can find the relevant div, then verify that its parent li has class 'isFavorite'.
  2. We can find all li elements with class 'isFavorite', then verify that one of them contains the relevant div.

There are a lot of things we need to be aware of here.

For Selenium, XPath selectors are good at finding by text, but poor at finding by class. CSS selectors are good at finding by class, but cannot find by text. Neither of these is ideal for finding the div we are after.

As mentioned above, we can get the class (attribute) of an element using element['class']. As we found out, element.class calls Object#class, giving us Selenium::WebDriver::Element. el['class'], in this case, gives us the String 'name'. If called on its parent element, we would get 'resultItem isFavorite'.

We can get at an element's text using element.text. el.text would give us 'f,f' in this case. Like JavaScript's textContent function, it returns the text of the element and all of its descendents, so calling text() on the parent element would also give us 'f,f'. Note that this method can be slow, and will return an empty String if the element is not visible in some way. Use with caution. See Selenium::WebDriver::Element.text for more info.

Given the above, lets see how Methods #1 and #2 play out. (The following is Ruby 1.9.3.)

Method #1

div_elements = @driver.find_elements(:css, 'li > div.name').select { |e| e.text == 'f,f' }
div_element = div_elements.first

parent_li = div_element.find_element(:xpath, './..')
parent_li_classes = parent_li['class'].scan(/\S+/)
if parent_li_classes.include?('isFavorite')
  # PASS
else
  # FAIL
end

Method #2

favorite_items = @driver.find_elements(:css, 'li.isFavorite')
if favorite_items.any? { |item| item.find_element(:css, 'div.name').text == 'f,f' }
  # PASS
else
  # FAIL
end

Method #2, Refactored

if @driver.find_elements(:css, 'li.isFavorite').any? { |item| item.text == 'f,f' }
  # PASS
else
  # FAIL
end
like image 3
Ben Amos Avatar answered Oct 17 '22 11:10

Ben Amos


Ruby

element.attribute("attribute name")

Python

element.get_attribute("attribute name")

Java

element.getAttribute("attribute name")

C#

element.GetAttribute("attribute name");
like image 2
Shubham Jain Avatar answered Oct 17 '22 10:10

Shubham Jain