• Background Image

    Selenium Identifying Elements: Text Version

    June 27, 2017

June 27, 2017

Selenium Identifying Elements: Text Version

To work with a page under test using Selenium you will need to first be able to identify different elements on the page. Only after an element has been identified successfully it is possible to interact with it (e.g. clicking, text input …).

Finding Elements

Before you can interact with any element on the webpage you need to help Selenium find the correct element. This is relatively easy if we are talking about static elements but can get complex rather fast with elements that change dynamically. Let us tackle the easy ones first and then move on to a more complex example.

Finding Static Elements

Let us imagine that we have simple search engine page with just a text input and button as possible elements. The HTML for this could look something like this:


<form>
  <input name="searchQuery" type="text" /> 
  <input name="submitSearch" type="submit" />
</form>

As one would expect finding these static elements is a rather easy task using Selenium. You could simply search them by their unique name attribute.

  • WebDriver driver = new ChromeDriver();
    
    driver.navigate().to("http://www.selenium.academy/Examples/StaticElements.html");
    
    WebElement searchQuery = driver.findElement(By.name("searchQuery"));
    WebElement submitSearch = driver.findElement(By.name("submitSearch"));
    
    // ...
    
    driver.quit();
    

    Run Example Online

  • IWebDriver driver = new ChromeDriver();
     
    driver.Navigate().GoToUrl("http://www.selenium.academy/Examples/StaticElements.html");
     
    IWebElement searchQuery = driver.FindElement(By.Name("searchQuery"));
    IWebElement submitSearch = driver.FindElement(By.Name("submitSearch"));
     
    // ...
     
    driver.Quit();
    
    

    Run Example Online

  • 
    require 'selenium-webdriver'
    require 'test/unit'
    
    class SeleniumTest < Test::Unit::TestCase 
    
        def setup 
            # Start a new instance of Google Chrome 
            @driver = Selenium::WebDriver.for :chrome 
        end 
    
        def testChrome 
            @driver.navigate.to 'http://www.selenium.academy/Examples/StaticElements.html' 
            searchQuery = @driver.find_element(:name => 'searchQuery')
    	submitSearch = @driver.find_element(:name => 'submitSearch')
        end
    
        def teardown
    	@driver.quit
        end
    end
    
    

    Run Example Online

  • 
    import unittest
    from selenium import webdriver
    
    class TestChrome(unittest.TestCase):
    
        def setUp(self):
            # Start a new instance of Google Chrome
            self.driver = webdriver.Chrome()
    
        def tearDown(self):
            # close the Chrome instance
            self.driver.quit()
    
        def testChrome(self):
            self.driver.get('http://www.selenium.academy/Examples/StaticElements.html')
    
            searchQuery = self.driver.find_element_by_name('searchQuery')
            submitSearch = self.driver.find_element_by_name('submitSearch')
    
    if __name__ == "__main__":
        unittest.main() # run all tests
    
    

    Run Example Online

  • var assert = require('assert'),
    test = require('selenium-webdriver/testing'),
    webdriver = require('selenium-webdriver');
      
    test.describe('Selenium Academy',  async function() {
      test.it('should work in Chrome', async function() {
     
        this.timeout(5000);
     
        var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
        await driver.get('http://www.selenium.academy/Examples/StaticElements.html');
     
        var searchQuery = await driver.findElement(webdriver.By.name('searchQuery'));
        // ...
    
        var searchSubmit = await driver.findElement(webdriver.By.name('submitSearch'));
        // ...
     
        await driver.quit();
      });
    });
    

    Run Example Online

Of course, the name attribute will not always be unique or the best option. Other search possibilities are:

  • ClassName
  • LinkText
  • PartialLinkText
  • TagName
  • CSS
  • XCode

Finding Dynamic Elements

Unfortunately, in many cases, the elements will not have a static unique identifier you can use. For our next example, we take a look at a category list in a web shop implementation. As categories are added or removed the links and their attributes will change so we cannot just target one of the visible ids.


<ul>
    <li><a href="#software" id="14_category">Software</a></li>  
    <li><a href="#hardware" id="33_category">Hardware</a></li>   
    <li><a href="#printer" id="19_category">Printer</a></li>
</ul>

So how can we write test code that is able to identify the Hardware category regardless of id and position in the list? Firstly we will identify all category links by using a CSS selector. Then we can iterate all found links until we find the one which has ‘Hardware’ as a link text.

  • WebDriver driver = new ChromeDriver();
    
    driver.navigate().to("http://www.selenium.academy/Examples/DynamicElements.html");
    
    List<WebElement> links = driver.findElements(By.cssSelector("a[id$='_category']"));
    for (int i = 0; i< links.size(); i++)
    {
        WebElement link = links.get(i);
        if ("Hardware".equals(link.getText()))
        {
           // ...
        }
    }
    
    driver.quit();
    

    Run Example Online

  • IWebDriver driver = new ChromeDriver();
     
    driver.Navigate().GoToUrl("http://www.selenium.academy/Examples/DynamicElements.html");
     
    IReadOnlyCollection<IWebElement> links = driver.FindElements(By.CssSelector("a[id$='_category']"));
    foreach (IWebElement link in links)
    {
        if (link.Text.Equals("Hardware"))
        {
           // ...
        }
    }
     
    driver.Quit();
    

    Run Example Online

  • require 'selenium-webdriver'
    require 'test/unit'
    
    class SeleniumTest < Test::Unit::TestCase 
        
        def setup 
            # Start a new instance of Google Chrome 
            @driver = Selenium::WebDriver.for :chrome 
        end 
        
        def testChrome 
            @driver.navigate.to 'http://www.selenium.academy/Examples/DynamicElements.html' 
    
            links = @driver.find_elements(:css => "a[id$='_category']")
            links.each do |link|
                if link.text.eql? 'Hardware'
                    # ...
                end
            end        
        end
    
        def teardown
    	@driver.quit
        end
    end
    

    Run Example Online

  • 
    import unittest
    from selenium import webdriver
    
    
    class TestChrome(unittest.TestCase):
    
        def setUp(self):
            # Start a new instance of Google Chrome
            self.driver = webdriver.Chrome()
    
        def tearDown(self):
            # close the Chrome instance
            self.driver.quit()
    
        def testChrome(self):
            self.driver.get('http://www.selenium.academy/Examples/DynamicElements.html')
    
            links = self.driver.find_elements_by_css_selector("a[id$='_category']")
            for link in links:
                if link.text == 'Hardware':
                    print link.text
    
    if __name__ == "__main__":
        unittest.main() # run all tests
    
    

    Run Example Online

  • var assert = require('assert'),
    test = require('selenium-webdriver/testing'),
    webdriver = require('selenium-webdriver');
      
    test.describe('Selenium Academy', async function() {
      test.it('should work in Chrome', async function() {
     
        this.timeout(5000);
     
        var driver = new webdriver.Builder().withCapabilities(webdriver.Capabilities.chrome()).build();
        await driver.get('http://www.selenium.academy/Examples/DynamicElements.html');
     
        var links = await driver.findElements(webdriver.By.css("a[id$='_category']"));
    
        links.forEach(function(link) {
          if (link.text === 'Hardware') {
            // ...
          }
        }, this);
     
        await driver.quit();
      });
    });
    

    Run Example Online

This way you can find elements which are dynamically placed on the page and do not have a unique page-wide identifier.

Next Steps

In our next lesson we will cover how you can interact with the elements you just identified.