Click on Pseudo Element Using Selenium

Click on pseudo element using Selenium

I've encounter the same problem while writing Selenium tests for Salesforce and managed to solve it by direct control over mouse using Actions.

Wrapper table for this button has hardcoded width of 250px, and you have spotted that. To locate where the mouse is, you can use contextClick() method instead of Click(). It simulates right mouse button so it will always open browser menu.

If you do:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).ContextClick().Build().Perform();

you will spot that mouse moves to the middle of the WebElement, not the top left corner (I thought that it does too). Since that element width is constant, we can move mouse just by 250 / 2 - 1 to the right and it will work :)
code:

Actions build = new Actions(Session.Driver);
build.MoveToElement(FindElement(By.Id("ext-gen33"))).MoveByOffset(124, 0).Click().Build().Perform();

How to click on the element using selenium where only "::Before" tag is present

I am not 100% sure if WebDriver can retrieve pseudo element content for you. I think you would need to use Javascript. Below works, I tested.

Open date picker

driver.findElement(By.xpath("//input[@class='fl-input _9KqY' and @data-reactid='195']")).click();   

click on next elements or next month

JavascriptExecutor js = (JavascriptExecutor) driver; 
js.executeScript("document.querySelector('a.react-datepicker__navigation--next',':before').click();");

How locate the pseudo-element ::before using Selenium Python

Pseudo Elements

A CSS pseudo-element is used to style specified parts of an element. It can be used to:

  • Style the first letter, or line, of an element
  • Insert content before, or after, the content of an element

::after

::after is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is, and would essentially be like this:

CSS:

div::after {
content: "hi";
}

::before

::before is exactly the same only it inserts the content before any other content in the HTML instead of after. The only reasons to use one over the other are:

  • You want the generated content to come before the element content, positionally.
  • The ::after content is also "after" in source-order, so it will position on top of ::before if stacked on top of each other naturally.

Demonstration of extracting properties of pseudo-element

As per the discussion above you can't locate the ::before element within the DOM Tree but you can always be able to retrieve the contents of the pseudo-elements, i.e. ::before and ::after elements. Here's an example:

To demonstrate, we will be extracting the content of ::after element (snapshot below) within this website:

after_element

  • Code Block:

    from selenium import webdriver

    options = webdriver.ChromeOptions()
    options.add_argument("start-maximized")
    options.add_experimental_option("excludeSwitches", ["enable-automation"])
    options.add_experimental_option('useAutomationExtension', False)
    driver = webdriver.Chrome(options=options, executable_path=r'C:\WebDrivers\chromedriver.exe')
    driver.get('https://meyerweb.com/eric/css/tests/pseudos-inspector-test.html')
    script = "return window.getComputedStyle(document.querySelector('body>p.el'),':after').getPropertyValue('content')"
    print(driver.execute_script(script).strip())
  • Console Output:

    " (fin.)"

This console output exactly matches the value of the content property of the ::after element as seen in the HTML DOM:

after_content


This usecase

To extract the value of the content property of the ::before element you can use the following solution:

script = "return window.getComputedStyle(document.querySelector('div.crow'),':before').getPropertyValue('content')"
print(driver.execute_script(script).strip())

Outro

A couple of relevant documentations:

  • Document.querySelector()
  • Window.getComputedStyle()

Interact with pseudo-elements with Selenium Webdriver?

If it is Java bindings and all you want to do is to click on an achor tag which has Raw view as a text.

You could try with ExplicitWaits :

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(By.partialLinkText("Raw View"))).click();

how to select a pseudo-element and change status from :: after a :: before?

You can try to use a Javascript click to click your desired element and work around the ElementNotInteractable exception:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


# first invoke WebDriverWait and wait for the element to exist
checkbox = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "gdpr_26839")))

# use Javascript to click checkbox
driver.execute_script("arguments[0].click();", checkbox)

You may need to modify the selector method By.ID, "gdpr_26839" if this does not work. Something such as By.XPATH, //input[contains(@id, 'gdpr')] might work better, depending on whether or not gdpr_26839 is a unique / dynamically-generated ID.



Related Topics



Leave a reply



Submit