Skip to content

FindElement By CssSelector

Getting to grips with finding an element using CssSelector or XPath is a pain when you’re not familiar with these options.
XPath is a little easier to figure out, but can run you into trouble because of IE compared to different browsers and how XPath is shown.

XPath is a last resort way to find elements in my opinion. Don’t use it unless you really have to. As a single change to a page can break your test.
CssSelector is more efficient and easier to work with once you understand how to use it.

A basic CssSelect could look like this:

This is using an attribute selector to find the name attribute of some html.

driver.FindElement(By.CssSelector("input[name='Test']"));

Here is the HTML the above example would find:

<input type="radio" name="Test" id="radio" value="Default Selection">

You might come across situations where one attribute may not be sufficient to locate an element and you need to combine additional attributes for a precise match. For example, a set of radio buttons all named the same and you wanted to check each to see which one is the selected one:

<input type="radio" name="Test" id="radio" value="Default Selection" checked="checked">
<input type="radio" name="Test" id="radio" value="Another value">
<input type="radio" name="Test" id="radio" value="Value three">

So you could search through them like so:

WebElement radioButton = driver.FindElement(By.CssSelector("input[name='Test'][checked='checked']"));

That would find the radio buttons with a name of “Test” and then look for the one that was checked.

The following table shows how you can locate an attribute within an element using “Starting With”, “Ending With” or “Containing”.
These should function with all the FindElement options (CssSelector, Id, etc)

Syntax Example Description
^= input[id^=’ctrl’] Starting with:
For example, if the ID of an element is ctrl_12,
this will locate and return elements with ctrl at
the beginning of the ID.
$= input[id$=’_userName’] Ending with:
For example, if the ID for an element is a_1_
userName, this will locate and return elements
with _userName at the end of the ID.
*= Input[id*=’userName’] Containing:
For example, if the ID of an element is panel_
login_userName_textfield, this will use
the userName part in the middle to match and
locate the element.

FindElement by LinkText or PartialLinkText

Everytime I tried to find an element on a web page using LinkText or PartialLinkText, things always went pear shaped.
Turns out I’ve been using it wrong all along (learning by mistakes quite a lot recently it seems).

So when you want to locate an element by either of these two options. Instead of trying to locate the actual element via the href text, you need to locate it via the visible text that shows on screen.

So for example, if you have a page that has the following on it

<a href="link_to_a_page.html">This is my link I want to test</a>

and you want to test to see if that link shows up on the page when it’s loaded. You would use something like this:

var href = driver.FindElement(By.PartialLinkText("This is")).GetAttribute("href");
AssertTrue(href.Contains("link_to"));

Now obviously I’m sure this could be done a better way. However, I’m merely providing this as an example.
Using FindElement(By.LinkText()) would simply be including the full displayed text of the link you wish to locate on the page.

Now to explain what I was doing, so there’s an example of how not to use it.
Using that same bit of html above, I was originally trying to locate the link by the actual text in the href attribute.
So my original code looked like this

var href = driver.FindElement(By.PartialLinkText("link_to_a_page")).GetAttribute("href");
AssertTrue(href.Contains("link_to"));

This will fail as FindElement isn’t looking for the actual text contained in the href attribute.

Hope this is helpful.

Handling Select lists in Selenium Webdriver

The scenario:
You’ve been assigned a task to get all the options from every single select drop down list on a website, and then you need to compare them to a list that has been given to you and is what _should_ be on the site.
Here’s something I found on stackoverflow.com that helped me out. I had to alter it a little, as it didn’t originally function using Select. Instead I used the SelectElement as I couldn’t locate Select anywhere in any of the namespaces shown in my using list.

So here’s what I have and then I’ll explain my goal:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI; //This is the one you need for SelectElement
using OpenQA.Selenium.IE;

