Playwright Scripting Guide

Prev Next

Playwright is a versatile end-to-end testing framework that provides high-level browser automation through an intuitive API. With Playwright, you can create multi-step browser transaction tests to ensure your web applications perform seamlessly. Scripts developed using Playwright can be executed with Catchpoint, making it a robust choice for comprehensive web testing.

This article provides several examples to assist you in developing your own Playwright scripts for monitoring purposes. To learn more about Playwright scripting, see our Playwright Scripting Videos.

Prerequisites for fully utilizing this guide:
Knowledge of XPath.
Understanding of CSS Selectors.

Playwright Commands

Actions using Locator

In Playwright, actions are methods that allow you to interact with web elements, such as clicking, typing, and dragging.

The page.locator() method in Playwright allows you to create a locator that can be used to interact with elements on a web page. It provides a powerful way to perform actions like clicking, typing, and asserting the state of elements, making it easier to write reliable and maintainable tests.

click()

The click() method is used to click on an element identified by the locator. This method ensures that the element is visible and enabled before performing the click action, making it reliable for automated testing.

Syntax:
await page.locator(selector).click();

Example:

// Click on the button.
await page.locator(`//input[@name="btnK"]`).click();

Learn more about clicking in Playwright.

type()

Typing into an input field is one of the most common actions in Playwright. You can use the type() method to input text into a form field or search box.

Syntax:
await page.locator(selector).type('text to type');

Example

// Type a search query into the search input field.
await page.locator('//input[@name="q"]').type('Playwright Documentation');

Best Practices:

  • Ensure the locator accurately identifies the input field.
  • Use expect assertions to verify the field contains the expected value after typing.

Learn more about typing in Playwright.

selectOption()

Selecting an option from a dropdown can be achieved using the selectOption() method. This method works with <select> elements.

Syntax
await page.locator(selector).selectOption('value');

Example

// Select the option with value "option1" in the dropdown.
await page.locator('//select[@id="dropdown"]').selectOption('option1');

Best Practices:

  • Use expect assertions to confirm the correct value is selected.
  • Ensure the dropdown element is visible and enabled before interacting with it.

Learn more about selecting dropdowns in Playwright.

check()

Radio buttons can be selected using the check() method. This method ensures that the radio button is enabled and visible before selecting it.

Syntax
await page.locator(selector).check();

Example

// Select the radio button with value "male".
await page.locator('//input[@type="radio" and @value="male"]').check();

Best Practices:

  • Confirm that the radio button is not already selected to avoid unnecessary actions.
  • Use expect assertions to verify that the button is selected.

Learn more about working with radio buttons in Playwright.

check() / uncheck()

Checkboxes can be toggled using the check() and uncheck() methods. These methods ensure that the checkbox is in the desired state.

Syntax
await page.locator(selector).check(); // To check a checkbox.
await page.locator(selector).uncheck(); // To uncheck a checkbox.

Example

// Check the checkbox. 
await page.locator('//input[@type="checkbox" and @id="subscribe"]').check();
@id="subscribe"]').uncheck();

Best Practices:

  • Use expect assertions to validate the checkbox state after the action.
  • Avoid unnecessary actions by checking the state of the checkbox before interacting.

Learn more about checkboxes in Playwright.

Assertions in Playwright

Assertions in Playwright ensure your tests validate expected behaviors, making them reliable and robust. Below are commonly used assertions.

expect(page).toHaveURL()

Verifies that the current page URL matches the expected URL or pattern. This ensures successful navigation to the intended page.

Syntax
await expect(page).toHaveURL(urlOrRegex);

Example

// Verify the page navigated to the correct URL.
await expect(page).toHaveURL("https://example.com/navigate");

// Using regular expressions to match URL patterns.
await expect(page).toHaveURL(/.*checkout/);

Learn more about "toHaveURL" in Playwright

expect(page).not.toHaveURL()

Ensures the page URL does not match the specified URL or pattern. Useful for verifying that a page did not redirect to error pages.

Syntax
await expect(page).not.toHaveURL(urlOrRegex);

Example

