Each test will have an Appetize session for you to interact with your device (like a page in Playwright). You can then assert the app based on some criteria, such as the existence of a UI element, a network request, or do a screenshot test.
Your first test
Take a look at the following test example:
import { test, expect } from'@appetize/playwright'// reinstall app after each test to reset datatest.afterEach(async ({ session }) => {awaitsession.reinstallApp()})test('logs in to the app',async ({ session }) => {// type usernameawaitsession.tap({ element: { attributes: { accessibilityIdentifier:'username_field' } } })awaitsession.type('jordan')// type passwordawaitsession.tap({ element: { attributes: { accessibilityIdentifier:'password_field' } } })awaitsession.type('secretpassword')// tap login buttonawaitsession.tap({ element: { attributes: { text:'Login' } } })// assert that an element with 'Hello Jordan' exists on the screenawaitexpect(session).toHaveElement({ attributes: { text:'Hello Jordan' } })})
This will load a hypothetical app with a login screen. It will tap on the username and password fields, type some credentials, log in, and assert that a UI element with text "Hello Jordan" exists.
Actions
Each test provides the session for your app. You can use Automation actions here to interact with it as you need.
test('scrolls through the news feed',async ({ session }) => {awaitsession.swipe({ position: { x:'50%', y:'50%', }, gesture:'up' })})
Sequencing actions
All actions are promises that will await until the interaction has been played on the device. If your action targets an element, Appetize will wait for the element to appear before proceeding, which is helpful when your action results in a change in UI.
All actions that target an element will wait up to 10 seconds for an element to appear. If you need to wait for an element to appear without interacting on it, you can use waitForElement()
test('screenshot of the settings page',async ({ session }) => {// tapping on 'Settings' will trigger a screen transitionawaitsession.tap({ element: { text:'Settings' } })// wait for a UI element to appearawaitsession.waitForElement({ text:'Notifications' })// take a screenshotconstscreenshot=awaitsession.screenshot()expect(screenshot.data).toMatchSnapshot() })
These timeouts are also configurable (see Timeouts.)
Assertions
expect
Playwright uses the expect library for assertions. We have added custom async matchers for asserting on application state.
toHaveElement
Asserts that an element exists in the current application UI
It can take additional options to change the behaviour of the assertion:
awaitexpect(session).toHaveElement( { attributes: { text:'Hello', } }, { timeout:10000,// time in ms to wait for element to appear (default 10000) matches:1// require this amount of elements to be found })
not.toHaveElement
Asserts that an element does not exists in the current application UI
awaitexpect(session).not.toHaveElement( { attributes: { text:'Hello' } }, {// We recommend setting a lower timeout for elements we know will not appear, // as it will spend this time looking for the element. timeout:1000,// time in ms to wait for element to appear (default 10000) } )
Note: screenshot tests are fragile by nature as any change in the UI could cause it to fail. It is always better to assert on a narrow piece of application state, such astoHaveElement, or on network/debug log output.
test('loads the home tab',async ({ sesssion }) => {awaitsession.findElement({ attributes: { text:'Home' } })constscreenshot=awaitsession.screenshot()awaitexpect(session.data).toMatchSnapshot()})
Network
An example of how you can assert that a network request was made.
test.use({ config: { proxy:'intercept', }})test('makes a network request to the API with authentication',async ({ session }) => {const { request } =awaitsession.waitForEvent('network', event => {if (event.request.url.startsWith('https://api.example.com')) {returntrue; } })// request.headers is an array of objectsexpect(request.headers).toContainEqual({ name:'Authorization', value:expect.stringMatching(/^Basic /), })})
Helpers
session contains a few helper methods for writing tests that may come in handy
waitForElement
Waits for an element to appear.
awaitsession.waitForElement({ attributes: { text:"Hello" } })awaitsession.waitForElement( { attributes: { text:"Hello" } }, { matches:2,// wait for exactly 2 elements to match the selector timeout:10000// wait a maximum of 10 seconds (default) })
waitForEvent
Waits for an event to occur
constnetworkEvent=awaitsession.waitForEvent('network')constrequestEvent=awaitsession.waitForEvent('network', event => {// resolves only when this condition is metreturnevent.type ==='request'})
waitForTimeout
Waits for the given time to elapse (in ms)
awaitsession.waitForTimeout(5000)
Real life applications
The Common Testing Scenarios page highlights typical challenges mobile developers face when writing tests and explains how to use key features covered on this page, such as waiting for network events, validating elements, and comparing screenshots.