namespace Test
{
    [TestFixture]
    class TestClass : CommonLibrary
    {
        [Test]
        public void MyTest()
        {
            driver.Navigate().GoToUrl("webpage here"));
            Assert.True(driver.PageSource.Contains("Title"));

            // Get all values from a specific drop down list on page and output to console
            SelectElement select = new SelectElement(driver.FindElement(By.Id("elementID")));
            IList<IWebElement> options = select.Options; // this select.Options pulls all the options and holds them while the foreach below iterates through the list and outputs to the console
            foreach (IWebElement option in options)
            {
                System.Console.WriteLine(option.Text);
            }
        }
    }
}

So what I’m working on is figuring out how to store all of these items and then compare them against either a file containing the list or something that’s already coded into the project (a string array or something?). However, I’m pleased I was able to get this first part working as desired.

Source: http://stackoverflow.com/questions/4657465/using-selenium-2s-iwebdriver-to-interact-with-elements-on-the-page

After thinking about it for a minute, I realised I could use this as a common function and moved it to my CommonLibrary class where I could get at it from all my tests if needed.
Here’s how I set it up:

        public void GetSelectsByID(string selection)
        {
            // Test drop downs contain values
            SelectElement select = new SelectElement(driver.FindElement(By.Id(selection)));
            IList<IWebElement> options = select.Options;
            foreach (IWebElement option in options)
            {
                System.Console.WriteLine(option.Text);
            }
        }

So now in my tests i would simply find the element ID of the drop down list I want to get and use that name in the function when I called it.
For example:
Form on webpage contains two drop down lists.

<!DOCTYPE html>
<head>
<title>Disposable Page</title>
</head>
    <body >
        <select id="carBrand">
          <option value="Saab">Saab</option>
          <option value="Mercedes">Mercedes</option>
          <option value="Audi">Audi</option>
        </select>

        <select id="Colour">
          <option value="White">White</option>
          <option value="Red">Red</option>
          <option value="Silver">Silver</option>
          <option value="Black">Black</option>
        </select>
    </body>
</html>

Now I want to get the options for both lists. So I would use:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI; //This is the one you need for SelectElement
using OpenQA.Selenium.IE;

namespace Test
{
    [TestFixture]
    class TestClass : CommonLibrary
    {
        [Test]
        public void Cars()
        {
            driver.Navigate().GoToUrl("webpage here"));
            Assert.True(driver.PageSource.Contains("Disposable Page"));
            GetSelectsByID("carBrand"); //use the ID of the dropdown list and this passes to the function as a string
            GetSelectsByID("Colour");
        }
    }
}

Base Class for NUnit to use

So I was getting a bit fed up with having to copy and paste the [TestFixtureSetup] and [TestFixtureTearDown] sections to new tests.
I remembered something I’d learnt a while ago about how you can use classes together by creating sub classes of a base class.
The great bit about this, is the sub classes can be new files. After doing a little research online to work out if this would be possible with NUnit, I went about creating my base class and a quick test in a new sub class, to make sure I understood what was happening myself.

My base class has a few things going on.

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Selenium;

namespace Automation
{
    class CommonLibrary
    {
        // Internet Explorer webdriver.
        // URL can be set to any url needed. This is simply the page IE will start on when it opens
        // IE_DRIVER_PATH is the path to the IEDriverServer.exe file
        private const string URL = "about:home";
        private const string IE_DRIVER_PATH = "path\\to\\IEDriverServer";
        public IWebDriver driver;

