> For the complete documentation index, see [llms.txt](https://docs.stoobly.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.stoobly.com/guides/how-to-integrate-e2e-testing.md).

# How to Integrate E2E Testing

Use the scaffold command to greatly simplify integrating E2E testing!

## Background

{% content-ref url="/pages/hvGjzhgu6l2Nw4iB48E6" %}
[Scaffold](/core-concepts/scaffold.md)
{% endcontent-ref %}

## Getting Started

Create a declarative scaffold config at **`.stoobly/scaffold.yml`**. This file maps 1:1 to scaffold CLI commands and can be applied, shared, and version-controlled:

```yaml
# .stoobly/scaffold.yml
version: 1
commands:
  - resource: app
    action: create
    options:
      app_name: <APP-NAME>
      # For E2E testing, add plugin: [playwright] or plugin: [cypress]
      plugin: [playwright]

  - resource: service
    action: create
    options:
      service_name: <SERVICE-NAME>
      hostname: <SERVICE-HOSTNAME>
      scheme: <SERVICE-SCHEME>
      port: <SERVICE-PORT>
```

Then validate and apply the config:

```bash
stoobly-agent scaffold apply .stoobly/scaffold.yml --dry-run
stoobly-agent scaffold apply .stoobly/scaffold.yml
```

{% hint style="info" %}
**Recommended:** For E2E testing, include `plugin: [playwright]` or `plugin: [cypress]` in the app step. This sets up the necessary configuration files and dependencies for your chosen test framework.
{% endhint %}

To learn about each individual command:

`app create`

{% content-ref url="/pages/tP6ceRL955iEhJFFSO2W" %}
[How to Scaffold an App](/guides/how-to-integrate-e2e-testing/how-to-scaffold-an-app.md)
{% endcontent-ref %}

`service create`

{% content-ref url="/pages/BKCC6lKg9jOIW8EYkhK8" %}
[Scaffolding a Service](/guides/how-to-integrate-e2e-testing/how-to-scaffold-an-app/scaffolding-a-service.md)
{% endcontent-ref %}

`scaffold apply`

{% content-ref url="/pages/IsP4sqSmIxdC4r86BS5O" %}
[Applying a Scaffold Config](/guides/how-to-integrate-e2e-testing/how-to-scaffold-an-app/applying-a-scaffold-config.md)
{% endcontent-ref %}

### Example

```yaml
# .stoobly/scaffold.yml
version: 1
commands:
  - resource: app
    action: create
    options:
      app_name: stoobly
      plugin: [playwright]

  - resource: service
    action: create
    options:
      service_name: docs.stoobly.com
      hostname: docs.stoobly.com
      scheme: https
      port: 443
```

```bash
stoobly-agent scaffold apply .stoobly/scaffold.yml --dry-run
stoobly-agent scaffold apply .stoobly/scaffold.yml
```

{% hint style="info" %}
For Cypress, use `plugin: [cypress]` instead. You can also use both: `plugin: [playwright, cypress]`
{% endhint %}

## Using the JavaScript Client Library

{% hint style="info" %}
**Recommended:** Use the Stoobly JavaScript client library (`stoobly`) to integrate Stoobly directly into your Playwright or Cypress tests. This approach provides programmatic control over recording, mocking, and scenario management from within your test code.
{% endhint %}

The JavaScript client library simplifies E2E testing by allowing you to:

* **Intercept requests automatically** from Playwright or Cypress without manual proxy configuration
* **Control recording and mocking** directly in your test code
* **Manage scenarios** programmatically (create, switch, and manage test scenarios)
* **Configure URL filtering** to specify which requests to intercept

**Quick Start:**

1. Install the library:

```bash
npm install stoobly --save-dev
```

2. Use the interceptor in your tests:

```typescript
import Stoobly from 'stoobly';

const stoobly = new Stoobly();
const interceptor = stoobly.playwrightInterceptor({
  urls: [new RegExp('https://api.example.com/.*')],
});

test.beforeEach(async ({ page }) => {
  interceptor.withPage(page);
  await interceptor.enable();
});
```

For complete documentation on using the JavaScript client library:

{% content-ref url="/pages/hDDc1Xebqnzg9NR2Z6uG" %}
[JS Client](/faq/scaffold/e2e-testing/js-client.md)
{% endcontent-ref %}

Check in `.stoobly/scaffold.yml` to version control so you can re-apply or update the scaffold later. To learn more:

{% content-ref url="/pages/33Q0OfLXlzbByHH9QvmZ" %}
[How to Update a Scaffold](/guides/how-to-integrate-e2e-testing/how-to-update-a-scaffold.md)
{% endcontent-ref %}

## Next Steps

### Save the app scaffold in version control

Check in `.stoobly/scaffold.yml`, the app, and all of its services into your version control such as Git.

### Run workflows in the following order

First, to run a workflow:

{% content-ref url="/pages/7J10qWFxe9zweKA3YQtH" %}
[How to Run a Workflow](/guides/how-to-integrate-e2e-testing/how-to-run-a-workflow.md)
{% endcontent-ref %}

Before running another workflow, it is recommended to stop the current workflow:

{% content-ref url="/pages/W4Tm0VSz4ZZ0HPVz4vtR" %}
[How to Stop a Workflow](/guides/how-to-integrate-e2e-testing/how-to-stop-a-workflow.md)
{% endcontent-ref %}

{% stepper %}
{% step %}

#### Run record workflow

This allows you to check if all your scaffolded services run and can record requests.
{% endstep %}

{% step %}

#### Run mock workflow

This allows you to check if the previously recorded requests are mocked. Your E2E tests or app should now be able to send requests to the mocked services.
{% endstep %}

{% step %}

#### Run test workflow

Finally, add a command to run the E2E tests to the `entrypoint` service as part of its custom docker compose file. Next, run the `test` workflow to check if tests pass locally. Once the `test` workflow passes, you can now use it in your CI pipelines.
{% endstep %}
{% endstepper %}
