Skip to content

A handle on one element, or a group of elements, on the page, found by a selector. Create one with `browser.locator(selector)`. A locator does not touch the page when it is created. Every function called on it searches the page again, so a locator keeps working when the page re-renders, and one locator can be used for several actions. Actions use the first element that matches; `list` returns all of them. **Selenium selectors (`Sel`)** - `xpath=//button[@type='submit']`, `css=form .primary`, `id=username`, `name=email`, `class=btn` (one class name only), `tag=h1` and `linkText=Sign in` (exact link text). - A bare selector is XPath only when it starts with `/`, `./` or `(`; otherwise it is CSS. - Semantic selectors: `role=button[name="Save"]`, `text=Save`, `label=Email`, `placeholder=Email`, `alt=Logo`, `title=Help`, `testid=save` (also `testId=`). Quoted text is exact; unquoted text matches a case-insensitive substring. **Playwright selectors (`Play`)** - `xpath=`, `css=`, `id=`, `name=`, `class=`, `tag=` and `linkText=` work as in Selenium (`class=` accepts several class names). Playwright's own `text=Log in` (case-insensitive substring; `text="Log in"` for an exact match) and `role=button[name="Save"]` work too. - A selector without prefix is XPath when it starts with `/`, `./` or `(`, and CSS otherwise. So `button` is CSS here. - `label=`, `placeholder=`, `alt=`, `title=` and `testId=` use the corresponding Playwright getBy functions. **Chains.** `css=form >> css=input` finds the input inside the form: each step is a selector of its own (any prefix) that is searched inside the elements the previous step found. `>>` inside quotes is left alone. **Shadow DOM.** `css=my-app >>> css=button` is short for `css=my-app >> shadow >> css=button`: the `shadow` step enters the host's open shadow root (closed shadow roots cannot be entered). On Selenium, a selector without a chain that is not found in the page is also searched in the open shadow roots of every element on the page (nested ones included), and elements found in a shadow root are clicked with JavaScript (`element.click()`), which skips the visibility and overlay checks of a real click. Playwright pierces open shadow roots by itself for `css=` and `text=` selectors; `>>>` is turned into `>>`. XPath does not pierce shadow roots on Playwright. **Iframes.** There is no frame to switch to: a selector that is not found in the main page is searched in every iframe, nested ones included, and the first match wins. On Selenium the browser stays inside that frame until the next lookup, which matters for `browser.executeJs` and `browser.source`. **`?Label` selectors.** A selector that starts with `?` is looked up in the project's `locators.yaml` instead of being used directly: ```yaml shorts: # which page you are on - url: "example.com" # part of the current URL (plain substring, not a pattern) id: "example" actions: - action: "fill" # the action: click, fill, type, radio, select, text, ... id: ["example"] # the shorts that apply locators: # tried in this order, first one that exists wins - "xpath=//label[normalize-space()='${place}']/following::input[1]" - "css=input[placeholder='${place}']" ``` `${place}` is the text after the `?`, so `browser.locator("?Email")` gives `Email`. `${label}` is the value the action works with (the text for `fill` and `type`, the option for `select`, the value for `radio`, the file for `send`, the script for `execute`); it is only available for actions that take a value. The action names are the function names, except `execute` (`evaluate`), `enter` (`buttonEnter`) and `tab` (`buttonTab`). Resolution is retried for each action, including `wait`. If `locators.yaml` is missing it is fetched from the project on the server; if no candidate matches, the error lists the selectors that were tried. **Results and failures.** Actions (`click`, `fill`, `type`, `select`, ...) return a table `{locator, succeeded}`: `result[1]` is this locator and `result[2]` is `true`. They are retried until the browser's timeout; when they still fail, the script stops with an error unless `browser.stopOnFailure(false)` was called, in which case `result[2]` is `false`. Reading functions (`text`, `attribute`, `property`, `tag`) return the value, or nil after a failure that did not stop the script. The wait-style checks (`exists`, `visible`, `enabled`, `selected`) return a boolean and never raise an error.

  • Kind Object
  • Category Browser
  • Functions 21

How to get one

  1. Sel .start()
  2. Browser .locator()
  3. Locator
local browser = Sel.start()
local locator = browser.locator(selector)

