Rayrun

Mastering Playwright Test Automation: Your Comprehensive Cheat Sheet

This cheat sheet is designed to provide you with everything you need to kickstart your Playwright journey – from setting up your first test to tackling advanced scenarios.
  1. Starting Point: Basic Test Structure
    1. Playwright in Action: Common Actions
      1. Navigating the Web
        1. Seeking Out Page Elements
          1. Entering Text Into Fields
            1. Clicking Elements
              1. Handling Dropdowns
                1. Dealing with Checkboxes and Radio Buttons
                  1. Diving into iFrames
                    1. Handling Alerts and Dialogs
                    2. Making Assertions
                      1. Checking the Page Title
                        1. Checking if an Element is Visible
                        2. Leveling Up: Advanced Scenarios
                          1. Managing Browser Contexts
                            1. Capturing Screenshots
                              1. Emulating Mobile Devices
                                1. Managing Cookies
                                  1. Pressing Keys on the Keyboard
                                    1. Pressing Special Keys
                                      1. Performing Drag-and-Drop
                                        1. Waiting for Events or Conditions
                                        2. Fine-Tuning: Test Configuration
                                          1. Adjusting Timeouts
                                            1. Running Tests in Parallel
                                              1. Running Tests Across Browsers
                                              2. Automating It All: Continuous Integration
                                                1. Integrating with GitHub Actions
                                                  1. Retrying Failed Tests
                                                  2. Troubleshooting: Debugging
                                                    1. Pausing Tests for Debugging
                                                      1. Debugging Test Failures

                                                      Starting Point: Basic Test Structure

                                                      Your starting point looks something like this:

                                                      import { test, expect } from '@playwright/test';
                                                      
                                                      test('has the expected title', async ({ page }) => {
                                                        await page.goto('/');
                                                      
                                                        expect(page).toHaveTitle('Playwright');
                                                      });

                                                      This simple test navigates to 'https://ray.run/', grabs the page's title, and asserts that it matches the expected string.

                                                      Playwright in Action: Common Actions

                                                      // URLs are relative to the base URL specified in playwright.config.ts.
                                                      await page.goto('/blog');
                                                      
                                                      // You can also navigate to a specific URL.
                                                      await page.goto('https://ray.run/');

                                                      Seeking Out Page Elements

                                                      Playwright provides several ways to locate elements on a page.

                                                      The recommended way is use locators:

                                                      // to locate by explicit and implicit accessibility attributes
                                                      page.getByRole('heading', { name: 'Sign up' });
                                                      
                                                      // to locate by text content
                                                      page.getByText('Sign up');
                                                      page.getByText('Sign up', { exact: true });
                                                      page.getByText(/sign up/i);
                                                      
                                                      // to locate a form control by associated label's text
                                                      page.getByLabel('Password');
                                                      
                                                      // to locate an input by placeholder
                                                      page.getByPlaceholder('name@example.com');
                                                      
                                                      // to locate an element, usually image, by its text alternative
                                                      page.getByAltText('playwright logo');
                                                      
                                                      // to locate an element by its title attribute
                                                      page.getByTitle('Issues count')
                                                      
                                                      // to locate an element based on its data-testid attribute
                                                      page.getByTestId('directions');

                                                      Here's how you can use CSS or XPath page.locator() method:

                                                      Not recommended if you can use locators.

                                                      // CSS
                                                      page.locator('css=button');
                                                      // short form CSS
                                                      page.locator('button');
                                                      // XPath
                                                      page.locator('xpath=//button');

                                                      Entering Text Into Fields

                                                      await page.getByLabel('Password').fill('Hello, World!');

                                                      Clicking Elements

                                                      Clicking elements is as easy as finding the locator and using the click() method:

                                                      await page.getByRole('button').click();

                                                      Handling Dropdowns

                                                      To interact with a dropdown, simply select the option you want:

                                                      // Single selection matching the value
                                                      await page.getByLabel('Choose a color').selectOption('blue');
                                                      
                                                      // Single selection matching the label
                                                      await page.getByLabel('Choose a color').selectOption({ label: 'blue' });
                                                      
                                                      // Multiple selected items
                                                      await page.getByLabel('Choose a color').selectOption(['red', 'green', 'blue']);

                                                      Dealing with Checkboxes and Radio Buttons

                                                      Interacting with checkboxes and radio buttons is straightforward:

                                                      await page.getByRole('checkbox').check();
                                                      await page.getByRole('checkbox').uncheck();
                                                      
                                                      expect(await page.getByLabel('checkbox').isChecked()).toBeTruthy();

                                                      Diving into iFrames

                                                      If you need to interact with elements within an iFrame, use the frameLocator() method:

                                                      const iframeLocator = page.frameLocator('#iframeId');
                                                      
                                                      await iframeLocator.locator('#inputField').fill('Sample Text');

                                                      Handling Alerts and Dialogs

                                                      For accepting or dismissing browser dialogs and alerts, simply listen for the 'dialog' event:

                                                      page.on('dialog', async (dialog) => {
                                                        await dialog.accept();
                                                      });
                                                      
                                                      await page.getByRole('button').click();

                                                      Making Assertions

                                                      Playwright integrates seamlessly with assertion libraries, helping you validate your tests. Here are a couple of examples:

                                                      Checking the Page Title

                                                      await expect(page).toHaveTitle('Playwright');

                                                      Checking if an Element is Visible

                                                      Note: This is typically unnecessary as most actions (click(), fill(), ...) will wait for the element to be visible by default.

                                                      await expect(page.locator('#elementId')).toBeVisible();

                                                      Leveling Up: Advanced Scenarios

                                                      Playwright can handle a wide range of advanced scenarios, from browser context management to mobile emulation. Let's dive into a few:

                                                      Managing Browser Contexts

                                                      You can create isolated browsing sessions using browser contexts:

                                                      const { context } = await browser.newContext();
                                                      const page = await context.newPage();

                                                      Capturing Screenshots

                                                      // Capture a screenshot of the visible portion of the page
                                                      await page.screenshot({ path: 'screenshot.png' });
                                                      
                                                      // As if you had a very tall screen and the page could fit the the entire page
                                                      await page.screenshot({ path: 'screenshot.png', fullPage: true });
                                                      
                                                      // Screenshot a specific element
                                                      await page.locator('#foo').screenshot({ path: 'screenshot.png' });

                                                      Emulating Mobile Devices

                                                      Playwright comes with a registry of device parameters using playwright.devices for selected desktop, tablet and mobile devices.

                                                      const iPhone = devices['iPhone 13'];
                                                      const context = await browser.newContext({ ...iPhone });
                                                      const page = await context.newPage();
                                                      
                                                      await page.goto('/');

                                                      Managing Cookies

                                                      Playwright makes it easy to add, get, and delete cookies:

                                                      await context.addCookies([{ name: 'cookieName', value: 'cookieValue', domain: 'ray.run' }]);
                                                      
                                                      const cookies = await context.cookies('https://ray.run/');
                                                      
                                                      await context.clearCookies();

                                                      Pressing Keys on the Keyboard

                                                      In most cases, you should use locator.fill() instead. You only need to press keys one by one if there is special keyboard handling on the page.

                                                      // Types instantly
                                                      await page.getByLabel('Password').pressSequentially('Hello');
                                                      
                                                      // Types slower, like a user
                                                      await page.getByLabel('Password').pressSequentially('World', { delay: 100 });

                                                      Pressing Special Keys

                                                      await page.getByLabel('Password').press('Enter'); // Control, ArrowDown, ...

                                                      Performing Drag-and-Drop

                                                      Need to drag and drop elements? No problem:

                                                      const source = await page.locator('#sourceElement');
                                                      const target = await page.locator('#targetElement');
                                                      
                                                      await source.dragAndDrop(target);

                                                      Waiting for Events or Conditions

                                                      You can wait for specific events, elements, or custom conditions:

                                                      await page.waitForLoadState('networkidle');
                                                      await page.waitForSelector('#elementId');
                                                      
                                                      await page.waitForFunction(() => document.querySelector('#elementId').innerText === 'Expected Text');

                                                      Fine-Tuning: Test Configuration

                                                      Adjusting Timeouts

                                                      You can configure global and action-specific timeouts to suit your needs:

                                                      // Set global test timeout to 30 seconds
                                                      test.setTimeout(30000);
                                                      
                                                      // Set action-specific timeout to 5 seconds
                                                      await page.locator('#elementId').click({ timeout: 5000 });

                                                      Running Tests in Parallel

                                                      Running tests concurrently can save you a lot of time. Here's how you do it:

                                                      // In playwright.config.ts
                                                      export default {
                                                        workers: 4, // Run 4 tests concurrently
                                                      };

                                                      Running Tests Across Browsers

                                                      You can configure your tests to run on multiple browsers:

                                                      // In playwright.config.ts
                                                      export default {
                                                        projects: [
                                                          {
                                                            name: 'chrome',
                                                            use: { browserName: 'chromium' },
                                                          },
                                                          {
                                                            name: 'firefox',
                                                            use: { browserName: 'firefox' },
                                                          },
                                                        ],
                                                      };

                                                      Automating It All: Continuous Integration

                                                      Integrating with GitHub Actions

                                                      You can configure GitHub Actions to run your Playwright tests automatically:

                                                      # .github/workflows/playwright.yml
                                                      name: Playwright
                                                      
                                                      on: [push]
                                                      
                                                      jobs:
                                                        build:
                                                          runs-on: ubuntu-latest
                                                          steps:
                                                            - uses: actions/[email protected]
                                                      
                                                            - name: Setup node
                                                              uses: actions/[email protected]
                                                              with:
                                                                node-version: 14
                                                      
                                                            - name: Install dependencies
                                                              run: npm ci
                                                      
                                                            - name: Run Playwright tests
                                                              run: npm run test

                                                      Retrying Failed Tests

                                                      Sometimes, tests fail unexpectedly. You can configure Playwright to retry failed tests automatically:

                                                      // In playwright.config.ts
                                                      export default {
                                                        // Retry failed tests 2 times in CI
                                                        retries: process.env.CI ? 2 : 0,
                                                      };

                                                      Troubleshooting: Debugging

                                                      Pausing Tests for Debugging

                                                      If you need to inspect something during a test, you can pause the test execution:

                                                      // Pause test execution to debug
                                                      await page.pause();

                                                      Debugging Test Failures

                                                      When a test fails, it's important to understand why. Playwright can collect trace information, screenshots, and logs to help you:

                                                      // In playwright.config.ts
                                                      export default {
                                                        use: {
                                                          // Save trace information when a test fails
                                                          trace: 'on-first-retry',
                                                        },
                                                      };

                                                      And there you have it! With this comprehensive @playwright/test cheat sheet, you're well on your way to becoming a Playwright pro. Happy testing!

                                                      Thank you!
                                                      Was this helpful?

                                                      Now check your email!

                                                      To complete the signup, click the confirmation link in your inbox.

                                                      Subscribe to newsletter

                                                      You will receive a weekly email with the latest posts and QA jobs.

                                                      TwitterGitHubLinkedIn
                                                      AboutQuestionsDiscord ForumBrowser ExtensionTagsQA Jobs

                                                      Rayrun is a community for QA engineers. I am constantly looking for new ways to add value to people learning Playwright and other browser automation frameworks. If you have feedback, email luc@ray.run.