Skip to content
This repository was archived by the owner on Mar 5, 2022. It is now read-only.

Commit d1aece8

Browse files
committed
feat: update style options and document them well
1 parent 1d2c411 commit d1aece8

File tree

5 files changed

+113
-35
lines changed

5 files changed

+113
-35
lines changed

README.md

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,20 @@ describe('HelloState component', () => {
6464

6565
### styles
6666

67+
If you component imports its own style, the style should be applied during the Cypress test. But sometimes you need more power.
68+
69+
You can 3 options to load additional styles:
70+
71+
```js
72+
mount(<Component />, {
73+
style: string, // load inline style CSS
74+
cssFiles: string | string[], // load a single or a list of local CSS files
75+
stylesheets: string | string[] // load external stylesheets
76+
})
77+
```
78+
79+
#### Inline styles
80+
6781
You can add individual style to the mounted component by passing its text as an option
6882

6983
```js
@@ -89,31 +103,25 @@ it('can be passed as an option', () => {
89103
})
90104
```
91105

92-
Often your component rely on global CSS style imported from the root `index.js` or `app.js` file
106+
#### Load local CSS file
93107

94108
```js
95-
// index.js
96-
import './styles.css'
97-
// bootstrap application
109+
const cssFiles = 'cypress/integration/Button.css'
110+
cy.mount(<Button name="Orange" orange />, { cssFiles })
98111
```
99112

100-
You can read the CSS file and pass it as `style` option yourself
101-
102-
```js
103-
cy.readFile('cypress/integration/Button.css').then(style => {
104-
cy.mount(<Button name="Orange" orange />, { style })
105-
})
106-
```
113+
See [cypress/integration/inject-style-spec.js](cypress/integration/inject-style-spec.js) for more examples.
107114

108-
You can even let Cypress read the file and inject the style
115+
#### Load external stylesheets
109116

110117
```js
111-
const cssFile = 'cypress/integration/Button.css'
112-
cy.mount(<Button name="Orange" orange />, { cssFile })
118+
mount(<Todo todo={todo} />, {
119+
stylesheets: [
120+
'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css',
121+
],
122+
})
113123
```
114124

115-
See [cypress/integration/inject-style-spec.js](cypress/integration/inject-style-spec.js) for more examples.
116-
117125
## Configuration
118126

119127
If your React and React DOM libraries are installed in non-standard paths (think monorepo scenario), you can tell this plugin where to find them. In `cypress.json` specify paths like this:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
button {
2+
height: 50px;
3+
}

cypress/component/component tests/basic/css-file/css-file-spec.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,35 @@ describe('cssFile', () => {
66
it('is loaded', () => {
77
const Component = () => <button className="green">Green button</button>
88
mount(<Component />, {
9-
cssFile: 'cypress/component/component tests/basic/css-file/index.css',
9+
cssFiles: 'cypress/component/component tests/basic/css-file/index.css',
1010
})
1111

1212
cy.get('button')
1313
.should('have.class', 'green')
1414
.and('have.css', 'background-color', 'rgb(0, 255, 0)')
1515
})
16+
17+
it('allows loading several CSS files', () => {
18+
const Component = () => (
19+
<button className="green">Large green button</button>
20+
)
21+
mount(<Component />, {
22+
cssFiles: [
23+
'cypress/component/component tests/basic/css-file/base.css',
24+
'cypress/component/component tests/basic/css-file/index.css',
25+
],
26+
})
27+
28+
// check the style from the first css file
29+
cy.get('button')
30+
.should('have.class', 'green')
31+
.invoke('css', 'height')
32+
.should(value => {
33+
// round the height, since in real browser it is never exactly 50
34+
expect(parseFloat(value), 'height is 50px').to.be.closeTo(50, 1)
35+
})
36+
37+
// and should have style from the second css file
38+
cy.get('button').and('have.css', 'background-color', 'rgb(0, 255, 0)')
39+
})
1640
})

lib/index.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ interface ReactModule {
1717
interface StyleOptions {
1818
stylesheets: string | string[]
1919
style: string
20-
cssFile: string
20+
cssFiles: string | string[]
2121
}
2222

2323
interface MountReactComponentOptions {

lib/utils.ts

Lines changed: 60 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,55 @@
1+
/**
2+
* Insert links to external style resources.
3+
*/
4+
function insertStylesheets(
5+
stylesheets: string[],
6+
document: Document,
7+
el: HTMLElement,
8+
) {
9+
stylesheets.forEach(href => {
10+
const link = document.createElement('link')
11+
link.type = 'text/css'
12+
link.rel = 'stylesheet'
13+
link.href = href
14+
document.body.insertBefore(link, el)
15+
})
16+
}
17+
18+
/**
19+
* Inserts a single stylesheet element
20+
*/
21+
function insertStyles(style: string, document: Document, el: HTMLElement) {
22+
const styleElement = document.createElement('style')
23+
styleElement.appendChild(document.createTextNode(style))
24+
document.body.insertBefore(styleElement, el)
25+
}
26+
27+
function insertSingleCssFile(
28+
cssFilename: string,
29+
document: Document,
30+
el: HTMLElement,
31+
) {
32+
return cy.readFile(cssFilename).then(css => {
33+
const style = document.createElement('style')
34+
style.appendChild(document.createTextNode(css))
35+
document.body.insertBefore(style, el)
36+
})
37+
}
38+
39+
/**
40+
* Reads the given CSS file from local file system
41+
* and adds the loaded style text as an element.
42+
*/
43+
function insertLocalCssFiles(
44+
cssFilenames: string[],
45+
document: Document,
46+
el: HTMLElement,
47+
) {
48+
return Cypress.Promise.mapSeries(cssFilenames, cssFilename =>
49+
insertSingleCssFile(cssFilename, document, el),
50+
)
51+
}
52+
153
/**
254
* Injects custom style text or CSS file or 3rd party style resources
355
* into the given document.
@@ -12,27 +64,18 @@ export const injectStylesBeforeElement = (
1264
options.stylesheets = [options.stylesheets]
1365
}
1466
if (Array.isArray(options.stylesheets)) {
15-
// console.log('adding stylesheets')
16-
options.stylesheets.forEach(href => {
17-
const link = document.createElement('link')
18-
link.type = 'text/css'
19-
link.rel = 'stylesheet'
20-
link.href = href
21-
document.body.insertBefore(link, el)
22-
})
67+
insertStylesheets(options.stylesheets, document, el)
2368
}
2469

2570
if (options.style) {
26-
const style = document.createElement('style')
27-
style.appendChild(document.createTextNode(options.style))
28-
document.body.insertBefore(style, el)
71+
insertStyles(options.style, document, el)
72+
}
73+
74+
if (Array.isArray(options.cssFiles)) {
75+
return insertLocalCssFiles(options.cssFiles, document, el)
2976
}
3077

31-
if (options.cssFile) {
32-
return cy.readFile(options.cssFile).then(css => {
33-
const style = document.createElement('style')
34-
style.appendChild(document.createTextNode(css))
35-
document.body.insertBefore(style, el)
36-
})
78+
if (typeof options.cssFiles === 'string') {
79+
return insertSingleCssFile(options.cssFiles, document, el)
3780
}
3881
}

0 commit comments

Comments
 (0)