cypress 13.11.0 → 13.13.0

Sign up to get free protection for your applications and to get access to all the features.
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 };