Troupeby AliveDocsSign in

Testing

Actions

An action does something to the device: a tap, text, a gesture, a key, a rotation. This page lists the actions on a locator and on the screen, how they wait, and which platform supports which.

Actions on an element

Call these on a locator. Each is one call to the runtime, which waits for the element, acts and answers.

MethodWhat it does
tap(options?)Taps the element, or position inside it
doubleTap(options?)Taps twice
longPress(options?)Presses and holds, for duration milliseconds (800 by default)
fill(value)Clears an editable element and sets its value
clear()Empties an editable element
type(text, { delay? })Taps the element, then types text key by key. pressSequentially is the same
swipe(direction, options?)Swipes on the element. direction is where the finger travels
scroll(direction, options?)Scrolls this container once. direction is where the content goes
scrollIntoView(options?)Scrolls the screen, or container, until the element is visible
dragTo(target, options?)Drags the element onto another locator's element
waitFor({ state? })Waits for the element to be visible, attached, hidden or detached
TypeScript
await screen.getByTestId('email').fill('ada@ex.co')
await screen.getByTestId('sign-in').tap()
await screen.getByTestId('gesture-area').longPress()
await screen.getByTestId('row-40').scrollIntoView({ maxScrolls: 15 })

Every method but clear also takes timeout in milliseconds. The other options:

OptionOnMeaningDefault
positiontap, doubleTap, longPressA point inside the element, from its top left, in pointsthe driver's own point
forcetap, doubleTap, longPressSkip the actionability checksfalse
durationlongPress, swipe, dragToHow long the gesture takes, in milliseconds800, 300, 500
distanceswipe, scrollA fraction of the element's extent, above 0 and at most 10.6 for swipe
delaytypeMilliseconds between keysnone
holddragToMilliseconds to hold before moving0
directionscrollIntoViewWhich way to scroll'down'
containerscrollIntoViewThe locator of the container to scrollthe screen
maxScrollsscrollIntoViewGive up after this many scrolls, 1 to 10010

How an action waits

You do not wait before an action. The runtime resolves the locator on the device again and again until the element passes the action's checks, then acts:

  • attached: the element is in the tree
  • visible: it has an area on screen
  • enabled
  • stable: its frame is the same on two looks in a row
  • hittable: the device reports that a touch would reach it
  • editable, for fill only: its role is textbox, searchbox, combobox or spinbutton

The wait lasts until the action's timeout, else the actionTimeout option, else what is left of the test's time, and never more than 300 seconds. What happens when it runs out depends on why:

ErrorMeaning
LOCATOR_NOT_FOUNDNothing matched the locator in time
LOCATOR_NOT_ACTIONABLEAn element matched but never passed a check. The error names the check and carries a log of the attempts
LOCATOR_STRICT_VIOLATIONMore than one element matched. This fails at once, without waiting
APP_CRASHEDThe app crashed or exited during the action
TIMEOUTwaitFor did not see its state in time

force: true skips the checks. A tap at a point with screen.tapAt never waits.

Text

fill replaces the whole value in one step and is the usual way to enter text. type sends the text as key events after tapping the element, which matters when the app reacts to each key.

TypeScript
await screen.getByLabel('Search').type('oat', { delay: 50 })
await screen.type(' milk') // into whatever has focus
await screen.pressKey('Enter') // Android Emulator only
await screen.hideKeyboard() // Android Emulator only

fill takes up to 65,536 characters and type up to 4,096. screen.pressKey(key, modifiers?) presses one key by its W3C KeyboardEvent.key name, with any of the modifiers Alt, Control, Meta and Shift. It goes to the focused element. screen.hideKeyboard() returns whether a keyboard was showing. The table below says where each one works.

Gestures and scrolling

The two direction arguments mean different things:

  • swipe('up') says where the finger travels. Swiping up on a list drags it up and shows what is below.
  • scroll('down') says where you want to go in the content. Scrolling down shows what is below.
TypeScript
await screen.getByTestId('carousel').swipe('left')
await screen.swipe('up', { distance: 0.8 })                 // across the whole screen
await screen.getByRole('list').scroll('down')               // one scroll of this list
await screen.scroll('down', { until: screen.getByText('Terms'), maxScrolls: 20 })
await screen.getByTestId('card').dragTo(screen.getByTestId('trash'))
await screen.tapAt({ x: 200, y: 400 })                      // a point, in points

scrollIntoView and screen.scroll with until scroll until the element is visible, and fail with LOCATOR_NOT_FOUND when it is not after maxScrolls. A long list often creates its rows lazily, so a far row does not exist until you scroll near it:

TypeScript
test('scroll a long list to a far row', async ({ screen }) => {
  await screen.getByTestId('nav-list').tap()
  // The list is lazy: row 40 is not in the tree until it is scrolled near (about 3 screens down).
  await expect(screen.getByTestId('row-40')).toBeHidden()
  await screen.getByTestId('row-40').scrollIntoView({ maxScrolls: 15 })
  await expect(screen.getByTestId('row-40')).toBeVisible()
})

Buttons and orientation

TypeScript
await screen.pressButton('home')
await screen.setOrientation('landscapeLeft')
await expect(screen.getByTestId('nav-controls')).toBeVisible()
await screen.setOrientation('portrait')

pressButton takes home, back, appSwitch, power, volumeUp or volumeDown, and an optional duration for a long press. setOrientation takes portrait, portraitUpsideDown, landscapeLeft or landscapeRight. To start every test of a project in an orientation, set the orientation option instead.

What each platform supports

A platform that cannot perform an action refuses it with CAPABILITY_UNSUPPORTED before it touches the device.

ActioniOS SimulatorAndroid EmulatorMac Catalyst
tapyesyesyes: it activates the element
fill, type, screen.typeyesyesyes
scroll, scrollIntoViewyesyesyes
doubleTap, longPress, swipe, dragTo, screen.tapAtyesyesno
screen.pressKeynoyesno
screen.pressButtonhomeall six buttonsno
screen.setOrientationyesyesno
screen.hideKeyboardnoyesno

Mac Catalyst has no touch input: a tap there activates the element through accessibility, and text goes into the focused field. A test that needs a gesture says so with test.requires('input.touch') and is skipped where it cannot run.

Next

esc

    Type to search every page, the protocol reference and the cloud API.