cypress 13.11.0 → 13.13.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.
Files changed (62) hide show
  1. package/angular/angular/dist/index.d.ts +1 -2
  2. package/angular/angular/dist/index.js +239 -239
  3. package/angular/angular/package.json +1 -1
  4. package/angular/dist/index.d.ts +1 -2
  5. package/angular/dist/index.js +239 -239
  6. package/angular/package.json +1 -1
  7. package/angular-signals/README.md +11 -0
  8. package/angular-signals/angular-signals/README.md +11 -0
  9. package/angular-signals/angular-signals/dist/index.d.ts +136 -0
  10. package/angular-signals/angular-signals/dist/index.js +1861 -0
  11. package/angular-signals/angular-signals/package.json +74 -0
  12. package/angular-signals/dist/index.d.ts +136 -0
  13. package/angular-signals/dist/index.js +1861 -0
  14. package/angular-signals/package.json +74 -0
  15. package/lib/cli.js +0 -1
  16. package/lib/exec/xvfb.js +0 -1
  17. package/lib/logger.js +0 -3
  18. package/mount-utils/dist/index.d.ts +1 -1
  19. package/mount-utils/mount-utils/dist/index.d.ts +1 -1
  20. package/mount-utils/mount-utils/package.json +1 -1
  21. package/mount-utils/package.json +1 -1
  22. package/package.json +11 -5
  23. package/react/dist/cypress-react.cjs.js +237 -237
  24. package/react/dist/cypress-react.esm-bundler.js +237 -237
  25. package/react/dist/index.d.ts +1 -1
  26. package/react/package.json +3 -3
  27. package/react/react/dist/cypress-react.cjs.js +237 -237
  28. package/react/react/dist/cypress-react.esm-bundler.js +237 -237
  29. package/react/react/dist/index.d.ts +1 -1
  30. package/react/react/package.json +3 -3
  31. package/react18/dist/cypress-react.cjs.js +222 -222
  32. package/react18/dist/cypress-react.esm-bundler.js +222 -222
  33. package/react18/dist/index.d.ts +1 -1
  34. package/react18/package.json +1 -1
  35. package/react18/react18/dist/cypress-react.cjs.js +222 -222
  36. package/react18/react18/dist/cypress-react.esm-bundler.js +222 -222
  37. package/react18/react18/dist/index.d.ts +1 -1
  38. package/react18/react18/package.json +1 -1
  39. package/svelte/dist/cypress-svelte.cjs.js +61 -61
  40. package/svelte/dist/cypress-svelte.esm-bundler.js +61 -61
  41. package/svelte/dist/index.d.ts +2 -2
  42. package/svelte/package.json +1 -1
  43. package/svelte/svelte/dist/cypress-svelte.cjs.js +61 -61
  44. package/svelte/svelte/dist/cypress-svelte.esm-bundler.js +61 -61
  45. package/svelte/svelte/dist/index.d.ts +2 -2
  46. package/svelte/svelte/package.json +1 -1
  47. package/vue/dist/cypress-vue.cjs.js +128 -128
  48. package/vue/dist/cypress-vue.esm-bundler.js +128 -128
  49. package/vue/dist/index.d.ts +5 -5
  50. package/vue/package.json +5 -5
  51. package/vue/vue/dist/cypress-vue.cjs.js +128 -128
  52. package/vue/vue/dist/cypress-vue.esm-bundler.js +128 -128
  53. package/vue/vue/dist/index.d.ts +5 -5
  54. package/vue/vue/package.json +5 -5
  55. package/vue2/dist/cypress-vue2.cjs.js +211 -211
  56. package/vue2/dist/cypress-vue2.esm-bundler.js +211 -211
  57. package/vue2/dist/index.d.ts +11 -11
  58. package/vue2/package.json +1 -1
  59. package/vue2/vue2/dist/cypress-vue2.cjs.js +211 -211
  60. package/vue2/vue2/dist/cypress-vue2.esm-bundler.js +211 -211
  61. package/vue2/vue2/dist/index.d.ts +11 -11
  62. package/vue2/vue2/package.json +1 -1
