Skip to content

Uncaught exception while using Skeleton Popup #406

Closed
@is-sematell

Description

@is-sematell

Summary

I've created a Tooltip component that utilizes Skeleton Popup. It works just fine in the browser.

However, when I try to test it via Testing Library, I get the below error. Seems like it is caused by userEvent.hover.

I've checked with the Skeleton community, and they believe that this is a Testing Library bug.

Error

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Unhandled Errors ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Vitest caught 1 unhandled error during the test run.
This might cause false positive tests. Resolve unhandled errors to make sure your tests are not affected.

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Uncaught Exception ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
SyntaxError: 'a[href], button, input, textarea, select, details, [tabindex]):not([tabindex="-1"]' is not a valid selector
 ❯ emit node_modules/.deno/[email protected]/node_modules/nwsapi/src/nwsapi.js:575:17
 ❯ Object._matches [as match] node_modules/.deno/[email protected]/node_modules/nwsapi/src/nwsapi.js:1438:9
 ❯ Array.Resolver node_modules/.deno/[email protected]/node_modules/nwsapi/src/nwsapi.js:777:17
 ❯ collect node_modules/.deno/[email protected]/node_modules/nwsapi/src/nwsapi.js:1594:21
 ❯ Object._querySelectorAll [as select] node_modules/.deno/[email protected]/node_modules/nwsapi/src/nwsapi.js:1549:36
 ❯ HTMLDivElementImpl.querySelectorAll node_modules/.deno/[email protected]/node_modules/jsdom/lib/jsdom/living/nodes/ParentNode-impl.js:78:26
 ❯ HTMLDivElement.querySelectorAll node_modules/.deno/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/Element.js:1119:58
 ❯ HTMLButtonElement.open node_modules/.deno/@[email protected]/node_modules/@skeletonlabs/skeleton/dist/utilities/Popup/popup.js:119:56
    118|     }
    119|     function close(callback) {
    120|         if (!elemPopup)
       |     ^
    121|             return;
    122|         // Set transition duration
 ❯ HTMLButtonElement.callTheUserObjectsOperation node_modules/.deno/[email protected]/node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30
 ❯ innerInvokeEventListeners node_modules/.deno/[email protected]/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯
Serialized Error: { code: 12, INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25, __proto__: { constructor: 'Function<DOMException>', name: '<unserializable>', message: '<unserializable>', code: '<unserializable>', INDEX_SIZE_ERR: 1, DOMSTRING_SIZE_ERR: 2, HIERARCHY_REQUEST_ERR: 3, WRONG_DOCUMENT_ERR: 4, INVALID_CHARACTER_ERR: 5, NO_DATA_ALLOWED_ERR: 6, NO_MODIFICATION_ALLOWED_ERR: 7, NOT_FOUND_ERR: 8, NOT_SUPPORTED_ERR: 9, INUSE_ATTRIBUTE_ERR: 10, INVALID_STATE_ERR: 11, SYNTAX_ERR: 12, INVALID_MODIFICATION_ERR: 13, NAMESPACE_ERR: 14, INVALID_ACCESS_ERR: 15, VALIDATION_ERR: 16, TYPE_MISMATCH_ERR: 17, SECURITY_ERR: 18, NETWORK_ERR: 19, ABORT_ERR: 20, URL_MISMATCH_ERR: 21, QUOTA_EXCEEDED_ERR: 22, TIMEOUT_ERR: 23, INVALID_NODE_TYPE_ERR: 24, DATA_CLONE_ERR: 25, toString: 'Function<toString>', __defineGetter__: 'Function<__defineGetter__>', __defineSetter__: 'Function<__defineSetter__>', hasOwnProperty: 'Function<hasOwnProperty>', __lookupGetter__: 'Function<__lookupGetter__>', __lookupSetter__: 'Function<__lookupSetter__>', isPrototypeOf: 'Function<isPrototypeOf>', propertyIsEnumerable: 'Function<propertyIsEnumerable>', valueOf: 'Function<valueOf>', __proto__: { constructor: 'Function<Error>', name: 'Error', message: '', toString: 'Function<toString>', __defineGetter__: 'Function<__defineGetter__>', __defineSetter__: 'Function<__defineSetter__>', hasOwnProperty: 'Function<hasOwnProperty>', __lookupGetter__: 'Function<__lookupGetter__>', __lookupSetter__: 'Function<__lookupSetter__>', isPrototypeOf: 'Function<isPrototypeOf>', propertyIsEnumerable: 'Function<propertyIsEnumerable>', valueOf: 'Function<valueOf>', __proto__: { constructor: 'Function<Object>', __defineGetter__: 'Function<__defineGetter__>', __defineSetter__: 'Function<__defineSetter__>', hasOwnProperty: 'Function<hasOwnProperty>', __lookupGetter__: 'Function<__lookupGetter__>', __lookupSetter__: 'Function<__lookupSetter__>', isPrototypeOf: 'Function<isPrototypeOf>', propertyIsEnumerable: 'Function<propertyIsEnumerable>', toString: 'Function<toString>', valueOf: 'Function<valueOf>', __proto__: null, toLocaleString: 'Function<toLocaleString>' }, toLocaleString: 'Function<toLocaleString>' }, toLocaleString: 'Function<toLocaleString>' } }
This error originated in "src/lib/components/skeleton-test/Tooltip.test.ts" test file. It doesn't mean the error was thrown inside the file itself, but while it was running.
The latest test that might've caused the error is "should render the tooltip content on hover". It might mean one of the following:
- The error was thrown, while Vitest was running this test.
- If the error occurred after the test had been completed, this was the last documented test before it was thrown.
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

Reproduction steps

  1. Setup SvelteKit: https://svelte.dev/docs/kit/creating-a-project
  2. Setup Tailwind: https://tailwindcss.com/docs/guides/sveltekit
  3. Setup Vitest + Svelte Testing Library: https://testing-library.com/docs/svelte-testing-library/setup
    • Note: Don't install @sveltejs/vite-plugin-svelte since it isn't needed for SvelteKit and causes errors
  4. Add a workaround for window.matchMedia, otherwise it may produce errors: TypeError: window.matchMedia is not a function in Vitest vitest-dev/vitest#821
  5. Install userEvent for simulating user interaction: https://testing-library.com/docs/user-event/install
  6. Add teh code below to your repo
  7. Execute vitest

Code

Tooltip.svelte

<script lang="ts">
	import { popup, type PopupSettings } from '@skeletonlabs/skeleton';

	export let label: string;
	export let target: string;
	export let content: string;

	const popupHover: PopupSettings = {
		event: 'hover',
		target,
		placement: 'top'
	};
</script>

<button class="btn variant-filled [&>*]:pointer-events-none" use:popup={popupHover}>
	<span>{label}</span>
</button>

<div class="card p-4 variant-filled-secondary" data-popup={target}>
	<p>{content}</p>
	<div class="arrow variant-filled-secondary" />
</div>

TooltipTest.svelte

<script lang="ts">
	import { initializeStores, storePopup } from '@skeletonlabs/skeleton';
	import { computePosition, autoUpdate, offset, shift, flip, arrow } from '@floating-ui/dom';
	import Tooltip from './Tooltip.svelte';

	initializeStores();
	storePopup.set({ computePosition, autoUpdate, offset, shift, flip, arrow });
</script>

<Tooltip
	target="info"
	label="More Info"
	content="We're going to check if this component can be tested in Testing Library"
/>

Tooltip.test.ts

import { render } from '@testing-library/svelte';
import userEvent from '@testing-library/user-event';
import TooltipTest from './TooltipTest.svelte';

describe('TooltipTest.svelte', () => {
	it('should render the tooltip content on hover', async () => {
		const { getByText, queryByText } = render(TooltipTest);

		const triggerElement = getByText('More Info');
		await userEvent.hover(triggerElement);

		expect(
			getByText("We're going to check if this component can be tested in Testing Library")
		).toBeVisible();

		await userEvent.unhover(triggerElement);

		expect(
			queryByText("We're going to check if this component can be tested in Testing Library")
		).not.toBeVisible();
	});
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions