Skip to content

Commit 294985f

Browse files
fix: remove some CT functions and props (#24419)
* fix: remove mountHook function for React * fix: remove `unmount` from @cypress/react exports * fix: remove `unmount` from the @cypress/react readme * fix: don't alias React components on mount * fix: remove `mountCallback` from Vue adapters * fix: remove style injection utility functions from `mount-utils` * fix: fix React tests * fix: fix more React tests * fix: fix more tests * fix: fix screenshot test styles * fix: update documentation around mount-utils styles; fix tests * fix: update Vue docs to use `props` key rather than `propsData` * fix: add test styles back in * update unmount test and export getContainerEl for back compat * better errors * docs * error for unmount * test for error * fix last test * adjust language to reflect removed methods * one last deprecation * fix error * wip - [skip ci] * use proxy to catch errors * deprecate alias * update tests * update on link * use on links properly * revert changes Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
1 parent f39eb1c commit 294985f

File tree

56 files changed

+495
-916
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+495
-916
lines changed

npm/mount-utils/README.md

+5-23
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,7 @@ All the functionality used to create the first party Mount adapters is available
2525

2626
In addition, we recommend that Mount Adapters:
2727

28-
- receive a second argument that extends `StyleOptions` from `@cypress/mount-utils`
29-
- calls `injectStylesBeforeElement` from `@cypress/mount-utils` before mounting the component
30-
- calls `setupHooks` to register the required lifecycle hooks for `@cypress/mount-utils` to work
31-
32-
This will let the user inject styles `<style>...</style>` and stylesheets `<link rel="stylesheet">`, which is very useful for developing components.
28+
- call `setupHooks` to register the required lifecycle hooks for `@cypress/mount-utils` to work
3329

3430
### Example Mount Adapter: Web Components
3531

@@ -39,9 +35,7 @@ Here's a simple yet realistic example of Mount Adapter targeting Web Components.
3935
import {
4036
ROOT_SELECTOR,
4137
setupHooks,
42-
injectStylesBeforeElement,
43-
getContainerEl,
44-
StyleOptions
38+
getContainerEl
4539
} from "@cypress/mount-utils";
4640

4741
Cypress.on("run:start", () => {
@@ -69,8 +63,7 @@ function maybeRegisterComponent<T extends CustomElementConstructor>(
6963
}
7064

7165
export function mount(
72-
webComponent: CustomElementConstructor,
73-
options?: Partial<StyleOptions>
66+
webComponent: CustomElementConstructor
7467
): Cypress.Chainable {
7568
// Get root selector defined in `cypress/support.component-index.html
7669
const $root = document.querySelector(ROOT_SELECTOR)!;
@@ -83,9 +76,6 @@ export function mount(
8376
/// Register Web Component
8477
maybeRegisterComponent(name, webComponent);
8578

86-
// Inject user styles before mounting the component
87-
injectStylesBeforeElement(options ?? {}, document, getContainerEl())
88-
8979
// Render HTML containing component.
9080
$root.innerHTML = `<${name} id="root"></${name}>`;
9181

@@ -100,8 +90,7 @@ export function mount(
10090
return cy.wrap(document.querySelector("#root"), { log: false });
10191
}
10292

103-
// Setup Cypress lifecycle hooks. This tears down any styles
104-
// injected by injectStylesBeforeElement, etc.
93+
// Setup Cypress lifecycle hooks.
10594
setupHooks();
10695
```
10796

@@ -131,14 +120,7 @@ export class WebCounter extends HTMLElement {
131120

132121
describe('web-component.cy.ts', () => {
133122
it('playground', () => {
134-
cy.mount(WebCounter, {
135-
styles: `
136-
button {
137-
background: lightblue;
138-
color: white;
139-
}
140-
`
141-
})
123+
cy.mount(WebCounter)
142124
})
143125
})
144126
```

npm/mount-utils/src/index.ts

+40-186
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,3 @@
1-
/**
2-
* Additional styles to inject into the document.
3-
* A component might need 3rd party libraries from CDN,
4-
* local CSS files and custom styles.
5-
*/
6-
export interface StyleOptions {
7-
/**
8-
* Creates <link href="..." /> element for each stylesheet
9-
* @alias stylesheet
10-
*/
11-
stylesheets: string | string[]
12-
/**
13-
* Creates <link href="..." /> element for each stylesheet
14-
* @alias stylesheets
15-
*/
16-
stylesheet: string | string[]
17-
/**
18-
* Creates <style>...</style> element and inserts given CSS.
19-
* @alias styles
20-
*/
21-
style: string | string[]
22-
/**
23-
* Creates <style>...</style> element for each given CSS text.
24-
* @alias style
25-
*/
26-
styles: string | string[]
27-
/**
28-
* Loads each file and creates a <style>...</style> element
29-
* with the loaded CSS
30-
* @alias cssFile
31-
*/
32-
cssFiles: string | string[]
33-
/**
34-
* Single CSS file to load into a <style></style> element
35-
* @alias cssFile
36-
*/
37-
cssFile: string | string[]
38-
}
39-
401
export const ROOT_SELECTOR = '[data-cy-root]'
412

423
export const getContainerEl = (): HTMLElement => {
@@ -49,154 +10,12 @@ export const getContainerEl = (): HTMLElement => {
4910
throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`)
5011
}
5112

52-
/**
53-
* Remove any style or extra link elements from the iframe placeholder
54-
* left from any previous test
55-
*
56-
*/
57-
export function cleanupStyles () {
58-
const styles = document.body.querySelectorAll('[data-cy=injected-style-tag]')
59-
60-
styles.forEach((styleElement) => {
61-
if (styleElement.parentElement) {
62-
styleElement.parentElement.removeChild(styleElement)
13+
export function checkForRemovedStyleOptions (mountingOptions: Record<string, any>) {
14+
for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets'] as const) {
15+
if (mountingOptions[key]) {
16+
Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key)
6317
}
64-
})
65-
66-
const links = document.body.querySelectorAll('[data-cy=injected-stylesheet]')
67-
68-
links.forEach((link) => {
69-
if (link.parentElement) {
70-
link.parentElement.removeChild(link)
71-
}
72-
})
73-
}
74-
75-
/**
76-
* Insert links to external style resources.
77-
*/
78-
function insertStylesheets (
79-
stylesheets: string[],
80-
document: Document,
81-
el: HTMLElement | null,
82-
) {
83-
stylesheets.forEach((href) => {
84-
const link = document.createElement('link')
85-
86-
link.type = 'text/css'
87-
link.rel = 'stylesheet'
88-
link.href = href
89-
link.dataset.cy = 'injected-stylesheet'
90-
document.body.insertBefore(link, el)
91-
})
92-
}
93-
94-
/**
95-
* Inserts a single stylesheet element
96-
*/
97-
function insertStyles (styles: string[], document: Document, el: HTMLElement | null) {
98-
styles.forEach((style) => {
99-
const styleElement = document.createElement('style')
100-
101-
styleElement.dataset.cy = 'injected-style-tag'
102-
styleElement.appendChild(document.createTextNode(style))
103-
document.body.insertBefore(styleElement, el)
104-
})
105-
}
106-
107-
function insertSingleCssFile (
108-
cssFilename: string,
109-
document: Document,
110-
el: HTMLElement | null,
111-
log?: boolean,
112-
) {
113-
return cy.readFile(cssFilename, { log }).then((css) => {
114-
const style = document.createElement('style')
115-
116-
style.appendChild(document.createTextNode(css))
117-
document.body.insertBefore(style, el)
118-
})
119-
}
120-
121-
/**
122-
* Reads the given CSS file from local file system
123-
* and adds the loaded style text as an element.
124-
*/
125-
function insertLocalCssFiles (
126-
cssFilenames: string[],
127-
document: Document,
128-
el: HTMLElement | null,
129-
log?: boolean,
130-
) {
131-
return Cypress.Promise.mapSeries(cssFilenames, (cssFilename) => {
132-
return insertSingleCssFile(cssFilename, document, el, log)
133-
})
134-
}
135-
136-
/**
137-
* Injects custom style text or CSS file or 3rd party style resources
138-
* into the given document.
139-
*/
140-
export const injectStylesBeforeElement = (
141-
options: Partial<StyleOptions & { log: boolean }>,
142-
document: Document,
143-
el: HTMLElement | null,
144-
): HTMLElement => {
145-
if (!el) return
146-
147-
// first insert all stylesheets as Link elements
148-
let stylesheets: string[] = []
149-
150-
if (typeof options.stylesheet === 'string') {
151-
stylesheets.push(options.stylesheet)
152-
} else if (Array.isArray(options.stylesheet)) {
153-
stylesheets = stylesheets.concat(options.stylesheet)
15418
}
155-
156-
if (typeof options.stylesheets === 'string') {
157-
options.stylesheets = [options.stylesheets]
158-
}
159-
160-
if (options.stylesheets) {
161-
stylesheets = stylesheets.concat(options.stylesheets)
162-
}
163-
164-
insertStylesheets(stylesheets, document, el)
165-
166-
// insert any styles as <style>...</style> elements
167-
let styles: string[] = []
168-
169-
if (typeof options.style === 'string') {
170-
styles.push(options.style)
171-
} else if (Array.isArray(options.style)) {
172-
styles = styles.concat(options.style)
173-
}
174-
175-
if (typeof options.styles === 'string') {
176-
styles.push(options.styles)
177-
} else if (Array.isArray(options.styles)) {
178-
styles = styles.concat(options.styles)
179-
}
180-
181-
insertStyles(styles, document, el)
182-
183-
// now load any css files by path and add their content
184-
// as <style>...</style> elements
185-
let cssFiles: string[] = []
186-
187-
if (typeof options.cssFile === 'string') {
188-
cssFiles.push(options.cssFile)
189-
} else if (Array.isArray(options.cssFile)) {
190-
cssFiles = cssFiles.concat(options.cssFile)
191-
}
192-
193-
if (typeof options.cssFiles === 'string') {
194-
cssFiles.push(options.cssFiles)
195-
} else if (Array.isArray(options.cssFiles)) {
196-
cssFiles = cssFiles.concat(options.cssFiles)
197-
}
198-
199-
return insertLocalCssFiles(cssFiles, document, el, options.log)
20019
}
20120

20221
export function setupHooks (optionalCallback?: Function) {
@@ -220,6 +39,41 @@ export function setupHooks (optionalCallback?: Function) {
22039
// @ts-ignore
22140
Cypress.on('test:before:run', () => {
22241
optionalCallback?.()
223-
cleanupStyles()
22442
})
22543
}
44+
45+
/**
46+
* Remove any style or extra link elements from the iframe placeholder
47+
* left from any previous test
48+
*
49+
* Removed as of Cypress 11.0.0
50+
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
51+
*/
52+
export function cleanupStyles () {
53+
Cypress.utils.throwErrByPath('mount.cleanup_styles')
54+
}
55+
56+
/**
57+
* Additional styles to inject into the document.
58+
* A component might need 3rd party libraries from CDN,
59+
* local CSS files and custom styles.
60+
*
61+
* Removed as of Cypress 11.0.0.
62+
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
63+
*/
64+
export type StyleOptions = unknown
65+
66+
/**
67+
* Injects custom style text or CSS file or 3rd party style resources
68+
* into the given document.
69+
*
70+
* Removed as of Cypress 11.0.0.
71+
* @see https://on.cypress.io/migration-11-0-0-component-testing-updates
72+
*/
73+
export const injectStylesBeforeElement = (
74+
options: Partial<StyleOptions & { log: boolean }>,
75+
document: Document,
76+
el: HTMLElement | null,
77+
) => {
78+
Cypress.utils.throwErrByPath('mount.inject_styles_before_element')
79+
}

npm/react/README.md

+2-22
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,6 @@ For more information, please check the official docs for [running Cypress](https
3131

3232
- `mount` is the most important function, allows to mount a given React component as a mini web application and interact with it using Cypress commands
3333
- `createMount` factory function that creates new `mount` function with default options
34-
- `unmount` removes previously mounted component, mostly useful to test how the component cleans up after itself
35-
- `mountHook` mounts a given React Hook in a test component for full testing, see `hooks` example
3634

3735
## Examples
3836

@@ -65,20 +63,7 @@ it('looks right', () => {
6563
})
6664
```
6765

68-
### Extra styles
69-
70-
You can pass additional styles, css files and external stylesheets to load, see [docs/styles.md](./docs/styles.md) for the full list of options.
71-
72-
```js
73-
const todo = {
74-
id: '123',
75-
title: 'Write more tests',
76-
}
77-
mount(<Todo todo={todo} />, {
78-
stylesheets: [
79-
'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css',
80-
],
81-
})
66+
See [docs/styles.md](./docs/styles.md) for full list of options.
8267
```
8368
8469
You may also specify the `ReactDOM` package to use. This can be useful in complex monorepo setups that have different versions of React and React DOM installed. If you see an error relating to [mismatching versions of React or React DOM](https://reactjs.org/warnings/invalid-hook-call-warning.html#mismatching-versions-of-react-and-react-dom), this may be the solution. You can do this using the `ReactDom` option:
@@ -87,12 +72,7 @@ You may also specify the `ReactDOM` package to use. This can be useful in comple
8772
// if you have multiple versions of ReactDom in your monorepo
8873
import ReactDom from 'react-dom'
8974
90-
mount(<Todo todo={todo} />, {
91-
stylesheets: [
92-
'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css',
93-
],
94-
ReactDom
95-
})
75+
mount(<Todo todo={todo} />, { reactDom: ReactDom })
9676
```
9777

9878
## Compatibility
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
11
# testing React hooks
22

3-
- [counter-with-hooks.spec.js](counter-with-hooks.spec.js) and [counter2-with-hooks.spec.js](counter2-with-hooks.spec.js) test React components that uses hooks
4-
- [use-counter.spec.js](use-counter.spec.js) shows how to test a React hook using `mountHook` function
5-
6-
![Hook test](images/hook.png)
7-
8-
Note: hooks are mounted inside a test component following the approach shown in [react-hooks-testing-library](https://github.com/testing-library/react-hooks-testing-library/blob/master/src/pure.js)
3+
- [counter-with-hooks.spec.js](counter-with-hooks.spec.js) and [counter2-with-hooks.spec.js](counter2-with-hooks.spec.js) test React components that uses hooks
Binary file not shown.

npm/react/cypress/component/advanced/hooks/use-counter.cy.jsx

-25
This file was deleted.

0 commit comments

Comments
 (0)