mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
test(range): migrate tests to playwright (#25299)
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
import { toHaveReceivedEvent } from './toHaveReceivedEvent';
|
||||
import { toHaveReceivedEventDetail } from './toHaveReceivedEventDetail';
|
||||
|
||||
export const matchers = {
|
||||
toHaveReceivedEvent,
|
||||
toHaveReceivedEventDetail,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
|
||||
import type { EventSpy } from '../page/event-spy';
|
||||
|
||||
export function toHaveReceivedEventDetail(eventSpy: EventSpy, eventDetail: any) {
|
||||
if (!eventSpy) {
|
||||
return {
|
||||
message: () => `toHaveReceivedEventDetail event spy is null`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof (eventSpy as any).then === 'function') {
|
||||
return {
|
||||
message: () =>
|
||||
`expected spy to have received event, but it was not resolved (did you forget an await operator?).`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (!eventSpy.eventName) {
|
||||
return {
|
||||
message: () => `toHaveReceivedEventDetail did not receive an event spy`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (!eventSpy.lastEvent) {
|
||||
return {
|
||||
message: () => `event "${eventSpy.eventName}" was not received`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
const pass = deepEqual(eventSpy.lastEvent.detail, eventDetail);
|
||||
|
||||
expect(eventSpy.lastEvent.detail).toEqual(eventDetail);
|
||||
|
||||
return {
|
||||
message: () => `expected event "${eventSpy.eventName}" detail to ${pass ? 'not ' : ''}equal`,
|
||||
pass: pass,
|
||||
};
|
||||
}
|
||||
@@ -16,7 +16,7 @@ export class EventSpy {
|
||||
*/
|
||||
private cursor = 0;
|
||||
private queuedHandler: (() => void)[] = [];
|
||||
public events: Event[] = [];
|
||||
public events: CustomEvent[] = [];
|
||||
|
||||
constructor(public eventName: string) {}
|
||||
|
||||
@@ -24,6 +24,14 @@ export class EventSpy {
|
||||
return this.events.length;
|
||||
}
|
||||
|
||||
get firstEvent() {
|
||||
return this.events[0] || null;
|
||||
}
|
||||
|
||||
get lastEvent() {
|
||||
return this.events[this.events.length - 1] || null;
|
||||
}
|
||||
|
||||
public next() {
|
||||
const { cursor } = this;
|
||||
this.cursor++;
|
||||
@@ -48,7 +56,7 @@ export class EventSpy {
|
||||
}
|
||||
}
|
||||
|
||||
public push(ev: Event) {
|
||||
public push(ev: CustomEvent) {
|
||||
this.events.push(ev);
|
||||
const next = this.queuedHandler.shift();
|
||||
if (next) {
|
||||
@@ -91,8 +99,55 @@ export const addE2EListener = async (page: E2EPage, eventName: string, callback:
|
||||
|
||||
await page.evaluate(
|
||||
([eventName, id]) => {
|
||||
(window as any).stencilSerializeEventTarget = (target: any) => {
|
||||
// BROWSER CONTEXT
|
||||
if (!target) {
|
||||
return null;
|
||||
}
|
||||
if (target === window) {
|
||||
return { serializedWindow: true };
|
||||
}
|
||||
if (target === document) {
|
||||
return { serializedDocument: true };
|
||||
}
|
||||
if (target.nodeType != null) {
|
||||
const serializedElement: any = {
|
||||
serializedElement: true,
|
||||
nodeName: target.nodeName,
|
||||
nodeValue: target.nodeValue,
|
||||
nodeType: target.nodeType,
|
||||
tagName: target.tagName,
|
||||
className: target.className,
|
||||
id: target.id,
|
||||
};
|
||||
return serializedElement;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
(window as any).serializeStencilEvent = (orgEv: CustomEvent) => {
|
||||
const serializedEvent = {
|
||||
bubbles: orgEv.bubbles,
|
||||
cancelBubble: orgEv.cancelBubble,
|
||||
cancelable: orgEv.cancelable,
|
||||
composed: orgEv.composed,
|
||||
currentTarget: (window as any).stencilSerializeEventTarget(orgEv.currentTarget),
|
||||
defaultPrevented: orgEv.defaultPrevented,
|
||||
detail: orgEv.detail,
|
||||
eventPhase: orgEv.eventPhase,
|
||||
isTrusted: orgEv.isTrusted,
|
||||
returnValue: orgEv.returnValue,
|
||||
srcElement: (window as any).stencilSerializeEventTarget(orgEv.srcElement),
|
||||
target: (window as any).stencilSerializeEventTarget(orgEv.target),
|
||||
timeStamp: orgEv.timeStamp,
|
||||
type: orgEv.type,
|
||||
isSerializedEvent: true,
|
||||
};
|
||||
return serializedEvent;
|
||||
};
|
||||
|
||||
window.addEventListener(eventName as string, (ev: Event) => {
|
||||
(window as any).ionicOnEvent(id, ev);
|
||||
(window as any).ionicOnEvent(id, (window as any).serializeStencilEvent(ev));
|
||||
});
|
||||
},
|
||||
[eventName, id]
|
||||
|
||||
@@ -13,8 +13,13 @@ import type { Page } from '@playwright/test';
|
||||
*/
|
||||
export const setIonViewport = async (page: Page) => {
|
||||
const currentViewport = page.viewportSize();
|
||||
const ionContent = await page.$('ion-content');
|
||||
|
||||
const pixelAmountRenderedOffscreen = await page.evaluate(() => {
|
||||
if (ionContent) {
|
||||
await ionContent.waitForElementState('stable');
|
||||
}
|
||||
|
||||
const pixelAmountRenderedOffscreen = await page.evaluate(async () => {
|
||||
const content = document.querySelector('ion-content');
|
||||
if (content) {
|
||||
const innerScroll = content.shadowRoot!.querySelector('.inner-scroll')!;
|
||||
|
||||
@@ -4,7 +4,7 @@ import { addE2EListener, EventSpy } from '../event-spy';
|
||||
export const spyOnEvent = async (page: E2EPage, eventName: string): Promise<EventSpy> => {
|
||||
const spy = new EventSpy(eventName);
|
||||
|
||||
await addE2EListener(page, eventName, (ev: Event) => spy.push(ev));
|
||||
await addE2EListener(page, eventName, (ev: CustomEvent) => spy.push(ev));
|
||||
|
||||
return spy;
|
||||
};
|
||||
|
||||
@@ -3,6 +3,11 @@ interface CustomMatchers<R = unknown> {
|
||||
* Will check if the event spy received the expected event.
|
||||
*/
|
||||
toHaveReceivedEvent(): R;
|
||||
/**
|
||||
* Will check if the event spy received the expected event with the expected detail.
|
||||
* @param eventDetail The expected detail of the event.
|
||||
*/
|
||||
toHaveReceivedEventDetail(eventDetail: any): R;
|
||||
}
|
||||
|
||||
declare namespace PlaywrightTest {
|
||||
|
||||
Reference in New Issue
Block a user