Skip to content

Commit b9b0ce9

Browse files
authored
Create guide page for Testing
1 parent a90332d commit b9b0ce9

1 file changed

Lines changed: 85 additions & 0 deletions

File tree

docs/_guide/testing.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
chapter: 13
3+
subtitle: Testing
4+
---
5+
6+
Catalyst controllers are based on Web Components, and as such need the Web Platform environment to run in, including in tests. It's possible to run these tests in "browser like" environments such as NodeJS or Deno with libraries like jsdom, but it's best to run tests directly in the browser.
7+
8+
### Recommended Libraries
9+
10+
We recommend using [`@web/test-runner`](https://modern-web.dev/docs/test-runner/overview/), which provides the `web-test-runner` command line tool that can run [mocha](https://mochajs.org/) test files in a headless Chromium instance. We also recommend using [`@open-wc/testing`](https://open-wc.org/docs/testing/testing-package/) which provides a set of testing functions, including `expect` from [Chai](https://www.chaijs.com/api/bdd/). If you're using TypeScript, it may be worth also installing [`@web/dev-server-esbuild`](https://modern-web.dev/docs/dev-server/overview/) which can transpile TypeScript to JavaScript, allowing the use of TypeScript within test files themselves.
11+
12+
With these installed and configured your `package.json` might look something like:
13+
14+
```json
15+
{
16+
"name": "my-catalyst-component",
17+
"scripts": {
18+
"test": "web-test-server"
19+
},
20+
"devDependencies": {
21+
"@web/dev-server-esbuild": "^0.3.0",
22+
"@web/test-runner": "^0.13.27",
23+
"@open-wc/testing": "^3.1.2"
24+
}
25+
}
26+
```
27+
28+
You can configure the `web-test-server` by writing a `web-test-runner.config.js` file, which sets up the esbuild plugin to transpile TypeScript, and configure the directory containing your test files:
29+
30+
```typescript
31+
import {esbuildPlugin} from '@web/dev-server-esbuild'
32+
33+
export default {
34+
files: ['test/*'],
35+
nodeResolve: true,
36+
plugins: [esbuildPlugin({ts: true})]
37+
}
38+
```
39+
40+
#### Example Test File
41+
42+
With this set-up, the boilerplate for an Element test suite might look something like this:
43+
44+
```typescript
45+
// test/my-controller.ts
46+
import {expect, fixture, html} from '@open-wc/testing'
47+
import {MyController} from '../src/my-controller'
48+
49+
describe('MyController', () => {
50+
let instance
51+
beforeEach(async () => {
52+
instance = await fixture(html`<my-controller>
53+
<div class="expected-children"></div>
54+
</my-controller>`)
55+
})
56+
57+
it('is a Catalyst controller', () => {
58+
expect(instance).to.have.attribute('data-catalyst')
59+
})
60+
61+
it('matches snapshot', () => {
62+
expect(instance).dom.to.equalSnapshot()
63+
})
64+
65+
it('passes Axe tests', () =>
66+
expect(instance).to.be.accessible()
67+
})
68+
69+
it('...') // Fill out the rest
70+
})
71+
```
72+
73+
##### Useful Assertions
74+
75+
The `@open-wc/testing` package exports the `expect` function from Chai, but also automatically registers a set of plugins useful for writing web components, including [chai-a11y-axe](https://www.npmjs.com/package/chai-a11y-axe) and [chai-dom](https://www.npmjs.com/package/chai-dom). Here are some handy example assertions which may be commonly written:
76+
77+
78+
- `expect(instance).to.be.accessible()` - Runs a suite of [Axe](https://www.npmjs.com/package/axe) accessibility tests on the element.
79+
- `expect(instance).dom.to.equalSnapshot()` - Stores a snaphsot test of the existing DOM, which can be tested against later, for regressions.
80+
- `expect(instance).shadowDom.to.equalSnapshot()` - Stores a snaphsot test of the existing ShadowDOM, which can be tested against later, for regressions.
81+
- `expect(instance).to.have.class('foo')` - Checks the element has the `foo` class (like `el.classList.contains('foo')`).
82+
- `expect(instance).to.have.attribute('foo')` - Checks the element has the `foo` attribute (like `el.hasAttribute('foo')`).
83+
- `expect(instance).to.have.attribute('foo')` - Checks the element has the `foo` attribute (like `el.hasAttribute('foo')`).
84+
- `expect(instance).to.have.descendants('.foo')` - Checks the element has elements matching the selector `.foo` attribute (like `el.querySelectorAll('foo')`).
85+

0 commit comments

Comments
 (0)