diff --git a/API.md b/API.md index 4b96b5f9f..093cccca2 100644 --- a/API.md +++ b/API.md @@ -123,7 +123,7 @@ Once installed the DOM element assertions are available at `assert.dom(...).*`: **Parameters** * `target` **([string][114] | [HTMLElement][115])** A CSS selector that can be used to find elements using [`querySelector()`][116], or an \[HTMLElement]\[] (Not all assertions support both target types.) (optional, default `rootElement` or `document`) -* `rootElement` **[HTMLElement][115]?** The root element of the DOM in which to search for the `target` (optional, default `document`) +* `rootElement` **([HTMLElement][115] | [Document][152] | [ShadowRoot][153] | [null][154])?** The root element of the DOM in which to search for the `target` (optional, defaults `document` when `null` or not provided) **Examples** @@ -1194,3 +1194,9 @@ assert.dom('section#block').doesNotHaveTagName('div'); [150]: #hasValue [151]: https://developer.mozilla.org/en-US/docs/Web/API/Element/tagName + +[152]: https://developer.mozilla.org/en-US/docs/Web/API/Document + +[153]: https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot + +[154]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/null \ No newline at end of file diff --git a/packages/qunit-dom/lib/__tests__/root-element.ts b/packages/qunit-dom/lib/__tests__/root-element.ts new file mode 100644 index 000000000..358abc033 --- /dev/null +++ b/packages/qunit-dom/lib/__tests__/root-element.ts @@ -0,0 +1,152 @@ +import { describe, beforeEach, test, expect } from 'vitest'; + +import TestAssertions from '../helpers/test-assertions'; + +describe('assert.dom(..., rootElement)', () => { + let assert: TestAssertions; + + beforeEach(() => { + assert = new TestAssertions(); + }); + + test('passing an Element as rootElement', () => { + document.body.innerHTML = ` + dedcoy + +

+ real target +

+ `; + + const rootElement = document.querySelector('.parent'); + + assert.dom('.target', rootElement).exists({ count: 1 }); + assert.dom('.target', rootElement).hasText('real target'); + + expect(assert.results).toEqual([ + { + result: true, + actual: 'Element .target exists once', + expected: 'Element .target exists once', + message: 'Element .target exists once', + }, + { + result: true, + actual: 'real target', + expected: 'real target', + message: 'Element .target has text "real target"', + }, + ]); + }); + + test('not passing anything as rootElement', () => { + document.body.innerHTML = ` + decoy + +

+ real target +

+ `; + + assert.dom('.target').exists({ count: 2 }); + + expect(assert.results).toEqual([ + { + result: true, + actual: 'Element .target exists twice', + expected: 'Element .target exists twice', + message: 'Element .target exists twice', + }, + ]); + }); + + test('passing document as rootElement', () => { + document.body.innerHTML = ` + decoy + +

+ real target +

+ `; + + assert.dom('.target', document).exists({ count: 2 }); + + expect(assert.results).toEqual([ + { + result: true, + actual: 'Element .target exists twice', + expected: 'Element .target exists twice', + message: 'Element .target exists twice', + }, + ]); + }); + + test('passing null as rootElement', () => { + document.body.innerHTML = ` + decoy + +

+ real target +

+ `; + + assert.dom('.target', null).exists({ count: 2 }); + + expect(assert.results).toEqual([ + { + result: true, + actual: 'Element .target exists twice', + expected: 'Element .target exists twice', + message: 'Element .target exists twice', + }, + ]); + }); + + test('passing shadow root as rootElement', () => { + document.body.innerHTML = ` +
+ decoy +
+ `; + + const container = document.getElementById('container'); + const shadowRoot = container.attachShadow({ mode: 'closed' }); + + shadowRoot.innerHTML = 'real target'; + + assert.dom('.target').exists({ count: 1 }, 'Only decoy element is found outside shadow root'); + assert.dom('.target').hasText('real target', 'decoy element text'); + + assert.dom('.target', shadowRoot).exists({ count: 1 }, 'Only target found in shadow root'); + assert.dom('.target', shadowRoot).hasText('real target', 'Target element text'); + + console.log(assert.results); + + expect(assert.results).toEqual([ + { + result: true, + actual: 'Element .target exists once', + expected: 'Element .target exists once', + message: 'Only decoy element is found outside shadow root', + }, + { + result: false, + actual: 'decoy', + expected: 'real target', + message: 'decoy element text', + }, + { + result: true, + actual: 'Element .target exists once', + expected: 'Element .target exists once', + message: 'Only target found in shadow root', + }, + { + result: true, + actual: 'real target', + expected: 'real target', + message: 'Target element text', + }, + ]); + }); +}); diff --git a/packages/qunit-dom/lib/assertions.ts b/packages/qunit-dom/lib/assertions.ts index 8549cb018..9de2cfc24 100644 --- a/packages/qunit-dom/lib/assertions.ts +++ b/packages/qunit-dom/lib/assertions.ts @@ -31,7 +31,7 @@ type ActualCSSStyleDeclaration = Partial