logo logo

Working with pseudo-elements in Selenium

Working with pseudo-elements in Selenium

What is a pseudo-element?

There may be times when, while writing UI web automated tests, you will come across some elements that look like this:

Pseudo-elements example

These are called pseudo-elements, and they are CSS keywords added to the element’s selector which allow you to style only specific parts of that element. For example, the “::after” keyword adds some text value after the selected element and can apply a specific styling only to this text. Other pseudo-elements you might encounter are:

  • ::before, which works similarly to after, except it applies to the text added before the element
  • ::first-line, which applies the style to the first line in the element (usually a paragraph element)
  • ::placeholder, which means a placeholder text in an input or textarea element
  • ::selection, which applies the styling to the part of the document that the user highlighted (selected)
  • and the list goes on.

You can read more about how pseud-elements work and how they can be used in CSS on Mozilla’s developer website.

How to work with pseudo-elements in Selenium?

Now comes the tricky part. If we need to interact with a pseudo-element, Selenium WebDriver does not offer us the option to do so.

Let’s say we have an element with this HTML:

<button type="submit" class="okButton">
  "Submit"
</button>

and the CSS:

.okButton:after {
  content: 'Content displayed after the button.';
}

and our test requires us to verify the content displayed in the ::after block. Since this is not a regular element, we cannot identify it using the regular Selenium locators we are all familiar with.

For example, if we do this (the code samples are in C# but apply to other programming languages as well):

var element = _driver.FindElement(By.CssSelector(".okButton"));
Console.WriteLine(element.Text);

Selenium will not return to us the text content inside the before pseud-element.

Trying to locate the ::after pseudo-element by using a locator like “.okButton::after” or “.okButton:after” you will get a NoSuchElementException and still come up empty-handed.

So what’s the solution? Why, JavaScript, of course 😊 Because JavaScript is a front-end programming language, it enables us to go deeper in the HTML and CSS code and allows us to get the content from pseudo-elements in Selenium. So the code we need will be:

String script = "return window.getComputedStyle(document.querySelector('.okButton'),':after').getPropertyValue('content')";
IJavaScriptExecutor js = (IJavaScriptExecutor)_driver;
String content = (String) js.ExecuteScript(script);
Assert.AreEqual("Content displayed after the button.", content);

The JavaScript executor will run a script that takes the content inside the :after pseudo-element. We can then save this content to a string variable and compare it to the expected value and validate our test.

Conclusion

While Selenium itself does not allow interacting with pseudo-elements, we can use the JavaScript executor in our code and obtain the values we need to include in our tests.

About the author

Andreea Draniceanu

Andreea is a QA engineer, experienced in web and desktop applications, and always looking to improve her automation skills and knowledge. Her current focus is automation testing with C#.

Leave a Reply

FacebookLinkedInTwitterEmail