How To Deal with Shadow Root in Selenium Java – DZone – Uplaza

When automating assessments utilizing Selenium, there could also be a state of affairs the place you possibly can’t discover a component on an internet web page regardless that it appears to be within the Doc Object Mannequin (DOM).

On this case, Selenium throws a NoSuchElementException() error. 

One widespread motive for this error is the presence of Shadow DOM parts. Though the component is current within the DOM, it is encapsulated inside a Shadow root in Selenium and requires particular dealing with to entry it for automation testing. 

On this Selenium Java tutorial, we’ll delve into Shadow root parts, how they work, and, most significantly, how you can deal with Shadow root in Selenium Java.

What Is a Doc Object Mannequin?

A Doc Object Mannequin is a language-independent and cross-platform interface that serves the HTML or XML doc as a tree construction. On this tree construction, every node is an object that represents part of the doc. 

When an internet web page is loaded within the browser, the HTML code is transformed right into a hierarchical illustration of the HTML doc known as a DOM tree. It has a knowledge mannequin consisting of root nodes and a collection of kid node parts, attributes, and many others.

 Following is the HTML code when loaded on the internet web page:


  
    LambdaTest
  
  
    
    

Decode the way forward for testing

The above HTML code will probably be represented as a DOM tree as follows:

- Doc (root)
  - html
    - head
      - title
        - "LambdaTest"
    - physique
      - h1
        - "Welcome to Testu Conference"
      - p
        - "Decode the future of testing"

Right here is the precise illustration of HTML after it’s rendered within the browser.

Overview of Internet Elements

Internet parts are a preferred method to constructing micro frontends that assist develop reusable customized parts. 

It helps within the encapsulation and interoperability of particular person HTML parts. Internet parts are based mostly on present net requirements. Widgets and customized parts constructed on the internet part requirements can be utilized with any JavaScript library or framework that works with HTML. Internet parts work throughout all fashionable browsers.

Following are the 4 several types of net part requirements:

  • Customized parts
  • HTML templates
  • HTML imports
  • Shadow DOM

Within the subsequent part of this tutorial on dealing with Shadow root in Selenium Java, we are going to study extra concerning the Shadow root component of Shadow DOM.

What Is Shadow Root?

Shadow root is part of Shadow DOM. In Shadow DOM, the net browser renders the DOM parts with out including them to the principle DOM tree. It’s used to realize encapsulation in HTML paperwork. 

The fashion and conduct of 1 a part of the doc might be saved hidden and separate from the opposite code in the identical HTML doc to keep away from interference by implementing Shadow DOM. 

Ideally, the Shadow DOM parts are hidden; nevertheless, they are often seen utilizing the developer instruments choice within the browsers. The beneath screenshot is an instance of Shadow DOM. 

Within the code beneath, #shadow-root is named Shadow DOM. 

The next pictorial illustration will allow you to perceive Shadow DOM simply.

 The component from the place the Shadow DOM begins is named Shadow Host. A Shadow tree is the DOM tree inside Shadow DOM, and the basis node or the topmost node of the Shadow tree is named the Shadow Root.

A Shadow Boundary is the place the Shadow DOM ends and the common DOM begins. We have to find the Shadow Root first, as it’s the place from the place the Shadow DOM begins. 

Earlier than we dive deep into dealing with Shadow Root in Selenium Java, let’s study alternative ways to search out Shadow Root utilizing developer instruments.

On this part of this tutorial on dealing with Shadow Root in Selenium Java, we are going to have a look at how you can discover Shadow Root parts utilizing developer instruments. 

Shadow DOM parts are notably helpful when creating customized parts. Shadow DOM is used to encapsulate a component’s HTML, CSS, and JS, thus producing an internet part. 

Because the Shadow DOM parts are encapsulated from the common DOM, they don’t seem to be instantly accessible within the Developer Instruments window, as they’re hidden. We have to allow the “Show user agent shadow DOM” choice within the Developer Instruments window.

Enabling the “Show User Agent Shadow Dom”

The steps to allow the “Show user agent shadow DOM” choice are proven beneath.

Step 1

Open the Developer Instruments window within the Chrome browser by urgent F12 or clicking on the three dots on the fitting prime of the browser. After that, navigate to  Extra Instruments > Developer Instruments

Step 2

Click on on the gear icon on the highest proper nook of the Developer Instruments window to open the preferences display screen and tick on the “Show user agent shadow DOM” choice. 

We’ve set the choice efficiently. Press the Escape key to maneuver again to the Developer Instruments choice window to search out and validate the Shadow root component.