@@ -95,246 +95,246 @@ function setupHooks(optionalCallback) {
95
95
  });
96
96
  }
97
97
 
98
- /**
99
- * @hack fixes "Mocha has already been patched with Zone" error.
100
- */
101
- // @ts-ignore
102
- window.Mocha['__zone_patch__'] = false;
103
- let activeFixture = null;
104
- function cleanup() {
105
- // Not public, we need to call this to remove the last component from the DOM
106
- try {
107
- getTestBed().tearDownTestingModule();
108
- }
109
- catch (e) {
110
- const notSupportedError = new Error(`Failed to teardown component. The version of Angular you are using may not be officially supported.`);
111
- notSupportedError.docsUrl = 'https://on.cypress.io/component-framework-configuration';
112
- throw notSupportedError;
113
- }
114
- getTestBed().resetTestingModule();
115
- activeFixture = null;
116
- }
117
- // 'zone.js/testing' is not properly aliasing `it.skip` but it does provide `xit`/`xspecify`
118
- // Written up under https://github.com/angular/angular/issues/46297 but is not seeing movement
119
- // so we'll patch here pending a fix in that library
120
- // @ts-ignore Ignore so that way we can bypass semantic error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
121
- globalThis.it.skip = globalThis.xit;
122
- let CypressAngularErrorHandler = class CypressAngularErrorHandler {
123
- handleError(error) {
124
- throw error;
125
- }
126
- };
127
- CypressAngularErrorHandler = __decorate([
128
- Injectable()
129
- ], CypressAngularErrorHandler);
130
- /**
131
- * Bootstraps the TestModuleMetaData passed to the TestBed
132
- *
133
- * @param {Type<T>} component Angular component being mounted
134
- * @param {MountConfig} config TestBed configuration passed into the mount function
135
- * @returns {MountConfig} MountConfig
136
- */
137
- function bootstrapModule(component, config) {
138
- var _a;
139
- const testModuleMetaData = __rest(config, ["componentProperties"]);
140
- if (!testModuleMetaData.declarations) {
141
- testModuleMetaData.declarations = [];
142
- }
143
- if (!testModuleMetaData.imports) {
144
- testModuleMetaData.imports = [];
145
- }
146
- if (!testModuleMetaData.providers) {
147
- testModuleMetaData.providers = [];
148
- }
149
- // Replace default error handler since it will swallow uncaught exceptions.
150
- // We want these to be uncaught so Cypress catches it and fails the test
151
- testModuleMetaData.providers.push({
152
- provide: ErrorHandler,
153
- useClass: CypressAngularErrorHandler,
154
- });
155
- // check if the component is a standalone component
156
- if ((_a = component.ɵcmp) === null || _a === void 0 ? void 0 : _a.standalone) {
157
- testModuleMetaData.imports.push(component);
158
- }
159
- else {
160
- testModuleMetaData.declarations.push(component);
161
- }
162
- if (!testModuleMetaData.imports.includes(CommonModule)) {
163
- testModuleMetaData.imports.push(CommonModule);
164
- }
165
- return testModuleMetaData;
166
- }
167
- let CypressTestComponentRenderer = class CypressTestComponentRenderer extends TestComponentRenderer {
168
- insertRootElement(rootElId) {
169
- this.removeAllRootElements();
170
- const rootElement = getContainerEl();
171
- rootElement.setAttribute('id', rootElId);
172
- }
173
- removeAllRootElements() {
174
- getContainerEl().innerHTML = '';
175
- }
176
- };
177
- CypressTestComponentRenderer = __decorate([
178
- Injectable()
179
- ], CypressTestComponentRenderer);
180
- /**
181
- * Initializes the TestBed
182
- *
183
- * @param {Type<T> | string} component Angular component being mounted or its template
184
- * @param {MountConfig} config TestBed configuration passed into the mount function
185
- * @returns {Type<T>} componentFixture
186
- */
187
- function initTestBed(component, config) {
188
- const componentFixture = createComponentFixture(component);
189
- getTestBed().configureTestingModule(Object.assign({}, bootstrapModule(componentFixture, config)));
190
- getTestBed().overrideProvider(TestComponentRenderer, { useValue: new CypressTestComponentRenderer() });
191
- return componentFixture;
192
- }
193
- let WrapperComponent = class WrapperComponent {
194
- };
195
- WrapperComponent = __decorate([
196
- Component({ selector: 'cy-wrapper-component', template: '' })
197
- ], WrapperComponent);
198
- /**
199
- * Returns the Component if Type<T> or creates a WrapperComponent
200
- *
201
- * @param {Type<T> | string} component The component you want to create a fixture of
202
- * @returns {Type<T> | WrapperComponent}
203
- */
204
- function createComponentFixture(component) {
205
- if (typeof component === 'string') {
206
- // getTestBed().overrideTemplate is available in v14+
207
- // The static TestBed.overrideTemplate is available across versions
208
- TestBed.overrideTemplate(WrapperComponent, component);
209
- return WrapperComponent;
210
- }
211
- return component;
212
- }
213
- /**
214
- * Creates the ComponentFixture
215
- *
216
- * @param {Type<T>} component Angular component being mounted
217
- * @param {MountConfig<T>} config MountConfig
98
+ /**
99
+ * @hack fixes "Mocha has already been patched with Zone" error.
100
+ */
101
+ // @ts-ignore
102
+ window.Mocha['__zone_patch__'] = false;
103
+ let activeFixture = null;
104
+ function cleanup() {
105
+ // Not public, we need to call this to remove the last component from the DOM
106
+ try {
107
+ getTestBed().tearDownTestingModule();
108
+ }
109
+ catch (e) {
110
+ const notSupportedError = new Error(`Failed to teardown component. The version of Angular you are using may not be officially supported.`);
111
+ notSupportedError.docsUrl = 'https://on.cypress.io/component-framework-configuration';
112
+ throw notSupportedError;
113
+ }
114
+ getTestBed().resetTestingModule();
115
+ activeFixture = null;
116
+ }
117
+ // 'zone.js/testing' is not properly aliasing `it.skip` but it does provide `xit`/`xspecify`
118
+ // Written up under https://github.com/angular/angular/issues/46297 but is not seeing movement
119
+ // so we'll patch here pending a fix in that library
120
+ // @ts-ignore Ignore so that way we can bypass semantic error TS7017: Element implicitly has an 'any' type because type 'typeof globalThis' has no index signature.
121
+ globalThis.it.skip = globalThis.xit;
122
+ let CypressAngularErrorHandler = class CypressAngularErrorHandler {
123
+ handleError(error) {
124
+ throw error;
125
+ }
126
+ };
127
+ CypressAngularErrorHandler = __decorate([
128
+ Injectable()
129
+ ], CypressAngularErrorHandler);
130
+ /**
131
+ * Bootstraps the TestModuleMetaData passed to the TestBed
132
+ *
133
+ * @param {Type<T>} component Angular component being mounted
134
+ * @param {MountConfig} config TestBed configuration passed into the mount function
135
+ * @returns {MountConfig} MountConfig
136
+ */
137
+ function bootstrapModule(component, config) {
138
+ var _a;
139
+ const testModuleMetaData = __rest(config, ["componentProperties"]);
140
+ if (!testModuleMetaData.declarations) {
141
+ testModuleMetaData.declarations = [];
142
+ }
143
+ if (!testModuleMetaData.imports) {
144
+ testModuleMetaData.imports = [];
145
+ }
146
+ if (!testModuleMetaData.providers) {
147
+ testModuleMetaData.providers = [];
148
+ }
149
+ // Replace default error handler since it will swallow uncaught exceptions.
150
+ // We want these to be uncaught so Cypress catches it and fails the test
151
+ testModuleMetaData.providers.push({
152
+ provide: ErrorHandler,
153
+ useClass: CypressAngularErrorHandler,
154
+ });
155
+ // check if the component is a standalone component
156
+ if ((_a = component.ɵcmp) === null || _a === void 0 ? void 0 : _a.standalone) {
157
+ testModuleMetaData.imports.push(component);
158
+ }
159
+ else {
160
+ testModuleMetaData.declarations.push(component);
161
+ }
162
+ if (!testModuleMetaData.imports.includes(CommonModule)) {
163
+ testModuleMetaData.imports.push(CommonModule);
164
+ }
165
+ return testModuleMetaData;
166
+ }
167
+ let CypressTestComponentRenderer = class CypressTestComponentRenderer extends TestComponentRenderer {
168
+ insertRootElement(rootElId) {
169
+ this.removeAllRootElements();
170
+ const rootElement = getContainerEl();
171
+ rootElement.setAttribute('id', rootElId);
172
+ }
173
+ removeAllRootElements() {
174
+ getContainerEl().innerHTML = '';
175
+ }
176
+ };
177
+ CypressTestComponentRenderer = __decorate([
178
+ Injectable()
179
+ ], CypressTestComponentRenderer);
180
+ /**
181
+ * Initializes the TestBed
182
+ *
183
+ * @param {Type<T> | string} component Angular component being mounted or its template
184
+ * @param {MountConfig} config TestBed configuration passed into the mount function
185
+ * @returns {Type<T>} componentFixture
186
+ */
187
+ function initTestBed(component, config) {
188
+ const componentFixture = createComponentFixture(component);
189
+ getTestBed().configureTestingModule(Object.assign({}, bootstrapModule(componentFixture, config)));
190
+ getTestBed().overrideProvider(TestComponentRenderer, { useValue: new CypressTestComponentRenderer() });
191
+ return componentFixture;
192
+ }
193
+ let WrapperComponent = class WrapperComponent {
194
+ };
195
+ WrapperComponent = __decorate([
196
+ Component({ selector: 'cy-wrapper-component', template: '' })
197
+ ], WrapperComponent);
198
+ /**
199
+ * Returns the Component if Type<T> or creates a WrapperComponent
200
+ *
201
+ * @param {Type<T> | string} component The component you want to create a fixture of
202
+ * @returns {Type<T> | WrapperComponent}
203
+ */
204
+ function createComponentFixture(component) {
205
+ if (typeof component === 'string') {
206
+ // getTestBed().overrideTemplate is available in v14+
207
+ // The static TestBed.overrideTemplate is available across versions
208
+ TestBed.overrideTemplate(WrapperComponent, component);
209
+ return WrapperComponent;
210
+ }
211
+ return component;
212
+ }
213
+ /**
214
+ * Creates the ComponentFixture
215
+ *
216
+ * @param {Type<T>} component Angular component being mounted
217
+ * @param {MountConfig<T>} config MountConfig
218
218
 
219
- * @returns {ComponentFixture<T>} ComponentFixture
220
- */
221
- function setupFixture(component, config) {
222
- const fixture = getTestBed().createComponent(component);
223
- setupComponent(config, fixture);
224
- fixture.whenStable().then(() => {
225
- var _a;
226
- fixture.autoDetectChanges((_a = config.autoDetectChanges) !== null && _a !== void 0 ? _a : true);
227
- });
228
- return fixture;
229
- }
230
- /**
231
- * Gets the componentInstance and Object.assigns any componentProperties() passed in the MountConfig
232
- *
233
- * @param {MountConfig} config TestBed configuration passed into the mount function
234
- * @param {ComponentFixture<T>} fixture Fixture for debugging and testing a component.
235
- * @returns {T} Component being mounted
236
- */
237
- function setupComponent(config, fixture) {
238
- let component = fixture.componentInstance;
239
- if (config === null || config === void 0 ? void 0 : config.componentProperties) {
240
- component = Object.assign(component, config.componentProperties);
241
- }
242
- if (config.autoSpyOutputs) {
243
- Object.keys(component).forEach((key) => {
244
- const property = component[key];
245
- if (property instanceof EventEmitter) {
246
- component[key] = createOutputSpy(`${key}Spy`);
247
- }
248
- });
249
- }
250
- // Manually call ngOnChanges when mounting components using the class syntax.
251
- // This is necessary because we are assigning input values to the class directly
252
- // on mount and therefore the ngOnChanges() lifecycle is not triggered.
253
- if (component.ngOnChanges && config.componentProperties) {
254
- const { componentProperties } = config;
255
- const simpleChanges = Object.entries(componentProperties).reduce((acc, [key, value]) => {
256
- acc[key] = new SimpleChange(null, value, true);
257
- return acc;
258
- }, {});
259
- if (Object.keys(componentProperties).length > 0) {
260
- component.ngOnChanges(simpleChanges);
261
- }
262
- }
263
- }
264
- /**
265
- * Mounts an Angular component inside Cypress browser
266
- *
267
- * @param component Angular component being mounted or its template
268
- * @param config configuration used to configure the TestBed
269
- * @example
270
- * import { mount } from '@cypress/angular'
271
- * import { StepperComponent } from './stepper.component'
272
- * import { MyService } from 'services/my.service'
273
- * import { SharedModule } from 'shared/shared.module';
274
- * it('mounts', () => {
275
- * mount(StepperComponent, {
276
- * providers: [MyService],
277
- * imports: [SharedModule]
278
- * })
279
- * cy.get('[data-cy=increment]').click()
280
- * cy.get('[data-cy=counter]').should('have.text', '1')
281
- * })
282
- *
283
- * // or
284
- *
285
- * it('mounts with template', () => {
286
- * mount('<app-stepper></app-stepper>', {
287
- * declarations: [StepperComponent],
288
- * })
289
- * })
290
- *
291
- * @see {@link https://on.cypress.io/mounting-angular} for more details.
292
- *
293
- * @returns A component and component fixture
294
- */
295
- function mount(component, config = {}) {
296
- // Remove last mounted component if cy.mount is called more than once in a test
297
- if (activeFixture) {
298
- cleanup();
299
- }
300
- const componentFixture = initTestBed(component, config);
301
- activeFixture = setupFixture(componentFixture, config);
302
- const mountResponse = {
303
- fixture: activeFixture,
304
- component: activeFixture.componentInstance,
305
- };
306
- const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name;
307
- Cypress.log({
308
- name: 'mount',
309
- message: logMessage,
310
- consoleProps: () => ({ result: mountResponse }),
311
- });
312
- return cy.wrap(mountResponse, { log: false });
313
- }
314
- /**
315
- * Creates a new Event Emitter and then spies on it's `emit` method
316
- *
317
- * @param {string} alias name you want to use for your cy.spy() alias
318
- * @returns EventEmitter<T>
319
- * @example
320
- * import { StepperComponent } from './stepper.component'
321
- * import { mount, createOutputSpy } from '@cypress/angular'
322
- *
323
- * it('Has spy', () => {
324
- * mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } })
325
- * cy.get('[data-cy=increment]').click()
326
- * cy.get('@changeSpy').should('have.been.called')
327
- * })
328
- */
329
- const createOutputSpy = (alias) => {
330
- const emitter = new EventEmitter();
331
- cy.spy(emitter, 'emit').as(alias);
332
- return emitter;
333
- };
334
- // Only needs to run once, we reset before each test
335
- getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
336
- teardown: { destroyAfterEach: false },
337
- });
219
+ * @returns {ComponentFixture<T>} ComponentFixture
220
+ */
221
+ function setupFixture(component, config) {
222
+ const fixture = getTestBed().createComponent(component);
223
+ setupComponent(config, fixture);
224
+ fixture.whenStable().then(() => {
225
+ var _a;
226
+ fixture.autoDetectChanges((_a = config.autoDetectChanges) !== null && _a !== void 0 ? _a : true);
227
+ });
228
+ return fixture;
229
+ }
230
+ /**
231
+ * Gets the componentInstance and Object.assigns any componentProperties() passed in the MountConfig
232
+ *
233
+ * @param {MountConfig} config TestBed configuration passed into the mount function
234
+ * @param {ComponentFixture<T>} fixture Fixture for debugging and testing a component.
235
+ * @returns {T} Component being mounted
236
+ */
237
+ function setupComponent(config, fixture) {
238
+ let component = fixture.componentInstance;
239
+ if (config === null || config === void 0 ? void 0 : config.componentProperties) {
240
+ component = Object.assign(component, config.componentProperties);
241
+ }
242
+ if (config.autoSpyOutputs) {
243
+ Object.keys(component).forEach((key) => {
244
+ const property = component[key];
245
+ if (property instanceof EventEmitter) {
246
+ component[key] = createOutputSpy(`${key}Spy`);
247
+ }
248
+ });
249
+ }
250
+ // Manually call ngOnChanges when mounting components using the class syntax.
251
+ // This is necessary because we are assigning input values to the class directly
252
+ // on mount and therefore the ngOnChanges() lifecycle is not triggered.
253
+ if (component.ngOnChanges && config.componentProperties) {
254
+ const { componentProperties } = config;
255
+ const simpleChanges = Object.entries(componentProperties).reduce((acc, [key, value]) => {
256
+ acc[key] = new SimpleChange(null, value, true);
257
+ return acc;
258
+ }, {});
259
+ if (Object.keys(componentProperties).length > 0) {
260
+ component.ngOnChanges(simpleChanges);
261
+ }
262
+ }
263
+ }
264
+ /**
265
+ * Mounts an Angular component inside Cypress browser
266
+ *
267
+ * @param component Angular component being mounted or its template
268
+ * @param config configuration used to configure the TestBed
269
+ * @example
270
+ * import { mount } from '@cypress/angular'
271
+ * import { StepperComponent } from './stepper.component'
272
+ * import { MyService } from 'services/my.service'
273
+ * import { SharedModule } from 'shared/shared.module';
274
+ * it('mounts', () => {
275
+ * mount(StepperComponent, {
276
+ * providers: [MyService],
277
+ * imports: [SharedModule]
278
+ * })
279
+ * cy.get('[data-cy=increment]').click()
280
+ * cy.get('[data-cy=counter]').should('have.text', '1')
281
+ * })
282
+ *
283
+ * // or
284
+ *
285
+ * it('mounts with template', () => {
286
+ * mount('<app-stepper></app-stepper>', {
287
+ * declarations: [StepperComponent],
288
+ * })
289
+ * })
290
+ *
291
+ * @see {@link https://on.cypress.io/mounting-angular} for more details.
292
+ *
293
+ * @returns A component and component fixture
294
+ */
295
+ function mount(component, config = {}) {
296
+ // Remove last mounted component if cy.mount is called more than once in a test
297
+ if (activeFixture) {
298
+ cleanup();
299
+ }
300
+ const componentFixture = initTestBed(component, config);
301
+ activeFixture = setupFixture(componentFixture, config);
302
+ const mountResponse = {
303
+ fixture: activeFixture,
304
+ component: activeFixture.componentInstance,
305
+ };
306
+ const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name;
307
+ Cypress.log({
308
+ name: 'mount',
309
+ message: logMessage,
310
+ consoleProps: () => ({ result: mountResponse }),
311
+ });
312
+ return cy.wrap(mountResponse, { log: false });
313
+ }
314
+ /**
315
+ * Creates a new Event Emitter and then spies on it's `emit` method
316
+ *
317
+ * @param {string} alias name you want to use for your cy.spy() alias
318
+ * @returns EventEmitter<T>
319
+ * @example
320
+ * import { StepperComponent } from './stepper.component'
321
+ * import { mount, createOutputSpy } from '@cypress/angular'
322
+ *
323
+ * it('Has spy', () => {
324
+ * mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } })
325
+ * cy.get('[data-cy=increment]').click()
326
+ * cy.get('@changeSpy').should('have.been.called')
327
+ * })
328
+ */
329
+ const createOutputSpy = (alias) => {
330
+ const emitter = new EventEmitter();
331
+ cy.spy(emitter, 'emit').as(alias);
332
+ return emitter;
333
+ };
334
+ // Only needs to run once, we reset before each test
335
+ getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {
336
+ teardown: { destroyAfterEach: false },
337
+ });
338
338
  setupHooks(cleanup);
