From 0b0351e5cf9d474c17bd808ee36a74efb957ca08 Mon Sep 17 00:00:00 2001 From: Sebas Cruz Date: Fri, 16 Jan 2026 14:14:32 -0500 Subject: [PATCH 1/2] Add: toBeEmpty matcher and function created --- packages/dom/src/lib/ElementAssertion.ts | 34 +++++++++++++++++++++++- packages/dom/src/lib/helpers/helpers.ts | 11 +++++--- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/packages/dom/src/lib/ElementAssertion.ts b/packages/dom/src/lib/ElementAssertion.ts index 3b9bdc6..dae75c1 100644 --- a/packages/dom/src/lib/ElementAssertion.ts +++ b/packages/dom/src/lib/ElementAssertion.ts @@ -1,7 +1,7 @@ import { Assertion, AssertionError } from "@assertive-ts/core"; import equal from "fast-deep-equal"; -import { getExpectedAndReceivedStyles } from "./helpers/helpers"; +import { getExpectedAndReceivedStyles, isElementEmpty } from "./helpers/helpers"; export class ElementAssertion extends Assertion { @@ -260,6 +260,38 @@ export class ElementAssertion extends Assertion { }); } + /** + * Asserts that the element does not contain child nodes, excluding comments. + * + * @example + * ``` + * expect(component).toBeEmpty(); + * ``` + * + * @returns the assertion instance. + */ + + public toBeEmpty(): this { + + const isEmpty = isElementEmpty(this.actual); + + const error = new AssertionError({ + actual: this.actual, + message: "Expected the element to be empty.", + }); + + const invertedError = new AssertionError({ + actual: this.actual, + message: "Expected the element NOT to be empty.", + }); + + return this.execute({ + assertWhen: isEmpty, + error, + invertedError, + }); + } + /** * Helper method to assert the presence or absence of class names. * diff --git a/packages/dom/src/lib/helpers/helpers.ts b/packages/dom/src/lib/helpers/helpers.ts index e8eaab8..9baae69 100644 --- a/packages/dom/src/lib/helpers/helpers.ts +++ b/packages/dom/src/lib/helpers/helpers.ts @@ -49,8 +49,8 @@ function getReceivedStyle (props: string[], received: CSSStyleDeclaration): Styl }, {} as StyleDeclaration); } -export const getExpectedAndReceivedStyles = -(actual: Element, expected: Partial): StyleDeclaration[] => { +export function getExpectedAndReceivedStyles +(actual: Element, expected: Partial): StyleDeclaration[] { if (!actual.ownerDocument.defaultView) { throw new Error("The element is not attached to a document with a default view."); } @@ -72,4 +72,9 @@ export const getExpectedAndReceivedStyles = expectedStyle, elementProcessedStyle, ]; -}; +} + +export function isElementEmpty (element: Element): boolean { + const nonCommentChildNodes = [...element.childNodes].filter(child => child.nodeType !== 8); + return nonCommentChildNodes.length === 0; +} From a551b6ff87fe2452e9210d81c8c0d7cd75b90317 Mon Sep 17 00:00:00 2001 From: Sebas Cruz Date: Fri, 16 Jan 2026 14:15:10 -0500 Subject: [PATCH 2/2] Add: tests for toBeEmpty matcher created --- .../test/unit/lib/ElementAssertion.test.tsx | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/packages/dom/test/unit/lib/ElementAssertion.test.tsx b/packages/dom/test/unit/lib/ElementAssertion.test.tsx index 182ea34..fe6d8f7 100644 --- a/packages/dom/test/unit/lib/ElementAssertion.test.tsx +++ b/packages/dom/test/unit/lib/ElementAssertion.test.tsx @@ -411,4 +411,58 @@ describe("[Unit] ElementAssertion.test.ts", () => { }); }); }); + + describe(".toBeEmpty", () => { + context("when the element does not contain any child node", () => { + it("returns the assertion instance", () => { + const { getByTestId } = render(
); + const divTest = getByTestId("test-div"); + const test = new ElementAssertion(divTest); + + expect(test.toBeEmpty()).toBeEqual(test); + + expect(() => test.not.toBeEmpty()) + .toThrowError(AssertionError) + .toHaveMessage("Expected the element NOT to be empty."); + + }); + }); + + context("when the element contains a comment node", () => { + it("returns the assertion instance", () => { + const { getByTestId } = render(
); + const divTest = getByTestId("test-div"); + const comment = document.createComment("test comment"); + divTest.appendChild(comment); + const test = new ElementAssertion(divTest); + + expect(test.toBeEmpty()).toBeEqual(test); + + expect(() => test.not.toBeEmpty()) + .toThrowError(AssertionError) + .toHaveMessage("Expected the element NOT to be empty."); + + }); + }); + + context("when the element contains a child node", () => { + it("throws an assertion error", () => { + const { getByTestId } = render(
); + const divTest = getByTestId("test-div"); + + const emptyDiv = document.createElement("div"); + divTest.appendChild(emptyDiv); + + const test = new ElementAssertion(divTest); + + expect(() => test.toBeEmpty()) + .toThrowError(AssertionError) + .toHaveMessage("Expected the element to be empty."); + + expect(test.not.toBeEmpty()).toBeEqual(test); + + }); + }); + }); + });