Finding and Validating the Shadow Root Factor within the Browser

We are going to use the Menu Shadow DOM Demo web page for demonstration functions. This web page has a menu with Shadow DOM parts containing 4 menus: File, Edit, View, and Encoding. We are going to discover the locator for the File menu and likewise validate it within the Chrome browser console. 

Let’s go step-by-step and find the Shadow Root component within the browser. 

Step 1

Navigate to the Menu Shadow DOM Demo web page and open the Developer Instruments window. 

Step 2

Increase the node and verify for the Shadow Root component. 

Step 3

Find the File menu by clicking on the arrow icon on the highest left of the Developer Instruments window. 

Step 4

Right here, the ID selector used for the File menu is a dynamic worth. It modifications each time the web page is refreshed; therefore, we can not use this selector. 

So, let’s create the CSS Selector utilizing the parent-child relationship within the DOM. 

First, we must take into account the selector earlier than the #shadow-root. Right here, let’s take the category title smart-ui-component

Step 5

We have to take a locator from the primary HTML tagline after #shadow-root, as will probably be the mother or father of the Shadow Root component. 

Subsequent, find the File menu WebElement utilizing its respective HTML tag and sophistication title. 

We are going to use the CSS Selector, specializing in the category title and HTML tags right here. The ID selector within the DOM for this net component is dynamic, altering with every refresh of the net web page. 

Subsequent, we have to get the textual content of the File menu, which is File, and as seen within the Properties tab on the right-hand facet of the window, the attribute label can be utilized for it. 

So, the ultimate CSS Selector that we are able to use for finding the File menu is:

  • To find the Shadow host, use the category title .smart-ui-component.
  • To find the File menu contained in the Shadow root, use the .smart-element .smart-menu-main-container .smart-element.
  • As soon as the File menu WebElement is situated, use the attribute label to get its textual content.

We’ve the CSS Selector .smart-ui-component > .smart-element .smart-menu-main-container .smart-element. Nonetheless, we cannot instantly use this selector within the Components tab to find the net component as it’s a Shadow Root component.

It’s higher to validate this selector within the browser earlier than we use it in our assessments utilizing Selenium WebDriver as it’ll save time. In case the selector just isn’t legitimate, Selenium WebDriver will throw NoSuchElementException, and we are going to once more must verify for the legitimate selector. 

To validate the selector within the Developer Instruments window, use the next steps: 

  • Step 1: Navigate to the browser console. 
  • Step 2: Use the querySelector with the shadowRoot command and verify the output within the console. The next question can be utilized to find the Shadow host within the console:
doc.querySelector('.smart-ui-component').shadowRoot.querySelector('.smart-element .smart-menu-main-container .smart-element ').getAttribute('label')

After coming into the above question, press the Enter key to validate if we get the textual content of the menu title File within the output.  We will try the textual content File printed within the console output, thus making the validation for the selector profitable. We will use this selector whereas operating automated assessments utilizing Selenium with Java.

On this part, we now have discovered how you can deal with Shadow Root in Selenium Java utilizing developer instruments. Within the subsequent part, we are going to discover how you can deal with Shadow root in Selenium Java utilizing the getShadowRoot() technique and JavaScriptExecuter.

Discovering Shadow Root Utilizing Selenium Java

On this part of this tutorial on dealing with Shadow Root in Selenium Java, we are going to look into alternative ways to search out Shadow Root parts in Selenium. 

The Shadow Root parts cannot be instantly situated within the automated assessments utilizing Selenium WebDriver as we do for the conventional DOM parts. 

The next methods can be utilized to deal with Shadow root in Selenium Java.

  • Utilizing getShadowRoot() technique
  • Utilizing JavaScriptExecutor

Earlier than we start discussing the code and writing the automated assessments, allow us to first get some primary data relating to the net web page beneath take a look at and likewise the instruments used for take a look at automation.

  • Programming language – Java 17
  • Internet automation instrument – Selenium WebDriver 4.10.0
  • Construct instrument – Maven
  • Check runner – TestNG
  • Cloud-based testing platform – LambdaTest

Mission Setup  

Create a brand new Maven mission and replace the required dependencies for Selenium WebDriver and TestNG within the pom.xml. The next is the screenshot of pom.xml

Web page Object Mannequin (POM) in Selenium Java has been used on this mission because it helps keep the mission by bettering take a look at case upkeep and eradicating code duplication.

On this part of the tutorial on dealing with Shadow Root in Selenium Java, we are going to show how you can discover the Shadow root component of the Menu Shadow DOM Demo web page utilizing Selenium WebDriver.

