cypress 10.4.0 → 10.5.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
![Example component test](images/dynamic.gif)
|
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
|
|