skip to content

Acting on a Match

The call that finally changes the page: which verb to reach for, what each one takes as options, and which of them finish only when the browser answers back.

on this pageshow

explore

questions

15

In Playwright, how does locator.setInputFiles() attach a file without the OS picker?

level: juniorimportance: must knowfreq 80%

answer

  1. The native picker is unreachable
  2. Set the input's file list directly
  3. One path, many paths, or a buffer
  4. Empty array clears the selection
  5. Relative paths use the working directory

basics

~20 s

Playwright sets the file input's file list directly through the browser protocol instead of driving the native dialog. Pass one path, several paths, an in-memory buffer object, or an empty array to clear the selection.

solid answer

~40 s

`locator.setInputFiles()` targets an `<input type=file>` (or a `<label>` whose associated control is one) and assigns its file list over the browser's remote-debugging connection, so the operating system's picker never opens -- which is what makes uploads driveable at all. It accepts a single path string, an array of paths for an input marked `multiple`, one or more `{ name, mimeType, buffer }` objects that synthesise a file never written to disk, and `[]` to clear a previous selection. Relative paths resolve against the test process's current working directory, not the spec file's folder. For an input carrying `webkitdirectory`, pass a single directory path. Setting files fires the `input` and `change` events, so the issue tracker's attachment list re-renders exactly as it would for a real user.

code

typescript · 19 lines
typescript
import { test, expect } from '@playwright/test';

test('attach files to an issue', async ({ page }) => {
  await page.goto('/issues/ISS-482');
  const input = page.locator('input[type=file]');

  await input.setInputFiles('fixtures/crash-log.txt');
  await expect(page.getByText('crash-log.txt')).toBeVisible();

  await input.setInputFiles({
    name: 'triage.csv',
    mimeType: 'text/csv',
    buffer: Buffer.from('id,title,status'),
  });
  await expect(page.getByText('triage.csv')).toBeVisible();

  await input.setInputFiles([]);
  await expect(page.getByText('triage.csv')).toBeHidden();
});

go deeper

for a junior

Recall the call itself: locator.setInputFiles with a path string, and that no native picker ever opens. Attaching a fixture file and asserting the filename appears is the whole junior bar here.

for a middle

Explain the four argument shapes -- one path, an array, a name/mimeType/buffer object, and an empty array -- and that relative paths resolve against the test process's working directory rather than the spec file.

for a senior

Show judgment about how the input is reached in a real application, and be ready to say what setInputFiles cannot do when the page never renders a file input you can target.

for a principal

Own the convention: whether the suite ships binary fixtures or synthesises files in memory, and how much upload coverage belongs in end-to-end tests versus cheaper layers.

## The picker is not part of the page When a user clicks **Attach file** on an issue, the browser hands control to the operating system. The window that opens is an OS dialog: it has no DOM, no accessible tree the page can reach, and no protocol surface a browser automation tool can drive. Any strategy that begins "click the button, then choose the file" is dead before it starts. `locator.setInputFiles()` sidesteps that dialog entirely. Rather than simulating the user's trip through the file system, it assigns the input element's file list directly over the browser's remote-debugging connection and then lets the `input` and `change` events fire. From the application's point of view a file was chosen; from the test's point of view nothing ever blocked. ## What it can be pointed at The target must be an `<input type=file>`, or a `<label>` whose associated control is one -- Playwright retargets to the control for you, which is why a locator built from the visible label text usually works. Point it at anything else and the call raises an error rather than quietly doing nothing, so a mis-aimed locator shows up as a failure instead of an upload that never happened. Real applications frequently hide the input behind a styled button. That does not change the approach: you target the input element, not the thing the user clicks. ## The four argument shapes | argument | what it does | | --- | --- | | `'fixtures/crash-log.txt'` | attaches one file read from disk | | `['before.png', 'after.png']` | attaches several; the input needs the `multiple` attribute | | `{ name, mimeType, buffer }` | synthesises a file in memory, nothing on disk | | `[]` | clears the current selection | Consequences worth holding onto: - Relative paths resolve against the **current working directory of the test process**, not the folder holding the spec file. Invoking the runner from a subdirectory changes what a relative path means, so anchoring on a path built at runtime removes the surprise. - Passing several files to an input that lacks `multiple` fails loudly instead of attaching only the first one. - The buffer form produces a complete file: `name` is what the application reads as the file's name, `mimeType` is its type, and `buffer` is the bytes. Nothing touches disk, so there is no binary fixture in the repository and nothing to clean up. - An empty array is a real operation, not a no-op. It resets the file list and fires the same events, so the issue tracker's attachment strip re-renders empty. - For an input carrying the `webkitdirectory` attribute, pass a single directory path and the browser expands it into the files underneath. ## A worked shape 1. Locate the input itself, even when it is visually hidden behind a styled control. 2. Call `setInputFiles()` with a path, an array, or a buffer object. 3. Assert on what the application did with it -- the filename in the attachment list, an upload progress row, a submit button that disables while the request is in flight. Step 3 is the step people skip. `setInputFiles()` resolves once the file list is set and the events are dispatched; it does not wait for the application's own upload request to finish. If the very next line submits the comment, the test is racing the network. Assert on a user-visible consequence before moving on. ## When there is nothing to point at Some upload controls never render a reachable input: script creates one, clicks it, and throws it away. Those pages ask the browser for a file picker instead, and Playwright surfaces that request as a page event you can wait for and answer with the same argument shapes. Reach for it only when there is genuinely no input to target -- a plain `setInputFiles()` call has no event ordering to get wrong. ## Failure modes you will actually meet - **Wrong element.** A locator matching the styled button rather than the input produces an error about the element not being a file input. - **Path drift.** Fixture paths that work under one invocation and break under another are almost always working-directory assumptions in disguise. - **Nothing uploaded.** The file list is set correctly, but the application only uploads on a separate submit action the test never performs. - **Stale assertion.** The test asserts the filename before the application has re-rendered, which is a timing bug in the assertion, not in the upload.

  • What happens if you call setInputFiles on an element that is not a file input?
    It throws. The method requires an `input[type=file]`, or a `<label>` whose associated control is one -- Playwright retargets to that control automatically. Anything else fails with an error naming the element, so a mis-aimed locator surfaces as a real failure rather than an upload that silently never happened.
  • How do you attach two files at once to the same input?
    Pass an array of paths, or an array of buffer objects. The input must carry the `multiple` attribute; without it Playwright raises an error rather than quietly attaching only the first file, which is a useful signal that the markup does not support what the test assumes.

