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

When automating exams utilizing Selenium, there could also be a situation 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 frequent motive for this error is the presence of Shadow DOM components. Though the ingredient 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 components, how they work, and, most significantly, learn how to 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 referred to as a DOM tree. It has an information mannequin consisting of root nodes and a collection of kid node components, attributes, and so forth.

 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 Net Parts

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

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

Following are the 4 several types of net element requirements:

  • Customized components
  • 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 be taught extra in regards to the Shadow root ingredient of Shadow DOM.

What Is Shadow Root?

Shadow root is part of Shadow DOM. In Shadow DOM, the online browser renders the DOM components with out including them to the principle DOM tree. It’s used to attain 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 components are hidden; nevertheless, they are often seen utilizing the developer instruments possibility within the browsers. The under screenshot is an instance of Shadow DOM. 

Within the code under, #shadow-root is known as Shadow DOM. 

The next pictorial illustration will provide help to perceive Shadow DOM simply.

 The ingredient from the place the Shadow DOM begins is known as Shadow Host. A Shadow tree is the DOM tree inside Shadow DOM, and the foundation node or the topmost node of the Shadow tree is known as 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 be taught 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 take a look at learn how to discover Shadow Root components utilizing developer instruments. 

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

Because the Shadow DOM components are encapsulated from the common DOM, they aren’t straight accessible within the Developer Instruments window, as they’re hidden. We have to allow the “Show user agent shadow DOM” desire within the Developer Instruments window.

Enabling the “Show User Agent Shadow Dom”

The steps to allow the “Show user agent shadow DOM” desire are proven under.

Step 1

Open the Developer Instruments window within the Chrome browser by urgent F12 or clicking on the three dots on the appropriate high 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” possibility. 

We have now set the desire efficiently. Press the Escape key to maneuver again to the Developer Instruments possibility window to search out and validate the Shadow root ingredient.

Finding and Validating the Shadow Root Factor within the Browser

We’ll use the Menu Shadow DOM Demo web page for demonstration functions. This web page has a menu with Shadow DOM components containing 4 menus: File, Edit, View, and Encoding. We’ll 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 ingredient within the browser. 

Step 1

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

Step 2

Develop the node and test for the Shadow Root ingredient. 

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’t use this selector. 

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

First, we should think about the selector earlier than the #shadow-root. Right here, let’s take the category title smart-ui-component

consider the selector before the #shadow-root

Step 5

We have to take a locator from the primary HTML tagline after #shadow-root, as it is going to be the father or mother of the Shadow Root ingredient. 

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

We’ll use the CSS Selector, specializing in the category title and HTML tags right here. The ID selector within the DOM for this net ingredient is dynamic, altering with every refresh of the online 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 aspect of the window, the attribute label can be utilized for it. 

So, the ultimate CSS Selector that we will 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 positioned, use the attribute label to get its textual content.

We have now the CSS Selector .smart-ui-component > .smart-element .smart-menu-main-container .smart-element. Nevertheless, we can’t straight use this selector within the Components tab to find the online ingredient as it’s a Shadow Root ingredient.

It’s higher to validate this selector within the browser earlier than we use it in our exams utilizing Selenium WebDriver as it’s going to save time. In case the selector just isn’t legitimate, Selenium WebDriver will throw NoSuchElementException, and we are going to once more need to test 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 test 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 exams utilizing Selenium with Java.

On this part, we now have realized learn how to deal with Shadow Root in Selenium Java utilizing developer instruments. Within the subsequent part, we are going to discover learn how to 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 components in Selenium. 

The Shadow Root components can’t be straight positioned within the automated exams utilizing Selenium WebDriver as we do for the traditional DOM components. 

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 exams, allow us to first get some primary data relating to the online web page underneath take a look at and likewise the instruments used for take a look at automation.

  • Programming language – Java 17
  • Net automation software – Selenium WebDriver 4.10.0
  • Construct software – Maven
  • Take a look at runner – TestNG
  • Cloud-based testing platform – LambdaTest

