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

feat: webdriverio (+ custom providers) integration for browser mode #2999

Merged
merged 70 commits into from Mar 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
23d8915
init
Aslemammad Mar 8, 2023
98432c4
update test
Aslemammad Mar 8, 2023
11bb786
update
Aslemammad Mar 8, 2023
718c2eb
fix run mode
Aslemammad Mar 8, 2023
e480d9a
fix run mode
Aslemammad Mar 10, 2023
f413000
update options
Aslemammad Mar 10, 2023
5950cb0
fix nextTick
Aslemammad Mar 12, 2023
7796933
remove runMode and add isCI instead of process.env.CI
Aslemammad Mar 12, 2023
d357950
remove browser in inverting
Aslemammad Mar 12, 2023
e840307
update modern-node-polyfills
Aslemammad Mar 12, 2023
30050b4
?? instead of ||
Aslemammad Mar 12, 2023
d803fba
shouldKeepServer instead of explicit conditions
Aslemammad Mar 12, 2023
4dc4839
add test
Aslemammad Mar 16, 2023
7cda620
add ci
Aslemammad Mar 16, 2023
eb7a8b1
update
Aslemammad Mar 16, 2023
54c6215
update
Aslemammad Mar 16, 2023
dfb0014
update
Aslemammad Mar 16, 2023
f96aead
add edge to types
Aslemammad Mar 16, 2023
78341d9
update
Aslemammad Mar 16, 2023
4512b64
enable
Aslemammad Mar 16, 2023
77d37a9
update
Aslemammad Mar 16, 2023
6d922ba
check safaridriver
Aslemammad Mar 17, 2023
c7fe5e7
update (from macos)
Aslemammad Mar 17, 2023
1bbb22f
update (from macos)
Aslemammad Mar 17, 2023
aaae97f
update (from macos)
Aslemammad Mar 17, 2023
bb62d21
update (from macos)
Aslemammad Mar 17, 2023
37c3c2c
update (from macos)
Aslemammad Mar 17, 2023
982e2e4
update (from macos) and enable debugging
Aslemammad Mar 17, 2023
57d40bf
update (from macos) and enable debugging
Aslemammad Mar 17, 2023
e7361e9
update
Aslemammad Mar 17, 2023
1625970
update
Aslemammad Mar 17, 2023
e079807
update with sudo
Aslemammad Mar 17, 2023
37b3e18
lint fix
Aslemammad Mar 17, 2023
ba6f870
more unified isForSafari
Aslemammad Mar 17, 2023
d257d3d
shouldStartBrowser
Aslemammad Mar 17, 2023
39c8103
attempt to add some docs
Aslemammad Mar 17, 2023
ed1919d
fix some docs
Aslemammad Mar 17, 2023
ef7e653
move shouldKeepServer
Aslemammad Mar 17, 2023
160ea27
move shouldKeepServer
Aslemammad Mar 17, 2023
2d0036c
follow the interface pattern
Aslemammad Mar 17, 2023
848bd43
follow the interface pattern
Aslemammad Mar 17, 2023
7046137
Update docs/guide/browser.md
Aslemammad Mar 17, 2023
dc64374
Update docs/guide/browser.md
Aslemammad Mar 17, 2023
9ffa373
Update docs/guide/browser.md
Aslemammad Mar 17, 2023
fea8fdd
Update docs/guide/browser.md
Aslemammad Mar 17, 2023
005b7e4
docs fix
Aslemammad Mar 17, 2023
ea47f34
feat: add option to customize browser provider and options
sheremet-va Mar 18, 2023
7e6b965
chore: cleanup
sheremet-va Mar 18, 2023
f7d81be
chore: cleanup
sheremet-va Mar 18, 2023
abb2142
refactor: add support for "isolate" flag in browser tests
sheremet-va Mar 18, 2023
f084de8
chore: run browser copy script on root build
userquin Mar 18, 2023
fc624ea
chore: prevent reloading page when running with ui
userquin Mar 18, 2023
cf41f47
Apply suggestions from code review
sheremet-va Mar 18, 2023
9bd41b4
Update packages/vitest/src/node/cli.ts
sheremet-va Mar 18, 2023
237fc60
refactor: always use provider for browser tests, auto detect browser
sheremet-va Mar 18, 2023
6d2cbef
chore: remove if browser checks
sheremet-va Mar 18, 2023
7671d5c
chore: cleanup
sheremet-va Mar 18, 2023
5426417
refactor: move browser pool initialization
sheremet-va Mar 18, 2023
87441b8
fix: watch mode works with browser
sheremet-va Mar 18, 2023
aaee7a8
refactor: browser options is not an object, run browser using separat…
sheremet-va Mar 19, 2023
3a883fd
chore: cleanup
sheremet-va Mar 19, 2023
7c395fa
chore: cleanup
sheremet-va Mar 19, 2023
8e90cd7
chore: run tests headless
sheremet-va Mar 19, 2023
f335cd2
chore: add test files to entries in Vite optimizer
sheremet-va Mar 19, 2023
8379e86
chore: remove browser from mixed pool for now
sheremet-va Mar 19, 2023
3cc66a8
chore: cleanup
sheremet-va Mar 19, 2023
89e9e56
chore: don't mention url in client code, check for browser
sheremet-va Mar 19, 2023
66ee692
chore: cleanup
sheremet-va Mar 19, 2023
89f9951
chore: cleanup
sheremet-va Mar 19, 2023
5958d75
Update docs/config/index.md
sheremet-va Mar 20, 2023
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
58 changes: 58 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -101,3 +101,61 @@ jobs:

