Essential Playwright APIs: forms, files, dialogs, frames
Working with form elements — 80% of daily work:
fill(value)— input/textarea; clears the field first.type()is deprecated and slow; usepressSequentially()only when character-by-character typing is genuinely required (autocomplete, masked fields)selectOption('baku')—<select>; by value, label or{ index }; an array for multi-selectcheck()/uncheck()— checkboxes and radios. Better thanclick()because it is idempotent: if already checked, it won't unchecksetInputFiles('path')—<input type="file">; passing[]clears the selectionclear()— empties the field (equivalent tofill(''))
An important detail: setInputFiles does not open the OS file dialog — it assigns the file straight to the input element. That's what frees automation from OS dependence.
Event-based APIs — one rule solves them all: start waiting BEFORE the click that triggers the event. Otherwise the event fires between the click and the wait, and the test times out.
- Download:
const dl = page.waitForEvent('download')→ click →await dl. ThensuggestedFilename(),path(),saveAs() - New tab:
const p = context.waitForEvent('page')→ click (target="_blank") →await p - File chooser:
page.waitForEvent('filechooser')for custom buttons wrapping a hidden input
Dialogs (alert, confirm, prompt) behave differently: Playwright auto-dismisses them, otherwise the page would hang. Consequence: to "see" a dialog, the page.on('dialog', ...) handler must be registered before the click.
iframes are separate DOM documents — ordinary locators don't reach inside. page.frameLocator('iframe[title="3D Secure"]') switches into the frame context; regular locators work from there.
Tab vs window vs context: page is one tab; context is an isolated browser profile (its own cookies, its own storage); browser is the process. To act as two different users in one test you need two contexts — two tabs won't do, because tabs share the session.
| Task | API | Typical mistake |
|---|---|---|
| Ticking a checkbox | check() | click() — unticks it when already ticked |
| Uploading a file | setInputFiles() | Trying to drive the OS dialog with a robot |
| Downloading a file | waitForEvent('download') + click | Starting the wait AFTER the click |
| Accepting a confirm() dialog | page.once('dialog', d => d.accept()) | Registering the handler after the click |
| Reaching an element inside an iframe | page.frameLocator(...) | Searching with a plain locator — never found |
| Acting as two users in one test | browser.newContext() × 2 | Opening two tabs — the session is shared |
The three most-asked interview questions from this topic: "how do you work with iframes?", "what if a new tab opens?", "how do you test file upload?". All three are simple, but not knowing them immediately signals "no real project experience". Keep a one-sentence answer ready for each — these are among the few APIs genuinely worth memorising.
📚 Sources and documentation
- Page APIofficialplaywright.dev