// Ensure the page did not navigate to an error page.
await expect(page).not.toHaveURL(/.*error.html/);
await expect(page).not.toHaveURL(/.*notfound.html/);

Learn more about "not.toHaveURL" in Playwright

expect(page).toHaveTitle()

Checks if the current page's title matches the expected title or pattern.

Syntax
await expect(page).toHaveTitle(titleOrRegex);

Example

// Verify the page title.
await expect(page).toHaveTitle("Page Title");

// Using regular expressions for the title.
await expect(page).toHaveTitle(/.*Page Title/);

Learn more about "toHaveTitle" in Playwright

expect(locator).toBeVisible()

Used to check if something on a webpage, like a button, text, or image, is visible in the browser window. It confirms the element loaded in the DOM, is not hidden, not behind something else, and not set to "invisible."

Syntax
await expect(locator).toBeVisible();

Example

// Check if an element is visible.
await expect(page.getByText('Welcome')).toBeVisible();

Learn more about "toBeVisible" in Playwright

expect(locator).toBeEnabled()

Verifies that the locator points to an enabled and interactable element.

Syntax
await expect(locator).toBeEnabled();

Example

// If you have a "Submit" button on a form:
// Enabled button: The button is active and can be clicked.
// Disabled button: The button is grayed out and cannot be clicked.
await expect(page.locator('button[type=submit]')).toBeEnabled();

Learn more about "toBeEnabled" in Playwright

expect(locator).toBeDisabled()

Ensures the locator points to a disabled element.

Syntax

await expect(locator).toBeDisabled();

Example

// Verify that a button is disabled.
await expect(page.locator('button[type=submit]')).toBeDisabled();

Learn more about "toBeDisabled" in Playwright

expect(locator).toBeChecked()

Used in tests to check if a checkbox or radio button is checked (selected).

Syntax
await expect(locator).toBeChecked();

Example

// Ensure a checkbox is checked.
await expect(page.locator('input[type=checkbox]')).toBeChecked();

// If you’re testing a "Subscribe to Newsletter" checkbox:
await const locator = page.getByLabel('Subscribe to newsletter');
await expect(locator).toBeChecked();

Learn more about "toBeChecked" in Playwright

expect(locator).toHaveAttribute(attribute, value)

Used to verify that a specific HTML element has a particular attribute with a specific value.

Syntax
await expect(locator).toHaveAttribute(attribute, value);

Example

// If you are testing a link like this:
// <a id="learn-more" href="https://example.com" target="_blank">Learn More</a>
await const locator = page.locator('#learn-more');

// Check if the href attribute has the correct value
await expect(locator).toHaveAttribute('href', 'https://example.com');

// Check if the target attribute has the correct value
await expect(locator).toHaveAttribute('target', '_blank');

// Verify the type attribute of an input element.
await expect(page.locator('input')).toHaveAttribute('type', 'text');

Learn more about "toHaveAttribute" in Playwright

expect(locator).toHaveText()

Used to verify that a specific element on the page contains the expected text.

Key Features:

  • Exact Match: By default, it checks for an exact match with the provided text.
  • Partial Matches: If you want to check for partial text or use patterns, you can use regular expressions.
  • All Nested Elements Considered: Playwright includes text from nested elements when calculating overall text content.

Syntax
await expect(locator).toHaveText(textOrRegex);

Example

// Check the exact text of an element.
await expect(page.locator('.title')).toHaveText("Welcome, Test User");

// Using regular expressions for text.
await expect(page.locator('.title')).toHaveText(/.*Test User/);

Learn more about "toHaveText" in Playwright

expect(locator).toContainText()

Description: This is used to check if an element's text contains a specific substring, rather than requiring an exact match. This is particularly useful for partial text matching. You can use regular expressions for the value as well.

Syntax
await expect(locator).toContainText(textOrRegex);

Example

// HTML: <div id="message">Welcome to Playwright Testing!</div>
await const locator = page.locator('#message');
await expect(locator).toContainText('Playwright');

