Write a synthetic test

edit

[beta] This functionality is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features. To write synthetic tests for your application, you’ll need to know basic JavaScript and Playwright syntax. The synthetics agent exposes an API for creating and running tests, including:

journey

Tests one discrete unit of functionality. Takes two parameters: a name (string) and a callback (function). See Create a journey.

step

Actions within a journey that should be completed in a specific order. Takes two parameters: a name (string) and a callback (function). See Add steps.

beforeAll

Runs a provided function once, before any journey runs. If the provided function is a promise, the runner will wait for the promise to resolve before invoking the journey. Takes one parameter: a callback (function). See Set up and remove a global state.

before

Runs a provided function before a single journey runs. Takes one parameter: a callback (function). See Set up and remove a global state.

afterAll

Runs a provided function once, after all the journey runs have completed. Takes one parameter: a callback (function). See Set up and remove a global state.

after

Runs a provided function after a single journey has completed. Takes one parameter: a callback (function). See Set up and remove a global state.

Playwright is a browser testing library developed by Microsoft. It’s reliable and fast and features a modern API that automatically waits for page elements to be ready.

Create a journey
edit

Start by creating a new file using the .journey.ts or .journey.js file extension, importing the synthetics library, and adding a new journey.

A journey tests one discrete unit of functionality. For example, logging into a website, adding something to a cart, or joining a mailing list.

The journey function takes two parameters: a name and a callback. The name helps you identify an individual journey. The callback argument is a function that encapsulates what the journey does. The callback provides access to fresh Playwright page, params, browser, and context instances.

journey('Journey name', ({ page, browser, context, params }) => {
  // Add steps here
});

name

A user-defined string to describe the journey.

page

A page object from Playwright that lets you control the browser’s current page.

browser

A browser object created by Playwright.

context

A browser context that doesn’t share cookies or cache with other browser contexts.

params

User-defined variables that allow you to invoke the Synthetics suite with custom parameters. For example, if you want to use a different homepage depending on the env (localhost for dev and a URL for prod). See Working with parameters and secrets for more information.

Add steps
edit

A journey consists of one or more steps. Steps are actions that should be completed in a specific order. Steps are displayed individually in the Uptime app along with screenshots for convenient debugging and error tracking.

A basic two-step journey would look like this:

journey('Journey name', ({ page, browser, client, params }) => {
    step('Step 1 name', () => {
      // Do something here
    });
    step('Step 2 name', () => {
      // Do something else here
    });
});

Steps can be as simple or complex as you need them to be. For example, a basic first step might load a web page:

step('Load the demo page', () => {
  await page.goto('https://elastic.github.io/synthetics-demo/'); 
});

See the page.goto reference for more information.

A more complex step might wait for a page element to be selected and then make sure that it matches an expected value.

For example, on a page using the following HTML:

<header class="header">
  <h1>todos</h1>
  <input class="new-todo"
    autofocus autocomplete="off"
    placeholder="What needs to be done?">
</header>

You can verify that the input element with class new-todo has the expected placeholder value (the hint text for input elements) with the following test:

step('Assert placeholder text', async () => {
  const placeholderValue = await page.getAttribute(
      'input.new-todo',
      'placeholder'
  ); 
  expect(placeholderValue).toBe('What needs to be done?'); 
});

Find the input element with class new-todo and get the value of the placeholder attribute. See the page.getAttribute reference for more information.

Use the assertion library provided by the Synthetics agent to look for the expected value. See Jest expect docs for more information.

Set up and remove a global state
edit

If there are any actions that should be done before or after journeys, you can use before, beforeAll, after, or afterAll.

To set up global state or a server that will be used for a single journey, for example, use a before hook. To perform this setup once before all journeys, use a beforeAll hook.

before(({ params }) => {
  // Actions to take
});

beforeAll(({ params }) => {
  // Actions to take
});

You can clean up global state or close a server used for a single journey using an after hook. To perform this cleanup once after all journeys, use an afterAll hook.

after(({ params }) => {
  // Actions to take
});

afterAll(({ params }) => {
  // Actions to take
});
Sample synthetic test
edit

A complete example of a basic synthetic test looks like this:

import { journey, step, expect } from '@elastic/synthetics';

journey('Ensure placeholder is correct', ({ page }) => {
  step('Load the demo page', async () => {
    await page.goto('https://elastic.github.io/synthetics-demo/');
  });
  step('Assert placeholder text', async () => {
    const placeholderValue = await page.getAttribute(
      'input.new-todo',
      'placeholder'
    );
    expect(placeholderValue).toBe('What needs to be done?');
  });
});