This guide will get you all set up and ready to use Selectify. We'll cover how to get started using one of our SDKs and how to integrate your first selector prediction.

Choose your client

Before making your first API request, you need to pick which API client you will use. We maintain official helper libraries for Cypress and Playwright that cover the most common headless browser deployments. If you're using another library (or not a headless browser at all) you can use our Node tutorial to see how to interact with API endpoints manually.

# Install the Selectify JavaScript SDK
npm install @selectify/client --save

# If you're using Node greater than v17.5.0, you likely already have experimental
# fetch support through --experimental-fetch
# Otherwise you'll need to install node-fetch manually
npm install node-fetch --save

Configure your API Key

Selectify relies on the SELECTIFY_API_KEY environment variable to authorize to the server. You can either export this within your Terminal or set up a .env file to store it alongside your tests. For this tutorial we'll use an .env file:

# .env

Integrate with your runner

Now that you've installed Selectify's dependencies, it's time to integrate with your project. These instructions vary a bit depending on the specifics of your testing harness configuration. We cover the most common cases here.


Since we'll be writing our Node code from scratch, we set up our auth flow and common functions that will make our pipeline cleaner later one.

// pipeline.js
import dotenv from 'dotenv';

import { Session, createPageState, upsertResource, getSelector } from '@selectify/client';

Capture session resources

For Selectify to replay your session as you see it, it needs to be aware of the different resources that are being requested and returned to your browser. These resources include files like stylesheets, scripts, and images. We have some convenience hooks for this purpose that should be added to your script lifecycle before tests start running.

Most headless browsers based on Webkit (Safari) or Chromium (Chrome, Chromium) support request interception, which is what these hooks use internally. If you're implementing support for another headless browser you'll want to look at the specifics for how it intercepts requests and responses.

If you're making raw HTML queries like with fetch or requests and don't receive the resource payloads, Selectify can also retrieve them for you. This lets you review a page visually even if you just upload raw text.

// Either install browser hooks if you're rendering headfull
// Or you can retrieve explicit dependencies if you know they exist
const retrieveStylesheet = async (session) => {
  const dependencyUrl = 'https://example.com/styles.css';
  const response = await fetch(dependencyUrl)
  const body = await response.text()

  return await upsertResource(
      payload: {
        url: dependencyUrl,
        content: body.toString('base64'),
        contentType: 'stylesheet',
        resourceType: 'stylesheet',

Starting a session

A Selectify session wraps one given user journey. Typically, one integration test is one session. You'll usually want a session to test for the same (or similar) thing over time so you can scan through to see how behavior changes.

const runPipeline = async () => {
  const session = new Session({ workflowName: 'YOUR_PROJECT'});
  await session.start();

  const pageUrl = 'https://example.com';
  const response = await fetch(pageUrl)
  const html = await response.text()


  await session.stop();

Finding your stable selector

So far, this is a pretty common test setup. Now we get to the good part - actually using Selectify to find elements on the page. And once you set this up, you're never going to have to tweak these selectors every time your webapp changes.

const runPipeline = async () => {
  const session = new Session({ workflowName: 'YOUR_PROJECT'});
  await session.start();

  const pageUrl = 'https://example.com';
  const response = await fetch(pageUrl)
  const html = await response.text()

  const stylesheetResource = await retrieveStylesheet(session);

  const pageState = await createPageState({

  const selector = await getSelector({
      description: 'Learn more about this domain'

  // Echo the xpaths that Selectify found

  await session.stop();

At this point you have your selectors of interest. If you're using one of our libraries, the selectors will be returned as native elements. Playwright returns a list of locators, Cypress returns a list of elements, etc. If you're interacting with the raw return payload, you can also use the selectedXpaths to find the elements via XPath.

Extend this code to cover as many selectors as you'd like within your session.

What's next?

Now that your code is integrated, head over to the Console to view your page archives, selectors, and more. Also check out our more detailed API documentation if you're working on an implementation that our libraries don't cover out of the box. We'd love to hear about what you're up to.