339
339
 
340
340
  export { CypressTestComponentRenderer, createOutputSpy, mount };
@@ -16,7 +16,7 @@
16
16
  "@angular/core": "^14.2.0",
17
17
  "@angular/platform-browser-dynamic": "^14.2.0",
18
18
  "@cypress/mount-utils": "0.0.0-development",
19
- "typescript": "^4.7.4",
19
+ "typescript": "~5.4.5",
20
20
  "zone.js": "~0.11.4"
21
21
  },
22
22
  "peerDependencies": {
@@ -0,0 +1,11 @@
1
+ # @cypress/angular-signals
2
+
3
+ Mount Angular components in the open source [Cypress.io](https://www.cypress.io/) test runner. This package is an extension of `@cypress/angular`, but with [signals](https://angular.dev/guide/signals) support.
4
+
5
+ > **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Angular Component Testing Docs](https://docs.cypress.io/guides/component-testing/angular/overview) for mounting Angular components. Installing and importing `mount` from `@cypress/angular-signals` should only be done for advanced use-cases.
6
+
7
+ ## Development
8
+
9
+ Run `yarn build` to compile and sync packages to the `cypress` cli package.
10
+
11
+ ## [Changelog](./CHANGELOG.md)
@@ -0,0 +1,11 @@
1
+ # @cypress/angular-signals
2
+
3
+ Mount Angular components in the open source [Cypress.io](https://www.cypress.io/) test runner. This package is an extension of `@cypress/angular`, but with [signals](https://angular.dev/guide/signals) support.
4
+
5
+ > **Note:** This package is bundled with the `cypress` package and should not need to be installed separately. See the [Angular Component Testing Docs](https://docs.cypress.io/guides/component-testing/angular/overview) for mounting Angular components. Installing and importing `mount` from `@cypress/angular-signals` should only be done for advanced use-cases.
6
+
7
+ ## Development
8
+
9
+ Run `yarn build` to compile and sync packages to the `cypress` cli package.
10
+
11
+ ## [Changelog](./CHANGELOG.md)
@@ -0,0 +1,136 @@
1
+ /// <reference types="cypress" />
2
+
3
+ import { InputSignal, WritableSignal, Type } from '@angular/core';
4
+ import { TestModuleMetadata, ComponentFixture, TestComponentRenderer } from '@angular/core/testing';
5
+
6
+ /**
7
+ * Additional module configurations needed while mounting the component, like
8
+ * providers, declarations, imports and even component @Inputs()
9
+ *
10
+ * @interface MountConfig
11
+ * @see https://angular.io/api/core/testing/TestModuleMetadata
12
+ */
13
+ interface MountConfig<T> extends TestModuleMetadata {
14
+ /**
15
+ * @memberof MountConfig
16
+ * @description flag to automatically create a cy.spy() for every component @Output() property
17
+ * @example
18
+ * export class ButtonComponent {
19
+ * @Output clicked = new EventEmitter()
20
+ * }
21
+ *
22
+ * cy.mount(ButtonComponent, { autoSpyOutputs: true })
23
+ * cy.get('@clickedSpy).should('have.been.called')
24
+ */
25
+ autoSpyOutputs?: boolean;
26
+ /**
27
+ * @memberof MountConfig
28
+ * @description flag defaulted to true to automatically detect changes in your components
29
+ */
30
+ autoDetectChanges?: boolean;
31
+ /**
32
+ * @memberof MountConfig
33
+ * @example
34
+ * import { ButtonComponent } from 'button/button.component'
35
+ * it('renders a button with Save text', () => {
36
+ * cy.mount(ButtonComponent, { componentProperties: { text: 'Save' }})
37
+ * cy.get('button').contains('Save')
38
+ * })
39
+ *
40
+ * it('renders a button with a cy.spy() replacing EventEmitter', () => {
41
+ * cy.mount(ButtonComponent, {
42
+ * componentProperties: {
43
+ * clicked: cy.spy().as('mySpy)
44
+ * }
45
+ * })
46
+ * cy.get('button').click()
47
+ * cy.get('@mySpy').should('have.been.called')
48
+ * })
49
+ */
50
+ componentProperties?: Partial<{
51
+ [P in keyof T]: T[P] extends InputSignal<infer V> ? InputSignal<V> | WritableSignal<V> | V : T[P];
52
+ }>;
53
+ }
54
+ /**
55
+ * Type that the `mount` function returns
56
+ * @type MountResponse<T>
57
+ */
58
+ type MountResponse<T> = {
59
+ /**
60
+ * Fixture for debugging and testing a component.
61
+ *
62
+ * @memberof MountResponse
63
+ * @see https://angular.io/api/core/testing/ComponentFixture
64
+ */
65
+ fixture: ComponentFixture<T>;
66
+ /**
67
+ * The instance of the root component class
68
+ *
69
+ * @memberof MountResponse
70
+ * @see https://angular.io/api/core/testing/ComponentFixture#componentInstance
71
+ */
72
+ component: T;
73
+ };
74
+ declare class CypressTestComponentRenderer extends TestComponentRenderer {
75
+ insertRootElement(rootElId: string): void;
76
+ removeAllRootElements(): void;
77
+ }
78
+ /**
79
+ * Mounts an Angular component inside Cypress browser
80
+ *
81
+ * @param component Angular component being mounted or its template
82
+ * @param config configuration used to configure the TestBed
83
+ * @example
84
+ * import { mount } from '@cypress/angular-signals'
85
+ * import { StepperComponent } from './stepper.component'
86
+ * import { MyService } from 'services/my.service'
87
+ * import { SharedModule } from 'shared/shared.module';
88
+ * it('mounts', () => {
89
+ * mount(StepperComponent, {
90
+ * providers: [MyService],
91
+ * imports: [SharedModule]
92
+ * })
93
+ * cy.get('[data-cy=increment]').click()
94
+ * cy.get('[data-cy=counter]').should('have.text', '1')
95
+ * })
96
+ *
97
+ * // or
98
+ *
99
+ * it('mounts with template', () => {
100
+ * mount('<app-stepper></app-stepper>', {
101
+ * declarations: [StepperComponent],
102
+ * })
103
+ * })
104
+ *
105
+ * @see {@link https://on.cypress.io/mounting-angular} for more details.
106
+ *
107
+ * @returns A component and component fixture
108
+ */
109
+ declare function mount<T>(component: Type<T> | string, config?: MountConfig<T>): Cypress.Chainable<MountResponse<T>>;
110
+ /**
111
+ * Creates a new Event Emitter and then spies on it's `emit` method
112
+ *
113
+ * @param {string} alias name you want to use for your cy.spy() alias
114
+ * @returns EventEmitter<T>
115
+ * @example
116
+ * import { StepperComponent } from './stepper.component'
117
+ * import { mount, createOutputSpy } from '@cypress/angular-signals'
118
+ *
119
+ * it('Has spy', () => {
120
+ * mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } })
121
+ * cy.get('[data-cy=increment]').click()
122
+ * cy.get('@changeSpy').should('have.been.called')
123
+ * })
124
+ *
125
+ * // Or for use with Angular Signals following the output nomenclature.
126
+ * // see https://v17.angular.io/guide/model-inputs#differences-between-model-and-input/
127
+ *
128
+ * it('Has spy', () => {
129
+ * mount(StepperComponent, { componentProperties: { count: signal(0), countChange: createOutputSpy('countChange') } })
130
+ * cy.get('[data-cy=increment]').click()
131
+ * cy.get('@countChange').should('have.been.called')
132
+ * })
133
+ */
134
+ declare const createOutputSpy: <T>(alias: string) => any;
135
+
136
+ export { CypressTestComponentRenderer, MountConfig, MountResponse, createOutputSpy, mount };