/** * @cypress/angular-signals v0.0.0-development * (c) 2024 Cypress.io * Released under the MIT License */ import 'zone.js'; import 'zone.js/testing'; import { CommonModule } from '@angular/common'; import { assertInInjectionContext, inject, Injector, effect, untracked, DestroyRef, Injectable, Component, EventEmitter, SimpleChange, ErrorHandler, signal } from '@angular/core'; import { getTestBed, TestComponentRenderer, TestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; /****************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise, SuppressedError, Symbol */ function __rest(s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; } function __decorate(decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 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; return c > 3 && r && Object.defineProperty(target, key, r), r; } typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ***************************************************************************** */ /* global Reflect, Promise */ var extendStatics = function(d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; function __extends(d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } /** PURE_IMPORTS_START PURE_IMPORTS_END */ function isFunction(x) { return typeof x === 'function'; } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var _enable_super_gross_mode_that_will_cause_bad_things = false; var config = { Promise: undefined, set useDeprecatedSynchronousErrorHandling(value) { if (value) { var error = /*@__PURE__*/ new Error(); /*@__PURE__*/ console.warn('DEPRECATED! RxJS was set to use deprecated synchronous error handling behavior by code at: \n' + error.stack); } _enable_super_gross_mode_that_will_cause_bad_things = value; }, get useDeprecatedSynchronousErrorHandling() { return _enable_super_gross_mode_that_will_cause_bad_things; }, }; /** PURE_IMPORTS_START PURE_IMPORTS_END */ function hostReportError(err) { setTimeout(function () { throw err; }, 0); } /** PURE_IMPORTS_START _config,_util_hostReportError PURE_IMPORTS_END */ var empty$1 = { closed: true, next: function (value) { }, error: function (err) { if (config.useDeprecatedSynchronousErrorHandling) { throw err; } else { hostReportError(err); } }, complete: function () { } }; /** PURE_IMPORTS_START PURE_IMPORTS_END */ var isArray = /*@__PURE__*/ (function () { return Array.isArray || (function (x) { return x && typeof x.length === 'number'; }); })(); /** PURE_IMPORTS_START PURE_IMPORTS_END */ function isObject(x) { return x !== null && typeof x === 'object'; } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var UnsubscriptionErrorImpl = /*@__PURE__*/ (function () { function UnsubscriptionErrorImpl(errors) { Error.call(this); this.message = errors ? errors.length + " errors occurred during unsubscription:\n" + errors.map(function (err, i) { return i + 1 + ") " + err.toString(); }).join('\n ') : ''; this.name = 'UnsubscriptionError'; this.errors = errors; return this; } UnsubscriptionErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); return UnsubscriptionErrorImpl; })(); var UnsubscriptionError = UnsubscriptionErrorImpl; /** PURE_IMPORTS_START _util_isArray,_util_isObject,_util_isFunction,_util_UnsubscriptionError PURE_IMPORTS_END */ var Subscription = /*@__PURE__*/ (function () { function Subscription(unsubscribe) { this.closed = false; this._parentOrParents = null; this._subscriptions = null; if (unsubscribe) { this._ctorUnsubscribe = true; this._unsubscribe = unsubscribe; } } Subscription.prototype.unsubscribe = function () { var errors; if (this.closed) { return; } var _a = this, _parentOrParents = _a._parentOrParents, _ctorUnsubscribe = _a._ctorUnsubscribe, _unsubscribe = _a._unsubscribe, _subscriptions = _a._subscriptions; this.closed = true; this._parentOrParents = null; this._subscriptions = null; if (_parentOrParents instanceof Subscription) { _parentOrParents.remove(this); } else if (_parentOrParents !== null) { for (var index = 0; index < _parentOrParents.length; ++index) { var parent_1 = _parentOrParents[index]; parent_1.remove(this); } } if (isFunction(_unsubscribe)) { if (_ctorUnsubscribe) { this._unsubscribe = undefined; } try { _unsubscribe.call(this); } catch (e) { errors = e instanceof UnsubscriptionError ? flattenUnsubscriptionErrors(e.errors) : [e]; } } if (isArray(_subscriptions)) { var index = -1; var len = _subscriptions.length; while (++index < len) { var sub = _subscriptions[index]; if (isObject(sub)) { try { sub.unsubscribe(); } catch (e) { errors = errors || []; if (e instanceof UnsubscriptionError) { errors = errors.concat(flattenUnsubscriptionErrors(e.errors)); } else { errors.push(e); } } } } } if (errors) { throw new UnsubscriptionError(errors); } }; Subscription.prototype.add = function (teardown) { var subscription = teardown; if (!teardown) { return Subscription.EMPTY; } switch (typeof teardown) { case 'function': subscription = new Subscription(teardown); case 'object': if (subscription === this || subscription.closed || typeof subscription.unsubscribe !== 'function') { return subscription; } else if (this.closed) { subscription.unsubscribe(); return subscription; } else if (!(subscription instanceof Subscription)) { var tmp = subscription; subscription = new Subscription(); subscription._subscriptions = [tmp]; } break; default: { throw new Error('unrecognized teardown ' + teardown + ' added to Subscription.'); } } var _parentOrParents = subscription._parentOrParents; if (_parentOrParents === null) { subscription._parentOrParents = this; } else if (_parentOrParents instanceof Subscription) { if (_parentOrParents === this) { return subscription; } subscription._parentOrParents = [_parentOrParents, this]; } else if (_parentOrParents.indexOf(this) === -1) { _parentOrParents.push(this); } else { return subscription; } var subscriptions = this._subscriptions; if (subscriptions === null) { this._subscriptions = [subscription]; } else { subscriptions.push(subscription); } return subscription; }; Subscription.prototype.remove = function (subscription) { var subscriptions = this._subscriptions; if (subscriptions) { var subscriptionIndex = subscriptions.indexOf(subscription); if (subscriptionIndex !== -1) { subscriptions.splice(subscriptionIndex, 1); } } }; Subscription.EMPTY = (function (empty) { empty.closed = true; return empty; }(new Subscription())); return Subscription; }()); function flattenUnsubscriptionErrors(errors) { return errors.reduce(function (errs, err) { return errs.concat((err instanceof UnsubscriptionError) ? err.errors : err); }, []); } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var rxSubscriber = /*@__PURE__*/ (function () { return typeof Symbol === 'function' ? /*@__PURE__*/ Symbol('rxSubscriber') : '@@rxSubscriber_' + /*@__PURE__*/ Math.random(); })(); /** PURE_IMPORTS_START tslib,_util_isFunction,_Observer,_Subscription,_internal_symbol_rxSubscriber,_config,_util_hostReportError PURE_IMPORTS_END */ var Subscriber = /*@__PURE__*/ (function (_super) { __extends(Subscriber, _super); function Subscriber(destinationOrNext, error, complete) { var _this = _super.call(this) || this; _this.syncErrorValue = null; _this.syncErrorThrown = false; _this.syncErrorThrowable = false; _this.isStopped = false; switch (arguments.length) { case 0: _this.destination = empty$1; break; case 1: if (!destinationOrNext) { _this.destination = empty$1; break; } if (typeof destinationOrNext === 'object') { if (destinationOrNext instanceof Subscriber) { _this.syncErrorThrowable = destinationOrNext.syncErrorThrowable; _this.destination = destinationOrNext; destinationOrNext.add(_this); } else { _this.syncErrorThrowable = true; _this.destination = new SafeSubscriber(_this, destinationOrNext); } break; } default: _this.syncErrorThrowable = true; _this.destination = new SafeSubscriber(_this, destinationOrNext, error, complete); break; } return _this; } Subscriber.prototype[rxSubscriber] = function () { return this; }; Subscriber.create = function (next, error, complete) { var subscriber = new Subscriber(next, error, complete); subscriber.syncErrorThrowable = false; return subscriber; }; Subscriber.prototype.next = function (value) { if (!this.isStopped) { this._next(value); } }; Subscriber.prototype.error = function (err) { if (!this.isStopped) { this.isStopped = true; this._error(err); } }; Subscriber.prototype.complete = function () { if (!this.isStopped) { this.isStopped = true; this._complete(); } }; Subscriber.prototype.unsubscribe = function () { if (this.closed) { return; } this.isStopped = true; _super.prototype.unsubscribe.call(this); }; Subscriber.prototype._next = function (value) { this.destination.next(value); }; Subscriber.prototype._error = function (err) { this.destination.error(err); this.unsubscribe(); }; Subscriber.prototype._complete = function () { this.destination.complete(); this.unsubscribe(); }; Subscriber.prototype._unsubscribeAndRecycle = function () { var _parentOrParents = this._parentOrParents; this._parentOrParents = null; this.unsubscribe(); this.closed = false; this.isStopped = false; this._parentOrParents = _parentOrParents; return this; }; return Subscriber; }(Subscription)); var SafeSubscriber = /*@__PURE__*/ (function (_super) { __extends(SafeSubscriber, _super); function SafeSubscriber(_parentSubscriber, observerOrNext, error, complete) { var _this = _super.call(this) || this; _this._parentSubscriber = _parentSubscriber; var next; var context = _this; if (isFunction(observerOrNext)) { next = observerOrNext; } else if (observerOrNext) { next = observerOrNext.next; error = observerOrNext.error; complete = observerOrNext.complete; if (observerOrNext !== empty$1) { context = Object.create(observerOrNext); if (isFunction(context.unsubscribe)) { _this.add(context.unsubscribe.bind(context)); } context.unsubscribe = _this.unsubscribe.bind(_this); } } _this._context = context; _this._next = next; _this._error = error; _this._complete = complete; return _this; } SafeSubscriber.prototype.next = function (value) { if (!this.isStopped && this._next) { var _parentSubscriber = this._parentSubscriber; if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { this.__tryOrUnsub(this._next, value); } else if (this.__tryOrSetError(_parentSubscriber, this._next, value)) { this.unsubscribe(); } } }; SafeSubscriber.prototype.error = function (err) { if (!this.isStopped) { var _parentSubscriber = this._parentSubscriber; var useDeprecatedSynchronousErrorHandling = config.useDeprecatedSynchronousErrorHandling; if (this._error) { if (!useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { this.__tryOrUnsub(this._error, err); this.unsubscribe(); } else { this.__tryOrSetError(_parentSubscriber, this._error, err); this.unsubscribe(); } } else if (!_parentSubscriber.syncErrorThrowable) { this.unsubscribe(); if (useDeprecatedSynchronousErrorHandling) { throw err; } hostReportError(err); } else { if (useDeprecatedSynchronousErrorHandling) { _parentSubscriber.syncErrorValue = err; _parentSubscriber.syncErrorThrown = true; } else { hostReportError(err); } this.unsubscribe(); } } }; SafeSubscriber.prototype.complete = function () { var _this = this; if (!this.isStopped) { var _parentSubscriber = this._parentSubscriber; if (this._complete) { var wrappedComplete = function () { return _this._complete.call(_this._context); }; if (!config.useDeprecatedSynchronousErrorHandling || !_parentSubscriber.syncErrorThrowable) { this.__tryOrUnsub(wrappedComplete); this.unsubscribe(); } else { this.__tryOrSetError(_parentSubscriber, wrappedComplete); this.unsubscribe(); } } else { this.unsubscribe(); } } }; SafeSubscriber.prototype.__tryOrUnsub = function (fn, value) { try { fn.call(this._context, value); } catch (err) { this.unsubscribe(); if (config.useDeprecatedSynchronousErrorHandling) { throw err; } else { hostReportError(err); } } }; SafeSubscriber.prototype.__tryOrSetError = function (parent, fn, value) { if (!config.useDeprecatedSynchronousErrorHandling) { throw new Error('bad call'); } try { fn.call(this._context, value); } catch (err) { if (config.useDeprecatedSynchronousErrorHandling) { parent.syncErrorValue = err; parent.syncErrorThrown = true; return true; } else { hostReportError(err); return true; } } return false; }; SafeSubscriber.prototype._unsubscribe = function () { var _parentSubscriber = this._parentSubscriber; this._context = null; this._parentSubscriber = null; _parentSubscriber.unsubscribe(); }; return SafeSubscriber; }(Subscriber)); /** PURE_IMPORTS_START _Subscriber PURE_IMPORTS_END */ function canReportError(observer) { while (observer) { var _a = observer, closed_1 = _a.closed, destination = _a.destination, isStopped = _a.isStopped; if (closed_1 || isStopped) { return false; } else if (destination && destination instanceof Subscriber) { observer = destination; } else { observer = null; } } return true; } /** PURE_IMPORTS_START _Subscriber,_symbol_rxSubscriber,_Observer PURE_IMPORTS_END */ function toSubscriber(nextOrObserver, error, complete) { if (nextOrObserver) { if (nextOrObserver instanceof Subscriber) { return nextOrObserver; } if (nextOrObserver[rxSubscriber]) { return nextOrObserver[rxSubscriber](); } } if (!nextOrObserver && !error && !complete) { return new Subscriber(empty$1); } return new Subscriber(nextOrObserver, error, complete); } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var observable = /*@__PURE__*/ (function () { return typeof Symbol === 'function' && Symbol.observable || '@@observable'; })(); /** PURE_IMPORTS_START PURE_IMPORTS_END */ function identity(x) { return x; } /** PURE_IMPORTS_START _identity PURE_IMPORTS_END */ function pipeFromArray(fns) { if (fns.length === 0) { return identity; } if (fns.length === 1) { return fns[0]; } return function piped(input) { return fns.reduce(function (prev, fn) { return fn(prev); }, input); }; } /** PURE_IMPORTS_START _util_canReportError,_util_toSubscriber,_symbol_observable,_util_pipe,_config PURE_IMPORTS_END */ var Observable = /*@__PURE__*/ (function () { function Observable(subscribe) { this._isScalar = false; if (subscribe) { this._subscribe = subscribe; } } Observable.prototype.lift = function (operator) { var observable = new Observable(); observable.source = this; observable.operator = operator; return observable; }; Observable.prototype.subscribe = function (observerOrNext, error, complete) { var operator = this.operator; var sink = toSubscriber(observerOrNext, error, complete); if (operator) { sink.add(operator.call(sink, this.source)); } else { sink.add(this.source || (config.useDeprecatedSynchronousErrorHandling && !sink.syncErrorThrowable) ? this._subscribe(sink) : this._trySubscribe(sink)); } if (config.useDeprecatedSynchronousErrorHandling) { if (sink.syncErrorThrowable) { sink.syncErrorThrowable = false; if (sink.syncErrorThrown) { throw sink.syncErrorValue; } } } return sink; }; Observable.prototype._trySubscribe = function (sink) { try { return this._subscribe(sink); } catch (err) { if (config.useDeprecatedSynchronousErrorHandling) { sink.syncErrorThrown = true; sink.syncErrorValue = err; } if (canReportError(sink)) { sink.error(err); } else { console.warn(err); } } }; Observable.prototype.forEach = function (next, promiseCtor) { var _this = this; promiseCtor = getPromiseCtor(promiseCtor); return new promiseCtor(function (resolve, reject) { var subscription; subscription = _this.subscribe(function (value) { try { next(value); } catch (err) { reject(err); if (subscription) { subscription.unsubscribe(); } } }, reject, resolve); }); }; Observable.prototype._subscribe = function (subscriber) { var source = this.source; return source && source.subscribe(subscriber); }; Observable.prototype[observable] = function () { return this; }; Observable.prototype.pipe = function () { var operations = []; for (var _i = 0; _i < arguments.length; _i++) { operations[_i] = arguments[_i]; } if (operations.length === 0) { return this; } return pipeFromArray(operations)(this); }; Observable.prototype.toPromise = function (promiseCtor) { var _this = this; promiseCtor = getPromiseCtor(promiseCtor); return new promiseCtor(function (resolve, reject) { var value; _this.subscribe(function (x) { return value = x; }, function (err) { return reject(err); }, function () { return resolve(value); }); }); }; Observable.create = function (subscribe) { return new Observable(subscribe); }; return Observable; }()); function getPromiseCtor(promiseCtor) { if (!promiseCtor) { promiseCtor = Promise; } if (!promiseCtor) { throw new Error('no Promise impl found'); } return promiseCtor; } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var ObjectUnsubscribedErrorImpl = /*@__PURE__*/ (function () { function ObjectUnsubscribedErrorImpl() { Error.call(this); this.message = 'object unsubscribed'; this.name = 'ObjectUnsubscribedError'; return this; } ObjectUnsubscribedErrorImpl.prototype = /*@__PURE__*/ Object.create(Error.prototype); return ObjectUnsubscribedErrorImpl; })(); var ObjectUnsubscribedError = ObjectUnsubscribedErrorImpl; /** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ var SubjectSubscription = /*@__PURE__*/ (function (_super) { __extends(SubjectSubscription, _super); function SubjectSubscription(subject, subscriber) { var _this = _super.call(this) || this; _this.subject = subject; _this.subscriber = subscriber; _this.closed = false; return _this; } SubjectSubscription.prototype.unsubscribe = function () { if (this.closed) { return; } this.closed = true; var subject = this.subject; var observers = subject.observers; this.subject = null; if (!observers || observers.length === 0 || subject.isStopped || subject.closed) { return; } var subscriberIndex = observers.indexOf(this.subscriber); if (subscriberIndex !== -1) { observers.splice(subscriberIndex, 1); } }; return SubjectSubscription; }(Subscription)); /** PURE_IMPORTS_START tslib,_Observable,_Subscriber,_Subscription,_util_ObjectUnsubscribedError,_SubjectSubscription,_internal_symbol_rxSubscriber PURE_IMPORTS_END */ var SubjectSubscriber = /*@__PURE__*/ (function (_super) { __extends(SubjectSubscriber, _super); function SubjectSubscriber(destination) { var _this = _super.call(this, destination) || this; _this.destination = destination; return _this; } return SubjectSubscriber; }(Subscriber)); var Subject = /*@__PURE__*/ (function (_super) { __extends(Subject, _super); function Subject() { var _this = _super.call(this) || this; _this.observers = []; _this.closed = false; _this.isStopped = false; _this.hasError = false; _this.thrownError = null; return _this; } Subject.prototype[rxSubscriber] = function () { return new SubjectSubscriber(this); }; Subject.prototype.lift = function (operator) { var subject = new AnonymousSubject(this, this); subject.operator = operator; return subject; }; Subject.prototype.next = function (value) { if (this.closed) { throw new ObjectUnsubscribedError(); } if (!this.isStopped) { var observers = this.observers; var len = observers.length; var copy = observers.slice(); for (var i = 0; i < len; i++) { copy[i].next(value); } } }; Subject.prototype.error = function (err) { if (this.closed) { throw new ObjectUnsubscribedError(); } this.hasError = true; this.thrownError = err; this.isStopped = true; var observers = this.observers; var len = observers.length; var copy = observers.slice(); for (var i = 0; i < len; i++) { copy[i].error(err); } this.observers.length = 0; }; Subject.prototype.complete = function () { if (this.closed) { throw new ObjectUnsubscribedError(); } this.isStopped = true; var observers = this.observers; var len = observers.length; var copy = observers.slice(); for (var i = 0; i < len; i++) { copy[i].complete(); } this.observers.length = 0; }; Subject.prototype.unsubscribe = function () { this.isStopped = true; this.closed = true; this.observers = null; }; Subject.prototype._trySubscribe = function (subscriber) { if (this.closed) { throw new ObjectUnsubscribedError(); } else { return _super.prototype._trySubscribe.call(this, subscriber); } }; Subject.prototype._subscribe = function (subscriber) { if (this.closed) { throw new ObjectUnsubscribedError(); } else if (this.hasError) { subscriber.error(this.thrownError); return Subscription.EMPTY; } else if (this.isStopped) { subscriber.complete(); return Subscription.EMPTY; } else { this.observers.push(subscriber); return new SubjectSubscription(this, subscriber); } }; Subject.prototype.asObservable = function () { var observable = new Observable(); observable.source = this; return observable; }; Subject.create = function (destination, source) { return new AnonymousSubject(destination, source); }; return Subject; }(Observable)); var AnonymousSubject = /*@__PURE__*/ (function (_super) { __extends(AnonymousSubject, _super); function AnonymousSubject(destination, source) { var _this = _super.call(this) || this; _this.destination = destination; _this.source = source; return _this; } AnonymousSubject.prototype.next = function (value) { var destination = this.destination; if (destination && destination.next) { destination.next(value); } }; AnonymousSubject.prototype.error = function (err) { var destination = this.destination; if (destination && destination.error) { this.destination.error(err); } }; AnonymousSubject.prototype.complete = function () { var destination = this.destination; if (destination && destination.complete) { this.destination.complete(); } }; AnonymousSubject.prototype._subscribe = function (subscriber) { var source = this.source; if (source) { return this.source.subscribe(subscriber); } else { return Subscription.EMPTY; } }; return AnonymousSubject; }(Subject)); /** PURE_IMPORTS_START tslib,_Subscription PURE_IMPORTS_END */ var Action = /*@__PURE__*/ (function (_super) { __extends(Action, _super); function Action(scheduler, work) { return _super.call(this) || this; } Action.prototype.schedule = function (state, delay) { return this; }; return Action; }(Subscription)); /** PURE_IMPORTS_START tslib,_Action PURE_IMPORTS_END */ var AsyncAction = /*@__PURE__*/ (function (_super) { __extends(AsyncAction, _super); function AsyncAction(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; _this.scheduler = scheduler; _this.work = work; _this.pending = false; return _this; } AsyncAction.prototype.schedule = function (state, delay) { if (delay === void 0) { delay = 0; } if (this.closed) { return this; } this.state = state; var id = this.id; var scheduler = this.scheduler; if (id != null) { this.id = this.recycleAsyncId(scheduler, id, delay); } this.pending = true; this.delay = delay; this.id = this.id || this.requestAsyncId(scheduler, this.id, delay); return this; }; AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) { if (delay === void 0) { delay = 0; } return setInterval(scheduler.flush.bind(scheduler, this), delay); }; AsyncAction.prototype.recycleAsyncId = function (scheduler, id, delay) { if (delay === void 0) { delay = 0; } if (delay !== null && this.delay === delay && this.pending === false) { return id; } clearInterval(id); return undefined; }; AsyncAction.prototype.execute = function (state, delay) { if (this.closed) { return new Error('executing a cancelled action'); } this.pending = false; var error = this._execute(state, delay); if (error) { return error; } else if (this.pending === false && this.id != null) { this.id = this.recycleAsyncId(this.scheduler, this.id, null); } }; AsyncAction.prototype._execute = function (state, delay) { var errored = false; var errorValue = undefined; try { this.work(state); } catch (e) { errored = true; errorValue = !!e && e || new Error(e); } if (errored) { this.unsubscribe(); return errorValue; } }; AsyncAction.prototype._unsubscribe = function () { var id = this.id; var scheduler = this.scheduler; var actions = scheduler.actions; var index = actions.indexOf(this); this.work = null; this.state = null; this.pending = false; this.scheduler = null; if (index !== -1) { actions.splice(index, 1); } if (id != null) { this.id = this.recycleAsyncId(scheduler, id, null); } this.delay = null; }; return AsyncAction; }(Action)); /** PURE_IMPORTS_START tslib,_AsyncAction PURE_IMPORTS_END */ var QueueAction = /*@__PURE__*/ (function (_super) { __extends(QueueAction, _super); function QueueAction(scheduler, work) { var _this = _super.call(this, scheduler, work) || this; _this.scheduler = scheduler; _this.work = work; return _this; } QueueAction.prototype.schedule = function (state, delay) { if (delay === void 0) { delay = 0; } if (delay > 0) { return _super.prototype.schedule.call(this, state, delay); } this.delay = delay; this.state = state; this.scheduler.flush(this); return this; }; QueueAction.prototype.execute = function (state, delay) { return (delay > 0 || this.closed) ? _super.prototype.execute.call(this, state, delay) : this._execute(state, delay); }; QueueAction.prototype.requestAsyncId = function (scheduler, id, delay) { if (delay === void 0) { delay = 0; } if ((delay !== null && delay > 0) || (delay === null && this.delay > 0)) { return _super.prototype.requestAsyncId.call(this, scheduler, id, delay); } return scheduler.flush(this); }; return QueueAction; }(AsyncAction)); var Scheduler = /*@__PURE__*/ (function () { function Scheduler(SchedulerAction, now) { if (now === void 0) { now = Scheduler.now; } this.SchedulerAction = SchedulerAction; this.now = now; } Scheduler.prototype.schedule = function (work, delay, state) { if (delay === void 0) { delay = 0; } return new this.SchedulerAction(this, work).schedule(state, delay); }; Scheduler.now = function () { return Date.now(); }; return Scheduler; }()); /** PURE_IMPORTS_START tslib,_Scheduler PURE_IMPORTS_END */ var AsyncScheduler = /*@__PURE__*/ (function (_super) { __extends(AsyncScheduler, _super); function AsyncScheduler(SchedulerAction, now) { if (now === void 0) { now = Scheduler.now; } var _this = _super.call(this, SchedulerAction, function () { if (AsyncScheduler.delegate && AsyncScheduler.delegate !== _this) { return AsyncScheduler.delegate.now(); } else { return now(); } }) || this; _this.actions = []; _this.active = false; _this.scheduled = undefined; return _this; } AsyncScheduler.prototype.schedule = function (work, delay, state) { if (delay === void 0) { delay = 0; } if (AsyncScheduler.delegate && AsyncScheduler.delegate !== this) { return AsyncScheduler.delegate.schedule(work, delay, state); } else { return _super.prototype.schedule.call(this, work, delay, state); } }; AsyncScheduler.prototype.flush = function (action) { var actions = this.actions; if (this.active) { actions.push(action); return; } var error; this.active = true; do { if (error = action.execute(action.state, action.delay)) { break; } } while (action = actions.shift()); this.active = false; if (error) { while (action = actions.shift()) { action.unsubscribe(); } throw error; } }; return AsyncScheduler; }(Scheduler)); /** PURE_IMPORTS_START tslib,_AsyncScheduler PURE_IMPORTS_END */ var QueueScheduler = /*@__PURE__*/ (function (_super) { __extends(QueueScheduler, _super); function QueueScheduler() { return _super !== null && _super.apply(this, arguments) || this; } return QueueScheduler; }(AsyncScheduler)); /** PURE_IMPORTS_START _QueueAction,_QueueScheduler PURE_IMPORTS_END */ var queueScheduler = /*@__PURE__*/ new QueueScheduler(QueueAction); var queue = queueScheduler; /** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ var EMPTY = /*@__PURE__*/ new Observable(function (subscriber) { return subscriber.complete(); }); function empty(scheduler) { return scheduler ? emptyScheduled(scheduler) : EMPTY; } function emptyScheduled(scheduler) { return new Observable(function (subscriber) { return scheduler.schedule(function () { return subscriber.complete(); }); }); } /** PURE_IMPORTS_START PURE_IMPORTS_END */ function isScheduler(value) { return value && typeof value.schedule === 'function'; } /** PURE_IMPORTS_START PURE_IMPORTS_END */ var subscribeToArray = function (array) { return function (subscriber) { for (var i = 0, len = array.length; i < len && !subscriber.closed; i++) { subscriber.next(array[i]); } subscriber.complete(); }; }; /** PURE_IMPORTS_START _Observable,_Subscription PURE_IMPORTS_END */ function scheduleArray(input, scheduler) { return new Observable(function (subscriber) { var sub = new Subscription(); var i = 0; sub.add(scheduler.schedule(function () { if (i === input.length) { subscriber.complete(); return; } subscriber.next(input[i++]); if (!subscriber.closed) { sub.add(this.schedule()); } })); return sub; }); } /** PURE_IMPORTS_START _Observable,_util_subscribeToArray,_scheduled_scheduleArray PURE_IMPORTS_END */ function fromArray(input, scheduler) { if (!scheduler) { return new Observable(subscribeToArray(input)); } else { return scheduleArray(input, scheduler); } } /** PURE_IMPORTS_START _util_isScheduler,_fromArray,_scheduled_scheduleArray PURE_IMPORTS_END */ function of() { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var scheduler = args[args.length - 1]; if (isScheduler(scheduler)) { args.pop(); return scheduleArray(args, scheduler); } else { return fromArray(args); } } /** PURE_IMPORTS_START _Observable PURE_IMPORTS_END */ function throwError(error, scheduler) { if (!scheduler) { return new Observable(function (subscriber) { return subscriber.error(error); }); } else { return new Observable(function (subscriber) { return scheduler.schedule(dispatch, 0, { error: error, subscriber: subscriber }); }); } } function dispatch(_a) { var error = _a.error, subscriber = _a.subscriber; subscriber.error(error); } /** PURE_IMPORTS_START _observable_empty,_observable_of,_observable_throwError PURE_IMPORTS_END */ var Notification = /*@__PURE__*/ (function () { function Notification(kind, value, error) { this.kind = kind; this.value = value; this.error = error; this.hasValue = kind === 'N'; } Notification.prototype.observe = function (observer) { switch (this.kind) { case 'N': return observer.next && observer.next(this.value); case 'E': return observer.error && observer.error(this.error); case 'C': return observer.complete && observer.complete(); } }; Notification.prototype.do = function (next, error, complete) { var kind = this.kind; switch (kind) { case 'N': return next && next(this.value); case 'E': return error && error(this.error); case 'C': return complete && complete(); } }; Notification.prototype.accept = function (nextOrObserver, error, complete) { if (nextOrObserver && typeof nextOrObserver.next === 'function') { return this.observe(nextOrObserver); } else { return this.do(nextOrObserver, error, complete); } }; Notification.prototype.toObservable = function () { var kind = this.kind; switch (kind) { case 'N': return of(this.value); case 'E': return throwError(this.error); case 'C': return empty(); } throw new Error('unexpected notification kind value'); }; Notification.createNext = function (value) { if (typeof value !== 'undefined') { return new Notification('N', value); } return Notification.undefinedValueNotification; }; Notification.createError = function (err) { return new Notification('E', undefined, err); }; Notification.createComplete = function () { return Notification.completeNotification; }; Notification.completeNotification = new Notification('C'); Notification.undefinedValueNotification = new Notification('N', undefined); return Notification; }()); /** PURE_IMPORTS_START tslib,_Subscriber,_Notification PURE_IMPORTS_END */ var ObserveOnSubscriber = /*@__PURE__*/ (function (_super) { __extends(ObserveOnSubscriber, _super); function ObserveOnSubscriber(destination, scheduler, delay) { if (delay === void 0) { delay = 0; } var _this = _super.call(this, destination) || this; _this.scheduler = scheduler; _this.delay = delay; return _this; } ObserveOnSubscriber.dispatch = function (arg) { var notification = arg.notification, destination = arg.destination; notification.observe(destination); this.unsubscribe(); }; ObserveOnSubscriber.prototype.scheduleMessage = function (notification) { var destination = this.destination; destination.add(this.scheduler.schedule(ObserveOnSubscriber.dispatch, this.delay, new ObserveOnMessage(notification, this.destination))); }; ObserveOnSubscriber.prototype._next = function (value) { this.scheduleMessage(Notification.createNext(value)); }; ObserveOnSubscriber.prototype._error = function (err) { this.scheduleMessage(Notification.createError(err)); this.unsubscribe(); }; ObserveOnSubscriber.prototype._complete = function () { this.scheduleMessage(Notification.createComplete()); this.unsubscribe(); }; return ObserveOnSubscriber; }(Subscriber)); var ObserveOnMessage = /*@__PURE__*/ (function () { function ObserveOnMessage(notification, destination) { this.notification = notification; this.destination = destination; } return ObserveOnMessage; }()); /** PURE_IMPORTS_START tslib,_Subject,_scheduler_queue,_Subscription,_operators_observeOn,_util_ObjectUnsubscribedError,_SubjectSubscription PURE_IMPORTS_END */ var ReplaySubject = /*@__PURE__*/ (function (_super) { __extends(ReplaySubject, _super); function ReplaySubject(bufferSize, windowTime, scheduler) { if (bufferSize === void 0) { bufferSize = Number.POSITIVE_INFINITY; } if (windowTime === void 0) { windowTime = Number.POSITIVE_INFINITY; } var _this = _super.call(this) || this; _this.scheduler = scheduler; _this._events = []; _this._infiniteTimeWindow = false; _this._bufferSize = bufferSize < 1 ? 1 : bufferSize; _this._windowTime = windowTime < 1 ? 1 : windowTime; if (windowTime === Number.POSITIVE_INFINITY) { _this._infiniteTimeWindow = true; _this.next = _this.nextInfiniteTimeWindow; } else { _this.next = _this.nextTimeWindow; } return _this; } ReplaySubject.prototype.nextInfiniteTimeWindow = function (value) { if (!this.isStopped) { var _events = this._events; _events.push(value); if (_events.length > this._bufferSize) { _events.shift(); } } _super.prototype.next.call(this, value); }; ReplaySubject.prototype.nextTimeWindow = function (value) { if (!this.isStopped) { this._events.push(new ReplayEvent(this._getNow(), value)); this._trimBufferThenGetEvents(); } _super.prototype.next.call(this, value); }; ReplaySubject.prototype._subscribe = function (subscriber) { var _infiniteTimeWindow = this._infiniteTimeWindow; var _events = _infiniteTimeWindow ? this._events : this._trimBufferThenGetEvents(); var scheduler = this.scheduler; var len = _events.length; var subscription; if (this.closed) { throw new ObjectUnsubscribedError(); } else if (this.isStopped || this.hasError) { subscription = Subscription.EMPTY; } else { this.observers.push(subscriber); subscription = new SubjectSubscription(this, subscriber); } if (scheduler) { subscriber.add(subscriber = new ObserveOnSubscriber(subscriber, scheduler)); } if (_infiniteTimeWindow) { for (var i = 0; i < len && !subscriber.closed; i++) { subscriber.next(_events[i]); } } else { for (var i = 0; i < len && !subscriber.closed; i++) { subscriber.next(_events[i].value); } } if (this.hasError) { subscriber.error(this.thrownError); } else if (this.isStopped) { subscriber.complete(); } return subscription; }; ReplaySubject.prototype._getNow = function () { return (this.scheduler || queue).now(); }; ReplaySubject.prototype._trimBufferThenGetEvents = function () { var now = this._getNow(); var _bufferSize = this._bufferSize; var _windowTime = this._windowTime; var _events = this._events; var eventsCount = _events.length; var spliceCount = 0; while (spliceCount < eventsCount) { if ((now - _events[spliceCount].time) < _windowTime) { break; } spliceCount++; } if (eventsCount > _bufferSize) { spliceCount = Math.max(spliceCount, eventsCount - _bufferSize); } if (spliceCount > 0) { _events.splice(0, spliceCount); } return _events; }; return ReplaySubject; }(Subject)); var ReplayEvent = /*@__PURE__*/ (function () { function ReplayEvent(time, value) { this.time = time; this.value = value; } return ReplayEvent; }()); /** * @license Angular v17.3.10 * (c) 2010-2024 Google LLC. https://angular.io/ * License: MIT */ /** * Exposes the value of an Angular `Signal` as an RxJS `Observable`. * * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`. * * `toObservable` must be called in an injection context unless an injector is provided via options. * * @developerPreview */ function toObservable(source, options) { !options?.injector && assertInInjectionContext(toObservable); const injector = options?.injector ?? inject(Injector); const subject = new ReplaySubject(1); const watcher = effect(() => { let value; try { value = source(); } catch (err) { untracked(() => subject.error(err)); return; } untracked(() => subject.next(value)); }, { injector, manualCleanup: true }); injector.get(DestroyRef).onDestroy(() => { watcher.destroy(); subject.complete(); }); return subject.asObservable(); } const ROOT_SELECTOR = '[data-cy-root]'; /** * Gets the root element used to mount the component. * @returns {HTMLElement} The root element * @throws {Error} If the root element is not found */ const getContainerEl = () => { const el = document.querySelector(ROOT_SELECTOR); if (el) { return el; } throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`); }; /** * Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook * @param optionalCallback Callback to be called before the next test runs */ function setupHooks(optionalCallback) { // We don't want CT side effects to run when e2e // testing so we early return. // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts if (Cypress.testingType !== 'component') { return; } // When running component specs, we cannot allow "cy.visit" // because it will wipe out our preparation work, and does not make much sense // thus we overwrite "cy.visit" to throw an error Cypress.Commands.overwrite('visit', () => { throw new Error('cy.visit from a component spec is not allowed'); }); Cypress.Commands.overwrite('session', () => { throw new Error('cy.session from a component spec is not allowed'); }); Cypress.Commands.overwrite('origin', () => { throw new Error('cy.origin from a component spec is not allowed'); }); // @ts-ignore Cypress.on('test:before:after:run:async', () => { optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback(); }); } /** * @hack fixes "Mocha has already been patched with Zone" error. */ // @ts-ignore window.Mocha['__zone_patch__'] = false; let activeFixture = null; let activeInternalSubscriptions = []; function cleanup() { // Not public, we need to call this to remove the last component from the DOM try { getTestBed().tearDownTestingModule(); } catch (e) { const notSupportedError = new Error(`Failed to teardown component. The version of Angular you are using may not be officially supported.`); notSupportedError.docsUrl = 'https://on.cypress.io/component-framework-configuration'; throw notSupportedError; } // clean up internal subscriptions if any exist. We use this for two-way data binding for // signal() models activeInternalSubscriptions.forEach((subscription) => { subscription.unsubscribe(); }); getTestBed().resetTestingModule(); activeFixture = null; activeInternalSubscriptions = []; } // 'zone.js/testing' is not properly aliasing `it.skip` but it does provide `xit`/`xspecify` // Written up under https://github.com/angular/angular/issues/46297 but is not seeing movement // so we'll patch here pending a fix in that library // @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. globalThis.it.skip = globalThis.xit; let CypressAngularErrorHandler = class CypressAngularErrorHandler { handleError(error) { throw error; } }; CypressAngularErrorHandler = __decorate([ Injectable() ], CypressAngularErrorHandler); /** * Bootstraps the TestModuleMetaData passed to the TestBed * * @param {Type} component Angular component being mounted * @param {MountConfig} config TestBed configuration passed into the mount function * @returns {MountConfig} MountConfig */ function bootstrapModule(component, config) { var _a; const testModuleMetaData = __rest(config, ["componentProperties"]); if (!testModuleMetaData.declarations) { testModuleMetaData.declarations = []; } if (!testModuleMetaData.imports) { testModuleMetaData.imports = []; } if (!testModuleMetaData.providers) { testModuleMetaData.providers = []; } // Replace default error handler since it will swallow uncaught exceptions. // We want these to be uncaught so Cypress catches it and fails the test testModuleMetaData.providers.push({ provide: ErrorHandler, useClass: CypressAngularErrorHandler, }); // check if the component is a standalone component if ((_a = component.ɵcmp) === null || _a === void 0 ? void 0 : _a.standalone) { testModuleMetaData.imports.push(component); } else { testModuleMetaData.declarations.push(component); } if (!testModuleMetaData.imports.includes(CommonModule)) { testModuleMetaData.imports.push(CommonModule); } return testModuleMetaData; } let CypressTestComponentRenderer = class CypressTestComponentRenderer extends TestComponentRenderer { insertRootElement(rootElId) { this.removeAllRootElements(); const rootElement = getContainerEl(); rootElement.setAttribute('id', rootElId); } removeAllRootElements() { getContainerEl().innerHTML = ''; } }; CypressTestComponentRenderer = __decorate([ Injectable() ], CypressTestComponentRenderer); /** * Initializes the TestBed * * @param {Type | string} component Angular component being mounted or its template * @param {MountConfig} config TestBed configuration passed into the mount function * @returns {Type} componentFixture */ function initTestBed(component, config) { const componentFixture = createComponentFixture(component); getTestBed().configureTestingModule(Object.assign({}, bootstrapModule(componentFixture, config))); getTestBed().overrideProvider(TestComponentRenderer, { useValue: new CypressTestComponentRenderer() }); return componentFixture; } let WrapperComponent = class WrapperComponent { }; WrapperComponent = __decorate([ Component({ selector: 'cy-wrapper-component', template: '' }) ], WrapperComponent); /** * Returns the Component if Type or creates a WrapperComponent * * @param {Type | string} component The component you want to create a fixture of * @returns {Type | WrapperComponent} */ function createComponentFixture(component) { if (typeof component === 'string') { // getTestBed().overrideTemplate is available in v14+ // The static TestBed.overrideTemplate is available across versions TestBed.overrideTemplate(WrapperComponent, component); return WrapperComponent; } return component; } /** * Creates the ComponentFixture * * @param {Type} component Angular component being mounted * @param {MountConfig} config MountConfig * @returns {ComponentFixture} ComponentFixture */ function setupFixture(component, config) { const fixture = getTestBed().createComponent(component); setupComponent(config, fixture); fixture.whenStable().then(() => { var _a; fixture.autoDetectChanges((_a = config.autoDetectChanges) !== null && _a !== void 0 ? _a : true); }); return fixture; } // Best known way to currently detect whether or not a function is a signal is if the signal symbol exists. // From there, we can take our best guess based on what exists on the object itself. // @see https://github.com/cypress-io/cypress/issues/29731. function isSignal(prop) { try { const symbol = Object.getOwnPropertySymbols(prop).find((symbol) => symbol.toString() === 'Symbol(SIGNAL)'); return !!symbol; } catch (e) { // likely a primitive type, object, array, or something else (i.e. not a signal). // We can return false here. return false; } } // currently not a great way to detect if a function is an InputSignal. // @see https://github.com/cypress-io/cypress/issues/29731. function isInputSignal(prop) { return isSignal(prop) && typeof prop === 'function' && prop['name'] === 'inputValueFn'; } // currently not a great way to detect if a function is a Model Signal. // @see https://github.com/cypress-io/cypress/issues/29731. function isModelSignal(prop) { return isSignal(prop) && isWritableSignal(prop) && typeof prop.subscribe === 'function'; } // currently not a great way to detect if a function is a Writable Signal. // @see https://github.com/cypress-io/cypress/issues/29731. function isWritableSignal(prop) { return isSignal(prop) && typeof prop === 'function' && typeof prop.set === 'function'; } function convertPropertyToSignalIfApplicable(propValue, componentValue, injector) { const isComponentValueAnInputSignal = isInputSignal(componentValue); const isComponentValueAModelSignal = isModelSignal(componentValue); let convertedValueIfApplicable = propValue; // If the component has the property defined as an InputSignal, we need to detect whether a non signal value or not was passed into the component as a prop // and attempt to merge the value in correctly. // We don't want to expose the primitive created signal as it should really be one-way binding from within the component. // However, to make CT testing easier, a user can technically pass in a signal to an input component and assert on the signal itself and pass in updates // down to the component as 1 way binding is supported by the test harness if (isComponentValueAnInputSignal) { const isPassedInValueNotASignal = !isSignal(propValue); if (isPassedInValueNotASignal) { // Input signals require an injection context to set initial values. // Because of this, we cannot create them outside the scope of the component. // Options for input signals also don't allow the passing of an injection contexts, so in order to work around this, // we convert the non signal input passed into the input to a writable signal convertedValueIfApplicable = signal(propValue); } // If the component has the property defined as a ModelSignal, we need to detect whether a signal value or not was passed into the component as a prop. // If a non signal property is passed into the component model (primitive, object, array, etc), we need to set the model to that value and propagate changes of that model through the output spy. // Since the non signal type likely lives outside the context of Angular, the non signal type will NOT be updated outside of this context. Instead, the output spy will allow you // to see this change. // If the value passed into the property is in fact a signal, we need to set up two-way binding between the signals to make sure changes from one propagate to the other. } else if (isComponentValueAModelSignal) { const isPassedInValueLikelyARegularSignal = isWritableSignal(propValue); // if the value passed into the component is a signal, set up two-way binding if (isPassedInValueLikelyARegularSignal) { // update the passed in value with the models updates componentValue.subscribe((value) => { propValue.set(value); }); // update the model signal with the properties updates const convertedToObservable = toObservable(propValue, { injector, }); // push the subscription into an array to be cleaned up at the end of the test // to prevent a memory leak activeInternalSubscriptions.push(convertedToObservable.subscribe((value) => { componentValue.set(value); })); } else { // it's a non signal type, set it as we only need to handle updating the model signal and emit changes on this through the output spy. componentValue.set(propValue); convertedValueIfApplicable = componentValue; } } return convertedValueIfApplicable; } // In the case of signals, if we need to create an output spy, we need to check first whether or not a user has one defined first or has it created through // autoSpyOutputs. If so, we need to subscribe to the writable signal to push updates into the event emitter. We do NOT observe input signals and output spies will not // work for input signals. function detectAndRegisterOutputSpyToSignal(config, component, key, injector) { if (config.componentProperties) { const expectedChangeKey = `${key}Change`; let changeKeyIfExists = !!Object.keys(config.componentProperties).find((componentKey) => componentKey === expectedChangeKey); // since spies do NOT make change handlers by default, similar to the Output() decorator, we need to create the spy and subscribe to the signal if (!changeKeyIfExists && config.autoSpyOutputs) { component[expectedChangeKey] = createOutputSpy(`${expectedChangeKey}Spy`); changeKeyIfExists = true; } if (changeKeyIfExists) { const componentValue = component[key]; // if the user passed in a change key or we created one due to config.autoSpyOutputs being set to true for a given signal, // we will create a subscriber that will emit an event every time the value inside the signal changes. We only do this // if the signal is writable and not an input signal. if (isWritableSignal(componentValue) && !isInputSignal(componentValue)) { toObservable(componentValue, { injector, }).subscribe((value) => { var _a; (_a = component[expectedChangeKey]) === null || _a === void 0 ? void 0 : _a.emit(value); }); } } } } /** * Gets the componentInstance and Object.assigns any componentProperties() passed in the MountConfig * * @param {MountConfig} config TestBed configuration passed into the mount function * @param {ComponentFixture} fixture Fixture for debugging and testing a component. * @returns {T} Component being mounted */ function setupComponent(config, fixture) { let component = fixture.componentInstance; const injector = fixture.componentRef.injector; if (config === null || config === void 0 ? void 0 : config.componentProperties) { // convert primitives to signals if passed in type is a primitive but expected type is signal // a bit of magic. need to move to another function Object.keys(component).forEach((key) => { var _a; // only assign props if they are passed into the component if ((_a = config === null || config === void 0 ? void 0 : config.componentProperties) === null || _a === void 0 ? void 0 : _a.hasOwnProperty(key)) { // @ts-expect-error const passedInValue = config === null || config === void 0 ? void 0 : config.componentProperties[key]; const componentValue = component[key]; // @ts-expect-error config.componentProperties[key] = convertPropertyToSignalIfApplicable(passedInValue, componentValue, injector); detectAndRegisterOutputSpyToSignal(config, component, key, injector); } }); component = Object.assign(component, config.componentProperties); } if (config.autoSpyOutputs) { Object.keys(component).forEach((key) => { const property = component[key]; if (property instanceof EventEmitter) { component[key] = createOutputSpy(`${key}Spy`); } }); } // Manually call ngOnChanges when mounting components using the class syntax. // This is necessary because we are assigning input values to the class directly // on mount and therefore the ngOnChanges() lifecycle is not triggered. if (component.ngOnChanges && config.componentProperties) { const { componentProperties } = config; const simpleChanges = Object.entries(componentProperties).reduce((acc, [key, value]) => { acc[key] = new SimpleChange(null, value, true); return acc; }, {}); if (Object.keys(componentProperties).length > 0) { component.ngOnChanges(simpleChanges); } } } /** * Mounts an Angular component inside Cypress browser * * @param component Angular component being mounted or its template * @param config configuration used to configure the TestBed * @example * import { mount } from '@cypress/angular-signals' * import { StepperComponent } from './stepper.component' * import { MyService } from 'services/my.service' * import { SharedModule } from 'shared/shared.module'; * it('mounts', () => { * mount(StepperComponent, { * providers: [MyService], * imports: [SharedModule] * }) * cy.get('[data-cy=increment]').click() * cy.get('[data-cy=counter]').should('have.text', '1') * }) * * // or * * it('mounts with template', () => { * mount('', { * declarations: [StepperComponent], * }) * }) * * @see {@link https://on.cypress.io/mounting-angular} for more details. * * @returns A component and component fixture */ function mount(component, config = {}) { // Remove last mounted component if cy.mount is called more than once in a test if (activeFixture) { cleanup(); } const componentFixture = initTestBed(component, config); activeFixture = setupFixture(componentFixture, config); const mountResponse = { fixture: activeFixture, component: activeFixture.componentInstance, }; const logMessage = typeof component === 'string' ? 'Component' : componentFixture.name; Cypress.log({ name: 'mount', message: logMessage, consoleProps: () => ({ result: mountResponse }), }); return cy.wrap(mountResponse, { log: false }); } /** * Creates a new Event Emitter and then spies on it's `emit` method * * @param {string} alias name you want to use for your cy.spy() alias * @returns EventEmitter * @example * import { StepperComponent } from './stepper.component' * import { mount, createOutputSpy } from '@cypress/angular-signals' * * it('Has spy', () => { * mount(StepperComponent, { componentProperties: { change: createOutputSpy('changeSpy') } }) * cy.get('[data-cy=increment]').click() * cy.get('@changeSpy').should('have.been.called') * }) * * // Or for use with Angular Signals following the output nomenclature. * // see https://v17.angular.io/guide/model-inputs#differences-between-model-and-input/ * * it('Has spy', () => { * mount(StepperComponent, { componentProperties: { count: signal(0), countChange: createOutputSpy('countChange') } }) * cy.get('[data-cy=increment]').click() * cy.get('@countChange').should('have.been.called') * }) */ const createOutputSpy = (alias) => { const emitter = new EventEmitter(); cy.spy(emitter, 'emit').as(alias); return emitter; }; // Only needs to run once, we reset before each test getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), { teardown: { destroyAfterEach: false }, }); setupHooks(cleanup); export { CypressTestComponentRenderer, createOutputSpy, mount };