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, F1–F12, 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' }]);
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:
| Check | Description |
|---|---|
| Attached | Element is in the DOM |
| Visible | Not hidden, display:none, visibility:hidden, opacity:0 |
| Stable | Element is not animating / moving |
| Enabled | Not disabled |
| Editable | Input/textarea is not readonly (fill only) |
| Receives events | Not 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();