        #region Startup Functions 
        public void Logon()
        {
            driver.Navigate().GoToUrl(website);
            Console.WriteLine("Wait for page to load");
            System.Threading.Thread.Sleep(5000);
            driver.FindElement(By.Id("Username")).Clear();
            Console.WriteLine("Clear Username field");
            driver.FindElement(By.Id("Username")).SendKeys(Username);
            Console.WriteLine("Add username");
            driver.FindElement(By.Id("Password")).Clear();
            Console.WriteLine("Clear pwd field");
            driver.FindElement(By.Id("Password")).SendKeys(Password);
            Console.WriteLine("Enter pwd");
            driver.FindElement(By.Id("logon")).Submit();
            System.Threading.Thread.Sleep(10000);
            Console.WriteLine("Page title is: " + driver.Title);
            var currentURL = driver.Url.ToString();
            try
            {
                Assert.True(driver.Title.Equals(Title));
                Console.WriteLine("Login Successful");
            }
            catch (Exception)
            {
                Assert.IsFalse(driver.Title.Contains("Login"));
                Console.WriteLine("Login Unsuccessful, ending test");
                throw;
            }

            Console.WriteLine("Verifying Log on. Testing for Home link on navbar");

            try
            {
                driver.FindElement(By.Id("btn_home")).Click();
                Console.WriteLine("Found Element by ID.");
                Console.WriteLine("Current URL: " + currentURL);
            }
            catch
            {
                driver.FindElement(By.LinkText("../Welcome")).Click();
                Console.WriteLine("Found element by LinkText");
                Console.WriteLine("Current URL: " + currentURL);
            }
            Console.WriteLine("Log on Test Complete");
        }
        #endregion

        #region Full Setup
        [TestFixtureSetUp]
        public void LoadDriver()
        {
            Console.WriteLine("Running Setup Process");
            var options = new InternetExplorerOptions()
            {
                InitialBrowserUrl = URL,
                IntroduceInstabilityByIgnoringProtectedModeSettings = true
            };

            driver = new InternetExplorerDriver(IE_DRIVER_PATH, options);
            Console.WriteLine("Webdriver Loaded, setup complete");
            Console.WriteLine("Logging on");
            Logon();
        }
        #endregion

        #region Full Teardown
        [TestFixtureTearDown]
        public void Kill()
        {
            Console.WriteLine("Running TearDown process. Closing Browser, closing IEDriverServer process, ending Test");
            driver.Quit(); // closes IEDriverServer process
        }
        #endregion
    }
}

Once that was done. I then created a new class file and set up a little test to see if it would function with minimal time spent messing about with it.
I must’ve been lucky today, as it worked almost first time. Took a couple of tries to figure out what was wrong and I can’t say i really understand why it broke, but I was able to fix it.
Here’s the second class file.

using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Selenium;

namespace Automation
{
    [TestFixture]
    class Test : CommonLibrary
    {      
        [Test]
        public void Test()
        {
            driver.Navigate().GoToUrl(website);
            System.Threading.Thread.Sleep(5000);
            try
            {
                Assert.True(driver.Title.Contains(title));
                Console.WriteLine("Windows Title: " + driver.Title.ToString());
            }
            catch (Exception)
            {
                throw;
            }

            Console.WriteLine("Test completed");
        }
    }
}

So as you can see, this new class file is a sub class of the base class.
After building, NUnit reloaded the tests and I ran it to see what would happen.
NUnit grabs the Setup from the base class and runs that. Then it jumps over to the sub class and runs the test there. And finally returns to the base class and runs the TearDown.
This is magic, since it means I can spend less time worrying about layout of tests, and more time with the real guts of the test I’m working on.
Unfortunately my knowledge of how C# works isn’t great, so I’m not really able to explain this stuff too well yet. I’m getting there though. Slowly, but surely.

NUnit test adapter for VS Unit Test window

https://launchpad.net/nunit-vs-adapter

Not sure how useful this will be. But I’ll take a look at it and see how it works. Although to be honest, I’m happy with the way NUnit works as a standalone application right now.

Creating test layout for NUnit

When creating tests to run using NUnit, there are some categories that allow NUnit to recognise the layout of a test. If you’re setting up several tests to run then the [Setup] and [TearDown] sections are rather important. These categories will set up and tear down the test environment at the start and end of every test you create. This is great when you only have a single test to run in each test script you write. But can lead to extra lines of code that really can be avoided if you want to set up several tests to run consecutively.
For example if I wanted to run a test that tested the logon page of a website. Then I wanted another test to run that checked all the navbar links on the home page after logging on.
The basic layout would look like this for the script:

