feat(ct): support non-event-emitter outputs

This commit is contained in:
Younes Jaaidi 2023-11-13 23:12:18 +01:00 committed by sand4rt
parent 8844ebdb2d
commit bd67f8b176
2 changed files with 31 additions and 12 deletions

View file

@ -18,9 +18,15 @@
// This file is injected into the registry as text, no dependencies are allowed. // This file is injected into the registry as text, no dependencies are allowed.
import 'zone.js'; import 'zone.js';
import {
Component as defineComponent,
reflectComponentType
} from '@angular/core';
import { getTestBed, TestBed } from '@angular/core/testing'; import { getTestBed, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; import {
import { EventEmitter, reflectComponentType, Component as defineComponent } from '@angular/core'; BrowserDynamicTestingModule,
platformBrowserDynamicTesting,
} from '@angular/platform-browser-dynamic/testing';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
/** @typedef {import('@playwright/experimental-ct-core/types/component').Component} Component */ /** @typedef {import('@playwright/experimental-ct-core/types/component').Component} Component */
@ -34,6 +40,8 @@ const __pwLoaderRegistry = new Map();
const __pwRegistry = new Map(); const __pwRegistry = new Map();
/** @type {Map<string, import('@angular/core/testing').ComponentFixture>} */ /** @type {Map<string, import('@angular/core/testing').ComponentFixture>} */
const __pwFixtureRegistry = new Map(); const __pwFixtureRegistry = new Map();
/** @type {WeakMap<import('@angular/core/testing').ComponentFixture, Record<string, import('rxjs').Subscription>>} */
const __pwOutputSubscriptionRegistry = new WeakMap();
getTestBed().initTestEnvironment( getTestBed().initTestEnvironment(
BrowserDynamicTestingModule, BrowserDynamicTestingModule,
@ -96,12 +104,22 @@ function __pwUpdateProps(fixture, props = {}) {
* @param {import('@angular/core/testing').ComponentFixture} fixture * @param {import('@angular/core/testing').ComponentFixture} fixture
*/ */
function __pwUpdateEvents(fixture, events = {}) { function __pwUpdateEvents(fixture, events = {}) {
for (const [name, value] of Object.entries(events)) { const outputSubscriptionRecord =
fixture.debugElement.children[0].componentInstance[name] = { __pwOutputSubscriptionRegistry.get(fixture) ?? {};
...new EventEmitter(), for (const [name, listener] of Object.entries(events)) {
emit: event => value(event) /* Unsubscribe previous listener. */
}; outputSubscriptionRecord[name]?.unsubscribe();
const subscription = fixture.debugElement.children[0].componentInstance[
name
].subscribe((event) => listener(event));
/* Store new subscription. */
outputSubscriptionRecord[name] = subscription;
} }
/* Update output subscription registry. */
__pwOutputSubscriptionRegistry.set(fixture, outputSubscriptionRecord);
} }
function __pwUpdateSlots(Component, slots = {}, tagName) { function __pwUpdateSlots(Component, slots = {}, tagName) {
@ -211,8 +229,12 @@ window.playwrightMount = async (component, rootElement, hooksConfig) => {
window.playwrightUnmount = async rootElement => { window.playwrightUnmount = async rootElement => {
const fixture = __pwFixtureRegistry.get(rootElement.id); const fixture = __pwFixtureRegistry.get(rootElement.id);
if (!fixture) if (!fixture) throw new Error('Component was not mounted');
throw new Error('Component was not mounted');
/* Unsubscribe from all outputs. */
for (const subscription of Object.values(__pwOutputSubscriptionRegistry.get(fixture) ?? {}))
subscription?.unsubscribe();
__pwOutputSubscriptionRegistry.delete(fixture);
fixture.destroy(); fixture.destroy();
fixture.nativeElement.replaceChildren(); fixture.nativeElement.replaceChildren();

View file

@ -19,8 +19,6 @@ test('emit an submit event when the button is clicked', async ({ mount }) => {
test('replace existing listener when new listener is set', async ({ test('replace existing listener when new listener is set', async ({
mount, mount,
}) => { }) => {
test.skip(true, '🚧 work in progress');
let count = 0; let count = 0;
const component = await mount(ButtonComponent, { const component = await mount(ButtonComponent, {
@ -50,7 +48,6 @@ test('unsubscribe from events when the component is unmounted', async ({
mount, mount,
page, page,
}) => { }) => {
test.skip(true, '🚧 work in progress');
const component = await mount(OutputComponent, { const component = await mount(OutputComponent, {
on: { on: {
answerChange() {}, answerChange() {},