Mission Setup  

Create a brand new Maven venture 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 venture because it helps keep the venture 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 exhibit learn how to discover the Shadow root ingredient of the Menu Shadow DOM Demo web page utilizing Selenium WebDriver.

With the assistance of the take a look at situations, code walkthroughs will probably be supplied to assist perceive learn how to find and work together with the Shadow root components. 

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

Finding Shadow Root in Selenium Java Utilizing getShadowRoot() Technique

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 element. NoSuchElementException() is thrown by this technique if the Shadow DOM ingredient just isn’t discovered. 

Take a look at 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 Take a look at 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 accessible 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 ingredient we find is the shadowHost utilizing the classname smart-ui-component. That is required as it’s the ingredient 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 ingredient. 

So, we should find the Shadow Root ingredient utilizing this Shadow Host. The SearchContext interface is used right here to return the Shadow Root ingredient 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 ingredient for the File menu is positioned 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 have now positioned the File menu and the textual content of the menu; it’s now time to put in writing the take a look at and carry out the assertion. 

@Take a look at
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 dwelling web page, it’s going to test for the File menu textual content and assert it with the anticipated textual content File.

Take a look at State of affairs 2

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

Implementation: 

In Take a look at State of affairs 2, we have to click on on the File menu. After that, get the textual content of the New possibility displayed within the menu and assert its textual content. 

In Take a look at State of affairs 1, we now have already positioned 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 possibility. 

From the screenshot above, we will use the next CSS Selector to find the New possibility.

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

The next technique will assist us find the New possibility 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 possibility, 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 possibility. 

@Take a look at
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 possibility 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 strategy to discover and find Shadow Root in Selenium Java is by utilizing JavaScriptExecutor. When you have not upgraded to Selenium 4, this method will probably be helpful as it really works in all the newest 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 ingredient after which broaden and find the Shadow Root components utilizing it. 

Take a look at 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 situation, we are going to find the Shadow Root ingredient 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 ingredient. 

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

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 ingredient, 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 ingredient is positioned, 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 situation by performing an assertion. 

@Take a look at
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 situation 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. 

Take a look at State of affairs 4

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

Implementation:  

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

We’ll reuse the prevailing editMenu() technique created in Take a look at State of affairs 3 to find the Edit menu’s WebElement utilizing the expandRootElement() technique, which locates the Shadow Root ingredient 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 possibility 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");
}

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

@Take a look at
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 possibility. 

With this take a look at, we now have accomplished the code implementation of all 4 situations. Minor refactoring was achieved within the take a look at because the driver.get() assertion was getting repeated in all of the exams. 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 known as 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");
}

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

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

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

@Take a look at
public void testUndoMenuShadowRootElement() {
last HomePage homePage = new HomePage();
assertEquals(homePage.getUndoMenuText(), "Undo");
}
}
bundle 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 ingredient) {
        return (SearchContext) ((JavascriptExecutor) getDriver()).executeScript(
                "return arguments[0].shadowRoot", ingredient);
    }

    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");
    }
}

Take a look at Execution 

There are two methods to execute the exams:

Take a look at Execution Utilizing TestNG 

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

We have to add the next values to run the exams 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 exams run utilizing IntelliJ IDE: 

Take a look at Execution Utilizing Maven 

To execute the exams utilizing Maven, open the terminal, navigate to the foundation folder of the venture, and run the next command: 

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

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

As soon as the exams cross, you possibly can view the take a look at execution outcomes on the LambdaTest Net Automation Dashboard, which supplies all the small print of the take a look at execution. 

Conclusion

On this tutorial, we explored learn how to deal with Shadow Root in Selenium Java. 

We additionally mentioned the DOM, Shadow Tree, and Shadow Root components. Additional, to automate the Shadow root components, 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. Nevertheless, with the Selenium 4 launch, as we now have the getShadowRoot() technique, we will 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