Skip to content

JavaScript Recipes

These recipes use the globals available in Repeato Script steps and Advanced configuration. See the JavaScript API reference for every available property and method.

Use a Script step for logic that belongs inside a test, such as branching, entering generated data, querying the current screen, or calling an API.

Use Advanced configuration for lifecycle hooks and batch-wide behavior, such as creating reports, collecting device logs, or reacting to failed tests. Register each listener with a stable key so it replaces the same logical configuration and can be removed later.

Add this to a Script step after an optional assertion. Replace the step ID with the destination in your test.

if (!testRunner.lastStepResult.success) {
testRunner.setNextStepId('AH23D6')
}

Step IDs may be abbreviated as long as the supplied prefix identifies the intended step.

Store values on data in one Script step:

data.email = `tester-${Date.now()}@example.com`
await deviceConnector.sendString(data.email)

Read the value from a later Script step in the same test run:

log(`Continuing with ${data.email}`)

Touch coordinates are normalized from 0 to 1. This example drags vertically from 80% to 20% of the screen height through its horizontal center.

await deviceConnector.sendDown(0.5, 0.8)
await deviceConnector.sendMove(0.5, 0.5)
await deviceConnector.sendMove(0.5, 0.2)
await deviceConnector.sendUp(0.5, 0.2)

Always finish a gesture started with sendDown() by calling sendUp().

ADB commands work only with local Android devices and emulators. Cloud devices do not support them.

if (deviceConnector.selectedDeviceData.os === 'android') {
const output = await deviceConnector.sendAdbCommand('shell dumpsys battery')
log(output)
}

Use IDB for a connected iOS device or simulator:

if (deviceConnector.selectedDeviceData.os === 'ios') {
const output = await deviceConnector.sendIdbCommand('list-targets')
log(output)
}
await deviceConnector.setClipboard('Copied by Repeato')
const clipboardContent = await deviceConnector.getClipboard()
log(clipboardContent)

Clipboard support depends on the selected device type and its active connector.

Query the complete screen:

const answer = await deviceConnector.vision(
'Return the number displayed in the shopping cart as digits only.',
)
log(answer)

Limit analysis to a normalized region of the screen when the relevant area is known:

const answer = await deviceConnector.vision('Is the status indicator green?', {
x: 0.7,
y: 0,
width: 0.3,
height: 0.2,
})
log(answer)

Axios is available as a global, so no import is required.

const response = await axios.post(
'https://api.example.com/test-events',
{
testId: testRunner.currentTest.id,
successful: testRunner.currentTestRun.wasSuccessful,
},
{
headers: {
Authorization: `Bearer ${process.env.TEST_API_TOKEN}`,
},
},
)
log(`API response: ${response.status}`)

Keep credentials in environment variables or workspace-local files that are excluded from version control. Do not place secrets directly in test scripts.

Add this to Advanced configuration:

let logBuffer = []
deviceConnector.addOnDeviceLog('report-device-log', logEntry => {
logBuffer.push(logEntry)
})
testRunner.addOnStepCompleted('report-device-log', stepResult => {
if (logBuffer.length > 0) {
stepResult.setMessage(`${stepResult.message}\n${logBuffer.join('\n')}`)
}
logBuffer = []
})

Use the same key when removing these listeners:

testRunner.removeOnStepCompleted('report-device-log')

Add this to Advanced configuration. The callback runs after each batch, creates a local report, and uploads it to the optional Repeato cloud report service.

batchRunner.addOnBatchCompleted('upload-report', async batchRun => {
const reportPath = await batchRunner.createBatchRunExport()
const reportUrl = await batchRunner.uploadReport(reportPath)
log({
successful: batchRun.wasSuccessful,
reportPath,
reportUrl,
})
})

Local report generation does not require the cloud upload step.

audioTools.say('Starting the audio check')
const recordingUrl = await audioTools.recordAudio(5000)
await audioTools.playAudio(recordingUrl)

recordAudio() requires microphone access and resolves with a temporary object URL after the requested duration.

EN