Challenge: Setup a locator using XPath or CSS Selector that will identify the 3rd X or Tick symbol in the list that appears under the Demo Contact Form. The locator should identify the element regardless of if the symbol is currently a cross or tick.

Comment below with your answer. This will be the last challenge until after christmas. I will still be posting the answer to this weeks challenge next week.

This week I came across this brilliant website designed to help developers practice setting up UI tests. If anyone knows who created this wonderful website, please let me know. Someone posted about it on LinkedIn, but I can’t remember who posted about it or who they said created this website.

Link to website: https://aquabottesting.com/

About halfway down the home page it a Demo Contact Form. Under the image, there is a to-do list. At the start of each list item is a cross, if you click on the cross it will change to a tick. For this challenge, you need to identify the 3rd cross or tick symbol in this list. The locator should identify the same element regardless of if its current format.

Response To Last Weeks Challenge

Well done Henrik Andersson, Arek, Mandi, Emile Zwiggelaar and Craig Fisk

Last week, I asked you to pick setup a locator that can be used to identify the ‘View all’ link on the Events card on the Ministry of Testing website.

The previous weeks challenge used such a horribly designed website (deliberately so, in the developers defence) that I wanted to choose something a little nicer. As a website designed for testers and by testers, I knew the Ministry of testing would not let me down. The challenge was finding an element that would require more than just a single identifier.

I chose the ‘view all’ link from the events card because, even though it had some attributes that could be used in a locator, its attributes were not actually unique. There were several elements with the class ‘small’, several with the text ‘view all’ and an additional link to the events page on the other side of the home page. At least 2 different attributes had to be used to avoid an alternative element being identified by mistake.

<img src="https://louisegibbstest.files.wordpress.com/2021/12/image-5.png?w=396&quot; alt="Element information for the Events View All link <a class "small" href="events"> View all
Element information for the Events View All link
<img src="https://louisegibbstest.files.wordpress.com/2021/12/image-6.png?w=242&quot; alt="Element information for another Events link that appears on the page <a href]"/events">Events
Element information for another Events link that appears on the page

XPaths:

For my chosen XPath, I used the href and class element to unqiuely identify the Events View All link. By including both attributes, only elements which contain both conditions will be identified. This will allow the View All link to be identified but not the Events link which has the same href.

"//a[@href='/events'][@class='small']"

CSS Selectors:

For my chosen CSS Selector, I went for identifying the class ‘float-right’ so only elements on the right of the website would be identifies. I then identified the events view all link using the href.

".float-right [href='/events']"

Other Answers

A very diverse range of responses this week.

Henrik Andersson went for a CSS selector which was actually similar to the XPath I chose. This locator searches for an ‘a’ element with a class ‘small’ and href ‘/events’.

"a.small[href='/events']"

Arek commented with several different XPaths which would identify the element. I like to avoid using index numbers and I like to try to stick to one level. However this isn’t always possible so its good to have an understanding of how to setup XPath which include multiple child and parent elements.

"//*[@class = ‘small’ and @href = ‘/events’]"
"(//a[contains(text(),’View all’)])[2]"
 "//div[3]/div/div/a"
"//div[@id=’main’]/div[3]/div/div[2]/div[3]/div/div/a"

Emile Zwiggelaar came up with the following locator which identifies the a element that is a child element of a div element which has a header element which contains the Events text. It makes sure that the view all link is actually next to the Events card on the website.

"//div[h5[contains(text(),'Events')]]//a"

Mandi created an interesting XPath which is similar to Emile’s XPath. Instead of looking for a div that has the h5 Events text inside it, they look for the h5 element and then look for the preceding sibling.

"//h5[contains(text(),’Events’)]/preceding-sibling::div/a[@href=’/events’]"

Craig Fisk created the following CSS selector which uses a different element based on the class. I didn’t realise you could search for multiple classes this way. The view all link is a child element of a div element with a class ‘card mt-3 right-sidebar’. For a CSS Selector, you can search for a locator based on classname by adding a full stop before the word (.right-sidebar) for example. By include 2 classnames in the CSS Selector, you can search for an element which includes 2 classes. In this case, ‘right-sidebar’ and ‘class’. The 2nd part of the CSS Selector then searches for a child element which has a href attribute that equals ‘/events’.

“.right-sidebar.card [href=’/events’]”

Useful Resources

Two ‘games’ that will help you learn how to write XPaths and CSS Selectors.

Cheat Sheets

Sample Code

Here is some sample code which you can use to test your locator. If you need any help, feel free to contact me either on my blog, or via LinkedIn.

For this code to work, you’ll need to install the following NuGet packages:

  • Selenium.WebDriver
  • Selenium.WebDriver.ChromeDriver
  • NUnit
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Interactions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;

namespace LocatorChallenge
{
    public class Program
    {
        public static void Main(string[] args)
        {
                IWebDriver Driver = new ChromeDriver(Environment.CurrentDirectory);
                Driver.Navigate().GoToUrl("https://aquabottesting.com/");
                Driver.Manage().Window.Maximize();

                //ReadOnlyCollection<IWebElement> element= Driver.FindElement(By.CssSelector(""));
                ReadOnlyCollection<IWebElement> element = Driver.FindElements(By.XPath(""));
                Console.WriteLine(element[0].Text);

                Assert.AreEqual(1, element.Count);
        }
    }
}