Categories
Automated testing Python Selenium WebDriver

Locate web elements on the sites easily

In this post I’ll describe how to find elements on the page of the site you are testing. If you need to know how to start working with Selenium WebDriver, read my post where I tell about the initial configuration of Selenium WebDriver with Python.

Elements in HTML

All the elements on any web page have their tags and attributes.

<a href="www.google.com" target="_blank">Search engine</a>

This is a simple example of an HTML code of a link on a site. The tag here is “a”, and it has some attributes: “href”, “target”. The text that will be highlighted as a link is “Search engine”. Tag with its attributes is placed inside the “<>” before the text it is applied to. Finally, the “</a>” closes the element – that is where the element ends.

Method to find an element on the page

There is only one method that that is used to look for elements on the page. This is “find_element”. But it is useless without a strategy that is set with an attribute of class “By”. Here is an example of searching for an element that has an html attribute “id” with value “ui-id-3”.

from selenium.webdriver.common.by import By

element = driver.find_element(By.ID, 'ui-id-3')

If you don’t understand what is a “driver” here, read my post Selenium WebDriver with Python – initial configuration.

There are different options how to find an element on the page. The By.ID is only one of them.

By.ID

That’s the option you’ve seen in the previous example. You can find an element by the value of the html attribute “id”.

By.NAME

If you are lucky enough and the elements on the page have “name” attributes you can easily find them like this:

from selenium.webdriver.common.by import By

element = driver.find_element(By.NAME, 'submitMessage')

By.CLASS_NAME

This is a brief description of how By.CLASS_NAME works. You can see a more detailed description here: By.CLASS_NAME usage

One of the options widely used is searching for element by its “class” attribute value. Note that often an element has more than one class assigned to it. In this case the class names are divided by space. In order to find and element By.CLASS_NAME you need to specify only one of the element’s class. For example there is an element:

<a class="et_pb_button et_pb_button_4 et_pb_bg_layout_light" href="">Button</a>

The tag “a” has 3 classes in the “class” attribute. To locate this element by class you need to use one of these examples:

element = driver.find_element(By.CLASS_NAME, 'et_pb_button')
element = driver.find_element(By.CLASS_NAME, 'et_pb_button_4')
element = driver.find_element(By.CLASS_NAME, 'et_pb_bg_layout_light')

By.LINK_TEXT

In case you need to find a link and you know what text it should have, you can use this option. Assume, there is a link on the page and its html code looks like this:

<a href="www.google.com" target="_blank">Search engine</a>

So, let’s see how to find it:

element = driver.find_element(By.LINK_TEXT, 'Search engine')

By.PARTIAL_LINK_TEXT

The same as the previous one. But you can use it in case if you know only a part of the text the link should contain. So for the same link we can use this code:

element = driver.find_element(By.PARTIAL_LINK_TEXT, 'engine')

By.TAG_NAME

In case there is a unique element on the page with some specific tag you can find it using this strategy. So, for example you have only one heading on the page with tag “h1”. Here is the example how you can find it:

element = driver.find_element(By.TAG_NAME, 'h1')

If there are more than one element with tag ‘h1’, selenium will find only the first one.

By.CSS_SELECTOR

That’s a powerful method that allows you to specify more complicated combinations of tag names and attribute values to be able to find the element. Let’s look at this piece of html code:

<a href="https://www.facebook.com/mypage/" class="icon et_pb_with_border" >Follow</a>

That’s a link and let’s assume we don’t know its text. We can find it using the following code:

element = driver.find_element(By.CSS_SELECTOR, 'a[href = "https://www.facebook.com/mypage/"]')

You can see that I specified the name of the tag before the square brackets and inside I’ve set the attribute and value it should have. So, the result is: we are looking for an “a” tag with an attribute “href” that has the value “https://www.facebook.com/mypage/”.

By.XPATH

To continue the topic of powerful methods, let’s lookt at this one. You will find any element you couldn’t find using any other one. I’ll just show one example how you can use it. But finding elements with xpath is a topic of a separate tutorial like this.

So let’s consider this html code

<div class="alert alert-danger">
	<p>There is 1 error</p>
		<li>Invalid email address.</li>
</div>

You can see here that it’s not difficult to find the “div” tag. You can try to find it using By.CLASS_NAME or By.CSS_SELECTOR. But what if you need to find only the text “There is 1 error”? Here is where you need xpath.

element = driver.find_element(By.XPATH, '//div[@class="alert alert-danger"]/p')

To explain that xpath expression let’s look at it step by step. First of all we specify the place where we will search – that’s the whole page: we type “//” for that. Next goes the search of the parent element of the element we are looking for. So it’s a “div” with the value “alert alert-danger” of a “class” attribute. And than we put “/” to point that we need some child element. Finally we specify the tag name of the element we are looking for.

Deprecated method

Additionally, I would like to mention the method that had been used in earlier versions of the Selenium WebDriver. There were methods for every strategy.

  • find_element_by_class_name
  • find_element_by_css_selector
  • find_element_by_id
  • find_element_by_xpath
  • and so on…

Why mention methods that are already deprecated? First of all you will find them in the first answer on the stackoverflow. You can also find them in legacy test scripts for your application. Now you know about them and will not be scared.

By Eugene Okulik