Skip to main content
Glama
deleonio
by deleonio
input-callbacks-and-events.ts3.44 kB
import type { Locator } from '@playwright/test'; import { expect, type Page } from '@playwright/test'; import { type E2EPage, test } from '@stencil/playwright'; import type { InputTypeOnDefault } from '../schema'; import { Callback } from '../schema/enums'; import { KolEvent } from '../utils/events'; import type { FillAction } from './utils/FillAction'; import { INPUTS_SELECTOR } from './utils/inputsSelector'; type TestInputCallbacksAndEventsOptions = { additionalProperties?: string; componentName: string; equalityCheck?: 'toBe' | 'toEqual'; expectedValue?: unknown; fillAction?: FillAction; omittedEvents?: string[]; selectInput?: (page: Page & E2EPage) => Locator; testValue?: unknown; }; const testInputCallbacksAndEvents = <ElementType extends { _on?: InputTypeOnDefault } & (HTMLElement | SVGElement)>({ additionalProperties = '', componentName, equalityCheck = 'toBe', expectedValue, fillAction, omittedEvents = [], selectInput, testValue = 'Test Input', }: TestInputCallbacksAndEventsOptions) => { test.describe('Callbacks and DOM events', () => { const EVENTS: [string, Callback, KolEvent, unknown?, unknown?][] = [ ['click', Callback.onClick, KolEvent.click], ['focus', Callback.onFocus, KolEvent.focus], ['blur', Callback.onBlur, KolEvent.blur], ['input', Callback.onInput, KolEvent.input, testValue, expectedValue ?? testValue], ['change', Callback.onChange, KolEvent.change, testValue, expectedValue ?? testValue], ]; EVENTS.filter(([eventName]) => !omittedEvents.includes(eventName)).forEach(([nativeEventName, callbackName, kolEventName, testValue, expectedValue]) => { test(`should call ${callbackName} callback when internal input emits ${nativeEventName}`, async ({ page, browserName }) => { /* See https://github.com/microsoft/playwright/issues/33864 */ test.skip( componentName === 'kol-input-color' && nativeEventName === 'click' && browserName === 'firefox', 'Clicking on an input[type=color] in Firefox currently makes the page close itself.', ); await page.setContent(`<${componentName} _label="Input" ${additionalProperties}></${componentName}>`); const component = page.locator(componentName); const input = selectInput ? selectInput(page) : page.locator(INPUTS_SELECTOR); const callbackPromise = component.evaluate((element: ElementType, callbackName) => { return new Promise<unknown>((resolve) => { element._on = { [callbackName]: (_event: InputEvent, value?: unknown) => { resolve(value); }, }; }); }, callbackName); const eventPromise = component.evaluate((element: ElementType, kolEventName) => { return new Promise<unknown>((resolve) => { element.addEventListener(kolEventName, (event: Event) => { resolve((event as CustomEvent).detail); }); }); }, kolEventName); await page.waitForChanges(); if (fillAction) { await fillAction(page); } else if (typeof testValue === 'string') { await page.locator(INPUTS_SELECTOR).fill(testValue); } await page.waitForChanges(); await input.dispatchEvent(nativeEventName); await expect(callbackPromise).resolves[equalityCheck](expectedValue); await expect(eventPromise).resolves[equalityCheck](expectedValue ?? null); // For no value, callbacks use `undefined`, the event detail is `null`. }); }); }); }; export { testInputCallbacksAndEvents };

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/deleonio/public-ui-kolibri'

If you have feedback or need assistance with the MCP directory API, please join our Discord server