sodcalculator

10 Tech How-To

Selecting CSS Pseudo-Elements with Selenium

Guide 10-34161 · Updated · Step by step

This guide shows you how to target CSS pseudo-elements like ::before and ::after in Selenium WebDriver. These elements are not part of the DOM, so standard locators fail; you’ll learn how to read their content and styles using JavaScript execution, which works across all major browsers.

What You’ll Need

  • A working Selenium WebDriver setup (Java, Python, C#, or JavaScript)
  • A browser driver (ChromeDriver, GeckoDriver, etc.) installed and on your PATH
  • Basic knowledge of CSS selectors and your programming language’s syntax
  • Access to the page you’re testing (local or remote)

Step-by-Step

  1. Identify the pseudo-element you need. Open your browser’s DevTools (F12), inspect the element that has the pseudo-element, and note its CSS selector. For example, a button with class .btn might have a ::before that displays an icon.
  2. Choose your approach. Selenium cannot interact with pseudo-elements directly (no click, no sendKeys). You can only read their computed styles or content. Decide what you need: the text content (e.g., content property) or a style value (e.g., color, background).
  3. Write a JavaScript executor snippet. The core is getComputedStyle(element, '::before').content. Replace ::before with ::after if needed. For example, in Python: driver.execute_script("return getComputedStyle(arguments[0], '::before').content", element).
  4. Locate the parent element. Use your normal Selenium finder to get the element that owns the pseudo-element. For example: element = driver.find_element(By.CSS_SELECTOR, ".btn").
  5. Execute the script and capture the value. Pass the element as an argument. The returned value will be a string (like "\f004" for a FontAwesome icon) or a style value like "rgb(255, 0, 0)".
  6. Parse the result. If you’re reading content, it often comes with quotes (e.g., "✓"). Strip them with .replace(/['"]/g, '') if needed. For colors, convert from rgb/rgba to hex if your test expects that.
  7. Handle multiple pseudo-elements. If you have both ::before and ::after, run the script twice with the different pseudo-name.
  8. Use in assertions. Compare the extracted value to your expected value. For example, assert that the content is not empty, or that the color matches a specific hex.

Common Mistakes

  • Using element.text or getAttribute on pseudo-elements. These only see real DOM content, so they will return empty or null.
  • Forgetting the quotes around the pseudo-element name. In JavaScript, it must be a string: '::before', not ::before.
  • Assuming content is always text. It can be an image URL (url(...)) or a counter, so handle those cases.
  • Not waiting for the pseudo-element to appear. If it’s animated or loaded via JS, you may need an explicit wait before reading.
  • Using the wrong parent selector. If you target a child element, the pseudo-element might belong to the parent. Verify in DevTools.

Tips

  • Use a helper function. Wrap the script in a function like get_pseudo_style(driver, selector, pseudo) to avoid repeating code.
  • Test in the browser console first. Run getComputedStyle(document.querySelector('.btn'), '::before').content in DevTools to see what you expect.
  • For content that is an icon font, compare the unicode value. For example, FontAwesome uses "\f007"; you can assert that the content equals that string.
  • If you need to click a pseudo-element, simulate the click on the parent. Since pseudo-elements are not interactive, you cannot click them directly; instead, click the parent or use JavaScript to trigger the parent’s click.
  • Consider using arguments[0] to pass the element. This is more reliable than re-querying inside the script.

Troubleshooting

  • Script returns undefined or empty string. Check that the pseudo-element actually exists. In DevTools, see if the Styles panel shows ::before or ::after. If not, your selector might be wrong.
  • Get a JavascriptException or SyntaxError. Ensure your script is valid JavaScript. Common issues: missing quotes, extra commas, or using return outside a function (which is fine in execute_script).
  • The content is not what you expect. Some CSS uses content: "" (empty) for layout. If you see empty, that’s correct. Check the actual computed style in DevTools to compare.
  • Works in Chrome but not Firefox. Older Firefox versions had quirks with pseudo-element access. Update your browser and driver. Also, ensure you’re using the latest Selenium.
  • Element is not found. If the parent element is dynamically generated, use WebDriverWait to wait for it to be present before executing the script.

Frequently Asked Questions

Can I click a pseudo-element with Selenium?

No. Pseudo-elements are not part of the DOM, so Selenium cannot interact with them directly. You can click the parent element, or use JavaScript to trigger a click on the parent (which will also trigger the pseudo-element’s effects).

How do I get the text of a ::before element?

Use getComputedStyle(element, '::before').content. This returns the string set in the CSS content property, often with quotes. Strip them if needed.

Why does element.text not include pseudo-element text?

Because pseudo-elements are not part of the DOM tree. The text property only returns text from real child nodes.

Can I use XPath to select pseudo-elements?

No. XPath works on the DOM, and pseudo-elements are not in the DOM. You must use JavaScript with getComputedStyle.

How do I get the background color of a pseudo-element?

Use the same approach: getComputedStyle(element, '::before').backgroundColor. It will return a color string like rgb(0, 0, 0).

Is there a way to wait for a pseudo-element to have a certain value?

Yes. Use an explicit wait that repeatedly executes the script until the value matches your expectation. For example, in Python: WebDriverWait(driver, 10).until(lambda d: d.execute_script("return getComputedStyle(arguments[0], '::before').content", el) == "✓").

Related

General steps for current mainstream versions; menus can differ by device and version. See the disclaimer or report an error.

More in this bed

The whole Tech How-To bed →