Cross-document messages
Interact with the virtual device via a Javascript post-message API
Cross-document messages API is no longer receiving updates.
Please use our Javascript SDK for any new development.
Cross-document messaging, when enabled via the &xdocMsg=true query parameter, allows you to issue commands to the embedded iFrame via Javascript via postMessage(message, targetOrigin).
Messages without any parameters can be passed directly as strings, e.g.
postMessage('requestSession', '*')Messages with parameters should be passed as objects with the message name in the type field. E.g.
postMessage({ type: 'mouseclick', x: 100, y:100 }, '*')Sendable Messages
requestSession
Equivalent to clicking play
postMessage('requestSession', '*')emitHomeButton
Taps the home button for iOS apps when available
postMessage('emitHomeButton', '*')rotateLeft
Rotates counter-clockwise
postMessage('rotateLeft', '*')rotateRight
Rotates clockwise
postMessage('rotateRight', '*')setScale
Sets device scale to a value between 10 and 100
postMessage({ type: 'setScale', value: 50 })saveScreenshot
Prompts user to download screenshot
postMessage('saveScreenshot', '*')getScreenshot
Sends screenshot data directly to parent window. See the screenshot event the iFrame posts to the parent.
postMessage('getScreenshot', '*')heartbeat
Sends heartbeat to prevent inactivity timeout
postMessage('heartbeat', '*')mouseclick
Sends click event at the provided coordinates
postMessage({ type: 'mouseclick', x: 100, y:100 }, '*')pasteText
Pastes the provided text
postMessage({ type: 'pasteText', value: 'Hello World' }, '*')keypress
Sends keypress. key should be a string that identifies the key pressed, e.g. 'a'. Acceptable values on Android also include 'volumeUp' and 'volumeDown'.
postMessage({ type: 'keypress', key: 'a', shiftKey: true }, '*') // would send 'A"language
Sets language, restarts app
postMessage({ type: 'language', value: 'fr' }, '*')location
Sets location. value should be 2-length array that contains [latitude, longitude]
postMessage({ type: 'location', value: [50.0, -100.0] }, '*')url
Opens deep-link or regular URL in Safari
postMessage({ type: 'url', value: 'https://appetize.io' }, '*')shakeDevice
Send shake gesture to iOS apps
postMessage('shakeDevice', '*')androidKeycodeMenu
Sends Android KEYCODE_MENU command
postMessage('androidKeycodeMenu', '*')adbShellCommand
Executes an adb shell command on an Android device.
If a session is already running the command will be executed immediately. If the session has not been started, the command will execute upon start.
postMessage({
type: 'adbShellCommand',
value: 'am start -a android.intent.action.VIEW -d https://appetize.io/'
}, '*')biometryMatch
(Android 8+ only) simulate a matching fingerprint
postMessage('biometryMatch', '*')biometryNonMatch
(Android 8+ only) simulate a non-matching fingerprint
postMessage('biometryNonMatch', '*')disableInteractions
Disables all user interactions
postMessage('disableInteractions', '*')enableInteractions
Re-enables all user interactions
postMessage('enableInteractions', '*')restartApp
Kills and restarts app in same session
postMessage('restartApp', '*')endSession
Ends the session
postMessage('endSession', '*')Receivable Messages
The iFrame also posts messages to the parent window via message event. You can listen for them with an event handler on the window:
window.addEventListener('message', (event) => {
const type = typeof event.data === 'string' ? event.data : event.data.type
console.log(type)
})userInteractionReceived
Session has received an interaction from the user
{
data: {
type: "userInteractionReceived",
value: {
altKey: boolean,
shiftKey: boolean,
timeStamp: number,
type: string,
xPos: number,
yPost: number
}
}
}heartbeatReceived
Heartbeat event received
{
data: "heartbeatReceived"
}orientationChanged
Device orientation has changed
{
data: {
type: "orientationChanged",
value: "landscape" | "portrait"
}
}sessionRequested
Session has been requested
{
data: "sessionRequested"
}userError
An error occurred while starting session
{
data: {
type: "userError",
value: string // error message
}
}sessionQueued
You have entered a system-level queue (awaiting device availability)
{
data: "sessionQueued"
}sessionQueuedPosition
Position of session queue
{
data: {
type: "sessionQueuedPosition",
position: number
}
}accountQueued
You have entered an account-level queue (concurrent users)
{
data: "accountQueued"
}accountQueuedPosition
Account queue position
{
data: {
type: "accountQueuedPosition",
position: number
}
}appLaunch
App launch command sent
{
data: "appLaunch"
}firstFrameReceived
First frame received
{
data: "firstFrameReceived"
}timeoutWarning
Session is about to timeout in 10 seconds
{
data: "timeoutWarning"
}sessionEnded
Session has ended
{
data: "sessionEnded"
}screenshot
Screenshot data received
{
data: {
type: "screenshot",
data: string // base64 encoded image data
}
}sessionConnecting
Passes the identifying token for the session
{
data: {
type: "sessionConnecting",
token: string,
path: string
}
}chromeDevToolsUrl
URL to view dev tools for the device (only if network intercept enabled)
{
data: {
type: "chromeDevToolsUrl",
value: string
}
}interceptResponse
Intercepted network response.
This is only emitted if network intercept enabled (proxy=intercept query param)
{
data: {
type: "interceptResponse",
value: {
cache: object
request: {
bodySize: number
cookies: Array<{ name: string, value: string }>
headers: Array<{ name: string, value: string }>
headersSize: number
httpVersion: string
method: string
queryString: Array<{ name: string, value: string }>
url: string
}
requestId: string
serverIPAddress: string
}
}
}interceptRequest
Intercepted network request.
This is only emitted if network intercept enabled (proxy=intercept query param)
{
data: {
type: "interceptRequest",
value: {
cache: object
request: {
bodySize: number
cookies: Array<{ name: string, value: string }>
headers: Array<{ name: string, value: string }>
headersSize: number
httpVersion: string
method: string
queryString: Array<{ name: string, value: string }>
url: string
}
requestId: string
serverIPAddress: string
}
}
}debug
Logged messages from the device.
This is only emitted if debug log is enabled (debug=true query param)
{
data: {
type: "debug",
value: string
}
}deviceDimensions
The dimensions of the current device. If the screenOnly query param is true, the dimensions will be for the screen.
{
data: {
type: "deviceDimensions",
value: {
width: number,
height: number
}
}
}app
Information for the application
{
data: {
type: "app",
value: {
name: "Example",
appDisplayName: "Example",
bundle: "com.example.app",
publicKey: "p7nww3n6ubq73r1nh9jtauqy8w",
platform: "ios"
}
}
}Check out our JSFiddle.net example to see these messages in action!
Last updated