Functions

  • click table Clicks the element.
  • radio table Selects the radio input with the given value.
  • check table Ticks a checkbox or radio input if it is not selected yet.
  • fill table Replaces the content of an input or textarea with `value`.
  • type table Types `value` into an input key by key, after whatever is already in the field.
  • send table Attaches a file from the project to a file input (`<input type="file">`), as if the user had chosen it.
  • select table Picks an option in a `<select>` dropdown by the text the user sees.
  • exists boolean Returns true when the element is in the page within the wait time, false when it is not.
  • visible boolean Returns true when the element is visible, false when it is not or does not exist.
  • enabled boolean Returns true when the element is enabled (not disabled), false when it is not or does not exist.
  • selected boolean Returns true when a checkbox or radio button is ticked, or an option is selected; false when it is not or the element does not exist.
  • text string | nil Returns the text the user sees in the element, including its children.
  • attribute string | nil Returns the value of an HTML attribute as written in the page (for example `href="/home"` gives `/home`, not the full URL), or nil when the element does not have the attribute.
  • property string | nil Returns a property of the live DOM element as a string, for example `value` (what is currently in an input), `checked` (`"true"`/`"false"`) or `href` (the resolved absolute URL).
  • tag string | nil Returns the tag name of the element in lower case, for example `input` or `div`.
  • execute table Runs JavaScript with this element as `arguments[0]`, for example `arguments[0].scrollIntoView()`.
  • enter table Presses the Enter key on the element, for example to submit a search field.
  • tab table Presses the Tab key on the element, which moves focus to the next field and fires its blur handlers.
  • list Locator[] Returns every element that matches the selector as a table of locators, in document order (the table is empty when nothing matches).
  • wait self Waits until the element is visible and enabled, then returns this locator.
  • locator Locator Creates a new Locator for another selector.
locator.click()→table

Clicks the element. Selenium performs a real click on the element; when something covers it, the click is retried until the overlay is gone or the timeout passes. Playwright waits until the element is visible, stable, enabled and not covered. Elements found inside a shadow root are clicked with JavaScript on Selenium.

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

local browser = Sel.start()
browser.navigate("https://example.com/login")
browser.locator("id=username").fill("alice")
browser.locator("css=button[type=submit]").click()
browser.close()
locator.radio(value: string)→table

Selects the radio input with the given value. The selector can match that input or its container. An already selected input stays selected.

Parameters

value string
Value attribute of the radio input; also substitutes `${label}` in a `?Label` selector

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

-- Playwright: the selector matches the group, the value picks the option
local browser = Play.start()
browser.navigate("https://example.com/survey")
browser.locator("id=member").radio("yes")
browser.close()
locator.check()→table

Ticks a checkbox or radio input if it is not selected yet. Use `click` to untick a checkbox.

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false
locator.fill(value: string)→tablelocator.fill(value: string, fire: boolean)→table

Replaces the content of an input or textarea with `value`. With events on (the default), the field is clicked first, and after typing Tab is pressed and the field is clicked again if it is still enabled and visible, so that change and blur handlers run. With events off, only the content is replaced. Use `type` to append to what is already there.

Parameters

value string
The text to put in the field
fire boolean optional
`true` (default) clicks the field before and presses Tab after typing; `false` only replaces the content. An explicit nil counts as false

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

local browser = Sel.start()
browser.navigate("https://example.com/login")
browser.locator("id=username").fill("alice")
browser.locator("id=password").fill(secret("password"))
browser.close()
locator.type(value: string)→tablelocator.type(value: string, fire: boolean)→table

Types `value` into an input key by key, after whatever is already in the field. With events on (the default), the field is clicked first, and after typing Tab is pressed and the field is clicked again if it is still enabled and visible. Use `fill` to replace the content instead.

Parameters

value string
The text to type into the field
fire boolean optional
`true` (default) clicks the field before and presses Tab after typing; `false` only types. An explicit nil counts as false

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false
locator.send(value: string)→table

Attaches a file from the project to a file input (`<input type="file">`), as if the user had chosen it. If the file is not in the run's workspace yet it is fetched from the project on the server first. Nothing is submitted; click the form's button afterwards.

Parameters

value string
Path of the file, relative to the project directory

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

local browser = Sel.start()
browser.navigate("https://example.com/upload")
browser.locator("css=input[type=file]").send("files/report.pdf")
browser.locator("id=upload").click()
browser.close()
locator.select(value: string)→table

Picks an option in a `<select>` dropdown by the text the user sees. The text must match the option exactly. On Selenium the element must be a `<select>`; it fails with an error that is not retried otherwise.

Parameters

value string
Visible text of the option, exact match

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

local browser = Sel.start()
browser.navigate("https://example.com/form")
browser.locator("id=country").select("Netherlands")
browser.close()
locator.exists()→booleanlocator.exists(milliseconds: number)→boolean

Returns true when the element is in the page within the wait time, false when it is not. It never raises an error and does not stop the script. Visibility is not checked; use `visible` for that. Waits up to the browser's timeout unless a time is given. Pass at least 1: 0 means "use the default".

Parameters

milliseconds number optional
Maximum time to wait in milliseconds; 0 or nil uses the browser's timeout

Returns

boolean

Example

local browser = Sel.start()
browser.navigate("https://example.com")
if browser.locator("id=cookie-banner").exists(2000) then
browser.locator("id=accept").click()
end
browser.close()
locator.visible()→booleanlocator.visible(milliseconds: number)→boolean

Returns true when the element is visible, false when it is not or does not exist. It never raises an error and does not stop the script. Waits up to the timeout for visibility on either engine.

Parameters

milliseconds number optional
Maximum time to wait in milliseconds; 0 or nil uses the browser's timeout

Returns

boolean
locator.enabled()→booleanlocator.enabled(milliseconds: number)→boolean