saying these in an interview costs you the question

  • Claims Playwright can click buttons in the native OS file dialog
  • Assumes relative fixture paths resolve from the spec file's folder
  • Thinks setInputFiles types a filename into the input like text
  • Believes clearing a selection requires recreating the input
  • Assumes a buffer upload needs a temporary file on disk first
open as a page

In Playwright, how does locator.fill() differ from locator.pressSequentially() in what the page receives?

level: juniorimportance: must knowfreq 82%

basics

~20 s

locator.fill() focuses the field, selects any existing text and replaces it in one insertion, firing a single input event. locator.pressSequentially() sends keydown, keypress, input and keyup per character and does not clear the field first.

open as a page

In Playwright, what does locator.press('Control+Enter') send to the page, and how are key names resolved?

level: juniorimportance: must knowfreq 71%

basics

~10 s

locator.press focuses the matched element, holds Control, presses and releases Enter, then releases Control. The argument is one logical key name or a single character, with modifiers joined by plus signs.

open as a page

In Playwright, what happens to a window.confirm() dialog when no dialog handler is registered?

level: middleimportance: must knowfreq 70%

basics

~10 s

Playwright dismisses it automatically, so confirm() returns false and the click that opened it completes. Registering a dialog listener turns that off: your handler must then accept or dismiss, or the page freezes.

open as a page

In Playwright, which ways can locator.selectOption() identify the option it should select?

level: middleimportance: must knowfreq 66%

basics

~20 s

A plain string matches an option by its value or its label. An object narrows by value, label or index, and every property you state must match. An array selects several options in a multiple select.

open as a page

In Playwright, what do button, modifiers, position, clickCount and delay change about locator.click()?

level: middleimportance: must knowfreq 64%

basics

~20 s

They reshape one synthetic mouse gesture: which button is pressed, which modifier keys are held, where inside the element's padding box the pointer lands, how many clicks are sent, and the pause between mousedown and mouseup.

open as a page

Your Playwright dragTo() leaves an issue-board card in place. How do you diagnose it and hand-build the drag?

level: seniorimportance: must knowfreq 46%

basics

~20 s

dragTo moves to the source, presses, moves to the target and releases. A board built on HTML5 drag and drop needs at least two mouse moves before dragover fires, so rebuild the gesture and hover the target twice.

open as a page

In Playwright, why must a test call download.saveAs() before its browser context closes?

level: middleimportance: should knowfreq 57%

basics

~20 s

Playwright streams a download into a temporary location owned by the browser context and deletes it when that context closes. saveAs copies the bytes to a path you control; without it the file is gone once the test ends.

open as a page

In Playwright, what does locator.setChecked(true) do that a plain click on the checkbox does not?

level: middleimportance: should knowfreq 54%

basics

~20 s

setChecked reads the control's current state first, clicks only if it differs, and then verifies the new state. A plain click toggles blindly, so an already-checked box ends up unchecked and an intercepted click passes silently.

open as a page

In Playwright, how does locator.dispatchEvent('click') differ from locator.click(), and when is it wrong?

level: middleimportance: should knowfreq 43%

basics

~20 s

locator.click drives a real pointer to the element and sends mousedown and mouseup. dispatchEvent builds a synthetic event in the page and fires it straight at the node, whatever its visibility, with no pointer, no coordinates and isTrusted false.

open as a page

In Playwright, how do you attach a file when the page renders no file input to target?

level: seniorimportance: should knowfreq 46%

basics

~10 s

Wait for the page's filechooser event. Start waiting before clicking the control, then call setFiles on the FileChooser Playwright hands you; this works even when script creates the input and discards it.

open as a page

In Playwright, why might a comment box's @mention autocomplete never open when the test uses locator.fill()?

level: seniorimportance: should knowfreq 41%

basics

~20 s

fill inserts the whole string in one step and dispatches only an input event, never keydown or keyup. A menu that opens on key handlers therefore never sees a trigger. Type the trigger characters with pressSequentially instead.

open as a page

Should a Playwright suite auto-accept every dialog globally, or handle each one in its own test?

level: principalimportance: should knowfreq 35%

basics

~20 s

Handle them per test. A blanket accept-everything handler hides the dialogs a test should be asserting on, and turns a real regression -- a confirmation that stops appearing, or one that names the wrong issue -- into a silent pass.

open as a page

How do you decide when a Playwright suite may drive page.mouse and page.keyboard instead of locator verbs?

level: principalimportance: should knowfreq 33%

basics

~10 s

Treat the raw devices as a documented exception. page.mouse takes viewport coordinates and page.keyboard goes wherever focus already is, so neither re-resolves an element. Reserve them for gestures with no element to name.

open as a page

A team wants every Playwright form interaction to use pressSequentially for realism. How do you evaluate that?

level: principalimportance: nice to knowfreq 28%

basics

~20 s

Replace the blanket rule with a criterion. Typing costs one round trip per character and adds a re-render window between each, so reserve it for fields whose own behaviour depends on key events and use fill everywhere else.

open as a page