namespace NUnit.Tests
{
  using System;
  using NUnit.Framework;

  [TestFixture]
  [Category("My Test Suite")]
  public class MyTestClass1
  {
    [TestFixtureSetUp] public void Init() //Run before all tests 
    { /* ... */ } //Code could be as simple as just starting up the webdriver and browser

    [TestFixtureTearDown] public void Cleanup() //Run after all tests
    { /* ... */ } //Close browser and webdriver are two prime examples of what goes here

    [Test]
    [Category("Logon")]
    public void LogonTest()
    { /* ... */ }

    [Test]
    [Category("Navbar")]
    public void NavbarTest()
    { /* ... */ }
}

I will start explaining all the sections once I have a better understanding of them all myself.
There is some useful documentation on the NUnit website that definitely helped me understand all of this stuff.
Here’s the link: http://www.nunit.org/index.php?p=docHome&r=2.4.8

Getting past the unsigned certificate warning in HTTPS environment

One of the problems I first encountered with my testing in my new job, was the unsigned certificate on the test server.
You get to the site and immediately are presented with the message about the site not being trusted.

So I set to work to locate some code to get around this. Here’s the answer and it works great:

IWebDriver driver = new InternetExplorerDriver();
driver.Url(YOUR_URL);
driver.Navigate().GoToUrl("javascript:document.getElementById('overridelink').click()");

Source: http://stackoverflow.com/a/11577323

How to call the InternetExplorerDriver using the IEDriverServer.exe

This isn’t my code. However, I thought it was a great example to start working from.
The source is found at the bottom of this post.

Here’s a simple C# example of how to call the InternetExplorerDriver using the IEDriverServer.exe.
Refactor according to your needs.

Note: the use of driver.Quit() which ensures that the IEDriverServer.exe process is closed, after the test has finished.

using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;

namespace SeleniumTest
{
    [TestClass]
    public class IEDriverTest
    {
        private const string URL = "http://url";
        private const string IE_DRIVER_PATH = @"C:\PathTo\IEDriverServer";

        [TestMethod]
        public void Test()
        {
            var options = new InternetExplorerOptions()
            {
                InitialBrowserUrl = URL,
                IntroduceInstabilityByIgnoringProtectedModeSettings = true
            };
            var driver = new InternetExplorerDriver(IE_DRIVER_PATH, options);
            driver.Navigate();
            driver.Close(); // closes browser
            driver.Quit(); // closes IEDriverServer process
        }
    }
}

Source: http://stackoverflow.com/a/11154803

Selenium IDE Enhancements

Here’s a nice helpful link to help make SIDE work better for you:
http://www.guru99.com/enhancing-selenium-ide-script.html

I will still continue to post about SIDE, as it’s very handy to use in a pinch when you need a quick test created. Since it can actually be exported to a C# format after creation.

Getting started with Selenium Webdriver

Here’s a few links that helped me get moving quickly with Webdriver and NUnit:

http://docs.seleniumhq.org/docs/03_webdriver.jsp
http://www.nunit.org/index.php?p=home
http://relevantcodes.com/category/selenium/
http://relevantcodes.com/using-nunit-to-execute-selenium-webdriver-tests/
http://anoopjshetty.wordpress.com/2012/02/08/creating-test-automation-framework-using-c-selenium-and-nunit/

Next post will be on laying out the framework for your tests in NUnit. So the tests can be run as a whole, or specific tests easily picked out and run.

NE1 Atoll

The Official blog of NE1 Games

Selenium for .Net using C# language

Adventures in Coding, gaming and other fun things in my life

Coded UI 101 - Understanding Coded UI Tests

Adventures in Coding, gaming and other fun things in my life