With the assistance of the take a look at eventualities, code walkthroughs will probably be supplied to assist perceive how you can find and work together with the Shadow root parts. 

Let’s use the getShadowRoot() technique to find the Shadow root in Selenium Java.

Finding Shadow Root in Selenium Java Utilizing getShadowRoot() Methodology

The getShadowRoot() technique was launched with the discharge of Selenium WebDriver 4.0.0 and above. The getShadowRoot() technique returns a illustration of a component’s Shadow root for accessing the Shadow DOM of an internet part. NoSuchElementException() is thrown by this technique if the Shadow DOM component just isn’t discovered. 

Check State of affairs 1

  1. Navigate to the Menu Shadow DOM Demo web page.
  2. Find the File menu throughout the Shadow DOM.
  3. Carry out assertion by getting the textual content of the menu title File.

Implementation

In Check State of affairs 1, we have to navigate to the demo web page, find the File menu, and carry out assertion by getting the textual content of the menu File

Right here, we have to find the File menu first and use the getShadowRoot() technique in Selenium WebDriver to find it. 

The next technique obtainable within the HomePage class will find the File menu. 

public WebElement fileMenu() {
last WebElement shadowHost = getDriver().findElement(By.cssSelector(".smart-ui-component"));

last SearchContext shadowRoot = shadowHost.getShadowRoot();


return shadowRoot.findElement(By.cssSelector(".smart-element .smart-menu-main-container .smart-element"));
}

Within the fileMenu() technique, the primary net component we find is the shadowHost utilizing the classname smart-ui-component. That is required as it’s the component simply earlier than the Shadow DOM. 

Subsequent, we seek for the Shadow root within the DOM subsequent to it. The #shadow-root(open) is subsequent to the  HTML component. 

So, we must find the Shadow Root component utilizing this Shadow Host. The SearchContext interface is used right here to return the Shadow Root component utilizing the getShadowRoot() technique. getShadowRoot() technique is part of the WebElement interface, which is carried out within the RemoteWebElement class of Selenium WebDriver.

Lastly, the Shadow root component for the File menu is situated utilizing the CSS Selector .smart-element .smart-menu-main-container .smart-element

Now, to carry out assertion, we have to get the textual content of the menu, i.e., File. As seen within the screenshot above, the textual content might be retrieved utilizing the attribute label

The next technique will present us with the textual content.

public String getFileMenuText() {
return fileMenu().getAttribute("label");
}

We’ve situated the File menu and the textual content of the menu; it’s now time to write down the take a look at and carry out the assertion. 

@Check
public void testFileMenuShadowRootElement() {

getDriver().get("https://www.htmlelements.com/demos/menu/shadow-dom/index.htm");

last HomePage homePage = new HomePage();
assertEquals(homePage.getFileMenuText(), "File");

}

It is rather easy to know that this take a look at will navigate to the Menu Shadow DOM Demo web page. From the web site’s house web page, it’ll verify for the File menu textual content and assert it with the anticipated textual content File.

Check State of affairs 2

  1. Click on on the File menu that’s throughout the Shadow DOM.
  2. Find the New choice.
  3. Carry out assertion to verify that the textual content of the choice is New.

Implementation: 

In Check State of affairs 2, we have to click on on the File menu. After that, get the textual content of the New choice displayed within the menu and assert its textual content. 

In Check State of affairs 1, we now have already situated the File menu. Right here, we are going to open the File menu by clicking on it and getting the textual content of the New choice. 

From the screenshot above, we are able to use the next CSS Selector to find the New choice.

The CSS Selector .smart-menu-drop-down div smart-menu-item.smart-element can be utilized to find the New choice and its attribute label to get its textual content. 

The next technique will assist us find the New choice and get its textual content. 

public String getNewMenuText() {
openFileMenu();
return fileMenu().findElement(By.cssSelector(".smart-menu-drop-down div smart-menu-item.smart-element"))
.getAttribute("label");
}

The getNewMenuText() technique will open the File menu, search and find the New choice, and return the attribute label

Let’s write the take a look at and carry out the assertion for the textual content within the New choice. 

@Check
public void testNewMenuShadowRootElement() {

getDriver().get("https://www.htmlelements.com/demos/menu/shadow-dom/index.htm");

last HomePage homePage = new HomePage();
assertEquals(homePage.getNewMenuText(), "New");

}

On this take a look at, we first navigate to the Menu Shadow DOM Demo web page. From the house web page of the web site, get the textual content of the New choice and carry out assertion on the menu textual content.

Within the subsequent part, to search out Shadow Root in Selenium Java, we are going to use the JavaScriptExecutor technique.

