添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • Postman vs Insomnia
  • Testing REST API’s with Postman and Jenkins – Part 1
  • Testing REST API’s with Postman and Jenkins – Part 2
  • Testing REST API’s with Postman and Jenkins – Part 3
  • Mongo-DB
  • Unit Testing Mongo DB Connection
  • Protractor Interview Questions – Part-1
  • Protractor Interview Questions – Part-2
  • Reporting in Protractor
  • Playwright
  • Playwright Questions for Interview – Part -1
  • Playwright Questions Set- 2
  • Playwright Interview Questions – Part 3
  • Playwright Interview Questions – Part 4
  • Selenium vs Selenium Grid vs Maven vs Ant vs Jenkins
  • Selecting An IDE
  • Selenium Implementation
  • Selenium-Java
  • Installation -Ubuntu 14.04 LTS – Eclipse
  • Installation -Windows 7 using Eclipse
  • First Script-Selenium With Python
  • Running Script with Google Chrome
  • Marionette Driver -Firefox
  • Web Elements Locating Mechanisms
  • Locating WebElements On A Webpage
  • An Xpath Example
  • Writing A Proper Xpath
  • Python’s Unit Test Framework
  • Simple Script Using Unittest
  • Understanding Webdriver Waits
  • Implicit Waits and Explicit Waits
  • CheckBoxes and Radio Buttons
  • Basic Browser Commands
  • Browser Navigation
  • Refreshing Page In Different Ways Using Webdriver
  • Maximising Browser using Selenium
  • Hidden Elements In HTML Page
  • Handling Multiple CSS Selectors
  • Switching Between Different Windows
  • Using Actions Class
  • Taking Screenshot Of A Page
  • Mouse Hover Over
  • Advanced Topics
  • HTML Table Handling
  • Cropping An Image Using PIL
  • Generating A HTML Report
  • Finding Out All Links In A Webpage
  • Scrolling Down a Page
  • Playing With JavaScript and JavaScript Executor
  • ExecuteScript vs ExecuteAsyncScript in Selenium
  • Highlighting a Web Element on Webpage
  • Page Object Model
  • Example of POM
  • Handling Shadow DOM
  • Screenshot Of A Specific Element
  • Zoom Functionality On An E-Commerce Website
  • Using Excel and Selenium
  • Selenium – Interesting Scenarios
  • Comprehensive Selenium Tutorials
  • Code Snippets
  • Cypress
  • Cypress Links and Resources
  • Playwright
  • Playwright and Shadow DOM – A Love Story
  • Masked Screenshot in Playwright
  • Add and Remove an HTML Attribute using Playwright
  • Playing with SVG – Playwright
  • Working with File Uploads in Playwright
  • Playwright and CSS Validation
  • Some Useful Assertions in Playwright – Part -1
  • Some Useful Assertions in Playwright – Part -2
  • Playwright UI – Part 1
  • Playwright Timeouts
  • Playwright – Table Handling – 1
  • Playwright – Table Handling – 2
  • Playwright Resources
  • Starting First Job Using Jenkins
  • Jenkins- Installation on Ubuntu 14.04 LTS
  • Creating and Scheduling a Job
  • Mobile Testing
  • Detox- E2E Testing React Native App
  • Appium
  • Appium – Set Up
  • Initial Setup For App
  • Generating APK
  • Getting Started with Test Script
  • Creating first Script
  • Since Playwright came out of shadows, there has been a lot of buzz around it lately. One of the reason for this is how Playwright simplifies handling of complex page scenarios like Iframes , Shadow DOM elements etc.

    So, before Playwright, Selenium also was able to handle open Shadow DOM elements ( we’ll take about Open and Closed Shadow DOM in section below). However, it relied on the use of plain JS functions to get elements inside the Shadow DOM. Also, if you had multiple Shadow DOM hierarchies, then it became a bit tough ( although not impossible) to get inside the hierarchy.

    In this blog, we’ll see how Playwright solves these issues. We’ll see how it has made us fell in love again with the Shadow DOM elements – with multiple scenarios include a combination of Shadow DOM and iFrames also.

    We’ll not compare how the Playwright solves this issues with respect to Selenium, because I don’t think so that this warrants a comparison, and also I’m too lazy to create such a post 😀

    As you can see from above, one shadow root is open while the other one is closed. There is a difference in between open and closed shadow roots – the open shadow root can be accessed via the shadowRoot property of the HTML element, where as closed shadow root can be accessed. You can read this question on Stackoverflow about this here .

    We’ll take Sanjay Kumar’s SelectorsHub Practice page as the AUT since it has almost all of the complex scenarios we want to cover. Btw, if you haven’t you need to take a look at SelectorsHub extension, a very helpful extension for the automation engineers, which is under the umbrella of a host of other products offered by SelectorsHub .

    This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
    Show hidden characters This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
    Show hidden characters

    The thing about the practice page from Selectorshub is that there is no dearth of the complex scenarios on this page. Most of the practice pages out there have the basic scenarios, which is good, but when you’re working in an enterprise applications, then most of the times you will have to encounter more complex scenarios.

    One of such scenarios is when the element is inside an iframe, which is in turn embedded inside an open shadow root. How do you handle such scenarios? Let’s see and find out.

    This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
    Learn more about bidirectional Unicode characters
    Show hidden characters

    Up until now, we’ve seen scenarios where Playwright can directly or indirectly pierce the shadow root. Now if the element is inside a closed shadow root, how do we enter that element? There is a separate school of thought or approach as to why even automate that? I kind of agree to that, but any how let’s test if we can use any kind of workaround to get text to that element.

    import { chromium,test } from "@playwright/test";
    test.use({ viewport: { width: 1400, height: 1000 } });
    test('Launch the Selectors hub test page',async()=>{
    const browser = await chromium.launch({
    headless: false
    const context = await browser.newContext();
    const page = await context.newPage();
    await page.goto("https://selectorshub.com/xpath-practice-page/");
    await page.waitForSelector('.dropbtn',{
    state: "visible"
    await page.locator('div#userPass').click();
    await page.keyboard.press('Tab');
    await page.evaluate(() => document.activeElement.setAttribute('value','Top Gun Maverick'));
    await page.keyboard.press('Enter');
    await page.waitForTimeout(5000);

    The code runs successfully, without any failure but the input box doesn’t show the value. Hmm. Let’s see if the value is being set correctly.

    Add this piece of code

    let textcontent = await page.evaluate(()=> document.activeElement.getAttribute('value')); await console.log(`The value set is ${textcontent}`);

    This gives a console output which shows that value is set

    await page.locator("#userName input#pizza").click(); await page.keyboard.press('Tab'); await page.waitForTimeout(5000); await page.evaluate(() => document.activeElement.setAttribute('value','hawke')); const pagetext = await page.evaluate(() => document.activeElement.getAttribute('value')); await console.log(pagetext);

    In this case also the value attribute is set but the value doesn’t show up on the UI, which means that in Scenario 4, the type of input field which is password doesn’t make any difference. I’ll track this in the github issue mentioned above and let’s see what transpires.

    Edit 1 : I got a response on my question above and the solution is pretty simple. We can use the type command to sent the text input. So essentially we modified our code to this

    await page.locator("#userName input#pizza").click(); await page.keyboard.press('Tab'); await page.keyboard.type('I love pizza'); await page.waitForTimeout(5000);

    In the above 5 scenarios, we saw how Playwright makes it easy to interact with Shadow DOM elements. For the closed ones, I’ll try to work to see if there can be any other work around, which I think should be possible, given the power of JS. In the next blog, maybe we’ll have a look at how we can work with different scenarios in iframes.