-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update to the browser testing recipe to use jsdom directly
- Loading branch information
1 parent
52b2270
commit 2d3f394
Showing
1 changed file
with
25 additions
and
65 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,82 +1,42 @@ | ||
# Setting up AVA for browser testing | ||
|
||
Translations: [Español](https://github.com/avajs/ava-docs/blob/main/es_ES/docs/recipes/browser-testing.md), [Français](https://github.com/avajs/ava-docs/blob/main/fr_FR/docs/recipes/browser-testing.md), [Italiano](https://github.com/avajs/ava-docs/blob/main/it_IT/docs/recipes/browser-testing.md), [Русский](https://github.com/avajs/ava-docs/blob/main/ru_RU/docs/recipes/browser-testing.md), [简体中文](https://github.com/avajs/ava-docs/blob/main/zh_CN/docs/recipes/browser-testing.md) | ||
AVA is running in a __Node.js__ environment. JavaScript that runs in a browser will likely expect the browser DOM globals to be in place. | ||
With help from a package called [jsdom](https://github.com/jsdom/jsdom), | ||
you can write unit tests with `ava` also for JavaScript that will run in a browser | ||
and relying on browser specific globals such as `window`, `document` and `navigator`. | ||
|
||
AVA does not support running tests in browsers [yet](https://github.com/avajs/ava/issues/24). However JavaScript libraries that require browser specific globals (`window`, `document`, `navigator`, etc) can still be tested with AVA by mocking these globals. | ||
## Install jsdom | ||
|
||
This recipe works for any library that needs a mocked browser environment. | ||
|
||
## Install browser-env | ||
|
||
> **❗️ Important note** | ||
> | ||
>`browser-env` adds properties from the `jsdom` window namespace to the Node.js global namespace. This is explicitly [recommended against](https://github.com/tmpvar/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global) by `jsdom`. Please read through the linked wiki page and make sure you understand the caveats. If you don't have lots of dependencies that also require a browser environment then [`window`](https://github.com/lukechilds/window#universal-testing-pattern) may be a better solution. | ||
Install [browser-env](https://github.com/lukechilds/browser-env). | ||
|
||
> Simulates a global browser environment using jsdom. | ||
``` | ||
$ npm install --save-dev browser-env | ||
```bash | ||
npm install --save-dev jsdom | ||
``` | ||
|
||
## Setup browser-env | ||
|
||
Create a helper file, prefixed with an underscore. This ensures AVA does not treat it as a test. | ||
## Writing unit tests | ||
|
||
`test/_setup-browser-env.js`: | ||
Use `jsdom` to set the globals and the DOM elements that the test target is expecting. | ||
|
||
```js | ||
import browserEnv from 'browser-env'; | ||
browserEnv(); | ||
``` | ||
|
||
By default, `browser-env` will add all global browser variables to the Node.js global scope, creating a full browser environment. This should have good compatibility with most front-end libraries, however, it's generally not a good idea to create lots of global variables if you don't need to. If you know exactly which browser globals you need, you can pass an array of them. | ||
### An example Unit Test | ||
The JavaScript code to be tested is doing a DOM query, such as: `document.querySelector('#my-element-id')`. | ||
|
||
```js | ||
import browserEnv from 'browser-env'; | ||
browserEnv(['window', 'document', 'navigator']); | ||
``` | ||
|
||
You can expose more global variables by assigning them to the `global` object. For instance, jQuery is typically available through the `$` variable: | ||
|
||
```js | ||
import browserEnv from 'browser-env'; | ||
import jQuery from 'jquery'; | ||
|
||
browserEnv(); | ||
global.$ = jQuery(window); | ||
``` | ||
|
||
## Configure tests to use browser-env | ||
|
||
Configure AVA to `require` the helper before every test file. | ||
|
||
**`package.json`:** | ||
|
||
```json | ||
{ | ||
"ava": { | ||
"require": [ | ||
"./test/_setup-browser-env.js" | ||
] | ||
} | ||
} | ||
``` | ||
|
||
## Enjoy! | ||
|
||
Write your tests and enjoy a mocked browser environment. | ||
|
||
`test.js`: | ||
To make the code testable with `ava`, add the element to `jsdom` and set the global object. | ||
|
||
```js | ||
import test from 'ava'; | ||
import { JSDOM } from 'jsdom'; | ||
|
||
test('Insert to DOM', t => { | ||
const div = document.createElement('div'); | ||
document.body.appendChild(div); | ||
test.before(() => { | ||
const dom = new JSDOM('<div id="my-element-id" />'); // insert any html needed for the unit test suite here | ||
global.document = dom.window.document; // add the globals needed for the unit tests in this suite. | ||
}); | ||
|
||
test('this is an example', (t) => { | ||
const res = myTarget.runFunctionThatExpectsTheDocumentGlobalAndElement(); | ||
|
||
t.is(document.querySelector('div'), div); | ||
t.truthy(res); | ||
}); | ||
``` | ||
|
||
## Important note | ||
In general, adding globals to the `Node.js` environment is [recommended against](https://github.com/jsdom/jsdom/wiki/Don't-stuff-jsdom-globals-onto-the-Node-global) by `jsdom`. | ||
Please read through the linked wiki page and make sure you understand why. |