Categories
Technology

Playwright cheat sheet

Photo by Patrick Tomasso on Unsplash

⭐️ This post was featured in Software Testing Weekly #110 and Coding JAG #76

My first experience with Playwright was terrible. However the testing community seems to be loving it, thus I gave it another shot. I started by doing a free course, but I don’t recommend it, it’s very outdated by now.

I know you loved my Cypress recipes post, so here’s a new one for Playwright with up-to-date code snippets on how to implement common automation scenarios.

  • Setup
    • Test skeleton (Test version)
    • Test skeleton (Library version)
  • Actions
    • Visit URL
    • Select page element
    • Count selected elements
    • Type text
    • Click element
    • Dropdowns
    • Checkboxes and Radios
    • iFrames
    • Alerts / Dialog popups
    • Check status of element
  • Assertions
    • Check the page title
    • Check something exists in the page
  • Miscellaneous
    • Take a screenshot
    • Record a video
    • Emulate a mobile device

⚙️ Setup

Test skeleton (Test version)

const { expect, test } = require("@playwright/test");

test.describe("Google search", () => {
  test("is online", async ({ page }) => {
    await page.goto("https://google.com/");
    await expect(page).not.toBeNull();
  });
});

Test skeleton (Library version)

const { chromium } = require("playwright");

(async () => {
    const browser = await chromium.launch({ headless: false, slowMo: 100 }); // options
    const page = await browser.newPage();
    // do stuff
    await browser.close();
})();

⚡️ Actions

Visit URL

await page.goto("https://google.com");

Select page element

// locate based on user visible text
const emailInput = await page.locator("text=Action was successful");
// locate based on CSS selector
const emailInput = await page.locator("#cssSelector > goes here");

Count selected elements

const matches = await page.locator("#cssSelector > goes here");
const total = matches.count();
const firstMatch = matches.first();
const thirdMatch = matches.nth(2);  // index is 0-based
const lastMatch = matches.last();

Type text

const emailInput = ...;
await emailInput.fill("Text to type goes here");
// or inline
await page.locator("#cssSelector").fill("Fake user will type this");

// send keys to the page, regardless what is currently focused
await page.keyboard.type("pressing some KEYS!");
// send key combinations (e.g. shortcuts)
await page.keyboard.press('Ctrl+C');
// press and hold a key (e.g. select something)
await page.keyboard.down('Shift');
for (let i = 0; i < 'KEYS!'.length; i++)
  await page.keyboard.press('ArrowLeft');
await page.keyboard.up('Shift');

Click element

await page.locator("#cssSelector").click();

Dropdowns

await page.selectOption("#css", "blue" );                   // by internal value
await page.selectOption("#css", { label: "Blue ink" });     // by visible label
await page.selectOption("#css", { index: 1 });              // by 0-based index
await page.selectOption("#css", ["red", "blue"]);           // multi select

Checkboxes and Radios

await page.check('#css');
await page.uncheck('#css');
await page.check('text=XL'); // check radio

expect(await page.isChecked('#css')).toBeTruthy(); // assert state

iFrames

const iframeCheckoutSanddox = "#checkout-demo";
const sectionPaymentSummary = "#ProductSummary-totalAmount";
const inputEmail = "#email";

await page.goto("https://checkout.stripe.dev/preview");

// select the iframe
const stripeFrame = page.frameLocator(iframeCheckoutSanddox);
await expect(stripeFrame).not.toBeNull();

// assert elements withing the iframe
await expect(stripeFrame.locator(sectionPaymentSummary)).toBeVisible();

// interact with elements withing the iframe
await frame.locator(inputEmail).fill("[email protected]");

Alerts / Dialog popups

/* TODO: Update this code, I think it's outdated by now
  // code to listen for a dialog popup
  page.once("dialog", async (dialog) => {
      console.log(dialog.message()); // confirm msg seen by user
      await dialog.accept(); // close dialog
  });
  // actually trigger the dialog
  await page.click("#confirmButton");

  // using ".once" instead of ".on" allows multiple listeners in the same test
  page.once("dialog", async (dialog) => {
      await dialog.accept("Hello input!"); // to input something in a dialog
  });
  await page.click("#promptButton");
*/

Check status of element

await page.locator("#cssSelector").isVisible();

P.S: list with all the assertions available

✅ Assertions

Check the page title

await expect(page).toHaveTitle("The Geeky Gecko - The most amazing blog");

Check something exists in the page

await expect(page.locator("#cssSelector")).toBeVisible();

Miscellaneous

Take a screenshot

await page.screenshot({path: "path/to/generated_file.png"});          // page above the fold
await page.screenshot({path: "path/to/file.png", fullPage: true});    // entire page
await page.locator("#css").screenshot({path: "path/to/file.png"});    // just an element

Record a video

Check the official docs

Emulate a mobile device