Dynamic Web Tables in Playwright

In this blog, we will cover working with Dynamic web table operations and how to interact with them.

As a pre-requisite we have to check whether the following dependencies or installed or not:

  1. Project setup. 
  2. Run pip list in PyCharm terminal to check whether playwright is installed or not. 

As shown in the above picture playwright should be installed in the project.

If the playwright is not installed refer to Web Automation Testing using Playwright.

What is a Dynamic table?

A dynamic table is a table that changes its number of rows depending on the input received in the form. Such as railway reservation tables, bank user account tables, etc. It will keep on changing based on data and this is the area where we will be focusing on. 

In Playwright we can handle dynamic web tables using Sync and Async methods.

 (A) Using Sync API:

Different ways to Handle Dynamic Tables in Playwright:

  1. Using the Built-In method Augmenting existing locators:

By using the :scope we can apply filters on the locators/elements. It is just like a for loop and if condition. Its traversals through the list of provided elements and select the required element. 

  • We have to locate the list of elements I.e the parent element and store it in a variable. 
  • By using that variable, we have to access the further locators. 

2. Using Dynamic XPATH:

  • We can Create Dynamic XPATH and perform the operation on the required element. (Most Used way).
  • Dynamic XPATH directly works on the element and it takes less time as compared to other methods such as looping statements. 

1. Test Case using has_text method:

Step 1: – Launch the Browser. 

Step 2: – Navigate to https://testuserautomation.github.io/WebTable/

Step 3: – Search the name as JackMan and check the checkbox using the Built-In method()

Step 4: – Verify whether the checkbox is checked or not. 

Step 5: – Close the page and browser.  

from playwright.sync_api import sync_playwright, expect 
with sync_playwright() as page: 
    browser = page.chromium.launch(headless=False,slow_mo=1000) 
    page = browser.new_page() 
    page.goto("https://testuserautomation.github.io/WebTable/") 
    rows = page.locator("//table//tbody//tr") 
    checkbox = rows.locator(":scope",has_text="JackMan").locator("[type='checkbox']") 
    checkbox.check() 
    expect(checkbox).to_be_checked() 
    page.close() 
    browser.close() 

Code Explanation:

  1. Statement 3 to 6 is used to launch the browser and navigate to a website.
  2. The statement used in line no. 6 collects all the rows and stores them in the variable named rows.
  3. In the statement in line no. 7, here we have used the :scope method of the playwright. By using the :scope we can apply filters on the locators/elements and has_text will search the text named Ammy and the locator which we are passing to has_text will check the checkbox. 
  4. The statement at line no. 8 checks the checkbox. 
  5. The statement at line no. 9 is used to assert whether the checkbox is checked or not using the Built-In method I.e to_be_checked(). 
  6. The statement from 10 to 11 is used to close the page and browser. 

2. Test Case using Dynamic XPATH method:

Step 1: – Launch the Browser. 

Step 2: – Navigate to https://testuserautomation.github.io/WebTable/

Step 3: – Search the name as JackMan and check the checkbox using Dynamic XPATH. 

Step 4: – Verify whether the checkbox is checked or not. 

Step 5: – Close the page and browser.

from playwright.sync_api import sync_playwright, expect 
with sync_playwright() as page: 
    browser = page.chromium.launch(headless=False,slow_mo=1000) 
    page = browser.new_page() 
    page.goto("https://testuserautomation.github.io/WebTable/") 
    rows = page.locator("//table//tbody//tr") 
    checkbox = page.locator("//td[text()='JackMan']//preceding-sibling::td//input[@type='checkbox']").check() 
    expect(checkbox).to_be_checked() 
    page.close() 
    browser.close() 

Code Explanation:

  1. The Statement from 3 to 5 is used to launch the browser and navigate to a website. 
  2. The statement in line no. 7 will check the jackbox whose First name is JackMan and store results in a variable named checkbox.
  3. The Statement in line no. 8 is used to assert whether the checkbox is checked or not using the .to_be_checked() method. 
  4. The statement from 9 to 10 is used to close the page and browser. 

B) Using Async API:

In Async API we follow the same approach. The only difference is async API is more stable as compared to the sync API. Here we are using the same Built-In has_text and Dynamic XPATH methods. 

Using the Built-In method Augmenting existing locators:

By using the :scope we can apply filters on the locators/elements. It is just like a for loop and if condition. Its traversals through the list of provided elements and selects the required element. 

  1. We have to locate the list of elements I.e the parent element and store it in a variable. 
  2. By using that variable, we have to access the further locators. 

1. Test Case using has_text method:

Step 1: – Launch the Browser. 

Step 2: – Navigate to https://testuserautomation.github.io/WebTable/

Step 3: – Search the name as JackMan and check the checkbox using the Built-In method(). 

Step 4: – Verify whether the checkbox is checked or not. 

Step 5: – Close the page and browser. 

import asyncio 
from playwright.async_api import async_playwright,expect 
async def Dynamic_table(): 
    async with async_playwright() as page: 
        browser = await page.chromium.launch(headless=False) 
        page = await browser.new_page() 
        await page.goto("https://testuserautomation.github.io/WebTable/") 
        rows = page.locator("//table//tbody//tr") 
        checkbox = rows.locator(":scope", has_text="Ammy").locator("[type='checkbox']") 
        await checkbox.check() 
        await expect(checkbox).to_be_checked() 
        await page.close() 
        await browser.close() 

Code Explanation:

  1. Statement 5 to 7 is used to launch the browser and navigate to a website.
  2. The statement used in line no. 8 collects all the rows and stores them in the variable named rows. 
  3. In the statement in line no. 9, here we have used the :scope method of the playwright. By using the :scope we can apply filters on the locators/elements and has_text will search the text named Ammy and the locator which we are passing to has_text will check the checkbox. 
  4. The statement at line no. 10 checks the checkbox. 
  5. The statement in line no. 11 is used to assert whether the checkbox is checked or not using the Built-In method I.e to_be_checked(). 
  6. The statement from 12 to 13 is used to close the page and browser.  

2. Test Case using Dynamic XPATH method:

Step 1: – Launch the Browser. 

Step 2: – Navigate to https://testuserautomation.github.io/WebTable/

Step 3: – Search the name as JackMan and check the checkbox using Dynamic XPATH. 

Step 4: – Verify whether the checkbox is checked or not. 

Step 5: – Close the page and browser. 

import asyncio 
from playwright.async_api import async_playwright,expect 
async def Dynamic_table(): 
    async with async_playwright() as page: 
        browser = await page.chromium.launch(headless=False) 
        page = await browser.new_page() 
        await page.goto("https://testuserautomation.github.io/WebTable/") 
        checkbox = await page.locator("//td[text()='JackMan']//preceding-sibling::td//input[@type='checkbox']").check() 
        await page.wait_for_timeout(4000) 
        await expect(checkbox).to_be_checked() 
        await page.close() 
        await browser.close() 
asyncio.run(Dynamic_table()) 

Code Explanation:

  1. The Statement from 5 to 7 is used to launch the browser and navigate to a website. 
  2. The statement at line no. 8 will check the checkbox whose First name is JackMan and store results in a variable named checkbox. 
  3. The Statement at line no. 10 is used to assert whether the checkbox is checked or not using the .to_be_checked() method. 
  4. The statement from 11 to 12 is used to close the page and browser. 

Read the next Playwright blog Here.