Setup a local dev server for your Playwright tests
Tags: playwright, testing, e2e, server
Published: 2023-03-07 08:27:45

Playwright comes with a `webserver` option in the config file which gives you the ability to launch a local dev server before running your tests. This is ideal for when writing your tests during development and when you don't have a staging or production url to test against.

When you first [create a playwright project](https://playwright.dev/docs/intro) or add playwright to your project via the [VS Code extension](https://marketplace.visualstudio.com/items?itemName=ms-playwright) you will find the `webServer` option in your config commented out. Uncomment this section or manually add it to your config in order to run your local dev server before starting the tests.


```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
  },
});
```

## Command

The `command` is the shell command to start the local dev server of your app. This can be any command that starts a local dev server. For example, for most web frameworks its `npm run start` to start the dev server.

```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
  },
});
```

## URL

The `url` property is the URL of your http server that is expected to return a 2xx, 3xx, 400, 401, 402, or 403 status code when the server is ready to accept connections. This is for example `http://127.0.0.1:3000`. Once the server is ready the test-runner will start executing the tests.

```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
  },
});
```

## Reuse existing server

If `true`, it will re-use an existing server on the url when available. If no server is running on that url, it will run the command to start a new server. If `false`, it will throw if an existing process is listening on the url. This should be set to `!process.env.CI` to allow the local dev server to reuse the existing server when running tests locally but does not use an existing server on the CI.

```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
  },
});
```

## Adding a server timeout

Webservers can sometimes take longer to boot up. In this case, you can increase the timeout to wait for the server to start.

```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
    timeout: 120 * 1000,
  },
});
```

## Adding a baseURL

It is also recommended to specify the `baseURL` in the `use: {}` section of your config, so that tests can use relative urls and you don't have to specify the full URL over and over again.

```js
import { defineConfig } from '@playwright/test';

export default defineConfig({
  // Rest of your config...

  // Run your local dev server before starting the tests
  webServer: {
    command: 'npm run start',
    url: 'http://127.0.0.1:3000',
    reuseExistingServer: !process.env.CI,
  },
  use: {
    baseURL: 'http://127.0.0.1:3000',
  },
});
```

Now you can use a relative path when navigating the page:

```js
const { test } = require('@playwright/test');

test('my test', async ({ page }) => {
  // This will navigate to http://127.0.0.1:3000/about
  await page.goto('./about');
});
```

And that's it. Now when you run your tests a local server will spin up if you haven't already started one on that url and your tests will run against your local dev server.

## Useful links
[Playwright docs](https://www.playwright.dev)
[Playwright Community discord channel](https://aka.ms/playwright/discord)
[Playwright YouTube Channel](https://www.youtube.com/channel/UC46Zj8pDH5tDosqm1gd7WTg)
[Playwright on Twitter](https://twitter.com/playwrightweb)