Finding Shadow Root in Selenium Java Utilizing JavaScriptExecutor

One other technique to discover and find Shadow Root in Selenium Java is by utilizing JavaScriptExecutor. You probably have not upgraded to Selenium 4, this method will probably be helpful as it really works in all the most recent and older variations.

Utilizing JavaScriptExecutor to deal with Shadow Root in Selenium Java is fairly easy. We have to observe the identical steps as we did whereas working with the getShadowRoot() technique. First, discover the Shadow host component after which broaden and find the Shadow Root parts utilizing it. 

Check State of affairs 3

  1. Navigate to the Menu Shadow DOM Demo web page.
  2. Find the Edit menu that’s throughout the Shadow DOM.
  3. Carry out assertion by getting the textual content of the Edit menu.

Implementation:  

On this take a look at state of affairs, we are going to find the Shadow Root component for the Edit menu and carry out assertion by getting its textual content Edit. As we’re utilizing JavaScriptExecutor right here, the expandRootElement() technique is created to broaden and find the Shadow Root component. 

public SearchContext expandRootElement(last WebElement component) {
return (SearchContext) ((JavascriptExecutor) getDriver()).executeScript(
"return arguments[0].shadowRoot", component);
}

The above technique will execute the script return arguments[0].shadowRoot on the WebElement supplied within the technique parameter and get the Shadow Root.

Subsequent, let’s find the Edit menu and get its textual content.  The editMenu() technique returns the WebElement for the Edit menu. To get the Shadow Root component, the expandRootElement() technique is used the place the shadowHost WebElement is handed as a parameter.

public WebElement editMenu() {
last WebElement shadowHost = getDriver().findElement(By.cssSelector(".smart-ui-component"));
last SearchContext shadowRoot = expandRootElement(shadowHost);
return shadowRoot.findElement(By.cssSelector(".smart-element .smart-menu-main-container smart-menu-items-group:nth-child(2)"));
}

As soon as the Shadow Root component is situated, we seek for the Edit menu utilizing the CSS Selector and return the WebElement

The attribute label is used to get the textual content Edit from the menu title. The next technique, editMenuText(), returns the textual content in String format.

public String getEditMenuText() {
return editMenu().getAttribute("label");
}

Let’s write the take a look at and full the state of affairs by performing an assertion. 

@Check
public void testEditMenuShadowRootElement() {

getDriver().get("https://www.htmlelements.com/demos/menu/shadow-dom/index.htm");

last HomePage homePage = new HomePage();
assertEquals(homePage.getEditMenuText(), "Edit");
}

This take a look at completes the state of affairs the place we navigate to the Menu Shadow DOM Demo web page, find the Edit menu, and carry out assertion by verifying the Edit textual content of the menu title. 

Check State of affairs 4

  1. Click on on the Edit menu that’s throughout the Shadow DOM.
  2. Find the Undo choice.
  3. Carry out assertion to verify that the textual content of the menu is Undo.

Implementation:  

On this take a look at state of affairs, we are going to click on the Edit menu to open the dropdown. Within the dropdown, we find the Undo choice and carry out an assertion to confirm its textual content Undo.

We are going to reuse the prevailing editMenu() technique created in Check State of affairs 3 to find the Edit menu’s WebElement utilizing the expandRootElement() technique, which locates the Shadow Root component utilizing JavaScriptExecutorThe openEditMenu() technique will click on on the Edit menu and open the dropdown.

public void openEditMenu() {
editMenu().click on();
}

The getUndoMenuText() technique will find the Undo choice and return the textual content Undo within the String format.

public String getUndoMenuText() {
openEditMenu();
return editMenu().findElement(By.cssSelector(".smart-menu-drop-down div smart-menu-item.smart-element"))
.getAttribute("label");
}

Once we find the WebElements, let’s proceed and write the ultimate take a look at to finish Check State of affairs 4.

@Check
public void testUndoMenuShadowRootElement() {

getDriver().get("https://www.htmlelements.com/demos/menu/shadow-dom/index.htm");

last HomePage homePage = new HomePage();
assertEquals(homePage.getUndoMenuText(), "Undo");
}

On this take a look at, we navigate to the Menu Shadow DOM Demo web page. From the house web page, click on on the Edit menu and assert the textual content of the Undo choice. 

With this take a look at, we now have accomplished the code implementation of all 4 eventualities. Minor refactoring was performed within the take a look at because the driver.get() assertion was getting repeated in all of the assessments. I’ve moved that assertion out and positioned it in a navigateToWebsite() techniqueutilizing @BeforeClass annotation in TestNG. So, this annotation will probably be used as quickly as this class is named earlier than operating the take a look at. 

