Playwright Cheatsheet

Actions

Use this Playwright reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Click

await locator.click();
await locator.click({ button: 'right' });          // right-click
await locator.click({ button: 'middle' });         // middle-click
await locator.click({ clickCount: 2 });            // double-click
await locator.click({ modifiers: ['Shift'] });     // shift-click
await locator.click({ position: { x: 10, y: 20 } }); // relative to element
await locator.click({ force: true });              // skip actionability checks
await locator.click({ noWaitAfter: true });        // don't wait for nav/network
await locator.click({ delay: 100 });              // ms between mousedown/up
await locator.click({ timeout: 5000 });
await locator.dblclick();                          // double-click shorthand
await locator.tap();                               // touch tap (mobile)

Hover / mouse actions

await locator.hover();
await locator.hover({ modifiers: ['Alt'] });
await locator.hover({ position: { x: 5, y: 5 } });

// Low-level mouse
await page.mouse.move(100, 200);
await page.mouse.down();
await page.mouse.up();
await page.mouse.click(100, 200);
await page.mouse.dblclick(100, 200);
await page.mouse.wheel(0, 300);                   // scroll

Typing & filling

await locator.fill('hello world');                // clear + type (recommended)
await locator.clear();                            // clear input value
await locator.pressSequentially('hello', { delay: 50 }); // char-by-char with delay

// Keyboard
await locator.press('Enter');
await locator.press('Shift+Tab');
await locator.press('Control+A');                 // select all
await page.keyboard.type('hello');                // low-level type
await page.keyboard.press('Escape');
await page.keyboard.down('Shift');
await page.keyboard.up('Shift');
await page.keyboard.insertText('emoji 🎉');       // paste without key events

Key names

Enter, Tab, Escape, ArrowLeft, ArrowRight, ArrowUp, ArrowDown, Backspace, Delete, Home, End, PageUp, PageDown, F1F12, Control, Alt, Shift, Meta

Combos: 'Control+C', 'Meta+A', 'Shift+ArrowRight'

Select / dropdowns

await locator.selectOption('value-attr');              // by value
await locator.selectOption({ label: 'Label text' });   // by label
await locator.selectOption({ index: 2 });              // by index (0-based)
await locator.selectOption(['a', 'b']);                 // multi-select
await locator.selectOption([{ label: 'One' }, { label: 'Two' }]);

Checkboxes & radio buttons

await locator.check();                         // check (idempotent)
await locator.uncheck();                       // uncheck
await locator.setChecked(true);               // set to known state
await locator.setChecked(false);
const checked = await locator.isChecked();

File uploads

await locator.setInputFiles('path/to/file.pdf');
await locator.setInputFiles(['file1.png', 'file2.png']);        // multiple
await locator.setInputFiles({ name: 'test.txt', mimeType: 'text/plain', buffer: Buffer.from('hello') });
await locator.setInputFiles([]);                                 // clear

// Upload via file-chooser dialog
const [fileChooser] = await Promise.all([
  page.waitForEvent('filechooser'),
  locator.click(),
]);
await fileChooser.setFiles('upload.png');

Drag and drop

await page.dragAndDrop('#source', '#target');
await page.dragAndDrop('#source', '#target', {
  sourcePosition: { x: 10, y: 10 },
  targetPosition: { x: 5, y: 5 },
});

// Locator-based
await source.dragTo(target);
await source.dragTo(target, { sourcePosition: { x: 10, y: 10 } });

Focus & blur

await locator.focus();
await locator.blur();

Scrolling

await locator.scrollIntoViewIfNeeded();

// Page-level scroll
await page.mouse.wheel(0, 300);
await page.evaluate(() => window.scrollTo(0, 500));
await page.evaluate(() => document.querySelector('.list')?.scrollTo(0, 200));

Clipboard

// Read clipboard (requires grant in context)
const text = await page.evaluate(() => navigator.clipboard.readText());

// Grant clipboard permissions:
const context = await browser.newContext({
  permissions: ['clipboard-read', 'clipboard-write'],
});

Touch actions

await page.touchscreen.tap(100, 200);

Actionability checks (auto-run before actions)

Before any action Playwright verifies:

CheckDescription
AttachedElement is in the DOM
VisibleNot hidden, display:none, visibility:hidden, opacity:0
StableElement is not animating / moving
EnabledNot disabled
EditableInput/textarea is not readonly (fill only)
Receives eventsNot covered by another element

Use { force: true } to bypass all checks (use sparingly — masks real issues).

Waiting without an action

await page.waitForTimeout(500);                     // fixed pause (avoid in tests)
await page.waitForFunction(() => document.readyState === 'complete');
await page.waitForSelector('.toast', { state: 'visible' });
await page.waitForSelector('.spinner', { state: 'hidden' });

Getting values (read-only)

await locator.textContent()      // raw text including hidden children
await locator.innerText()        // rendered text (respects CSS visibility)
await locator.innerHTML()
await locator.inputValue()       // current value of input/textarea/select
await locator.getAttribute('href')
await locator.evaluate(el => el.scrollTop)     // arbitrary JS on element

evaluate / evaluateHandle

// Run JS in the page, get a serializable return value
const title = await page.evaluate(() => document.title);

// Pass values into the page
const count = await page.evaluate(([a, b]) => a + b, [1, 2]);

// Return a JSHandle (not serialized) for further chaining
const bodyHandle = await page.evaluateHandle(() => document.body);
await bodyHandle.dispose();