- name: Test UI
run: pnpm run ui:test

test-browser:
runs-on: ubuntu-latest
strategy:
matrix:
browser: [chrome, firefox, edge]

timeout-minutes: 10

env:
BROWSER: ${{ matrix.browser }}
steps:
- uses: actions/checkout@v3

- uses: ./.github/actions/setup-and-cache
with:
node-version: 18

- uses: browser-actions/setup-chrome@v1
- uses: browser-actions/setup-firefox@v1
- uses: browser-actions/setup-edge@v1

- name: Install
run: pnpm i

- name: Build
run: pnpm run build

- name: Test Browser
run: pnpm run browser:test

test-browser-safari:
runs-on: macos-latest
timeout-minutes: 10

env:
BROWSER: safari
steps:
- uses: actions/checkout@v3

- uses: ./.github/actions/setup-and-cache
with:
node-version: 18

- name: Info
run: system_profiler SPSoftwareDataType

- name: Install
run: pnpm i

- name: Build
run: pnpm run build

- name: Enable
run: sudo safaridriver --enable

- name: Test Browser
run: sudo pnpm run browser:test
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -16,6 +16,7 @@ ltex*
.DS_Store
bench/test/*/*/
**/benchmark/bench.json
**/browser/browser.json
cypress/videos
cypress/downloads
cypress/screenshots
Expand Down
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Expand Up @@ -175,6 +175,10 @@ export default withPwa(defineConfig({
text: 'Vitest UI',
link: '/guide/ui',
},
{
text: 'Browser Mode',
link: '/guide/browser',
},
{
text: 'In-source Testing',
link: '/guide/in-source',
Expand Down
80 changes: 78 additions & 2 deletions docs/config/index.md
Expand Up @@ -383,7 +383,7 @@ export default defineConfig({

### poolMatchGlobs

- **Type:** `[string, 'threads' | 'child_process'][]`
- **Type:** `[string, 'browser' | 'threads' | 'child_process'][]`
- **Default:** `[]`
- **Version:** Since Vitest 0.29.4

Expand All @@ -399,7 +399,9 @@ export default defineConfig({
poolMatchGlobs: [
// all tests in "worker-specific" directory will run inside a worker as if you enabled `--threads` for them,
['**/tests/worker-specific/**', 'threads'],
// all other tests will run based on "threads" option, if you didn't specify other globs
// run all tests in "browser" directory in an actual browser
['**/tests/browser/**', 'browser'],
// all other tests will run based on "browser.enabled" and "threads" options, if you didn't specify other globs
// ...
]
}
Expand Down Expand Up @@ -992,6 +994,80 @@ Open Vitest UI (WIP)

Listen to port and serve API. When set to true, the default port is 51204

### browser

- **Type:** `{ enabled?, name?, provider?, headless?, api? }`
- **Default:** `{ enabled: false, headless: process.env.CI, api: 63315 }`
- **Version:** Since Vitest 0.30.0
- **CLI:** `--browser`, `--browser=<name>`, `--browser.name=chrome --browser.headless`

Run Vitest tests in a browser. If the browser name is not specified, Vitest will try to determine your default browser automatically. We use [WebdriverIO](https://webdriver.io/) for running tests by default, but it can be configured with [browser.provider](/config/#browser-provider) option.

::: tip NOTE
Read more about testing in a real browser in the [guide page](/guide/browser).
:::

::: warning
This is an experimental feature. Breaking changes might not follow semver, please pin Vitest's version when using it.
:::

#### browser.enabled

- **Type:** `boolean`
- **Default:** `false`
- **CLI:** `--browser`, `--browser.enabled=false`

Run all tests inside a browser by default. Can be overriden with [`poolMatchGlobs`](/config/#poolmatchglobs) option.

#### browser&#46;name

- **Type:** `string`
- **Default:** _tries to find default browser automatically_
- **CLI:** `--browser=safari`

Run all tests in a specific browser. If not specified, tries to find a browser automatically.


#### browser.headless

- **Type:** `boolean`
- **Default:** `process.env.CI`
- **CLI:** `--browser.headless`, `--brower.headless=false`

Run the browser in a `headless` mode. If you are running Vitest in CI, it will be enabled by default.

#### browser.api

- **Type:** `number | { port?, strictPort?, host? }`
- **Default:** `63315`
- **CLI:** `--browser.api=63315`, `--browser.api.port=1234, --browser.api.host=example.com`

Configure options for Vite server that serves code in the browser. Does not affect [`test.api`](/config/#api) option.

#### browser.provider

- **Type:** `string`
- **Default:** `'webdriverio'`
- **CLI:** `--browser.provider=./custom-provider.ts`

Path to a provider that will be used when running browser tests. Provider should be exported using `default` export and have this shape:

```ts
export interface BrowserProvider {
initialize(ctx: Vitest): Awaitable<void>
createPool(): {
runTests: (files: string[], invalidated: string[]) => void
close: () => Awaited<void>
}
// signals that test file stopped running, if it was opened with `id=` query
testFinished?(testId: string): Awaitable<void>
}
```

::: warning
This is an advanced API for library authors. If you just need to run tests in a browser, use the [browser](/config/#browser) option.
:::

### clearMocks

- **Type:** `boolean`
Expand Down
89 changes: 89 additions & 0 deletions docs/guide/browser.md
@@ -0,0 +1,89 @@
---
title: Browser mode | Guide
---

# Browser mode (experimental)

This page provides information about the experimental browser mode feature in the Vitest API, which allows you to run your tests in the browser natively, providing access to browser globals like window and document. This feature is currently under development, and APIs may change in the future.

## Configuration

To activate browser mode in your Vitest configuration, you can use the `--browser` flag or set the `browser.enabled` field to `true` in your Vitest configuration file. Here is an example configuration using the browser field:

```ts
export default defineConfig({
test: {
browser: {
enabled: true
},
}
})
```

## Browser Option Types:

The browser option in Vitest can be set to either a boolean or a string type. If set to `true`, Vitest will try to automatically find your default browser. You can also specify a browser by providing its name as a `string`. The available browser options are:
- `firefox`
- `chrome`
- `edge`
- `safari`

Here's an example configuration setting chrome as the browser option:

```ts
export default defineConfig({
test: {
browser: {
enabled: true,
name: 'chrome',
},
}
})
```

## Cross-browser Testing:

When you specify a browser name in the browser option, Vitest will try to run the specified browser using [WebdriverIO](https://webdriver.io/) by default, and then run the tests there. This feature makes cross-browser testing easy to use and configure in environments like a CI. If you don't want to use WebdriverIO, you can configure the custom browser provider by using `browser.provider` option.

To specify a browser using the CLI, use the `--browser` flag followed by the browser name, like this:

```sh
npx vitest --browser=chrome
```

Or if you pass down several options, you dot-syntax:

```sh
npx vitest --browser.name=chrome --browser.headless
```

::: tip NOTE
When using the Safari browser option, the `safaridriver` needs to be activated by running `sudo safaridriver --enable` on your device.

Additionally, when running your tests, Vitest will attempt to install some drivers for compatibility with `safaridriver`.
:::

## Headless

Headless mode is another option available in the browser mode. In headless mode, the browser runs in the background without a user interface, which makes it useful for running automated tests. The headless option in Vitest can be set to a boolean value to enable or disable headless mode.

Here's an example configuration enabling headless mode:

```ts
export default defineConfig({
test: {
browser: {
enabled: true,
headless: true,
},
sheremet-va marked this conversation as resolved.
Show resolved Hide resolved
}
})
```

You can also set headless mode using the `--browser.headless` flag in the CLI, like this:

```sh
npx vitest --browser.name=chrome --browser.headless
```

In this case, Vitest will run in headless mode using the Chrome browser.
2 changes: 1 addition & 1 deletion docs/guide/cli.md
Expand Up @@ -84,7 +84,7 @@ Run only [benchmark](https://vitest.dev/guide/features.html#benchmarking-experim
| `--mode <name>` | Override Vite mode (default: `test`) |
| `--globals` | Inject APIs globally |
| `--dom` | Mock browser api with happy-dom |
| `--browser` | Run tests in browser |
| `--browser [options]` | Run tests in [the browser](/guide/browser) (default: `false`) |
| `--environment <env>` | Runner environment (default: `node`) |
| `--passWithNoTests` | Pass when no tests found |
| `--logHeapUsage` | Show the size of heap for each test |
Expand Down
5 changes: 3 additions & 2 deletions package.json
Expand Up @@ -7,7 +7,7 @@
"description": "A blazing fast unit test framework powered by Vite",
"scripts": {
"ci": "ni && nr typecheck && nr lint && nr build && nr test:all",
"build": "pnpm -r --filter='./packages/**' run build",
"build": "pnpm -r --filter='./packages/**' run build && pnpm -C ./packages/browser run copy",
"dev": "NODE_OPTIONS=\"--max-old-space-size=8192\" pnpm -r --parallel --filter='./packages/**' run dev",
"docs": "pnpm -C docs run dev",
"docs:build": "pnpm -C docs run build",
Expand All @@ -28,7 +28,8 @@
"typecheck:why": "tsc --noEmit --explainFiles > explainTypes.txt",
"ui:build": "vite build packages/ui",
"ui:dev": "vite packages/ui",
"ui:test": "npm -C packages/ui run test:run"
"ui:test": "npm -C packages/ui run test:run",
"browser:test": "npm -C test/browser run test"
},
"devDependencies": {
"@antfu/eslint-config": "^0.34.1",
Expand Down
7 changes: 5 additions & 2 deletions packages/browser/package.json
Expand Up @@ -24,7 +24,7 @@
"stubs"
],
"scripts": {
"build": "rimraf dist && pnpm build:node && pnpm build:client && pnpm copy",
"build": "rimraf dist && pnpm build:node && pnpm build:client",
"build:client": "vite build src/client",
"build:node": "rollup -c",
"dev:client": "vite build src/client --watch",
Expand All @@ -33,11 +33,14 @@
"copy": "esno scripts/copy-ui-to-browser.ts",
"prepublishOnly": "pnpm build"
},
"peerDependencies": {
"vitest": ">=0.30.0"
},
"dependencies": {
"@vitest/runner": "workspace:*",
"local-pkg": "^0.4.2",
"mlly": "^1.1.0",
"modern-node-polyfills": "0.0.9",
"modern-node-polyfills": "0.1.0",
"rollup-plugin-node-polyfills": "^0.2.1",
"sirv": "^2.0.2"
},
Expand Down