// Using Regular Expressions
// HTML: <p class="status">Your order #12345 is confirmed</p>
const locator = page.locator('.status');
await expect(locator).toContainText(/order #\d+/); // Matches "order #12345"

Learn more about "toContainText" in Playwright

expect(locator).toHaveValue(value)

Ensures the Locator points to an element with the given input value. You can use regular expressions for the value as well.

Syntax
await expect(locator).toHaveValue(valueOrRegex);

Example

// Verify the value of a number input.
await expect(page.locator('input[type=number]')).toHaveValue(9);

// Using regular expressions for input value.
await expect(page.locator('input[type=number]')).toHaveValue(/[0-9]/);

Learn more about "toHaveValue" in Playwright

expect(locator).toHaveCount()

Used to verify the number of elements matched by a locator. It checks if the locator matches exactly the expected number of elements.

Syntax
await expect(locator).toHaveCount(expectedCount)

Example

// HTML:
// <ul id="fruits">
// <li>Apple</li>
// <li>Banana</li>
// <li>Cherry</li>
// </ul>
await const locator = page.locator('#fruits li');
await expect(locator).toHaveCount(3); // Passes because there are 3 <li> elements

// Finds all elements with the class ".component" that are direct children of a <list> element.
// <list>
// <div class="component">Item 1</div>
// <div class="component">Item 2</div>
// <div class="component">Item 3</div>
// </list>
await expect(page.locator('list > .component')).toHaveCount(3);

Learn more about "toHaveCount" in Playwright

"Wait For" Methods

The page.waitFor() methods in Playwright allow you to wait for specific conditions to be met before proceeding with further actions. These methods are essential for handling asynchronous events and ensuring that your tests are reliable and maintainable.

waitForSelector()

Used to wait for an element to appear in the DOM. This method ensures that the element is present before performing any actions on it.

Syntax
await page.waitForSelector(selector);

Example

// Wait for the search input field to appear.
await page.waitForSelector('//input[@name="q"]');

Best Practices:

  • Ensure the selector accurately identifies the element.
  • Use a reasonable timeout to avoid indefinite waits.

Learn more about waiting for a selection in Playwright

waitForTimeout()

Used to pause the execution for a specified amount of time. This can be useful for debugging or waiting for non-deterministic events.

Syntax
await page.waitForTimeout(milliseconds);

Example

// Wait for 2 seconds.
await page.waitForTimeout(2000);

Best Practices:

  • Use this method sparingly, as it can introduce flakiness in tests.
  • Prefer other waitFor() methods that wait for specific conditions.

Learn more about waitForTimeout in Playwright

waitForEvent()

Used to wait for a specific event to occur on the page. This method is useful for handling events like navigation, network requests, or custom events.

Syntax
await page.waitForEvent(event);

Example

// Wait for the 'load' event.
await page.waitForEvent('load');

Best Practices:

  • Ensure the event name is correct and relevant to your test scenario.
  • Combine with other assertions to verify the event's outcome.

Learn more about waitForEvent in Playwright.

waitForRequest()

Used to wait for a network request matching a specific URL or predicate. This method is useful for ensuring that certain network activities have completed.

Syntax
await page.waitForRequest(urlOrPredicate);

Example

// Wait for a request to the specified URL.
await page.waitForRequest('https://example.com/api/data');

Best Practices:

  • Use precise URL patterns or predicates to avoid false positives.
  • Combine with other assertions to verify the request's outcome.

Learn more about waitForRequest in Playwright.

waitForResponse()

Used to wait for a network response matching a specific URL or predicate. This method is useful for ensuring that certain network responses have been received.

Syntax
await page.waitForResponse(urlOrPredicate);

Example

// Wait for a response from the specified URL.
await page.waitForResponse('https://example.com/api/data');

Best Practices:

  • Use precise URL patterns or predicates to avoid false positives.
  • Combine with other assertions to verify the response's outcome.

Learn more about waitForResponse in Playwright.

Catchpoint-Specific Methods

Catchpoint includes a package that adds supports some additional Catchpoint-specific methods.

Retrieving Credentials

Catchpoint.username() and Catchpoint.password()

Return the username and password values which are specified in this test's configuration (or inherited), and are not saved in the credential library.

Syntax
Catchpoint.username()
Catchpoint.password()

example

// Retrieve username and password from test configuration and assign to variables
let username1 = await Catchpoint.username();
let password1 = await Catchpoint.password();

// Authenticate using retrieved credentials
await page.goto("https://www.google.com/search?q="+username1+password1);

Catchpoint.username(credentialName) and Catchpoint.password(credentialName)

Returns username and password values by the credential name stored in the credential library.

Syntax
Catchpoint.username(credentialName)
Catchpoint.password(credentialName)

Example

// Retrieve username and password from credential stored in library as "BasicAuth"
let u1 = Catchpoint.username("BasicAuth") 
let p1 = Catchpoint.password("BasicAuth") 

// Authenticate using retrieved credentials
await page.goto("https://www.google.com/search?q="+u1+", "+p1) 

Global Variables

Catchpoint.storeGlobalVariable(globalVarValue, globalVarName)

Helps in creating, storing and updating a global variable that can be later consumed using the global variable macro in other tests. Read more about global variables here

Syntax
Catchpoint.storeGlobalVariable(<value>,"variable-name");

Example

// Store the value 10 in the global variable "search-results"
await Catchpoint.storeGlobalVariable('10',"search-results");
// Following command can be in the same test configuration or a different one. 
// Retrieve the value of the "search-results" variable.

await Catchpoint.storeGlobalVariable('10', "GlobalVariableTesting1") 
var resultsCount = `${globalVariable(GlobalVariableTesting1)}`; 
await page.goto("https://www.google.com/?q=" + resultsCount)

Insights

Catchpoint.setTracepoint(insightToken, insightValue) and Catchpoint.setIndicator(insightToken, insightValue)

Help in creating, storing and updating tracepoints and indicators from within a Playwright Script. Read more about Tracepoints and Indicators here.

Syntax
Catchpoint.setTracepoint("<tracepoint-token>","<value>" )
Catchpoint.setTracepoint("<indicator-token>",<value>)

Example

// Setting Tracepoint
await Catchpoint.setTracepoint("t600", "TracepointCheck1");

//Setting Indicator
await Catchpoint.setIndicator("i34974", 12345);

Creating Steps on Demand

Catchpoint.startStep()

Syntax
Catchpoint.startStep(stepName, [opt_disableAutoMatchRequests])

opt_disableAutoMatchRequests (boolean) - Optional parameter that controls the assignment of specific HTTP/S requests to a previous step under certain circumstances in web-browser test monitors. The default value is false. The comma (",") is a reserved character and cannot be used in the step name.

Example

// Open the home page and name the step. This step has all the requests
// executed while loading the page.
await Catchpoint.startStep("Step 1 -- Load Home Page");
await page.goto("https://www.catchpoint.com/");

// Next, open the portal page and name the step.
await Catchpoint.startStep("Step 2 -- Load Portal Page");
await page.goto("https://portal.catchpoint.com/");

Example Scripts

Example 1: Product Search and Wishlist

The following example demonstrates how to automate a product search and add items to the wishlist and shopping bag using Playwright. This step-by-step guide is designed for those new to Playwright.

Scenario: Search for a "sofa bed" on the IKEA website, view a specific product, add it to the wishlist, and then add it to the shopping bag.

Code:

// Navigate to the IKEA homepage
await page.goto('https://www.ikea.com/us/en/');

// Search for "sofa bed"
await page.getByPlaceholder('What are you looking for?').click();
await page.getByPlaceholder('What are you looking for?').fill('sofa bed');
await page.getByPlaceholder('What are you looking for?').press('Enter');

// Verify that the search results page is displayed
await page.goto('https://www.ikea.com/us/en/search/?q=sofa%20bed');

// Select a specific product
await page.getByRole('link', { name: 'FRIHETEN - Sleeper sectional,3 seat w/storage' }).click();

// Add the product to the wishlist
await page.getByRole('button', { name: 'Save to favorites' }).click();

// Add the product to the shopping bag
await page.getByRole('button', { name: 'Add to bag' }).click();

Best Practices

  • Use Meaningful Selectors: Ensure the selectors used, such as (getByPlaceholder and getByRole), are clear and accurately describe the element's role or purpose.
  • Test URLs and Navigation: Always validate that the correct pages load using goto or assertions.
  • Break Steps into Logical Units: Separate interactions logically to make scripts easier to read and debug.

Example 2: Adding Products to the Cart

The following example demonstrates how to automate adding multiple products to the shopping cart on the Automation Exercise website, and then proceed to checkout.

Scenario: Add three products to the shopping cart and proceed to the checkout page.

Code:

// Navigate to the Automation Exercise homepage
await page.goto('https://automationexercise.com/');

// Navigate to the "Products" page
await page.getByRole('link', { name: ' Products' }).click();

// Add the first product to the cart
await page.locator('div').filter({ hasText: 'Rs. 500 Blue Top Add to cart Rs. 500 Blue Top Add to cart' }).locator('a').nth(1).click();
await page.getByRole('button', { name: 'Continue Shopping' }).click();

// Add the second product to the cart
await page.locator('div').filter({ hasText: 'Rs. 400 Men Tshirt Add to cart Rs. 400 Men Tshirt Add to cart' }).locator('a').nth(1).click();
await page.getByRole('button', { name: 'Continue Shopping' }).click();

// Add the third product to the cart
await page.locator('div').filter({ hasText: 'Rs. 1000 Sleeveless Dress Add to cart Rs. 1000 Sleeveless Dress Add to cart' }).locator('a').nth(1).click();
await page.getByRole('button', { name: 'Continue Shopping' }).click();

// Navigate to the cart
await page.getByRole('link', { name: 'z Cart' }).click();

// Proceed to checkout
await page.getByText('Proceed To Checkout').click();

Example 3: Cart Checkout

The following example demonstrates how to automate adding multiple products to a shopping cart, entering user details, and checking out on the Danube website.

Scenario: Add three products to the cart, fill out the checkout form, and complete the order.

Code:

// Number of products to add to the cart
const productsNumber = 3;

// Wait for navigation to complete
const navigationPromise = page.waitForNavigation();
await page.goto('https://danube-web.shop/');

// Add products to the cart
for (let i = 1; i <= productsNumber; i++) {
await page.click(`.preview:nth-child(${i}) > .preview-author`);
await page.click('.detail-wrapper > .call-to-action');
await page.click('#logo');
}

// Proceed to checkout
await navigationPromise;
await page.click('#cart');
await page.click('.cart > .call-to-action');
await page.click('#app-content #s-name');

// Fill in shipping details
await page.type('#s-name', 'Max');
await page.type('#s-surname', 'Mustermann');
await page.type('#s-address', 'Charlottenstr. 57');
await page.type('#s-zipcode', '10117');
await page.type('#s-city', 'Berlin');
await page.type('#s-company', 'Firma GmbH');

// Confirm checkout
await page.click('.checkout > form');
await page.click('#asap');
await page.click('.checkout > .call-to-action');

// Wait for order confirmation
await page.waitForSelector('#order-confirmation', { visible: true });

Explanation of Steps

  • Add Products to the Cart:
    Loop through the desired number of products, click on each product, and add them to the cart.
  • Navigate to the Cart
    The click function opens the cart.
  • Fill in Shipping Details
    Uses type to fill in details like name, address, and city.
  • Complete the Order
    Uses click to proceed through the checkout process and confirm the order.

Best Practices

  • Parameterize Input: Use variables (e.g. productsNumber) to dynamically adjust scripts.
  • Wait for Elements: Ensure navigation or page loads are complete with waitForSelector or waitForNavigation.
  • Organize Steps: Group actions logically for readability.

Example 4: Product Search

The following example demonstrates how to search for a list of books on the Danube website and validate the search results.

Scenario: Search for books containing the word "for" in their title, validate the results, and ensure all expected books are found.

// List of expected book titles
const bookList = [
'The Foreigner',
'The Transformation',
'For Whom the Ball Tells',
'Baiting for Robot'
];

// Navigate to the Danube website
await page.goto('https://danube-web.shop/');

// Perform a search for books containing "for"
await page.click('.topbar > input');
await page.type('.topbar > input', 'for');
await page.click('#button-search');

// Wait for the search results to load
await page.waitForSelector('.shop-content > ul > .preview:nth-child(1) > .preview-title');

// Get the number of search results and validate it matches the expected count
const resultsNumber = (await page.$$('.preview-title')).length;
expect(resultsNumber).toHaveLength(bookList.length);

// Validate each search result title
for (let i = 0; i < resultsNumber; i++) {
const resultTitle = await page.eval(`.preview:nth-child(${i + 1}) > .preview-title`, (e) => e.innerText);

// Remove the found title from the expected list
const index = bookList.indexOf(resultTitle);
bookList.splice(index, 1);
}

// Assert that the book list is now empty (all expected titles were found)
expect(bookList).toHaveLength(0);

Explanation of Steps

  • Define the Expected Books: A list of book titles is defined for validation.
  • Search for Books: The type and click functions are used to input the search query and submit it.
  • Validate Results Count: The number of search results is compared to the expected count using assertions.
  • Match Titles: Each result title is checked against the expected list, and matches are removed from the list.
  • Final Validation: The expected list is asserted to be empty, confirming all titles were found.

Best Practices

  • Dynamic Selectors: Use child selectors like .nth-child() for precise element targeting.
  • Error Handling: Include assertions to halt the script if expectations are not met.

Example 5: Account Sign-In

The following script automates the login process for a user on the Danube website.

Scenario: Log in with a specific email and password.

// Navigate to the Danube website
await page.goto('https://danube-web.shop/');

// Open the login form
await page.click('#login');

// Fill in the login credentials
await page.click('#n-email');
await page.type('#n-email', 'john.doe@gmail.com');
await page.type('#n-password2', 'johndoe');

// Submit the login form
await page.click('#goto-signin-btn');

Explanation of Steps

  • Navigate to the Website: The goto function loads the Danube website.
  • Open Login Form: The click function opens the login form.
  • Enter Credentials: The type function fills in the email and password fields.
  • Submit Form: The login form is submitted using the click function.

Best Practices

  • Test Credentials: Use mock or test accounts to avoid affecting production data.
  • Error Scenarios: Validate incorrect login attempts to ensure error handling works as expected.

Example 6: Register User

This script demonstrates how to register a new user on the Automation Exercise website.

Scenario: Fill out the signup form with a name and email address, then submit it.

// Navigate to the Automation Exercise website
await page.goto('https://automationexercise.com/');

// Open the Signup/Login form
await page.getByRole('link', { name: '# Signup / Login' }).click();

// Fill in the registration details
await page.getByPlaceholder('Name').click();
await page.getByPlaceholder('Name').fill('john doe');
await page.getByPlaceholder('Name').press('Tab');
await page.locator('form').filter({ hasText: 'Signup' }).getByPlaceholder('Email Address').fill('johndoe@gmail.com');

// Submit the signup form
await page.getByRole('button', { name: 'Signup' }).click();

Explanation of Steps

  • Navigate to the Website: The goto function loads the Automation Exercise website.
  • Open Signup Form: The getByRole function clicks the "Signup / Login" link.
  • Fill Out Details: The getByPlaceholder and fill functions enter the name and email.
  • Submit Form: The getByRole function clicks the "Signup" button.

Best Practices

  • Input Validation: Ensure all fields are correctly filled before submission.
  • Error Feedback: Test error messages for invalid or duplicate inputs.

Unsupported Functions and Classes

The following Playwright functions and classes are not supported by Catchpoint's Playwright test:

Unsupported Functions
• addInitScript()
• close()
• pdf()
• routeFromHAR()
• screenshot()
• setDefaultNavigationTimeout()
• setDefaultTimeout()
• video()
• workers()

Unsupported Classes
• Browser
• BrowserContext
• BrowserServer
• BrowserType

Macros

You can use Macros to pull useful values into your scripts at runtime. Supported macros include:

Basic macros

Enhanced macros

Random List

Custom Timestamp