Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add playwright e2e testing docs #31974

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
148 changes: 146 additions & 2 deletions docs/tutorial/automated-testing.md
Expand Up @@ -58,8 +58,6 @@ To run your tests:
$ npx wdio run wdio.conf.js
```

[chrome-driver]: https://sites.google.com/chromium.org/driver/

### With Selenium

[Selenium](https://www.selenium.dev/) is a web automation framework that
Expand Down Expand Up @@ -116,6 +114,142 @@ driver.wait(() => {
driver.quit()
```

## Using Playwright

[Microsoft Playwright](https://playwright.dev) is an end-to-end testing framework built
using browser-specific remote debugging protocols, similar to the [Puppeteer] headless
Node.js API but geared towards end-to-end testing. Playwright has experimental Electron
support via Electron's support for the [Chrome DevTools Protocol] (CDP).

### Install dependencies

You can install Playwright through your preferred Node.js package manager. The Playwright team
recommends using the `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` environment variable to avoid
unnecessary browser downloads when testing an Electron app.

```sh npm2yarn
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm install --save-dev playwright
```

Playwright also comes with its own test runner, Playwright Test, which is built for end-to-end
testing. You can also install it as a dev dependency in your project:

```sh npm2yarn
npm install --save-dev @playwright/test
```

:::caution Dependencies
This tutorial was written `playwright@1.16.3` and `@playwright/test@1.16.3`. Check out
[Playwright's releases][playwright-releases] page to learn about
changes that might affect the code below.
:::

:::info Using third-party test runners
If you're interested in using an alternative test runner (e.g. Jest or Mocha), check out
Playwright's [Third-Party Test Runner][playwright-test-runners] guide.
:::

### Write your tests

Playwright launches your app in development mode through the `_electron.launch` API.
To point this API to your Electron app, you can pass the path to your main process
entry point (here, it is `main.js`).

```js {5}
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')

test('launch app', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
// close app
await electronApp.close()
})
```

After that, you will access to an instance of Playwright's `ElectronApp` class. This
is a powerful class that has access to main process modules for example:

```js {6-11}
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')

test('get isPackaged', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
const isPackaged = await electronApp.evaluate(async ({ app }) => {
// This runs in Electron's main process, parameter here is always
// the result of the require('electron') in the main app script.
return app.isPackaged
})
console.log(isPackaged) // false (because we're in development mode)
// close app
await electronApp.close()
})
```

It can also create individual [Page][playwright-page] objects from Electron BrowserWindow instances.
For example, to grab the first BrowserWindow and save a screenshot:

```js {6-7}
const { _electron: electron } = require('playwright')
const { test } = require('@playwright/test')

test('save screenshot', async () => {
const electronApp = await electron.launch({ args: ['main.js'] })
const window = await electronApp.firstWindow()
await window.screenshot({ path: 'intro.png' })
// close app
await electronApp.close()
})
```

Putting all this together using the PlayWright Test runner, let's create a `example.spec.js`
test file with a single test and assertion:

```js title='example.spec.js'
const { _electron: electron } = require('playwright')
const { test, expect } = require('@playwright/test')

test('example test', async () => {
const electronApp = await electron.launch({ args: ['.'] })
const isPackaged = await electronApp.evaluate(async ({ app }) => {
// This runs in Electron's main process, parameter here is always
// the result of the require('electron') in the main app script.
return app.isPackaged;
});

expect(isPackaged).toBe(false);

// Wait for the first BrowserWindow to open
// and return its Page object
const window = await electronApp.firstWindow()
await window.screenshot({ path: 'intro.png' })

// close app
await electronApp.close()
});
```

Then, run Playwright Test using `npx playwright test`. You should see the test pass in your
console, and have an `intro.png` screenshot on your filesystem.

```console
☁ $ npx playwright test

Running 1 test using 1 worker

✓ example.spec.js:4:1 › example test (1s)
```

:::info
Playwright Test will automatically run any files matching the `.*(test|spec)\.(js|ts|mjs)` regex.
You can customize this match in the [Playwright Test configuration options][playwright-test-config].
:::

:::tip Further reading
Check out Playwright's documentation for the full [Electron][playwright-electron]
and [ElectronApplication][playwright-electronapplication] class APIs.
:::

## Using a custom test driver

It's also possible to write your own custom driver using Node.js' built-in IPC-over-STDIO.
Expand Down Expand Up @@ -263,3 +397,13 @@ test.after.always('cleanup', async t => {
await app.stop()
})
```

[chrome-driver]: https://sites.google.com/chromium.org/driver/
[Puppeteer]: https://github.com/puppeteer/puppeteer
[playwright-electron]: https://playwright.dev/docs/api/class-electron/
[playwright-electronapplication]: https://playwright.dev/docs/api/class-electronapplication
[playwright-page]: https://playwright.dev/docs/api/class-page
[playwright-releases]: https://github.com/microsoft/playwright/releases
[playwright-test-config]: https://playwright.dev/docs/api/class-testconfig#test-config-test-match
[playwright-test-runners]: https://playwright.dev/docs/test-runners/
[Chrome DevTools Protocol]: https://chromedevtools.github.io/devtools-protocol/