diff --git a/packages/qunit-dom/lib/__tests__/descriptor.ts b/packages/qunit-dom/lib/__tests__/descriptor.ts
new file mode 100644
index 000000000..cf5803314
--- /dev/null
+++ b/packages/qunit-dom/lib/__tests__/descriptor.ts
@@ -0,0 +1,119 @@
+import { describe, beforeEach, test, expect } from 'vitest';
+
+import createDescriptor from '../descriptor';
+import TestAssertions from '../helpers/test-assertions';
+import {
+ resolveDOMElement,
+ resolveDOMElements,
+ resolveDescription,
+ createDescriptor as createDescriptorBase,
+} from 'dom-element-descriptors';
+
+describe('createQuery()', () => {
+ beforeEach(() => {
+ document.body.innerHTML =
+ '
';
+ });
+
+ test('it works with a selector', () => {
+ let expected = Array.from(document.querySelectorAll('.multiple'));
+ let descriptor = createDescriptor('.multiple', document);
+
+ expect(resolveDOMElement(descriptor)).toEqual(expected[0]);
+ expect(resolveDOMElements(descriptor)).toEqual(expected);
+ expect(resolveDescription(descriptor)).toEqual('.multiple');
+ });
+
+ test('selector respects the root element', () => {
+ document.body.innerHTML =
+ '';
+ let root = document.querySelector('.root');
+ let [outOfRoot, inRoot] = Array.from(document.querySelectorAll('.multiple'));
+
+ expect(resolveDOMElement(createDescriptor('.multiple', document))).toEqual(outOfRoot);
+ expect(resolveDOMElements(createDescriptor('.multiple', document))).toEqual([
+ outOfRoot,
+ inRoot,
+ ]);
+
+ expect(resolveDOMElement(createDescriptor('.multiple', root))).toEqual(inRoot);
+ expect(resolveDOMElements(createDescriptor('.multiple', root))).toEqual([inRoot]);
+ });
+
+ test('it works with an element', () => {
+ let expected = document.querySelector('.multiple');
+ let descriptor = createDescriptor(expected, document);
+
+ expect(resolveDOMElement(descriptor)).toEqual(expected);
+ expect(resolveDOMElements(descriptor)).toEqual([expected]);
+ expect(resolveDescription(descriptor)).toEqual('div.multiple');
+ });
+
+ test('it works with null', () => {
+ let descriptor = createDescriptor(null, document);
+
+ expect(resolveDOMElement(descriptor)).toEqual(null);
+ expect(resolveDOMElements(descriptor)).toEqual([]);
+ expect(resolveDescription(descriptor)).toEqual('
');
+ });
+
+ test('it works with a dom element descriptor', () => {
+ let expected = Array.from(document.querySelectorAll('.multiple'));
+ let descriptor = createDescriptor(
+ createDescriptorBase({ elements: expected, description: 'descriptoriffic' }),
+ document
+ );
+
+ expect(resolveDOMElement(descriptor)).toEqual(expected[0]);
+ expect(resolveDOMElements(descriptor)).toEqual(expected);
+ expect(resolveDescription(descriptor)).toEqual('descriptoriffic');
+ });
+
+ test('it works via assert.dom()', () => {
+ let assert = new TestAssertions();
+
+ assert
+ .dom(createDescriptorBase({ elements: Array.from(document.querySelectorAll('.single')) }))
+ .exists({ count: 1 });
+ assert
+ .dom(createDescriptorBase({ elements: Array.from(document.querySelectorAll('.multiple')) }))
+ .exists({ count: 2 });
+ assert
+ .dom(createDescriptorBase({ elements: Array.from(document.querySelectorAll('.single')) }))
+ .hasTagName('div');
+
+ expect(assert.results).toEqual([
+ {
+ actual: 'Element undefined exists once',
+ expected: 'Element undefined exists once',
+ message: 'Element undefined exists once',
+ result: true,
+ },
+ {
+ actual: 'Element undefined exists twice',
+ expected: 'Element undefined exists twice',
+ message: 'Element undefined exists twice',
+ result: true,
+ },
+ {
+ actual: 'div',
+ expected: 'div',
+ message: 'Element undefined has tagName div',
+ result: true,
+ },
+ ]);
+ });
+
+ test('throws for unexpected parameter types', () => {
+ expect(() => createDescriptor(5, document)).toThrow('Unexpected Parameter: 5');
+ expect(() => createDescriptor(true, document)).toThrow('Unexpected Parameter: true');
+ expect(() => createDescriptor(undefined, document)).toThrow('Unexpected Parameter: undefined');
+ expect(() => createDescriptor({}, document)).toThrow('Unexpected Parameter: [object Object]');
+ expect(() => createDescriptor({ element: document.createElement('div') }, document)).toThrow(
+ 'Unexpected Parameter: [object Object]'
+ );
+ expect(() => createDescriptor(document, document)).toThrow(
+ 'Unexpected Parameter: [object Document]'
+ );
+ });
+});
diff --git a/packages/qunit-dom/lib/assertions.ts b/packages/qunit-dom/lib/assertions.ts
index c117fe0d7..b6d83458e 100644
--- a/packages/qunit-dom/lib/assertions.ts
+++ b/packages/qunit-dom/lib/assertions.ts
@@ -9,9 +9,14 @@ import isValid from './assertions/is-valid.js';
import isVisible from './assertions/is-visible.js';
import isDisabled from './assertions/is-disabled.js';
import matchesSelector from './assertions/matches-selector.js';
-import elementToString from './helpers/element-to-string.js';
import collapseWhitespace from './helpers/collapse-whitespace.js';
-import { toArray } from './helpers/node-list.js';
+import {
+ type IDOMElementDescriptor,
+ resolveDOMElement,
+ resolveDOMElements,
+ resolveDescription,
+} from 'dom-element-descriptors';
+import createDescriptor from './descriptor';
export interface AssertionResult {
result: boolean;
@@ -29,11 +34,24 @@ type CSSStyleDeclarationProperty = keyof CSSStyleDeclaration;
type ActualCSSStyleDeclaration = Partial>;
export default class DOMAssertions {
+ /**
+ * The target of our assertions
+ */
+ private descriptor: IDOMElementDescriptor;
+ /**
+ * Whether we were constructed with an element, rather than a selector or
+ * descriptor. Used to make error messages more helpful.
+ */
+ private wasPassedElement: boolean;
+
constructor(
- private target: string | Element | null,
- private rootElement: RootElement,
+ target: string | Element | null | IDOMElementDescriptor,
+ rootElement: RootElement,
private testContext: Assert
- ) {}
+ ) {
+ this.descriptor = createDescriptor(target, rootElement);
+ this.wasPassedElement = target instanceof Element;
+ }
/**
* Assert an {@link HTMLElement} (or multiple) matching the `selector` exists.
@@ -1217,11 +1235,11 @@ export default class DOMAssertions {
* assert.dom('p.red').matchesSelector('div.wrapper p:last-child')
*/
matchesSelector(compareSelector: string, message?: string): DOMAssertions {
- let targetElements = this.target instanceof Element ? [this.target] : this.findElements();
+ let targetElements = this.findElements();
let targets = targetElements.length;
let matchFailures = matchesSelector(targetElements, compareSelector);
let singleElement: boolean = targets === 1;
- let selectedByPart = this.target instanceof Element ? 'passed' : `selected by ${this.target}`;
+ let selectedByPart = this.selectedBy;
let actual;
let expected;
@@ -1230,7 +1248,7 @@ export default class DOMAssertions {
if (!message) {
message = singleElement
? `The element ${selectedByPart} also matches the selector ${compareSelector}.`
- : `${targets} elements, selected by ${this.target}, also match the selector ${compareSelector}.`;
+ : `${targets} elements, ${selectedByPart}, also match the selector ${compareSelector}.`;
}
actual = expected = message;
this.pushResult({ result: true, actual, expected, message });
@@ -1240,7 +1258,7 @@ export default class DOMAssertions {
if (!message) {
message = singleElement
? `The element ${selectedByPart} did not also match the selector ${compareSelector}.`
- : `${matchFailures} out of ${targets} elements selected by ${this.target} did not also match the selector ${compareSelector}.`;
+ : `${matchFailures} out of ${targets} elements ${selectedByPart} did not also match the selector ${compareSelector}.`;
}
actual = singleElement ? message : `${difference} elements matched ${compareSelector}.`;
expected = singleElement
@@ -1263,11 +1281,11 @@ export default class DOMAssertions {
* assert.dom('input').doesNotMatchSelector('input[disabled]')
*/
doesNotMatchSelector(compareSelector: string, message?: string): DOMAssertions {
- let targetElements = this.target instanceof Element ? [this.target] : this.findElements();
+ let targetElements = this.findElements();
let targets = targetElements.length;
let matchFailures = matchesSelector(targetElements, compareSelector);
let singleElement: boolean = targets === 1;
- let selectedByPart = this.target instanceof Element ? 'passed' : `selected by ${this.target}`;
+ let selectedByPart = this.selectedBy;
let actual;
let expected;
if (matchFailures === targets) {
@@ -1275,7 +1293,7 @@ export default class DOMAssertions {
if (!message) {
message = singleElement
? `The element ${selectedByPart} did not also match the selector ${compareSelector}.`
- : `${targets} elements, selected by ${this.target}, did not also match the selector ${compareSelector}.`;
+ : `${targets} elements, ${selectedByPart}, did not also match the selector ${compareSelector}.`;
}
actual = expected = message;
this.pushResult({ result: true, actual, expected, message });
@@ -1285,7 +1303,7 @@ export default class DOMAssertions {
if (!message) {
message = singleElement
? `The element ${selectedByPart} must not also match the selector ${compareSelector}.`
- : `${difference} elements out of ${targets}, selected by ${this.target}, must not also match the selector ${compareSelector}.`;
+ : `${difference} elements out of ${targets}, ${selectedByPart}, must not also match the selector ${compareSelector}.`;
}
actual = singleElement
? `The element ${selectedByPart} matched ${compareSelector}.`
@@ -1407,10 +1425,10 @@ export default class DOMAssertions {
* @returns (HTMLElement|null) a valid HTMLElement, or null
*/
private findTargetElement(): Element | null {
- let el = this.findElement();
+ let el = resolveDOMElement(this.descriptor);
if (el === null) {
- let message = `Element ${this.target || ''} should exist`;
+ let message = `Element ${this.targetDescription} should exist`;
this.pushResult({ message, result: false, actual: undefined, expected: undefined });
return null;
}
@@ -1419,51 +1437,32 @@ export default class DOMAssertions {
}
/**
- * Finds a valid HTMLElement from target
+ * Finds a collection of Element instances from target using querySelectorAll
* @private
- * @returns (HTMLElement|null) a valid HTMLElement, or null
+ * @returns (Element[]) an array of Element instances
* @throws TypeError will be thrown if target is an unrecognized type
*/
- private findElement(): Element | null {
- if (this.target === null) {
- return null;
- } else if (typeof this.target === 'string') {
- if (!this.rootElement) {
- throw new Error('Cannot do selector-based queries without a root element');
- }
- return this.rootElement.querySelector(this.target);
- } else if (this.target instanceof Element) {
- return this.target;
- } else {
- throw new TypeError(`Unexpected Parameter: ${this.target}`);
- }
+ private findElements(): Element[] {
+ return Array.from(resolveDOMElements(this.descriptor));
}
/**
- * Finds a collection of Element instances from target using querySelectorAll
* @private
- * @returns (Element[]) an array of Element instances
- * @throws TypeError will be thrown if target is an unrecognized type
*/
- private findElements(): Element[] {
- if (this.target === null) {
- return [];
- } else if (typeof this.target === 'string') {
- if (!this.rootElement) {
- throw new Error('Cannot do selector-based queries without a root element');
- }
- return toArray(this.rootElement.querySelectorAll(this.target));
- } else if (this.target instanceof Element) {
- return [this.target];
- } else {
- throw new TypeError(`Unexpected Parameter: ${this.target}`);
- }
+ private get targetDescription(): string {
+ return resolveDescription(this.descriptor) ?? 'undefined';
}
/**
* @private
*/
- private get targetDescription(): string {
- return elementToString(this.target);
+ private get selectedBy(): string {
+ if (this.wasPassedElement) {
+ return 'passed';
+ } else if (resolveDOMElement(this.descriptor)) {
+ return `selected by ${this.targetDescription}`;
+ } else {
+ return 'selected by null';
+ }
}
}
diff --git a/packages/qunit-dom/lib/assertions/exists.ts b/packages/qunit-dom/lib/assertions/exists.ts
index 26f85d68b..b1ea43057 100644
--- a/packages/qunit-dom/lib/assertions/exists.ts
+++ b/packages/qunit-dom/lib/assertions/exists.ts
@@ -37,6 +37,10 @@ export default function exists(options?: ExistsOptions | string, message?: strin
}
function format(selector: string, num?: number) {
+ if (selector === '') {
+ selector = '';
+ }
+
if (num === undefined || num === null) {
return `Element ${selector} exists`;
} else if (num === 0) {
diff --git a/packages/qunit-dom/lib/assertions/focused.ts b/packages/qunit-dom/lib/assertions/focused.ts
index 3cbb459ec..cca6e97b5 100644
--- a/packages/qunit-dom/lib/assertions/focused.ts
+++ b/packages/qunit-dom/lib/assertions/focused.ts
@@ -6,7 +6,7 @@ export default function focused(message?: string) {
let result = document.activeElement === element;
let actual = elementToString(document.activeElement);
- let expected = elementToString(this.target);
+ let expected = this.targetDescription;
if (!message) {
message = `Element ${expected} is focused`;
diff --git a/packages/qunit-dom/lib/assertions/is-checked.ts b/packages/qunit-dom/lib/assertions/is-checked.ts
index d90ee62fc..363cac5fe 100644
--- a/packages/qunit-dom/lib/assertions/is-checked.ts
+++ b/packages/qunit-dom/lib/assertions/is-checked.ts
@@ -1,5 +1,3 @@
-import elementToString from '../helpers/element-to-string.js';
-
export default function checked(message?: string) {
let element = this.findTargetElement();
if (!element) return;
@@ -21,7 +19,7 @@ export default function checked(message?: string) {
let expected = 'checked';
if (!message) {
- message = `Element ${elementToString(this.target)} is checked`;
+ message = `Element ${this.targetDescription} is checked`;
}
this.pushResult({ result, actual, expected, message });
diff --git a/packages/qunit-dom/lib/assertions/is-not-checked.ts b/packages/qunit-dom/lib/assertions/is-not-checked.ts
index 60e81597e..471239858 100644
--- a/packages/qunit-dom/lib/assertions/is-not-checked.ts
+++ b/packages/qunit-dom/lib/assertions/is-not-checked.ts
@@ -1,5 +1,3 @@
-import elementToString from '../helpers/element-to-string.js';
-
export default function notChecked(message?: string) {
let element = this.findTargetElement();
if (!element) return;
@@ -21,7 +19,7 @@ export default function notChecked(message?: string) {
let expected = 'not checked';
if (!message) {
- message = `Element ${elementToString(this.target)} is not checked`;
+ message = `Element ${this.targetDescription} is not checked`;
}
this.pushResult({ result, actual, expected, message });
diff --git a/packages/qunit-dom/lib/assertions/is-not-required.ts b/packages/qunit-dom/lib/assertions/is-not-required.ts
index 555b39975..0f8ca4e04 100644
--- a/packages/qunit-dom/lib/assertions/is-not-required.ts
+++ b/packages/qunit-dom/lib/assertions/is-not-required.ts
@@ -1,5 +1,3 @@
-import elementToString from '../helpers/element-to-string.js';
-
export default function notRequired(message?: string) {
let element = this.findTargetElement();
if (!element) return;
@@ -19,7 +17,7 @@ export default function notRequired(message?: string) {
let expected = 'not required';
if (!message) {
- message = `Element ${elementToString(this.target)} is not required`;
+ message = `Element ${this.targetDescription} is not required`;
}
this.pushResult({ result, actual, expected, message });
diff --git a/packages/qunit-dom/lib/assertions/is-required.ts b/packages/qunit-dom/lib/assertions/is-required.ts
index ba49569f6..198d84efd 100644
--- a/packages/qunit-dom/lib/assertions/is-required.ts
+++ b/packages/qunit-dom/lib/assertions/is-required.ts
@@ -1,5 +1,3 @@
-import elementToString from '../helpers/element-to-string.js';
-
export default function required(message?: string) {
let element = this.findTargetElement();
if (!element) return;
@@ -19,7 +17,7 @@ export default function required(message?: string) {
let expected = 'required';
if (!message) {
- message = `Element ${elementToString(this.target)} is required`;
+ message = `Element ${this.targetDescription} is required`;
}
this.pushResult({ result, actual, expected, message });
diff --git a/packages/qunit-dom/lib/assertions/is-valid.ts b/packages/qunit-dom/lib/assertions/is-valid.ts
index a4740da0c..25b69bce4 100644
--- a/packages/qunit-dom/lib/assertions/is-valid.ts
+++ b/packages/qunit-dom/lib/assertions/is-valid.ts
@@ -1,5 +1,3 @@
-import elementToString from '../helpers/element-to-string.js';
-
export default function isValid(message?: string, options: { inverted?: boolean } = {}) {
let element = this.findTargetElement();
if (!element) return;
@@ -23,7 +21,7 @@ export default function isValid(message?: string, options: { inverted?: boolean
let expected = options.inverted ? 'not valid' : 'valid';
if (!message) {
- message = `Element ${elementToString(this.target)} is ${actual}`;
+ message = `Element ${this.targetDescription} is ${actual}`;
}
this.pushResult({ result, actual, expected, message });
diff --git a/packages/qunit-dom/lib/assertions/is-visible.ts b/packages/qunit-dom/lib/assertions/is-visible.ts
index 74cab96b8..5c681c847 100644
--- a/packages/qunit-dom/lib/assertions/is-visible.ts
+++ b/packages/qunit-dom/lib/assertions/is-visible.ts
@@ -38,6 +38,10 @@ export default function isVisible(options?: string | ExistsOptions, message?: st
}
function format(selector: string, num?: number) {
+ if (selector === '') {
+ selector = '';
+ }
+
if (num === undefined || num === null) {
return `Element ${selector} is visible`;
} else if (num === 0) {
diff --git a/packages/qunit-dom/lib/descriptor.ts b/packages/qunit-dom/lib/descriptor.ts
new file mode 100644
index 000000000..8b898179a
--- /dev/null
+++ b/packages/qunit-dom/lib/descriptor.ts
@@ -0,0 +1,69 @@
+import {
+ type IDOMElementDescriptor,
+ isDescriptor,
+ createDescriptor as create,
+} from 'dom-element-descriptors';
+import elementToString from './helpers/element-to-string';
+
+/**
+ * Descriptor data for creating an {@link IDOMElementDescriptor} from a CSS
+ * selector
+ */
+class SelectorData {
+ constructor(
+ private readonly selector: string,
+ private readonly rootElement: NonNullable
+ ) {}
+
+ get element() {
+ return this.rootElement.querySelector(this.selector);
+ }
+
+ get elements() {
+ return Array.from(this.rootElement.querySelectorAll(this.selector));
+ }
+
+ get description() {
+ return this.selector;
+ }
+}
+
+/**
+ * Descriptor data for creating an {@link IDOMElementDescriptor} from an
+ * {@link Element}
+ */
+class ElementData {
+ constructor(public readonly element: Element) {}
+
+ get description() {
+ return elementToString(this.element);
+ }
+}
+
+/**
+ * Create an {@link IDOMElementDescriptor} from a target and a root element
+ */
+export default function createDescriptor(
+ target: string | Element | null | IDOMElementDescriptor,
+ rootElement: RootElement
+): IDOMElementDescriptor {
+ if (typeof target === 'string') {
+ // selector
+ if (!rootElement) {
+ throw new Error('Cannot do selector-based queries without a root element');
+ }
+ return create(new SelectorData(target, rootElement));
+ } else if (target instanceof Element) {
+ // element
+ return create(new ElementData(target));
+ } else if (target === null) {
+ // null, which we treat as an unmatched element, e.g.
+ // `createDescriptor(document.querySelector('.does-not-exist'))`
+ return create({ element: null, description: '' });
+ } else if (isDescriptor(target)) {
+ // already a descriptor
+ return target;
+ } else {
+ throw new TypeError(`Unexpected Parameter: ${target}`);
+ }
+}
diff --git a/packages/qunit-dom/lib/helpers/test-assertions.ts b/packages/qunit-dom/lib/helpers/test-assertions.ts
index 06214ab35..baa432cf4 100644
--- a/packages/qunit-dom/lib/helpers/test-assertions.ts
+++ b/packages/qunit-dom/lib/helpers/test-assertions.ts
@@ -1,9 +1,10 @@
import DOMAssertions, { type AssertionResult } from '../assertions.js';
+import type { IDOMElementDescriptor } from 'dom-element-descriptors';
export default class TestAssertions {
public results: AssertionResult[] = [];
- dom(target: string | Element | null, rootElement?: RootElement) {
+ dom(target: string | Element | null | IDOMElementDescriptor, rootElement?: RootElement) {
return new DOMAssertions(target, rootElement || document, this as any);
}
diff --git a/packages/qunit-dom/lib/install.ts b/packages/qunit-dom/lib/install.ts
index 5c9034be1..5ee21797a 100644
--- a/packages/qunit-dom/lib/install.ts
+++ b/packages/qunit-dom/lib/install.ts
@@ -1,17 +1,21 @@
import DOMAssertions from './assertions.js';
import { getRootElement } from './root-element.js';
+import type { IDOMElementDescriptor } from 'dom-element-descriptors';
declare global {
type RootElement = Element | Document | ShadowRoot | null;
interface Assert {
- dom(target?: string | Element | null, rootElement?: RootElement): DOMAssertions;
+ dom(
+ target?: string | Element | IDOMElementDescriptor | null,
+ rootElement?: RootElement
+ ): DOMAssertions;
}
}
export default function (assert: Assert) {
assert.dom = function (
- target?: string | Element | null,
+ target?: string | Element | IDOMElementDescriptor | null,
rootElement?: RootElement
): DOMAssertions {
if (!isValidRootElement(rootElement)) {
diff --git a/packages/qunit-dom/package.json b/packages/qunit-dom/package.json
index bd10cc954..30f9a87da 100644
--- a/packages/qunit-dom/package.json
+++ b/packages/qunit-dom/package.json
@@ -64,6 +64,9 @@
"vitest": "1.0.1",
"webpack": "5.89.0"
},
+ "dependencies": {
+ "dom-element-descriptors": "^0.5.1"
+ },
"packageManager": "pnpm@8.8.0",
"volta": {
"extends": "../../package.json"
diff --git a/packages/qunit-dom/rollup.config.mjs b/packages/qunit-dom/rollup.config.mjs
index 29a9285c4..d8986b466 100644
--- a/packages/qunit-dom/rollup.config.mjs
+++ b/packages/qunit-dom/rollup.config.mjs
@@ -20,7 +20,7 @@ const copyStaticArtifacts = copy({
const iifeBundle = {
input: 'lib/qunit-dom.ts',
- external: ['qunit'],
+ external: ['qunit', 'dom-element-descriptors'],
plugins: [typescript({
...typescriptConfiguration,
tsconfigOverride: {
@@ -35,13 +35,16 @@ const iifeBundle = {
file: 'dist/qunit-dom.js',
format: 'iife',
sourcemap: true,
+ globals: {
+ 'dom-element-descriptors': 'DOMElementDescriptors',
+ },
},
};
const esBundle = {
input: 'lib/qunit-dom-modules.ts',
- external: ['qunit'],
+ external: ['qunit', 'dom-element-descriptors'],
plugins: [typescript(typescriptConfiguration)],
output: {
diff --git a/packages/qunit-dom/tsconfig.json b/packages/qunit-dom/tsconfig.json
index d2396043f..4d85b8208 100644
--- a/packages/qunit-dom/tsconfig.json
+++ b/packages/qunit-dom/tsconfig.json
@@ -7,11 +7,12 @@
"verbatimModuleSyntax": true,
// We build to ESM, so we need to tell TS that we build to ESM
// otherwise TS uses fake ESM (you use imports, but it assumes the compilation is to CJS)
- // These are also required when using
- // verbatimModuleSyntax, because it's an
+ // These are also required when using
+ // verbatimModuleSyntax, because it's an
// ESM-only feature
"target": "esnext",
"module": "esnext",
+ "moduleResolution": "bundler",
"lib": [
"ES6",
diff --git a/packages/test-types-resolution-node/package.json b/packages/test-types-resolution-node/package.json
index cc8aad976..e345c86a0 100644
--- a/packages/test-types-resolution-node/package.json
+++ b/packages/test-types-resolution-node/package.json
@@ -9,6 +9,7 @@
},
"devDependencies": {
"@types/qunit": "2.19.7",
+ "dom-element-descriptors": "^0.5.1",
"expect-type": "0.17.3",
"typescript": "5.2.2"
},
diff --git a/packages/test-types-resolution-node/test.ts b/packages/test-types-resolution-node/test.ts
index aac737a06..77cf303cb 100644
--- a/packages/test-types-resolution-node/test.ts
+++ b/packages/test-types-resolution-node/test.ts
@@ -1,10 +1,11 @@
import QUnit from 'qunit';
import { setup } from 'qunit-dom';
import { expectTypeOf } from 'expect-type'
+import type { IDOMElementDescriptor } from 'dom-element-descriptors';
setup(QUnit.assert);
-expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
+expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
// @ts-expect-error - there is only one parameter
expectTypeOf(QUnit.assert.dom).parameter(1).toEqualTypeOf();
diff --git a/packages/test-types-resolution-node16/package.json b/packages/test-types-resolution-node16/package.json
index 96c77df4f..08920402e 100644
--- a/packages/test-types-resolution-node16/package.json
+++ b/packages/test-types-resolution-node16/package.json
@@ -9,6 +9,7 @@
},
"devDependencies": {
"@types/qunit": "2.19.7",
+ "dom-element-descriptors": "^0.5.1",
"expect-type": "0.17.3",
"typescript": "5.2.2"
},
diff --git a/packages/test-types-resolution-node16/test.ts b/packages/test-types-resolution-node16/test.ts
index aac737a06..77cf303cb 100644
--- a/packages/test-types-resolution-node16/test.ts
+++ b/packages/test-types-resolution-node16/test.ts
@@ -1,10 +1,11 @@
import QUnit from 'qunit';
import { setup } from 'qunit-dom';
import { expectTypeOf } from 'expect-type'
+import type { IDOMElementDescriptor } from 'dom-element-descriptors';
setup(QUnit.assert);
-expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
+expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
// @ts-expect-error - there is only one parameter
expectTypeOf(QUnit.assert.dom).parameter(1).toEqualTypeOf();
diff --git a/packages/test-types/package.json b/packages/test-types/package.json
index 0558b871c..9cdd090c7 100644
--- a/packages/test-types/package.json
+++ b/packages/test-types/package.json
@@ -9,6 +9,7 @@
},
"devDependencies": {
"@types/qunit": "2.19.7",
+ "dom-element-descriptors": "^0.5.1",
"expect-type": "0.17.3",
"typescript": "5.2.2"
},
diff --git a/packages/test-types/test.ts b/packages/test-types/test.ts
index aac737a06..77cf303cb 100644
--- a/packages/test-types/test.ts
+++ b/packages/test-types/test.ts
@@ -1,10 +1,11 @@
import QUnit from 'qunit';
import { setup } from 'qunit-dom';
import { expectTypeOf } from 'expect-type'
+import type { IDOMElementDescriptor } from 'dom-element-descriptors';
setup(QUnit.assert);
-expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
+expectTypeOf(QUnit.assert.dom).parameter(0).toEqualTypeOf();
// @ts-expect-error - there is only one parameter
expectTypeOf(QUnit.assert.dom).parameter(1).toEqualTypeOf();
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 39b028478..0249f84fd 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -22,6 +22,10 @@ importers:
version: 2.8.8
packages/qunit-dom:
+ dependencies:
+ dom-element-descriptors:
+ specifier: ^0.5.1
+ version: 0.5.1
devDependencies:
'@arethetypeswrong/cli':
specifier: 0.12.2
@@ -361,6 +365,9 @@ importers:
'@types/qunit':
specifier: 2.19.7
version: 2.19.7
+ dom-element-descriptors:
+ specifier: ^0.5.1
+ version: 0.5.1
expect-type:
specifier: 0.17.3
version: 0.17.3
@@ -380,6 +387,9 @@ importers:
'@types/qunit':
specifier: 2.19.7
version: 2.19.7
+ dom-element-descriptors:
+ specifier: ^0.5.1
+ version: 0.5.1
expect-type:
specifier: 0.17.3
version: 0.17.3
@@ -399,6 +409,9 @@ importers:
'@types/qunit':
specifier: 2.19.7
version: 2.19.7
+ dom-element-descriptors:
+ specifier: ^0.5.1
+ version: 0.5.1
expect-type:
specifier: 0.17.3
version: 0.17.3
@@ -9142,6 +9155,9 @@ packages:
resolution: {integrity: sha512-CVzntLid1oFVHTKdTp/Qu7Kz+wSm8uO30TSQyAJ6n4Dz09yTzVQn3S1oRhVhUubxdMuKs1DjDqt88pubHagbPw==}
dev: true
+ /dom-element-descriptors@0.5.1:
+ resolution: {integrity: sha512-DLayMRQ+yJaziF4JJX1FMjwjdr7wdTr1y9XvZ+NfHELfOMcYDnCHneAYXAS4FT1gLILh4V0juMZohhH1N5FsoQ==}
+
/domexception@2.0.1:
resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==}
engines: {node: '>=8'}