cypress 10.4.0 → 10.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/angular/CHANGELOG.md +55 -0
- package/angular/README.md +154 -0
- package/angular/dist/index.d.ts +1 -0
- package/angular/dist/index.js +263 -0
- package/angular/dist/mount.d.ts +111 -0
- package/angular/package.json +70 -0
- package/mount-utils/CHANGELOG.md +7 -0
- package/package.json +10 -4
- package/react/CHANGELOG.md +13 -0
- package/react/dist/createMount.d.ts +2 -4
- package/react/dist/cypress-react.cjs.js +583 -35
- package/react/dist/cypress-react.esm-bundler.js +584 -36
- package/react/dist/mount.d.ts +1 -1
- package/react/dist/types.d.ts +1 -7
- package/react/package.json +2 -0
- package/react18/CHANGELOG.md +6 -0
- package/react18/dist/cypress-react.cjs.js +247 -36
- package/react18/dist/cypress-react.esm-bundler.js +247 -36
- package/react18/dist/index.d.ts +1 -1
- package/types/cypress.d.ts +14 -2
- package/vue/CHANGELOG.md +14 -0
- package/vue/package.json +0 -1
- package/vue2/CHANGELOG.md +7 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
# @cypress/angular-v1.0.0 (2022-08-04)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* **angular:** set rxjs versions > 6.6.0 as dependency ([#16676](https://github.com/cypress-io/cypress/issues/16676)) ([46de81e](https://github.com/cypress-io/cypress/commit/46de81e75fd18bc37cb884e9a751106fff4d08ad))
|
7
|
+
* scaffold correct config file ([#19776](https://github.com/cypress-io/cypress/issues/19776)) ([8f32960](https://github.com/cypress-io/cypress/commit/8f32960ef803f539f065d41f01fff33bfe33ed5d))
|
8
|
+
* scope config to current testing type ([#20677](https://github.com/cypress-io/cypress/issues/20677)) ([61f7cfc](https://github.com/cypress-io/cypress/commit/61f7cfc59284a2938e0a1c15d74ee75215ba5f8b))
|
9
|
+
* terminal error message for non migrated config ([#21467](https://github.com/cypress-io/cypress/issues/21467)) ([3274da7](https://github.com/cypress-io/cypress/commit/3274da7842f5ef1ddad62b1c630d0ff9120e4289))
|
10
|
+
* update scaffold template to use correct path ([#20047](https://github.com/cypress-io/cypress/issues/20047)) ([6e80359](https://github.com/cypress-io/cypress/commit/6e803597a379222cf936e5977c8314d693ee1912))
|
11
|
+
|
12
|
+
|
13
|
+
### Features
|
14
|
+
|
15
|
+
* add devServer to config file ([#18962](https://github.com/cypress-io/cypress/issues/18962)) ([2573375](https://github.com/cypress-io/cypress/commit/2573375b5b6616efd2d213a94cd55fd8e0385864))
|
16
|
+
* **angular:** angular mount ([#22858](https://github.com/cypress-io/cypress/issues/22858)) ([4131b1f](https://github.com/cypress-io/cypress/commit/4131b1fa8482ae08113bef337965baa1ac12f66c))
|
17
|
+
* Deprecate run-ct / open-ct, and update all examples to use --ct instead ([#18422](https://github.com/cypress-io/cypress/issues/18422)) ([196e8f6](https://github.com/cypress-io/cypress/commit/196e8f62cc6d27974f235945cb5700624b3dae41))
|
18
|
+
* ProjectLifecycleManager & general launchpad cleanup ([#19347](https://github.com/cypress-io/cypress/issues/19347)) ([4626f74](https://github.com/cypress-io/cypress/commit/4626f7481c9904fec484aa167a02e0197a3095c4))
|
19
|
+
* remove testFiles reference ([#20565](https://github.com/cypress-io/cypress/issues/20565)) ([5670344](https://github.com/cypress-io/cypress/commit/567034459089d9d53dfab5556cb9369fb335c3db))
|
20
|
+
* support specPattern, deprecate integrationFolder and componentFolder ([#19319](https://github.com/cypress-io/cypress/issues/19319)) ([792980a](https://github.com/cypress-io/cypress/commit/792980ac12746ef47b9c944ebe4c6c353a187ab2))
|
21
|
+
* support webpack-dev-server v4 ([#17918](https://github.com/cypress-io/cypress/issues/17918)) ([16e4759](https://github.com/cypress-io/cypress/commit/16e4759e0196f68c5f0525efb020211337748f94))
|
22
|
+
* swap the #__cy_root id selector to become data-cy-root for component mounting ([#20951](https://github.com/cypress-io/cypress/issues/20951)) ([0e7b555](https://github.com/cypress-io/cypress/commit/0e7b555f93fb403f431c5de4a07ae7ad6ac89ba2))
|
23
|
+
* Use .config files ([#18578](https://github.com/cypress-io/cypress/issues/18578)) ([081dd19](https://github.com/cypress-io/cypress/commit/081dd19cc6da3da229a7af9c84f62730c85a5cd6))
|
24
|
+
* use devServer instad of startDevServer ([#20092](https://github.com/cypress-io/cypress/issues/20092)) ([8a6768f](https://github.com/cypress-io/cypress/commit/8a6768fee6f46b908c5a9daf23da8b804a6c627f))
|
25
|
+
* use hoisted yarn install in binary build ([#17285](https://github.com/cypress-io/cypress/issues/17285)) ([e4f5b10](https://github.com/cypress-io/cypress/commit/e4f5b106d49d6ac0857c5fdac886f83b99558c88))
|
26
|
+
* Use plugins on config files ([#18798](https://github.com/cypress-io/cypress/issues/18798)) ([bb8251b](https://github.com/cypress-io/cypress/commit/bb8251b752ac44f1184f9160194cf12d41fc867f))
|
27
|
+
* use supportFile by testingType ([#19364](https://github.com/cypress-io/cypress/issues/19364)) ([0366d4f](https://github.com/cypress-io/cypress/commit/0366d4fa8971e5e5189c6fd6450cc3c8d72dcfe1))
|
28
|
+
|
29
|
+
# @cypress/angular-v1.0.0 (2022-08-04)
|
30
|
+
|
31
|
+
|
32
|
+
### Bug Fixes
|
33
|
+
|
34
|
+
* **angular:** set rxjs versions > 6.6.0 as dependency ([#16676](https://github.com/cypress-io/cypress/issues/16676)) ([46de81e](https://github.com/cypress-io/cypress/commit/46de81e75fd18bc37cb884e9a751106fff4d08ad))
|
35
|
+
* scaffold correct config file ([#19776](https://github.com/cypress-io/cypress/issues/19776)) ([8f32960](https://github.com/cypress-io/cypress/commit/8f32960ef803f539f065d41f01fff33bfe33ed5d))
|
36
|
+
* scope config to current testing type ([#20677](https://github.com/cypress-io/cypress/issues/20677)) ([61f7cfc](https://github.com/cypress-io/cypress/commit/61f7cfc59284a2938e0a1c15d74ee75215ba5f8b))
|
37
|
+
* terminal error message for non migrated config ([#21467](https://github.com/cypress-io/cypress/issues/21467)) ([3274da7](https://github.com/cypress-io/cypress/commit/3274da7842f5ef1ddad62b1c630d0ff9120e4289))
|
38
|
+
* update scaffold template to use correct path ([#20047](https://github.com/cypress-io/cypress/issues/20047)) ([6e80359](https://github.com/cypress-io/cypress/commit/6e803597a379222cf936e5977c8314d693ee1912))
|
39
|
+
|
40
|
+
|
41
|
+
### Features
|
42
|
+
|
43
|
+
* add devServer to config file ([#18962](https://github.com/cypress-io/cypress/issues/18962)) ([2573375](https://github.com/cypress-io/cypress/commit/2573375b5b6616efd2d213a94cd55fd8e0385864))
|
44
|
+
* **angular:** angular mount ([#22858](https://github.com/cypress-io/cypress/issues/22858)) ([4131b1f](https://github.com/cypress-io/cypress/commit/4131b1fa8482ae08113bef337965baa1ac12f66c))
|
45
|
+
* Deprecate run-ct / open-ct, and update all examples to use --ct instead ([#18422](https://github.com/cypress-io/cypress/issues/18422)) ([196e8f6](https://github.com/cypress-io/cypress/commit/196e8f62cc6d27974f235945cb5700624b3dae41))
|
46
|
+
* ProjectLifecycleManager & general launchpad cleanup ([#19347](https://github.com/cypress-io/cypress/issues/19347)) ([4626f74](https://github.com/cypress-io/cypress/commit/4626f7481c9904fec484aa167a02e0197a3095c4))
|
47
|
+
* remove testFiles reference ([#20565](https://github.com/cypress-io/cypress/issues/20565)) ([5670344](https://github.com/cypress-io/cypress/commit/567034459089d9d53dfab5556cb9369fb335c3db))
|
48
|
+
* support specPattern, deprecate integrationFolder and componentFolder ([#19319](https://github.com/cypress-io/cypress/issues/19319)) ([792980a](https://github.com/cypress-io/cypress/commit/792980ac12746ef47b9c944ebe4c6c353a187ab2))
|
49
|
+
* support webpack-dev-server v4 ([#17918](https://github.com/cypress-io/cypress/issues/17918)) ([16e4759](https://github.com/cypress-io/cypress/commit/16e4759e0196f68c5f0525efb020211337748f94))
|
50
|
+
* swap the #__cy_root id selector to become data-cy-root for component mounting ([#20951](https://github.com/cypress-io/cypress/issues/20951)) ([0e7b555](https://github.com/cypress-io/cypress/commit/0e7b555f93fb403f431c5de4a07ae7ad6ac89ba2))
|
51
|
+
* Use .config files ([#18578](https://github.com/cypress-io/cypress/issues/18578)) ([081dd19](https://github.com/cypress-io/cypress/commit/081dd19cc6da3da229a7af9c84f62730c85a5cd6))
|
52
|
+
* use devServer instad of startDevServer ([#20092](https://github.com/cypress-io/cypress/issues/20092)) ([8a6768f](https://github.com/cypress-io/cypress/commit/8a6768fee6f46b908c5a9daf23da8b804a6c627f))
|
53
|
+
* use hoisted yarn install in binary build ([#17285](https://github.com/cypress-io/cypress/issues/17285)) ([e4f5b10](https://github.com/cypress-io/cypress/commit/e4f5b106d49d6ac0857c5fdac886f83b99558c88))
|
54
|
+
* Use plugins on config files ([#18798](https://github.com/cypress-io/cypress/issues/18798)) ([bb8251b](https://github.com/cypress-io/cypress/commit/bb8251b752ac44f1184f9160194cf12d41fc867f))
|
55
|
+
* use supportFile by testingType ([#19364](https://github.com/cypress-io/cypress/issues/19364)) ([0366d4f](https://github.com/cypress-io/cypress/commit/0366d4fa8971e5e5189c6fd6450cc3c8d72dcfe1))
|
@@ -0,0 +1,154 @@
|
|
1
|
+
> A little helper to unit test React components in the open source [Cypress.io](https://www.cypress.io/) test runner **v7.0.0+**
|
2
|
+
|
3
|
+
**Jump to:** [Comparison](#comparison), [Blog posts](#blog-posts), [Install](#install), Examples: [basic](#basic-examples), [advanced](#advanced-examples), [full](#full-examples), [external](#external-examples), [Style options](#options), [Code coverage](#code-coverage), [Visual testing](#visual-testing), [Common problems](#common-problems), [Chat](#chat)
|
4
|
+
|
5
|
+
## TLDR
|
6
|
+
|
7
|
+
- What is this? This package allows you to use [Cypress](https://www.cypress.io/) test runner to unit test your Angular components with zero effort. Here is a typical component testing, notice there is not external URL shown, since it is mounting the component directly.
|
8
|
+
|
9
|
+

|
10
|
+
|
11
|
+
- How is this different from [Angular Testing](https://angular.io/guide/testing) or [ATL](https://testing-library.com/docs/angular-testing-library/intro/)? It is similar in functionality BUT runs the component in the real browser with full power of Cypress E2E test runner: [live GUI, full API, screen recording, CI support, cross-platform](https://www.cypress.io/features/), and [visual testing](https://on.cypress.io/visual-testing).
|
12
|
+
- Read [My Vision for Component Tests in Cypress](https://glebbahmutov.com/blog/my-vision-for-component-tests/) by Gleb Bahmutov
|
13
|
+
|
14
|
+
## Comparison
|
15
|
+
|
16
|
+
<!-- prettier-ignore-start -->
|
17
|
+
Feature | Jest / Karma / ATL | Cypress + `@cypress/angular`
|
18
|
+
--- | --- | ---
|
19
|
+
Test runs in real browser | ❌ | ✅
|
20
|
+
Supports shallow mount | ✅ | ❌
|
21
|
+
Supports full mount | ✅ | ✅
|
22
|
+
Test speed | 🏎 | [as fast as the app works in the browser](#fast-enough)
|
23
|
+
Test can use additional plugins | maybe | use any [Cypress plugin](https://on.cypress.io/plugins)
|
24
|
+
Test can interact with component | synthetic limited API | use any [Cypress command](https://on.cypress.io/api)
|
25
|
+
Test can be debugged | via terminal and Node debugger | use browser DevTools
|
26
|
+
Built-in time traveling debugger | ❌ | Cypress time traveling debugger
|
27
|
+
Re-run tests on file or test change | ✅ | ✅
|
28
|
+
Test output on CI | terminal | terminal, screenshots, videos
|
29
|
+
Tests can be run in parallel | ✅ | ✅ via [parallelization](https://on.cypress.io/parallelization)
|
30
|
+
Test against interface | if using `@testing-library/angular` | ✅ and can use `@testing-library/cypress`
|
31
|
+
Spying and stubbing methods | Jest mocks | [Sinon library](https://on.cypress.io/stubs-spies-and-clocks)
|
32
|
+
Stubbing imports | ✅ | ✅
|
33
|
+
Stubbing clock | ✅ | ✅
|
34
|
+
Code coverage | ✅ | ✅
|
35
|
+
<!-- prettier-ignore-end -->
|
36
|
+
|
37
|
+
If you are coming from Jest + ATL world, read [Test The Interface Not The Implementation](https://glebbahmutov.com/blog/test-the-interface/).
|
38
|
+
|
39
|
+
## Blog posts
|
40
|
+
|
41
|
+
- [My Vision for Component Tests in Cypress](https://glebbahmutov.com/blog/my-vision-for-component-tests/)
|
42
|
+
|
43
|
+
## Install
|
44
|
+
|
45
|
+
Requires [Node](https://nodejs.org/en/) version 12 or above.
|
46
|
+
|
47
|
+
```sh
|
48
|
+
npm install --save-dev cypress @cypress/angular @cypress/webpack-dev-server
|
49
|
+
```
|
50
|
+
|
51
|
+
|
52
|
+
## API
|
53
|
+
|
54
|
+
- `mount` allows you to mount a given Angular component as a mini web application and interact with it using Cypress commands
|
55
|
+
|
56
|
+
## Examples
|
57
|
+
|
58
|
+
```ts
|
59
|
+
import { mount } from '@cypress/angular'
|
60
|
+
import { HelloWorldComponent } from './hello-world.component'
|
61
|
+
|
62
|
+
describe('HelloWorldComponent', () => {
|
63
|
+
it('works', () => {
|
64
|
+
mount(HelloWorldComponent)
|
65
|
+
// now use standard Cypress commands
|
66
|
+
cy.contains('Hello World!').should('be.visible')
|
67
|
+
})
|
68
|
+
})
|
69
|
+
```
|
70
|
+
|
71
|
+
Look at the examples in [cypress/component](cypress/component) folder. Here is the list of examples showing various testing scenarios.
|
72
|
+
|
73
|
+
### Basic examples
|
74
|
+
Coming Soon...
|
75
|
+
|
76
|
+
|
77
|
+
### Advanced examples
|
78
|
+
Coming Soon...
|
79
|
+
|
80
|
+
### Full examples
|
81
|
+
Coming Soon...
|
82
|
+
|
83
|
+
### External examples
|
84
|
+
Coming Soon...
|
85
|
+
|
86
|
+
## Options
|
87
|
+
|
88
|
+
|
89
|
+
## Code coverage
|
90
|
+
|
91
|
+
In order to use code coverage you can follow the instructions from [docs](https://github.com/cypress-io/code-coverage). In most of cases you need to install 2 dependencies:
|
92
|
+
|
93
|
+
```
|
94
|
+
npm i @cypress/code-coverage babel-plugin-istanbul
|
95
|
+
|
96
|
+
yarn add @cypress/code-coverage babel-plugin-istanbul
|
97
|
+
```
|
98
|
+
|
99
|
+
If you are using [plugins/cra-v3](plugins/cra-v3) it instruments the code on the fly using `babel-plugin-istanbul` and generates report using dependency [cypress-io/code-coverage](https://github.com/cypress-io/code-coverage) (included). If you want to disable code coverage instrumentation and reporting, use `--env coverage=false` or `CYPRESS_coverage=false` or set in your `cypress.json` file
|
100
|
+
|
101
|
+
```json
|
102
|
+
{
|
103
|
+
"env": {
|
104
|
+
"coverage": false
|
105
|
+
}
|
106
|
+
}
|
107
|
+
```
|
108
|
+
|
109
|
+
## Visual testing
|
110
|
+
|
111
|
+
You can use any Cypress [Visual Testing plugin](https://on.cypress.io/plugins#visual-testing) to perform [visual testing](https://on.cypress.io/visual-testing) from the component tests. This repo has several example projects, see [visual-sudoku](examples/visual-sudoku), [visual-testing-with-percy](examples/visual-testing-with-percy), [visual-testing-with-happo](examples/visual-testing-with-happo), and [visual-testing-with-applitools](examples/visual-testing-with-applitools).
|
112
|
+
|
113
|
+
For a larger Do-It-Yourself example with an hour long list of explanation videos, see [bahmutov/sudoku](https://github.com/bahmutov/sudoku) repository. I explain how to write visual testing using open source tools in this [blog post](https://glebbahmutov.com/blog/open-source-visual-testing-of-components/), [video talk](https://www.youtube.com/watch?v=00BNExlJUU8), and [slides](https://slides.com/bahmutov/i-see-what-is-going-on).
|
114
|
+
|
115
|
+
## Common problems
|
116
|
+
|
117
|
+
|
118
|
+
## Chat
|
119
|
+
|
120
|
+
Come chat with us [on discord](https://discord.gg/7ZHYhZSW) in the #component-testing channel.
|
121
|
+
|
122
|
+
## Development
|
123
|
+
|
124
|
+
See [docs/development.md](./docs/development.md)
|
125
|
+
|
126
|
+
## Debugging
|
127
|
+
|
128
|
+
You can see verbose logs from this plugin by running with environment variable
|
129
|
+
|
130
|
+
```
|
131
|
+
DEBUG=@cypress/angular
|
132
|
+
```
|
133
|
+
|
134
|
+
Because finding and modifying Webpack settings while running this plugin is done by [find-webpack](https://github.com/bahmutov/find-webpack) module, you might want to enable its debug messages too.
|
135
|
+
|
136
|
+
```
|
137
|
+
DEBUG=@cypress/angular,find-webpack
|
138
|
+
```
|
139
|
+
|
140
|
+
## Changelog
|
141
|
+
|
142
|
+
[Changelog](./CHANGELOG.md)
|
143
|
+
|
144
|
+
## Related tools
|
145
|
+
|
146
|
+
Same feature for unit testing components from other frameworks using Cypress
|
147
|
+
|
148
|
+
- [@cypress/react](https://github.com/cypress-io/cypress/tree/develop/npm/react)
|
149
|
+
- [@cypress/vue](https://github.com/cypress-io/cypress/tree/develop/npm/vue)
|
150
|
+
- [cypress-cycle-unit-test](https://github.com/bahmutov/cypress-cycle-unit-test)
|
151
|
+
- [cypress-svelte-unit-test](https://github.com/bahmutov/cypress-svelte-unit-test)
|
152
|
+
- [@cypress/angular](https://github.com/bahmutov/@cypress/angular)
|
153
|
+
- [cypress-hyperapp-unit-test](https://github.com/bahmutov/cypress-hyperapp-unit-test)
|
154
|
+
- [cypress-angularjs-unit-test](https://github.com/bahmutov/cypress-angularjs-unit-test)
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './mount';
|
@@ -0,0 +1,263 @@
|
|
1
|
+
|
2
|
+
/**
|
3
|
+
* @cypress/angular v0.0.0-development
|
4
|
+
* (c) 2022 Cypress.io
|
5
|
+
* Released under the MIT License
|
6
|
+
*/
|
7
|
+
|
8
|
+
import 'zone.js';
|
9
|
+
import 'zone.js/testing';
|
10
|
+
import { CommonModule } from '@angular/common';
|
11
|
+
import { Component, EventEmitter } from '@angular/core';
|
12
|
+
import { getTestBed, TestBed } from '@angular/core/testing';
|
13
|
+
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
|
14
|
+
|
15
|
+
/*! *****************************************************************************
|
16
|
+
Copyright (c) Microsoft Corporation.
|
17
|
+
|
18
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
19
|
+
purpose with or without fee is hereby granted.
|
20
|
+
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
22
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
23
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
24
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
25
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
26
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
27
|
+
PERFORMANCE OF THIS SOFTWARE.
|
28
|
+
***************************************************************************** */
|
29
|
+
|
30
|
+
function __rest(s, e) {
|
31
|
+
var t = {};
|
32
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
33
|
+
t[p] = s[p];
|
34
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
35
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
36
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
37
|
+
t[p[i]] = s[p[i]];
|
38
|
+
}
|
39
|
+
return t;
|
40
|
+
}
|
41
|
+
|
42
|
+
function __decorate(decorators, target, key, desc) {
|
43
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
44
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
45
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
46
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
47
|
+
}
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Remove any style or extra link elements from the iframe placeholder
|
51
|
+
* left from any previous test
|
52
|
+
*
|
53
|
+
*/
|
54
|
+
function cleanupStyles() {
|
55
|
+
const styles = document.body.querySelectorAll('[data-cy=injected-style-tag]');
|
56
|
+
styles.forEach((styleElement) => {
|
57
|
+
if (styleElement.parentElement) {
|
58
|
+
styleElement.parentElement.removeChild(styleElement);
|
59
|
+
}
|
60
|
+
});
|
61
|
+
const links = document.body.querySelectorAll('[data-cy=injected-stylesheet]');
|
62
|
+
links.forEach((link) => {
|
63
|
+
if (link.parentElement) {
|
64
|
+
link.parentElement.removeChild(link);
|
65
|
+
}
|
66
|
+
});
|
67
|
+
}
|
68
|
+
function setupHooks(optionalCallback) {
|
69
|
+
// Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js'
|
70
|
+
// file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e
|
71
|
+
// testing so we early return.
|
72
|
+
// System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
|
73
|
+
if (Cypress.testingType !== 'component') {
|
74
|
+
return;
|
75
|
+
}
|
76
|
+
// When running component specs, we cannot allow "cy.visit"
|
77
|
+
// because it will wipe out our preparation work, and does not make much sense
|
78
|
+
// thus we overwrite "cy.visit" to throw an error
|
79
|
+
Cypress.Commands.overwrite('visit', () => {
|
80
|
+
throw new Error('cy.visit from a component spec is not allowed');
|
81
|
+
});
|
82
|
+
// @ts-ignore
|
83
|
+
Cypress.on('test:before:run', () => {
|
84
|
+
optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
|
85
|
+
cleanupStyles();
|
86
|
+
});
|
87
|
+
}
|
88
|
+
|
89
|
+
/**
|
90
|
+
* @hack fixes "Mocha has already been patched with Zone" error.
|
91
|
+
*/
|
92
|
+
// @ts-ignore
|
93
|
+
window.Mocha['__zone_patch__'] = false;
|
94
|
+
/**
|
95
|
+
* Bootstraps the TestModuleMetaData passed to the TestBed
|
96
|
+
*
|
97
|
+
* @param {Type<T>} component Angular component being mounted
|
98
|
+
* @param {MountConfig} config TestBed configuration passed into the mount function
|
99
|
+
* @returns {MountConfig} MountConfig
|
100
|
+
*/
|
101
|
+
function bootstrapModule(component, config) {
|
102
|
+
const testModuleMetaData = __rest(config, ["componentProperties"]);
|
103
|
+
if (!testModuleMetaData.declarations) {
|
104
|
+
testModuleMetaData.declarations = [];
|
105
|
+
}
|
106
|
+
if (!testModuleMetaData.imports) {
|
107
|
+
testModuleMetaData.imports = [];
|
108
|
+
}
|
109
|
+
// check if the component is a standalone component
|
110
|
+
if (component.ɵcmp.standalone) {
|
111
|
+
testModuleMetaData.imports.push(component);
|
112
|
+
}
|
113
|
+
else {
|
114
|
+
testModuleMetaData.declarations.push(component);
|
115
|
+
}
|
116
|
+
if (!testModuleMetaData.imports.includes(CommonModule)) {
|
117
|
+
testModuleMetaData.imports.push(CommonModule);
|
118
|
+
}
|
119
|
+
return testModuleMetaData;
|
120
|
+
}
|
121
|
+
/**
|
122
|
+
* Initializes the TestBed
|
123
|
+
*
|
124
|
+
* @param {Type<T> | string} component Angular component being mounted or its template
|
125
|
+
* @param {MountConfig} config TestBed configuration passed into the mount function
|
126
|
+
* @returns {Type<T>} componentFixture
|
127
|
+
*/
|
128
|
+
function initTestBed(component, config) {
|
129
|
+
const { providers } = config, configRest = __rest(config, ["providers"]);
|
130
|
+
const componentFixture = createComponentFixture(component);
|
131
|
+
TestBed.configureTestingModule(Object.assign({}, bootstrapModule(componentFixture, configRest)));
|
132
|
+
if (providers != null) {
|
133
|
+
TestBed.overrideComponent(componentFixture, {
|
134
|
+
add: {
|
135
|
+
providers,
|
136
|
+
},
|
137
|
+
});
|
138
|
+
}
|
139
|
+
return componentFixture;
|
140
|
+
}
|
141
|
+
let WrapperComponent = class WrapperComponent {
|
142
|
+
};
|
143
|
+
WrapperComponent = __decorate([
|
144
|
+
Component({ selector: 'cy-wrapper-component', template: '' })
|
145
|
+
], WrapperComponent);
|
146
|
+
/**
|
147
|
+
* Returns the Component if Type<T> or creates a WrapperComponent
|
148
|
+
*
|
149
|
+
* @param {Type<T> | string} component The component you want to create a fixture of
|
150
|
+
* @returns {Type<T> | WrapperComponent}
|
151
|
+
*/
|
152
|
+
function createComponentFixture(component) {
|
153
|
+
if (typeof component === 'string') {
|
154
|
+
TestBed.overrideTemplate(WrapperComponent, component);
|
155
|
+
return WrapperComponent;
|
156
|
+
}
|
157
|
+
return component;
|
158
|
+
}
|
159
|
+
/**
|
160
|
+
* Creates the ComponentFixture
|
161
|
+
*
|
162
|
+
* @param {Type<T>} component Angular component being mounted
|
163
|
+
* @param {MountConfig<T>} config MountConfig
|
164
|
+
|
165
|
+
* @returns {ComponentFixture<T>} ComponentFixture
|
166
|
+
*/
|
167
|
+
function setupFixture(component, config) {
|
168
|
+
const fixture = TestBed.createComponent(component);
|
169
|
+
fixture.whenStable().then(() => {
|
170
|
+
var _a;
|
171
|
+
fixture.autoDetectChanges((_a = config.autoDetectChanges) !== null && _a !== void 0 ? _a : true);
|
172
|
+
});
|
173
|
+
return fixture;
|
174
|
+
}
|
175
|
+
/**
|
176
|
+
* Gets the componentInstance and Object.assigns any componentProperties() passed in the MountConfig
|
177
|
+
*
|
178
|
+
* @param {MountConfig} config TestBed configuration passed into the mount function
|
179
|
+
* @param {ComponentFixture<T>} fixture Fixture for debugging and testing a component.
|
180
|
+
* @returns {T} Component being mounted
|
181
|
+
*/
|
182
|
+
function setupComponent(config, fixture) {
|
183
|
+
let component = fixture.componentInstance;
|
184
|
+
if (config === null || config === void 0 ? void 0 : config.componentProperties) {
|
185
|
+
component = Object.assign(component, config.componentProperties);
|
186
|
+
}
|
187
|
+
if (config.autoSpyOutputs) {
|
188
|
+
Object.keys(component).forEach((key, index, keys) => {
|
189
|
+
const property = component[key];
|
190
|
+
if (property instanceof EventEmitter) {
|
191
|
+
component[key] = createOutputSpy(`${key}Spy`);
|
192
|
+
}
|
193
|
+
});
|
194
|
+
}
|
195
|
+
return component;
|
196
|
+
}
|
197
|
+
/**
|
198
|
+
* Mounts an Angular component inside Cypress browser
|
199
|
+
*
|
200
|
+
* @param {Type<T> | string} component Angular component being mounted or its template
|
201
|
+
* @param {MountConfig<T>} config configuration used to configure the TestBed
|
202
|
+
* @example
|
203
|
+
* import { HelloWorldComponent } from 'hello-world/hello-world.component'
|
204
|
+
* import { MyService } from 'services/my.service'
|
205
|
+
* import { SharedModule } from 'shared/shared.module';
|
206
|
+
* import { mount } from '@cypress/angular'
|
207
|
+
* it('can mount', () => {
|
208
|
+
* mount(HelloWorldComponent, {
|
209
|
+
* providers: [MyService],
|
210
|
+
* imports: [SharedModule]
|
211
|
+
* })
|
212
|
+
* cy.get('h1').contains('Hello World')
|
213
|
+
* })
|
214
|
+
*
|
215
|
+
* or
|
216
|
+
*
|
217
|
+
* it('can mount with template', () => {
|
218
|
+
* mount('<app-hello-world></app-hello-world>', {
|
219
|
+
* declarations: [HelloWorldComponent],
|
220
|
+
* providers: [MyService],
|
221
|
+
* imports: [SharedModule]
|
222
|
+
* })
|
223
|
+
* })
|
224
|
+
* @returns Cypress.Chainable<MountResponse<T>>
|
225
|
+
*/
|
226
|
+
function mount(component, config = {}) {
|
227
|
+
const componentFixture = initTestBed(component, config);
|
228
|
+
const fixture = setupFixture(componentFixture, config);
|
229
|
+
const componentInstance = setupComponent(config, fixture);
|
230
|
+
const mountResponse = {
|
231
|
+
fixture,
|
232
|
+
component: componentInstance,
|
233
|
+
};
|
234
|
+
const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name;
|
235
|
+
Cypress.log({
|
236
|
+
name: 'mount',
|
237
|
+
message: logMessage,
|
238
|
+
consoleProps: () => ({ result: mountResponse }),
|
239
|
+
});
|
240
|
+
return cy.wrap(mountResponse, { log: false });
|
241
|
+
}
|
242
|
+
/**
|
243
|
+
* Creates a new Event Emitter and then spies on it's `emit` method
|
244
|
+
*
|
245
|
+
* @param {string} alias name you want to use for your cy.spy() alias
|
246
|
+
* @returns EventEmitter<T>
|
247
|
+
*/
|
248
|
+
const createOutputSpy = (alias) => {
|
249
|
+
const emitter = new EventEmitter();
|
250
|
+
cy.spy(emitter, 'emit').as(alias);
|
251
|
+
return emitter;
|
252
|
+
};
|
253
|
+
// Only needs to run once, we reset before each test
|
254
|
+
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
|
255
|
+
teardown: { destroyAfterEach: false },
|
256
|
+
});
|
257
|
+
setupHooks(() => {
|
258
|
+
// Not public, we need to call this to remove the last component from the DOM
|
259
|
+
TestBed['tearDownTestingModule']();
|
260
|
+
TestBed.resetTestingModule();
|
261
|
+
});
|
262
|
+
|
263
|
+
export { createOutputSpy, mount };
|
@@ -0,0 +1,111 @@
|
|
1
|
+
/// <reference types="cypress" />
|
2
|
+
import 'zone.js';
|
3
|
+
import 'zone.js/testing';
|
4
|
+
import { Type } from '@angular/core';
|
5
|
+
import { ComponentFixture, TestModuleMetadata } from '@angular/core/testing';
|
6
|
+
/**
|
7
|
+
* Additional module configurations needed while mounting the component, like
|
8
|
+
* providers, declarations, imports and even component @Inputs()
|
9
|
+
*
|
10
|
+
*
|
11
|
+
* @interface MountConfig
|
12
|
+
* @see https://angular.io/api/core/testing/TestModuleMetadata
|
13
|
+
*/
|
14
|
+
export interface MountConfig<T> extends TestModuleMetadata {
|
15
|
+
/**
|
16
|
+
* @memberof MountConfig
|
17
|
+
* @description flag to automatically create a cy.spy() for every component @Output() property
|
18
|
+
* @example
|
19
|
+
* export class ButtonComponent {
|
20
|
+
* @Output clicked = new EventEmitter()
|
21
|
+
* }
|
22
|
+
*
|
23
|
+
* cy.mount(ButtonComponent, { autoSpyOutputs: true })
|
24
|
+
* cy.get('@clickedSpy).should('have.been.called')
|
25
|
+
*/
|
26
|
+
autoSpyOutputs?: boolean;
|
27
|
+
/**
|
28
|
+
* @memberof MountConfig
|
29
|
+
* @description flag defaulted to true to automatically detect changes in your components
|
30
|
+
*/
|
31
|
+
autoDetectChanges?: boolean;
|
32
|
+
/**
|
33
|
+
* @memberof MountConfig
|
34
|
+
* @example
|
35
|
+
* import { ButtonComponent } from 'button/button.component'
|
36
|
+
* it('renders a button with Save text', () => {
|
37
|
+
* cy.mount(ButtonComponent, { componentProperties: { text: 'Save' }})
|
38
|
+
* cy.get('button').contains('Save')
|
39
|
+
* })
|
40
|
+
*
|
41
|
+
* it('renders a button with a cy.spy() replacing EventEmitter', () => {
|
42
|
+
* cy.mount(ButtonComponent, {
|
43
|
+
* componentProperties: {
|
44
|
+
* clicked: cy.spy().as('mySpy)
|
45
|
+
* }
|
46
|
+
* })
|
47
|
+
* cy.get('button').click()
|
48
|
+
* cy.get('@mySpy').should('have.been.called')
|
49
|
+
* })
|
50
|
+
*/
|
51
|
+
componentProperties?: Partial<{
|
52
|
+
[P in keyof T]: T[P];
|
53
|
+
}>;
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Type that the `mount` function returns
|
57
|
+
* @type MountResponse<T>
|
58
|
+
*/
|
59
|
+
export declare type MountResponse<T> = {
|
60
|
+
/**
|
61
|
+
* Fixture for debugging and testing a component.
|
62
|
+
*
|
63
|
+
* @memberof MountResponse
|
64
|
+
* @see https://angular.io/api/core/testing/ComponentFixture
|
65
|
+
*/
|
66
|
+
fixture: ComponentFixture<T>;
|
67
|
+
/**
|
68
|
+
* The instance of the root component class
|
69
|
+
*
|
70
|
+
* @memberof MountResponse
|
71
|
+
* @see https://angular.io/api/core/testing/ComponentFixture#componentInstance
|
72
|
+
*/
|
73
|
+
component: T;
|
74
|
+
};
|
75
|
+
/**
|
76
|
+
* Mounts an Angular component inside Cypress browser
|
77
|
+
*
|
78
|
+
* @param {Type<T> | string} component Angular component being mounted or its template
|
79
|
+
* @param {MountConfig<T>} config configuration used to configure the TestBed
|
80
|
+
* @example
|
81
|
+
* import { HelloWorldComponent } from 'hello-world/hello-world.component'
|
82
|
+
* import { MyService } from 'services/my.service'
|
83
|
+
* import { SharedModule } from 'shared/shared.module';
|
84
|
+
* import { mount } from '@cypress/angular'
|
85
|
+
* it('can mount', () => {
|
86
|
+
* mount(HelloWorldComponent, {
|
87
|
+
* providers: [MyService],
|
88
|
+
* imports: [SharedModule]
|
89
|
+
* })
|
90
|
+
* cy.get('h1').contains('Hello World')
|
91
|
+
* })
|
92
|
+
*
|
93
|
+
* or
|
94
|
+
*
|
95
|
+
* it('can mount with template', () => {
|
96
|
+
* mount('<app-hello-world></app-hello-world>', {
|
97
|
+
* declarations: [HelloWorldComponent],
|
98
|
+
* providers: [MyService],
|
99
|
+
* imports: [SharedModule]
|
100
|
+
* })
|
101
|
+
* })
|
102
|
+
* @returns Cypress.Chainable<MountResponse<T>>
|
103
|
+
*/
|
104
|
+
export declare function mount<T>(component: Type<T> | string, config?: MountConfig<T>): Cypress.Chainable<MountResponse<T>>;
|
105
|
+
/**
|
106
|
+
* Creates a new Event Emitter and then spies on it's `emit` method
|
107
|
+
*
|
108
|
+
* @param {string} alias name you want to use for your cy.spy() alias
|
109
|
+
* @returns EventEmitter<T>
|
110
|
+
*/
|
111
|
+
export declare const createOutputSpy: <T>(alias: string) => any;
|
@@ -0,0 +1,70 @@
|
|
1
|
+
{
|
2
|
+
"name": "@cypress/angular",
|
3
|
+
"version": "0.0.0-development",
|
4
|
+
"description": "Test Angular Components using Cypress",
|
5
|
+
"private": true,
|
6
|
+
"main": "dist/index.js",
|
7
|
+
"scripts": {
|
8
|
+
"prebuild": "rimraf dist",
|
9
|
+
"build": "rollup -c rollup.config.js",
|
10
|
+
"postbuild": "node ../../scripts/sync-exported-npm-with-cli.js",
|
11
|
+
"build-prod": "yarn build",
|
12
|
+
"check-ts": "tsc --noEmit"
|
13
|
+
},
|
14
|
+
"dependencies": {},
|
15
|
+
"devDependencies": {
|
16
|
+
"@angular/common": "^14.0.6",
|
17
|
+
"@angular/core": "^14.0.6",
|
18
|
+
"@angular/platform-browser-dynamic": "^14.0.6",
|
19
|
+
"@rollup/plugin-node-resolve": "^11.1.1",
|
20
|
+
"rollup-plugin-typescript2": "^0.29.0",
|
21
|
+
"typescript": "~4.2.3",
|
22
|
+
"zone.js": "~0.11.4"
|
23
|
+
},
|
24
|
+
"peerDependencies": {
|
25
|
+
"@angular/common": ">=13",
|
26
|
+
"@angular/core": ">=13",
|
27
|
+
"@angular/platform-browser-dynamic": ">=13",
|
28
|
+
"zone.js": ">=0.11.0"
|
29
|
+
},
|
30
|
+
"files": [
|
31
|
+
"dist"
|
32
|
+
],
|
33
|
+
"types": "dist/index.d.ts",
|
34
|
+
"license": "MIT",
|
35
|
+
"repository": {
|
36
|
+
"type": "git",
|
37
|
+
"url": "https://github.com/cypress-io/cypress.git"
|
38
|
+
},
|
39
|
+
"homepage": "https://github.com/cypress-io/cypress/blob/master/npm/angular/#readme",
|
40
|
+
"author": "Jordan Powell",
|
41
|
+
"bugs": "https://github.com/cypress-io/cypress/issues/new?assignees=&labels=npm%3A%20%40cypress%2Fangular&template=1-bug-report.md&title=",
|
42
|
+
"keywords": [
|
43
|
+
"angular",
|
44
|
+
"cypress",
|
45
|
+
"cypress-io",
|
46
|
+
"test",
|
47
|
+
"testing"
|
48
|
+
],
|
49
|
+
"contributors": [
|
50
|
+
{
|
51
|
+
"name": "Jordan Powell",
|
52
|
+
"social": "@jordanpowell88"
|
53
|
+
},
|
54
|
+
{
|
55
|
+
"name": "Zach Williams",
|
56
|
+
"social": "@ZachJW34"
|
57
|
+
}
|
58
|
+
],
|
59
|
+
"module": "dist/index.js",
|
60
|
+
"publishConfig": {
|
61
|
+
"access": "public"
|
62
|
+
},
|
63
|
+
"standard": {
|
64
|
+
"globals": [
|
65
|
+
"Cypress",
|
66
|
+
"cy",
|
67
|
+
"expect"
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
package/mount-utils/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# [@cypress/mount-utils-v2.0.1](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v2.0.0...@cypress/mount-utils-v2.0.1) (2022-08-11)
|
2
|
+
|
3
|
+
|
4
|
+
### Bug Fixes
|
5
|
+
|
6
|
+
* remove CT side effects from mount when e2e testing ([#22633](https://github.com/cypress-io/cypress/issues/22633)) ([a9476ec](https://github.com/cypress-io/cypress/commit/a9476ecb3d43f628b689e060294a1952937cb1a7))
|
7
|
+
|
1
8
|
# [@cypress/mount-utils-v2.0.0](https://github.com/cypress-io/cypress/compare/@cypress/mount-utils-v1.0.2...@cypress/mount-utils-v2.0.0) (2022-06-13)
|
2
9
|
|
3
10
|
|