Returns true when the element is enabled (not disabled), false when it is not or does not exist. It never raises an error and does not stop the script. Waits up to the timeout for the enabled state on either engine.

Parameters

milliseconds number optional
Maximum time to wait in milliseconds; 0 or nil uses the browser's timeout

Returns

boolean
locator.selected()→booleanlocator.selected(milliseconds: number)→boolean

Returns true when a checkbox or radio button is ticked, or an option is selected; false when it is not or the element does not exist. It never raises an error and does not stop the script. Waits up to the timeout for the selected state on either engine.

Parameters

milliseconds number optional
Maximum time to wait in milliseconds; 0 or nil uses the browser's timeout

Returns

boolean

Example

local browser = Sel.start()
browser.navigate("https://example.com/settings")
local newsletter = browser.locator("id=newsletter")
if not newsletter.selected(1000) then
newsletter.check()
end
browser.close()
locator.text()→string | nil

Returns the text the user sees in the element, including its children. Selenium returns an empty string for hidden elements; Playwright returns the element's rendered text. The element is retried until it exists; when it is still missing after the timeout the script stops, or nil is returned after `browser.stopOnFailure(false)`.

Returns

string | nil can be nil The text, nil after a failure that did not stop the script

Example

local browser = Sel.start()
browser.navigate("https://example.com")
print(browser.locator("css=h1").text())
browser.close()
locator.attribute(name: string)→string | nil

Returns the value of an HTML attribute as written in the page (for example `href="/home"` gives `/home`, not the full URL), or nil when the element does not have the attribute. To read the live state of the element (the current text of an input, the resolved `href`), use `property`.

Parameters

name string
Attribute name, for example `href` or `data-id`

Returns

string | nil can be nil The attribute value, nil when the attribute is absent
locator.property(name: string)→string | nil

Returns a property of the live DOM element as a string, for example `value` (what is currently in an input), `checked` (`"true"`/`"false"`) or `href` (the resolved absolute URL). Returns nil when the property is null or undefined. Use `attribute` for what is written in the HTML.

Parameters

name string
Property name, for example `value` or `checked`

Returns

string | nil can be nil The property value as a string, nil when it is null or undefined

Example

local browser = Sel.start()
browser.navigate("https://example.com/login")
browser.locator("id=username").fill("alice")
print(browser.locator("id=username").property("value")) -- alice
browser.close()
locator.tag()→string | nil

Returns the tag name of the element in lower case, for example `input` or `div`.

Returns

string | nil can be nil The tag name, nil after a failure that did not stop the script
locator.execute(script: string)→table

Runs JavaScript with this element as `arguments[0]`, for example `arguments[0].scrollIntoView()`. The return value of the script is discarded; to read a value use `browser.executeJs`, or `property`/`attribute`. The action name for `?Label` selectors in `locators.yaml` is `evaluate`.

Parameters

script string
JavaScript; the element is available as `arguments[0]`

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false

Example

local browser = Sel.start()
browser.navigate("https://example.com")
browser.locator("id=footer").execute("arguments[0].scrollIntoView()")
browser.close()
locator.enter()→table

Presses the Enter key on the element, for example to submit a search field. The action name for `?Label` selectors in `locators.yaml` is `buttonEnter`.

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false
locator.tab()→table

Presses the Tab key on the element, which moves focus to the next field and fires its blur handlers. The action name for `?Label` selectors in `locators.yaml` is `buttonTab`.

Returns

table Result table: [1] is this locator and [2] is true when the action succeeded. A failure stops the script unless `browser.stopOnFailure(false)` was called, in which case [2] is false
locator.list()→Locator[]

Returns every element that matches the selector as a table of locators, in document order (the table is empty when nothing matches). Each locator in the list is fixed to its element: it has no selector of its own and cannot be listed again. The page is not waited on for more elements to appear. On Selenium, all matches come from the first place that has any: the main page, else the open shadow roots, else the first iframe with a match. Playwright returns all matches, including iframe matches.

Returns

Locator[] A handle on one element, or a group of elements, on the page, found by a selector.

Example

local browser = Sel.start()
browser.navigate("https://example.com/orders")
for _, row in ipairs(browser.locator("css=table.orders tbody tr").list()) do
print(row.text())
end
browser.close()
locator.wait()→selflocator.wait(milliseconds: number)→self

Waits until the element is visible and enabled, then returns this locator. Uses action retries, failure screenshots and `stopOnFailure`; `?Label` candidates are resolved on every retry.

Parameters

milliseconds number optional
Maximum time to wait in milliseconds; 0 or nil uses the browser's timeout

Returns

self chainable The locator itself, so calls can be chained.

Example

local browser = Sel.start()
browser.navigate("https://example.com/report")
browser.locator("id=download").wait(30000).click()
browser.close()
locator.locator(selector: string)→Locator

Creates a new Locator for another selector. The selector is not relative to this element: it is searched in the whole page, exactly like `browser.locator`. To search inside an element, chain selectors with `>>`.

Parameters

selector string
Selector, see the Locator description

Returns

Locator A handle on one element, or a group of elements, on the page, found by a selector.