From 77c36041209aa5ec5af107c66e51ae1a72d63c4b Mon Sep 17 00:00:00 2001 From: nichoth Date: Fri, 27 Sep 2024 13:11:00 -0700 Subject: [PATCH] better click event --- src/index.ts | 48 +++++++++++++++++++++++++----------------------- src/util.ts | 9 ++++++++- test/index.ts | 16 ++++++++-------- 3 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/index.ts b/src/index.ts index 5b3d92e..009b566 100644 --- a/src/index.ts +++ b/src/index.ts @@ -279,48 +279,50 @@ export function waitFor ( /** * Dispatch the `click`` method on an element specified by selector. * - * @param {string|HTMLElement|Element} selector - A CSS selector string, or + * @param {string|Element} selector - A CSS selector string, or * an instance of an HTMLElement. * @returns {Promise} * * @example * ```js - * await t.click('.class button', 'Click a button') + * await click('.class button', 'Click a button') * ``` */ -export async function click (selector:HTMLElement|Element|string):Promise { - const el = toElement(selector) as HTMLElement +export async function click (selector:Element|string):Promise { + const element = toElement(selector) - if (globalThis.HTMLElement && !(el instanceof globalThis.HTMLElement)) { - throw new Error('selector needs to be instance of HTMLElement or resolve to one') - } + event(new globalThis.MouseEvent('click', { + bubbles: true, + cancelable: true, + button: 0 + }), element) - el!.click() await requestAnimationFrame() } /** - * Dispatch an event from the given element. + * @param {string|Event} event The event to dispatch + * @param {Element|window} [element] - The element to dispatch from, or + * will use `window` if none given. + * @returns {void} * - * @param {{ - * event: string | Event, - * element?: HTMLElement | Element | typeof window - * }} args + * @throws {Error} Throws an error if the `event` is not a string that can be + * converted to a CustomEvent or not an instance of Event. */ -export function event (args:{ - event:string|Event; - element?:HTMLElement|Element|typeof window -}):void { - let { - event, - element = window - } = args +export function event ( + event:string|InstanceType|InstanceType>, + element?:Element|Window +):void { + element = (element instanceof Window ? element : toElement(element)) if (typeof event === 'string') { - event = new window.CustomEvent(event) + event = new globalThis.CustomEvent(event) } - if (typeof event !== 'object') { + if ( + !(event instanceof Event) && + !((event as any) instanceof CustomEvent) + ) { throw new Error('event should be of type Event') } diff --git a/src/util.ts b/src/util.ts index 4aa4bfd..0367725 100644 --- a/src/util.ts +++ b/src/util.ts @@ -12,8 +12,13 @@ * HTMLElement, Element, or Window. * */ -export function toElement (_selector:string|HTMLElement|Element) { +export function toElement ( + _selector?:string|HTMLElement|Element +):Element|InstanceType { + if (!_selector) return window + let selector:string|Element|null = _selector + if (globalThis.document) { if (typeof selector === 'string') { selector = globalThis.document.querySelector(selector) @@ -28,6 +33,8 @@ export function toElement (_selector:string|HTMLElement|Element) { } return selector + } else { + return window } } diff --git a/test/index.ts b/test/index.ts index 87fe288..50a6411 100644 --- a/test/index.ts +++ b/test/index.ts @@ -233,23 +233,23 @@ test('dom.event', t => { t.plan(3) dom.qs('#test-two')!.addEventListener('hello', ev => { - t.ok(ev, 'should get the event') + t.ok(ev, 'should get the custom event') }) dom.qs('#test-two')!.addEventListener('testing-event', (ev) => { - t.ok(ev, 'should get another event') + t.ok(ev, 'should get another custom event') t.equal((ev as CustomEvent).detail, 'test', - 'has the right event properties') + 'Can pass in properties to customize the event') }) - dom.event({ event: 'hello', element: dom.qs('#test-two')! }) - dom.event({ - event: new CustomEvent('testing-event', { + dom.event('hello', dom.qs('#test-two')!) + dom.event( + new CustomEvent('testing-event', { bubbles: true, detail: 'test' }), - element: dom.qs('#test-two')! - }) + dom.qs('#test-two')! + ) }) test('waitForText', async t => {