Skip to content

Commit b6b95df

Browse files
43081jchrisbreidingbahmutov
authored
add Shadow DOM / LitElement recipe (#501)
Co-authored-by: Chris Breiding <[email protected]> Co-authored-by: Gleb Bahmutov <[email protected]>
1 parent bec1f34 commit b6b95df

File tree

13 files changed

+195
-4
lines changed

13 files changed

+195
-4
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Recipe | Description
3030
[Evaluate performance metrics](./examples/testing-dom__performance-metrics) | Utilize Cypress to monitor a website
3131
[Root style](./examples/testing-dom__root-style) | Trigger input color change that modifies CSS variable
3232
[Select widgets](./examples/testing-dom__select2) | Working with `<select>` elements and [Select2](https://select2.org/) widgets
33+
[Lit Elements](./examples/testing-dom__lit-element) | Testing Lit Elements with Shadow DOM
3334

3435
## Logging in recipes
3536

circle.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,8 @@ jobs:
237237
<<: *defaults
238238
testing-dom__hover-hidden-elements:
239239
<<: *defaults
240+
testing-dom__lit-element:
241+
<<: *defaults
240242
testing-dom__tab-handling-links:
241243
<<: *defaults
242244
testing-dom__wait-for-resource:
@@ -428,6 +430,9 @@ all_jobs: &all_jobs
428430
- testing-dom__hover-hidden-elements:
429431
requires:
430432
- build
433+
- testing-dom__lit-element:
434+
requires:
435+
- build
431436
- testing-dom__tab-handling-links:
432437
requires:
433438
- build
@@ -537,6 +542,7 @@ all_jobs: &all_jobs
537542
- testing-dom__drag-drop
538543
- testing-dom__form-interactions
539544
- testing-dom__hover-hidden-elements
545+
- testing-dom__lit-element
540546
- testing-dom__tab-handling-links
541547
- testing-dom__wait-for-resource
542548
- testing-dom__csv-table
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"plugins": [
3+
"@cypress/dev"
4+
],
5+
"extends": [
6+
"plugin:@cypress/dev/general"
7+
],
8+
"env": {
9+
"browser": true
10+
}
11+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# lit-element
2+
> Testing page with lit-element components that use Shadow DOM
3+
4+
- Test simple shadow DOM assertions in [lit-elements](https://lit-element.polymer-project.org/)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"pluginsFile": false,
3+
"supportFile": false,
4+
"fixturesFolder": false,
5+
"experimentalShadowDomSupport": true
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"plugins": [
3+
"@cypress/dev"
4+
],
5+
"extends": [
6+
"plugin:@cypress/dev/tests"
7+
]
8+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/// <reference types="cypress" />
2+
3+
describe('element-one', () => {
4+
beforeEach(() => {
5+
cy.visit('/index.html')
6+
})
7+
8+
it('renders a button', () => {
9+
cy
10+
.get('element-one')
11+
.shadow()
12+
.find('button')
13+
.should('exist')
14+
})
15+
16+
it('renders a message on button click', () => {
17+
cy
18+
.get('element-one')
19+
.shadow()
20+
.find('button')
21+
.click()
22+
23+
cy
24+
.get('element-one')
25+
.shadow()
26+
.find('p')
27+
.then((node) => {
28+
expect(node.text()).to.equal('I am element 1!')
29+
})
30+
})
31+
})
32+
33+
describe('element-two', () => {
34+
it('renders a default slot', () => {
35+
cy
36+
.get('element-two')
37+
.find('.container > slot', { includeShadowDom: true })
38+
.then(($slot) => {
39+
expect($slot[0].assignedElements()[0]).to.equal(cy.$$('element-two > p')[0])
40+
})
41+
})
42+
})
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { LitElement, html } from 'https://unpkg.com/lit-element/lit-element.js?module'
2+
3+
window.customElements.define('element-one', class extends LitElement {
4+
static get properties () {
5+
return {
6+
_message: {
7+
type: String,
8+
},
9+
}
10+
}
11+
12+
_onClick () {
13+
this._message = 'I am element 1!'
14+
}
15+
16+
render () {
17+
return html`
18+
<p>${this._message || ''}</p>
19+
<button @click=${this._onClick}>Click me</button>
20+
`
21+
}
22+
})
23+
24+
window.customElements.define('element-two', class extends LitElement {
25+
render () {
26+
return html`
27+
<div class="container">
28+
<slot></slot>
29+
</div>
30+
`
31+
}
32+
})
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<script type="module" src="./elements.js"></script>
5+
</head>
6+
<body>
7+
<element-one></element-one>
8+
<div class="container-2">
9+
<element-two>
10+
<p>Testing 123</p>
11+
</element-two>
12+
</div>
13+
</body>
14+
</html>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "unit-test-lit-element",
3+
"version": "1.0.0",
4+
"description": "Load and unit test lit-element projects",
5+
"scripts": {
6+
"cypress:open": "../../node_modules/.bin/cypress open",
7+
"cypress:run": "../../node_modules/.bin/cypress run",
8+
"start": "echo there is no web server to start in this project",
9+
"test:ci": "npm run cypress:run",
10+
"test:ci:firefox": "npm run cypress:run -- --browser firefox",
11+
"test:ci:windows": "bin-up cypress run"
12+
}
13+
}
Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,46 @@
1-
# Testing shadow DOM
1+
# Shadow DOM
22

3-
Currently it is not yet supported out of the box, so you can use any of the custom commands below:
3+
Cypress natively supports traversing shadow DOM trees, both from a component testing point of view, and an application testing point of view.
44

5-
- [cypress-shadow-dom](https://github.com/abramenal/cypress-shadow-dom)
6-
- [cypress-daywalker](https://github.com/JaySunSyn/cypress-daywalker)
5+
## Explicitly traversing shadow DOM
6+
7+
If you are testing components, or you simply prefer writing explicit selectors, you may traverse into any given shadow DOM tree like so:
8+
9+
```javascript
10+
cy
11+
.get('my-element')
12+
.shadow()
13+
.find('button')
14+
.click()
15+
16+
/*
17+
<my-element>
18+
#shadow-root
19+
<button>Click me!</button>
20+
</my-element>
21+
*/
22+
```
23+
24+
## Ignoring shadow boundaries
25+
26+
Alternatively, you may use the `includeShadowDom: true` option when traversing the DOM to look beyond each shadow root's boundary:
27+
28+
```javascript
29+
cy
30+
.get('button', { includeShadowDom: true })
31+
.click()
32+
33+
/*
34+
<my-element>
35+
#shadow-root
36+
<button>Click me!</button>
37+
</my-element>
38+
*/
39+
```
40+
41+
This effectively treats the DOM as if shadow boundaries do not exist and will traverse into them like any other elements.
42+
43+
The following commands support the `includeShadowDom` option:
44+
45+
* `cy.get()`
46+
* `cy.find()`

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"jquery": "3.4.0",
5656
"json-server": "0.14.0",
5757
"jsonwebtoken": "8.5.1",
58+
"lit-element": "2.3.1",
5859
"lodash": "4.17.13",
5960
"minimist": "1.2.3",
6061
"morgan": "1.9.1",

0 commit comments

Comments
 (0)