PageSourceSearch

https://playwright.dev/assets/js/b49e274c.02000b9c.js

js playwright.dev collected 2026-09-24 06:55:33 UTC 18,126 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkplaywright_dev=self.webpackChunkplaywright_dev||[]).push([["3738"],{54283(e,t,n){n.r(t),n.d(t,{metadata:()=>i,default:()=>h,frontMatter:()=>o,contentTitle:()=>s,toc:()=>r,assets:()=>c});var i=JSON.parse('{"id":"input","title":"Actions","description":"Introduction","source":"@site/docs/input.mdx","sourceDirName":".","slug":"/input","permalink":"/docs/next/input","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"id":"input","title":"Actions"},"sidebar":"docs","previous":{"title":"Accessibility testing","permalink":"/docs/next/accessibility-testing"},"next":{"title":"Assertions","permalink":"/docs/next/test-assertions"}}'),l=n(74848),a=n(28453);n(13554),n(41647),n(83137);let o={id:"input",title:"Actions"},s,c={},r=[{value:"Introduction",id:"introduction",level:2},{value:"Text input",id:"text-input",level:2},{value:"Checkboxes and radio buttons",id:"checkboxes-and-radio-buttons",level:2},{value:"Select options",id:"select-options",level:2},{value:"Mouse click",id:"mouse-click",level:2},{value:"Forcing the click",id:"forcing-the-click",level:4},{value:"Programmatic click",id:"programmatic-click",level:4},{value:"Type characters",id:"type-characters",level:2},{value:"Keys and shortcuts",id:"keys-and-shortcuts",level:2},{value:"Upload files",id:"upload-files",level:2},{value:"Focus element",id:"focus-element",level:2},{value:"Drag and Drop",id:"drag-and-drop",level:2},{value:"Dragging manually",id:"dragging-manually",level:3},{value:"Scrolling",id:"scrolling",level:2}];function d(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",h3:"h3",h4:"h4",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.R)(),...e.components};return(0,l.jsxs)(l.Fragment,{children:[(0,l.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,l.jsx)(t.p,{children:"Playwright can interact with HTML Input elements such as text inputs, checkboxes, radio buttons, select options, mouse clicks, type characters, keys and shortcuts as well as upload files and focus elements."}),"\n",(0,l.jsx)(t.h2,{id:"text-input",children:"Text input"}),"\n",(0,l.jsxs)(t.p,{children:["Using ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-fill",children:"locator.fill()"})," is the easiest way to fill out the form fields. It focuses the element and triggers an ",(0,l.jsx)(t.code,{children:"input"})," event with the entered text. It works for ",(0,l.jsx)(t.code,{children:"<input>"}),", ",(0,l.jsx)(t.code,{children:"<textarea>"})," and ",(0,l.jsx)(t.code,{children:"[contenteditable]"})," elements."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Text input\nawait page.getByRole('textbox').fill('Peter');\n\n// Date input\nawait page.getByLabel('Birth date').fill('2020-02-02');\n\n// Time input\nawait page.getByLabel('Appointment time').fill('13:15');\n\n// Local datetime input\nawait page.getByLabel('Local time').fill('2020-03-02T05:15');\n"})}),"\n",(0,l.jsx)(t.h2,{id:"checkboxes-and-radio-buttons",children:"Checkboxes and radio buttons"}),"\n",(0,l.jsxs)(t.p,{children:["Using ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-set-checked",children:"locator.setChecked()"})," is the easiest way to check and uncheck a checkbox or a radio button. This method can be used with ",(0,l.jsx)(t.code,{children:"input[type=checkbox]"}),", ",(0,l.jsx)(t.code,{children:"input[type=radio]"})," and ",(0,l.jsx)(t.code,{children:"[role=checkbox]"})," elements."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Check the checkbox\nawait page.getByLabel('I agree to the terms above').check();\n\n// Assert the checked state\nexpect(page.getByLabel('Subscribe to newsletter')).toBeChecked();\n\n// Select the radio button\nawait page.getByLabel('XL').check();\n"})}),"\n",(0,l.jsx)(t.h2,{id:"select-options",children:"Select options"}),"\n",(0,l.jsxs)(t.p,{children:["Selects one or multiple options in the ",(0,l.jsx)(t.code,{children:"<select>"})," element with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-select-option",children:"locator.selectOption()"}),". You can specify option ",(0,l.jsx)(t.code,{children:"value"}),", or ",(0,l.jsx)(t.code,{children:"label"})," to select. Multiple options can be selected."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Single selection matching the value or label\nawait page.getByLabel('Choose a color').selectOption('blue');\n\n// Single selection matching the label\nawait page.getByLabel('Choose a color').selectOption({ label: 'Blue' });\n\n// Multiple selected items\nawait page.getByLabel('Choose multiple colors').selectOption(['red', 'green', 'blue']);\n"})}),"\n",(0,l.jsx)(t.h2,{id:"mouse-click",children:"Mouse click"}),"\n",(0,l.jsx)(t.p,{children:"Performs a simple human click."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Generic click\nawait page.getByRole('button').click();\n\n// Double click\nawait page.getByText('Item').dblclick();\n\n// Right click\nawait page.getByText('Item').click({ button: 'right' });\n\n// Shift + click\nawait page.getByText('Item').click({ modifiers: ['Shift'] });\n\n// Ctrl + click on Windows and Linux\n// Meta + click on macOS\nawait page.getByText('Item').click({ modifiers: ['ControlOrMeta'] });\n\n// Hover over element\nawait page.getByText('Item').hover();\n\n// Click the top left corner\nawait page.getByText('Item').click({ position: { x: 0, y: 0 } });\n"})}),"\n",(0,l.jsx)(t.p,{children:"Under the hood, this and other pointer-related methods:"}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"wait for element with given selector to be in DOM"}),"\n",(0,l.jsxs)(t.li,{children:["wait for it to become displayed, i.e. not empty, no ",(0,l.jsx)(t.code,{children:"display:none"}),", no ",(0,l.jsx)(t.code,{children:"visibility:hidden"})]}),"\n",(0,l.jsx)(t.li,{children:"wait for it to stop moving, for example, until css transition finishes"}),"\n",(0,l.jsx)(t.li,{children:"scroll the element into view"}),"\n",(0,l.jsx)(t.li,{children:"wait for it to receive pointer events at the action point, for example, waits until element becomes non-obscured by other elements"}),"\n",(0,l.jsx)(t.li,{children:"retry if the element is detached during any of the above checks"}),"\n"]}),"\n",(0,l.jsx)(t.h4,{id:"forcing-the-click",children:"Forcing the click"}),"\n",(0,l.jsxs)(t.p,{children:["Sometimes, apps use non-trivial logic where hovering the element overlays it with another element that intercepts the click. This behavior is indistinguishable from a bug where element gets covered and the click is dispatched elsewhere. If you know this is taking place, you can bypass the ",(0,l.jsx)(t.a,{href:"/docs/next/actionability",children:"actionability"})," checks and force the click:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"await page.getByRole('button').click({ force: true });\n"})}),"\n",(0,l.jsx)(t.h4,{id:"programmatic-click",children:"Programmatic click"}),"\n",(0,l.jsxs)(t.p,{children:["If you are not interested in testing your app under the real conditions and want to simulate the click by any means possible, you can trigger the ",(0,l.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click",children:(0,l.jsx)(t.code,{children:"HTMLElement.click()"})})," behavior via simply dispatching a click event on the element with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-dispatch-event",children:"locator.dispatchEvent()"}),":"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"await page.getByRole('button').dispatchEvent('click');\n"})}),"\n",(0,l.jsx)(t.h2,{id:"type-characters",children:"Type characters"}),"\n",(0,l.jsx)(t.admonition,{type:"caution",children:(0,l.jsxs)(t.p,{children:["Most of the time, you should input text with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-fill",children:"locator.fill()"}),". See the ",(0,l.jsx)(t.a,{href:"#text-input",children:"Text input"})," section above. You only need to type characters if there is special keyboard handling on the page."]})}),"\n",(0,l.jsxs)(t.p,{children:["Type into the field character by character, as if it was a user with a real keyboard with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-press-sequentially",children:"locator.pressSequentially()"}),"."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Press keys one by one\nawait page.locator('#area').pressSequentially('Hello World!');\n"})}),"\n",(0,l.jsxs)(t.p,{children:["This method will emit all the necessary keyboard events, with all the ",(0,l.jsx)(t.code,{children:"key
1down"}),", ",(0,l.jsx)(t.code,{children:"keyup"}),", ",(0,l.jsx)(t.code,{children:"keypress"})," events in place. You can even specify the optional ",(0,l.jsx)(t.code,{children:"delay"})," between the key presses to simulate real user behavior."]}),"\n",(0,l.jsx)(t.h2,{id:"keys-and-shortcuts",children:"Keys and shortcuts"}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Hit Enter\nawait page.getByText('Submit').press('Enter');\n\n// Dispatch Control+Right\nawait page.getByRole('textbox').press('Control+ArrowRight');\n\n// Press $ sign on keyboard\nawait page.getByRole('textbox').press('$');\n"})}),"\n",(0,l.jsxs)(t.p,{children:["The ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-press",children:"locator.press()"})," method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the ",(0,l.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key",children:"keyboardEvent.key"})," property of the keyboard events:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-txt",children:"Backquote, Minus, Equal, Backslash, Backspace, Tab, Delete, Escape,\nArrowDown, End, Enter, Home, Insert, PageDown, PageUp, ArrowRight,\nArrowUp, F1 - F12, Digit0 - Digit9, KeyA - KeyZ, etc.\n"})}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsxs)(t.li,{children:["You can alternatively specify a single character you'd like to produce such as ",(0,l.jsx)(t.code,{children:'"a"'})," or ",(0,l.jsx)(t.code,{children:'"#"'}),"."]}),"\n",(0,l.jsxs)(t.li,{children:["Following modification shortcuts are also supported: ",(0,l.jsx)(t.code,{children:"Shift, Control, Alt, Meta"}),"."]}),"\n"]}),"\n",(0,l.jsxs)(t.p,{children:["Simple version produces a single character. This character is case-sensitive, so ",(0,l.jsx)(t.code,{children:'"a"'})," and ",(0,l.jsx)(t.code,{children:'"A"'})," will produce different results."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// <input id=name>\nawait page.locator('#name').press('Shift+A');\n\n// <input id=name>\nawait page.locator('#name').press('Shift+ArrowLeft');\n"})}),"\n",(0,l.jsxs)(t.p,{children:["Shortcuts such as ",(0,l.jsx)(t.code,{children:'"Control+o"'})," or ",(0,l.jsx)(t.code,{children:'"Control+Shift+T"'})," are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed."]}),"\n",(0,l.jsxs)(t.p,{children:["Note that you still need to specify the capital ",(0,l.jsx)(t.code,{children:"A"})," in ",(0,l.jsx)(t.code,{children:"Shift-A"})," to produce the capital character. ",(0,l.jsx)(t.code,{children:"Shift-a"})," produces a lower-case one as if you had the ",(0,l.jsx)(t.code,{children:"CapsLock"})," toggled."]}),"\n",(0,l.jsx)(t.h2,{id:"upload-files",children:"Upload files"}),"\n",(0,l.jsxs)(t.p,{children:["You can select input files for upload using the ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-set-input-files",children:"locator.setInputFiles()"})," method. It expects first argument to point to an ",(0,l.jsx)(t.a,{href:"https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input",children:"input element"})," with the type ",(0,l.jsx)(t.code,{children:'"file"'}),". Multiple files can be passed in the array. If some of the file paths are relative, they are resolved relative to the current working directory. Empty array clears the selected files."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Select one file\nawait page.getByLabel('Upload file').setInputFiles(path.join(__dirname, 'myfile.pdf'));\n\n// Select multiple files\nawait page.getByLabel('Upload files').setInputFiles([\n  path.join(__dirname, 'file1.txt'),\n  path.join(__dirname, 'file2.txt'),\n]);\n\n// Select a directory\nawait page.getByLabel('Upload directory').setInputFiles(path.join(__dirname, 'mydir'));\n\n// Remove all the selected files\nawait page.getByLabel('Upload file').setInputFiles([]);\n\n// Upload buffer from memory\nawait page.getByLabel('Upload file').setInputFiles({\n  name: 'file.txt',\n  mimeType: 'text/plain',\n  buffer: Buffer.from('this is test')\n});\n"})}),"\n",(0,l.jsxs)(t.p,{children:["If you don't have input element in hand (it is created dynamically), you can handle the ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-page#page-event-file-chooser",children:"page.on('filechooser')"})," event or use a corresponding waiting method upon your action:"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Start waiting for file chooser before clicking. Note no await.\nconst fileChooserPromise = page.waitForEvent('filechooser');
1\nawait page.getByLabel('Upload file').click();\nconst fileChooser = await fileChooserPromise;\nawait fileChooser.setFiles(path.join(__dirname, 'myfile.pdf'));\n"})}),"\n",(0,l.jsx)(t.h2,{id:"focus-element",children:"Focus element"}),"\n",(0,l.jsxs)(t.p,{children:["For the dynamic pages that handle focus events, you can focus the given element with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-focus",children:"locator.focus()"}),"."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"await page.getByLabel('Password').focus();\n"})}),"\n",(0,l.jsx)(t.h2,{id:"drag-and-drop",children:"Drag and Drop"}),"\n",(0,l.jsxs)(t.p,{children:["You can perform drag&drop operation with ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-drag-to",children:"locator.dragTo()"}),". This method will:"]}),"\n",(0,l.jsxs)(t.ul,{children:["\n",(0,l.jsx)(t.li,{children:"Hover the element that will be dragged."}),"\n",(0,l.jsx)(t.li,{children:"Press left mouse button."}),"\n",(0,l.jsx)(t.li,{children:"Move mouse to the element that will receive the drop."}),"\n",(0,l.jsx)(t.li,{children:"Release left mouse button."}),"\n"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"await page.locator('#item-to-be-dragged').dragTo(page.locator('#item-to-drop-at'));\n"})}),"\n",(0,l.jsx)(t.h3,{id:"dragging-manually",children:"Dragging manually"}),"\n",(0,l.jsxs)(t.p,{children:["If you want precise control over the drag operation, use lower-level methods like ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-hover",children:"locator.hover()"}),", ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-mouse#mouse-down",children:"mouse.down()"}),", ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-mouse#mouse-move",children:"mouse.move()"})," and ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-mouse#mouse-up",children:"mouse.up()"}),"."]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"await page.locator('#item-to-be-dragged').hover();\nawait page.mouse.down();\nawait page.locator('#item-to-drop-at').hover();\nawait page.mouse.up();\n"})}),"\n",(0,l.jsx)(t.admonition,{type:"note",children:(0,l.jsxs)(t.p,{children:["If your page relies on the ",(0,l.jsx)(t.code,{children:"dragover"})," event being dispatched, you need at least two mouse moves to trigger it in all browsers. To reliably issue the second mouse move, repeat your ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-mouse#mouse-move",children:"mouse.move()"})," or ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-hover",children:"locator.hover()"})," twice. The sequence of operations would be: hover the drag element, mouse down, hover the drop element, hover the drop element second time, mouse up."]})}),"\n",(0,l.jsx)(t.h2,{id:"scrolling",children:"Scrolling"}),"\n",(0,l.jsx)(t.p,{children:"Most of the time, Playwright will automatically scroll for you before doing any actions. Therefore, you do not need to scroll explicitly."}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Scrolls automatically so that button is visible\nawait page.getByRole('button').click();\n"})}),"\n",(0,l.jsx)(t.p,{children:'However, in rare cases you might need to manually scroll. For example, you might want to force an "infinite list" to load more elements, or position the page for a specific screenshot. In such a case, the most reliable way is to find an element that you want to make visible at the bottom, and scroll it into view.'}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Scroll the footer into view, forcing an \"infinite list\" to load more content\nawait page.getByText('Footer text').scrollIntoViewIfNeeded();\n"})}),"\n",(0,l.jsxs)(t.p,{children:["If you would like to control the scrolling more precisely, use ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-mouse#mouse-wheel",children:"mouse.wheel()"})," or ",(0,l.jsx)(t.a,{href:"/docs/next/api/class-locator#locator-evaluate",children:"locator.evaluate()"}),":"]}),"\n",(0,l.jsx)(t.pre,{children:(0,l.jsx)(t.code,{className:"language-js",children:"// Position the mouse and scroll with the mouse wheel\nawait page.getByTestId('scrolling-container').hover();\nawait page.mouse.wheel(0, 10);\n\n// Alternatively, programmatically scroll a specific element\nawait page.getByTestId('scrolling-container').evaluate(e => e.scrollTop += 100);\n"})})]})}function h(e={}){let{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,l.jsx)(t,{...e,children:(0,l.jsx)(d,{...e})}):d(e)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.