The simplicity of Python Playwright is one of its main advantages. It is suitable for various testing and automation jobs because it is simple and requires little setup. It also provides a wide range of features and skills, such as navigating web pages, interacting with web components, and managing dialogue boxes and modal windows.
In this Playwright Python tutorial, let’s understand why it is easier to use it, its key features, installation steps, and a few test cases.
Table of ContentsMicrosoft’s Playwright is a potent tool for automating and testing web applications. It offers a straightforward, understandable API for managing a web browser and interacting with web elements and pages.
Here are a few key characteristics of the Playwright testing framework:
Automating your web testing with Playwright has the following benefits:
End-to-end testing is a software testing methodology that examines an application’s flow from beginning to end. End-to-end testing aims to validate the system under test and its components for integration and data integrity by simulating the real user scenario.
It is carried out end-to-end under real-world conditions, including interactions between the application and the hardware, network, database, and other applications.
These four features make it more reliable and efficient than other tools for End-to-end testing.
Playwright uses the Chrome DevTools protocol to interact directly with browsers. Compared to alternatives, the protocol enables a quicker and less error-prone execution. Even if we are only discussing fractions of seconds, they are advantageous!
You can “just” click the Playwright button to avoid waiting. The element must be actionable for the Framework to wait for it, which requires that it be in the DOM, visible, not animated, enabled, and unobscured by other elements.
This auto-waiting approach greatly streamlines UI tests, allowing you to concentrate on behavior testing rather than writing code to wait.
Your tests can be parallelized in Playwright and run in worker processes coordinated by OS processes. Set the number of workers you want to start, specify the parallel processes, and end the day. There isn’t much to it, but parallel testing will make your tests run faster.
Writing new tests takes time. Therefore, code generation is useful in this situation. Run a single CLI command to begin capturing the framework for your upcoming end-to-end test.
playwright codegen test_url
The Playwright Inspector and a browser window will open due to the command. The created script will keep track of browser behaviors like link clicks and form fills. Take the script after your recording is complete, modify the selectors, add assertions, and then add the modified script to your codebase.
Let’s walk through the simple setup of Playwright with Python.
Step 1: Installing Prerequisites
Step 2: Installing Playwright for Python
pip install pytest-playwright
additionally, to set up the Playwright WebKit
playwright install
Playwright’s built-in WebKit is installed using the command mentioned above. This gives you the ability to test for several web browsers.
Step 3: Setting up the Project
Selectors are used to make locators. It explains how to find any element on the page.
Numerous selectors and ways are supported by Playwright, including the Text Selector, XPath Selector, CSS Selector, etc.
Examples of Selectors
Text Selector
text=Sign In
CSS Selector
#signin
XPath Selector
//a[@id='signin']
Locators show how to find an element or elements. These are utilized to carry out operations on elements via various methods, including click(), fill(), type(), etc. The primary component of the Playwright’s auto-waiting and retry-ability is its locators.
Syntax
page.locator(selector[, options])
The selector is the one we mentioned earlier and the option has different values that can be has, hastext, etc.
On BrowserStack Demo Website, we are automating two test scenarios to show Playwright Python for end-to-end testing. The following are the scenarios for this Playwright tutorial:
Scenario-1 (User Login)
Test Script
Add a new Python file to the project, first. ( for example, test_scenarios.py) import pytest from playwright.sync_api import Page, expect def test_login(page:Page): #launch browserstack demo page.goto("https://bstackdemo.com/") #click on sign button page.click('#signin') #select Username page.get_by_text("Select Username").click() page.locator("#react-select-2-option-0-0").click() #select Password page.get_by_text("Select Password").click() page.locator("#react-select-3-option-0-0").click() #click login page.get_by_role("button", name="Log In").click() #verify user have logged in assert page.get_by_text("demouser").is_visible()
Our test script is complete for this scenario, and we can easily run it using below command:
pytest
Scenario-2 (Item Purchase)
Test Script
import pytest from playwright.sync_api import Page, expect def test_item_purchase(page:Page): page.goto("https://bstackdemo.com/") #add to cart page.locator("[id=\"\\35 \"]").get_by_text("Add to cart").click() #checkout page.get_by_text("Checkout").click() #login page.type("#react-select-2-input", "demouser\n") page.type("#react-select-3-input", "testingisfun99\n") page.get_by_role("button", name="Log In").click() #fill shipping address page.get_by_label("First Name").fill("Test") page.get_by_label("Last Name").fill("Test") page.get_by_label("Address").fill("Test address") page.get_by_label("State/Province").fill("Test State") page.get_by_label("Postal Code").fill("123456") #click submit page.locator("#checkout-shipping-continue").click() #verify success message page.wait_for_timeout(1000) assert page.locator("#confirmation-message").is_visible()
End-to-end testing for several browsers at once makes it easier to identify problems quickly and move on to other tasks. For testing efficiency, we shall keep the same browser setups throughout the simultaneous test.
You can emulate a cloud server instance where you can run your test cases concurrently on different cloud host machines by running them in parallel. This allows you to determine whether your app functions properly across various integration contexts.
You can run parallel tests across all browsers using Playwright. It has many capabilities supported by BrowserStack, like resiliency, auto-wait, recording test traces, and others. All you have to do is include the appropriate BrowserStack capabilities in your existing test scripts.
Let’s demonstrate how to run the test mentioned above scripts on BrowserStack:
import json import urllib import subprocess import pytest from playwright.sync_api import sync_playwright desired_cap = { 'browser': 'chrome', 'browser_version': 'latest', 'os': 'osx', 'os_version': 'catalina', 'name': 'BrowserStack Demo', 'build': 'playwright-python-tutorial', 'browserstack.username': 'BROWSERSTACK_USERNAME', 'browserstack.accessKey': 'BROWSERSTACK_ACCESS_KEY' } clientPlaywrightVersion = str(subprocess.getoutput('playwright --version')).strip().split(" ")[1] desired_cap['client.playwrightVersion'] = clientPlaywrightVersion @pytest.mark.login def test_login(playwright): desired_cap['browser'] = "edge" desired_cap['name'] = "Test Login" cdpUrl = 'wss://cdp.browserstack.com/playwright?caps=' + urllib.parse.quote(json.dumps(desired_cap)) browser = playwright.chromium.connect(cdpUrl) page = browser.new_page() try: page.goto("https://bstackdemo.com/") page.click('#signin') page.get_by_text("Select Username").click() page.locator("#react-select-2-option-0-0").click() page.get_by_text("Select Password").click() page.locator("#react-select-3-option-0-0").click() page.get_by_role("button", name="Log In").click() if page.get_by_text("demouser").is_visible(): mark_test_status("passed", "User successfull logged in", page) else: mark_test_status("failed", "User log in failure", page) except Exception as err: mark_test_status("failed", str(err), page) browser.close() def mark_test_status(status, reason, page): page.evaluate("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\""+ status + "\", \"reason\": \"" + reason + "\"}}"); with sync_playwright() as playwright: test_login(playwright) @pytest.mark.item_purchase def test_item_purchase(playwright): desired_cap['browser'] = "chrome" desired_cap['name'] = "Test Item Purchase" cdpUrl = 'wss://cdp.browserstack.com/playwright?caps=' + urllib.parse.quote(json.dumps(desired_cap)) browser = playwright.chromium.connect(cdpUrl) page = browser.new_page() try: page.goto("https://bstackdemo.com/") page.locator("[id=\"\\35 \"]").get_by_text("Add to cart").click() page.get_by_text("Checkout").click() page.type("#react-select-2-input", "demouser\n") page.type("#react-select-3-input", "testingisfun99\n") page.get_by_role("button", name="Log In").click() page.get_by_label("First Name").fill("Test") page.get_by_label("Last Name").fill("Test") page.get_by_label("Address").fill("Test address") page.get_by_label("State/Province").fill("Test State") page.get_by_label("Postal Code").fill("123456") page.locator("#checkout-shipping-continue").click() page.wait_for_timeout(1000) if page.locator("#confirmation-message").is_visible(): mark_test_status("passed", "Order placed successfully", page) else: mark_test_status("failed", "Order not placed", page) except Exception as err: mark_test_status("failed", str(err), page) browser.close() def mark_test_status(status, reason, page): page.evaluate("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\""+ status + "\", \"reason\": \"" + reason + "\"}}"); with sync_playwright() as playwright: test_item_purchase(playwright)
In the scenario above, two different test cases are being run on two different browsers. The test results can be viewed on the BrowserStack Automate Dashboard.
Summary
Due to its support for numerous browsers and streamlined API, the Python Playwright module is a fantastic option for scripting tests involving web automation. This article functions as in-depth guide for Playwright Python, along with examples. Additionally teams can execute it in parallel using BrowserStack, which makes testing 10X faster.
Start Playwright Testing on BrowserStack
ncG1vNJzZmivp6x7o77OsKqeqqOprqS3jZympmeXqralsY6po5qxp6e2qLTTZqeyrJiku27A1K2mq6GRoQ%3D%3D