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.
@@ -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
+ }
@@ -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