public class ShadowRootTests extends BaseTest {

@BeforeClass
public void navigateToWebsite() {
getDriver().get("https://www.htmlelements.com/demos/menu/shadow-dom/index.htm");
}

@Check
public void testFileMenuShadowRootElement() {
last HomePage homePage = new HomePage();
assertEquals(homePage.getFileMenuText(), "File");
}

@Check
public void testNewMenuShadowRootElement() {
last HomePage homePage = new HomePage();
assertEquals(homePage.getNewMenuText(), "New");
}

@Check
public void testEditMenuShadowRootElement() {
last HomePage homePage = new HomePage();
assertEquals(homePage.getEditMenuText(), "Edit");
}

@Check
public void testUndoMenuShadowRootElement() {
last HomePage homePage = new HomePage();
assertEquals(homePage.getUndoMenuText(), "Undo");
}
}
package deal pages.htmlelements;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;

import static setup.DriverManager.getDriver;

public class HomePage {

    public WebElement fileMenu() {
        last WebElement shadowHost = getDriver().findElement(By.cssSelector(".smart-ui-component"));
        last SearchContext shadowRoot = shadowHost.getShadowRoot();
        return shadowRoot.findElement(By.cssSelector(".smart-element .smart-menu-main-container .smart-element"));
    }

    public String getFileMenuText() {
        return fileMenu().getAttribute("label");
    }

    public void openFileMenu() {
        fileMenu().click on();
    }

    public String getNewMenuText() {
        openFileMenu();
        return fileMenu().findElement(By.cssSelector(".smart-menu-drop-down div smart-menu-item.smart-element"))
                .getAttribute("label");
    }

    public SearchContext expandRootElement(last WebElement component) {
        return (SearchContext) ((JavascriptExecutor) getDriver()).executeScript(
                "return arguments[0].shadowRoot", component);
    }

    public WebElement editMenu() {
        last WebElement shadowHost = getDriver().findElement(By.cssSelector(".smart-ui-component"));
        last SearchContext shadowRoot = expandRootElement(shadowHost);
        return shadowRoot.findElement(By.cssSelector(".smart-element .smart-menu-main-container smart-menu-items-group:nth-child(2)"));
    }

    public String getEditMenuText() {
        return editMenu().getAttribute("label");
    }

    public void openEditMenu() {
        editMenu().click on();
    }

    public String getUndoMenuText() {
        openEditMenu();
        return editMenu().findElement(By.cssSelector(".smart-menu-drop-down div smart-menu-item.smart-element"))
                .getAttribute("label");
    }
}

Check Execution 

There are two methods to execute the assessments:

Check Execution Utilizing TestNG 

We have to have the testng.xml file within the mission’s root folder. The next take a look at blocks are required within the testng.xml file to run all our assessments. The assessments will probably be operating on the LambdaTest cloud grid on the Chrome browser.

We have to add the next values to run the assessments on the LambdaTest cloud grid:

  • LambdaTest Username
  • LambdaTest Entry Key

These values might be handed utilizing the Run Configuration window within the IDE as -DLT_USERNAME = -DLT_ACCESSKEY=

To run this testng.xml file, right-click on it and choose the choice Run ‘…/testng.xml.

Right here is the screenshot of the assessments run utilizing IntelliJ IDE: 

Check Execution Utilizing Maven 

To execute the assessments utilizing Maven, open the terminal, navigate to the basis folder of the mission, and run the next command: 

mvn clear take a look at -DLT_USERNAME =  -DLT_ACCESSKEY= 

Right here is the screenshot of the assessments run utilizing the terminal: 

As soon as the assessments move, you possibly can view the take a look at execution outcomes on the LambdaTest Internet Automation Dashboard, which supplies all the main points of the take a look at execution. 

Conclusion

On this tutorial, we explored how you can deal with Shadow Root in Selenium Java. 

We additionally mentioned the DOM, Shadow Tree, and Shadow Root parts. Additional, to automate the Shadow root parts, we used the getShadowRoot() technique, which was launched with Selenium WebDriver 4. 

The JavaScriptExecutor can be utilized to deal with Shadow Root in Selenium Java. In case you are engaged on the Selenium WebDriver model lower than 4, utilizing JavaScriptExecutor is a perfect resolution to deal with Shadow Root in Selenium Java. Nonetheless, with the Selenium 4 launch, as we now have the getShadowRoot() technique, we are able to use it as it’s a lot simpler than JavaScriptExecutor.

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version