'xpath to find pseudo-element ::after in side a div element with out any content

I am trying to write xpath to find a checkbox selected or not, this checkbox is being changed using css ::after element. Below are two elements I have

//div[@class='FormBlock-formItem2' and .//text()='Scoped In']//div[@class='FormBlock-controlIndicator']

two elements for checkboxes

I need to find that 'Scoped Out' is not selected and 'Scoped In' is selected. The only difference I see is '::after' in the second section of checkbox. I tried the xpath :" //div[@class='FormBlock-formItem2' and .//text()='Scoped In']//div[@class='FormBlock-controlIndicator'] " but this is finding the 'Scoped In' element but I am not able to verify if its checked or not. Struggling from couple of days. Kindly help.



Solution 1:[1]

Check code below if return correct true/false:

driver.findElement(By.xpath("//label[./div[@class='FormBlock-itemText' and .='Scope In']]/input")).isSelected();

Solution 2:[2]

Unfortunately, that's not possible with XPath. As mentioned by Tomalak, Pseudo-elements don't exist in the DOM tree (hence the name), therefore they cannot be selected with XPath and Selenium does not expose them as well. In general, ::before and ::after pseudo-elements are used for styling of containing element.

If you want to check whether ::before or ::after pseudo-elements are present or what's their content you can use a CSS selector, like this:

console.log(window.window.getComputedStyle(
	document.querySelector('#item'), ':begin'
));
//or
window.getComputedStyle(
	document.querySelector('#item'), ':after'
).getPropertyValue('color');
#item::after {
    content: 'checked';
    color: rgb(255, 0, 0);
}
<div id="item">
</div>

And then use a JavascriptExecutor to inject the JS into the browser and get the return value:

JavascriptExecutor js = (JavascriptExecutor) driver;         
js.executeScript("return document.title");

Solution 3:[3]

You can try using UI state pseudo-classes, using which we can find elements for various states, such as when control is enabled, disabled, and checked.

Pseudo-classes with input example are -

  1. input:enabled - This will find all the elements that are enabled for user input.
  2. input:disabled - This will find all the elements that are disabled for user input.
  3. input:checked - This will find all the elements(check boxes) that are checked.

    WebElement checkBoxStatus = driver.findElement(By.cssSelector("input:checked"));

More details can be found here on w3c site

Solution 4:[4]

Please check the below screenshot. I try using the CSS selector and checking visibility of element located with wait driver time. It worked.

Html code with after:: pseudo code

python code with css selector and wait time that worked out

Solution 5:[5]

It is possible to use XPath in Selenium WebDriver to access pseudo-elements, but not directly - via JavascriptExecutor.

  1. Find the needed parent element for pseudo-element by XPath and Selenium, save it as e.g. webElement.
  2. Call window.getComputedStyle() function via Selenium JavascriptExecutor, use webElement as parameter. It can be accessible in script by arguments[0] variable.
WebElement webElement = driver.findElement(By.xpath("//div[@class='FormBlock-controlIndicator']");
String script = "return window.getComputedStyle(arguments[0],':after').getPropertyValue('content')";
IJavaScriptExecutor js = (IJavaScriptExecutor)_driver;
String content = (String) js.ExecuteScript(script, webElement);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Sers
Solution 2 wp78de
Solution 3 Amit Jain
Solution 4 Anil Shrestha
Solution 5 Viktor Chmel