Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions packages/dom/src/lib/ElementAssertion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,46 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
});
}

/**
* Asserts that the element contains the specified HTML.
*
* @example
* ```
* expect(container).toContainHTML('<span>Hello</span>');
* expect(container).toContainHTML('<div class="foo">Bar</div>');
* ```
*
* @param htmlText The HTML text that should be contained in the element
* @returns the assertion instance.
*/
public toContainHTML(htmlText: string): this {
if (typeof htmlText !== "string") {
throw new Error(`.toContainHTML() expects a string value, got ${typeof htmlText}`);
}

if (htmlText === "") {
throw new Error(".toContainHTML() expects a non-empty string");
}

const error = new AssertionError({
actual: this.actual,
expected: htmlText,
message: `Expected the element to contain HTML: ${htmlText}`,
});

const invertedError = new AssertionError({
actual: this.actual,
expected: htmlText,
message: `Expected the element NOT to contain HTML: ${htmlText}`,
});

return this.execute({
assertWhen: this.actual.outerHTML.includes(htmlText),
error,
invertedError,
});
}

/**
* Helper method to assert the presence or absence of class names.
*
Expand Down
69 changes: 69 additions & 0 deletions packages/dom/test/unit/lib/ElementAssertion.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NestedElementsTest } from "./fixtures/NestedElementsTest";
import { PressedTestComponent } from "./fixtures/PressedTestComponent";
import { SimpleTest } from "./fixtures/SimpleTest";
import { WithAttributesTest } from "./fixtures/WithAttributesTest";
import { ContainHtmlTestComponent } from "./fixtures/containHtmlTestComponent";
import { DescriptionTestComponent } from "./fixtures/descriptionTestComponent";
import { FocusTestComponent } from "./fixtures/focusTestComponent";

Expand Down Expand Up @@ -823,4 +824,72 @@ describe("[Unit] ElementAssertion.test.ts", () => {
});
});
});

describe(".toContainHTML", () => {
context("when the element contains the expected HTML", () => {
it("returns the assertion instance", () => {
const { getByTestId } = render(<ContainHtmlTestComponent />);
const container = getByTestId("container");
const test = new ElementAssertion(container);

expect(test.toContainHTML('<span data-testid="child-span">Hello World</span>')).toBeEqual(test);

expect(() => test.not.toContainHTML('<span data-testid="child-span">Hello World</span>'))
.toThrowError(AssertionError)
.toHaveMessage('Expected the element NOT to contain HTML: <span data-testid="child-span">Hello World</span>');
});
});

context("when the element contains nested HTML", () => {
it("returns the assertion instance", () => {
const { getByTestId } = render(<ContainHtmlTestComponent />);
const container = getByTestId("container");
const test = new ElementAssertion(container);

expect(test.toContainHTML("<p>Nested content</p>")).toBeEqual(test);

expect(() => test.not.toContainHTML("<p>Nested content</p>"))
.toThrowError(AssertionError)
.toHaveMessage("Expected the element NOT to contain HTML: <p>Nested content</p>");
});
});

context("when the element does not contain the expected HTML", () => {
it("throws an assertion error", () => {
const { getByTestId } = render(<ContainHtmlTestComponent />);
const container = getByTestId("container");
const test = new ElementAssertion(container);

expect(() => test.toContainHTML("<div>Not present</div>"))
.toThrowError(AssertionError)
.toHaveMessage("Expected the element to contain HTML: <div>Not present</div>");

expect(test.not.toContainHTML("<div>Not present</div>")).toBeEqual(test);
});
});

context("when a non-string value is passed", () => {
it("throws an error", () => {
const { getByTestId } = render(<ContainHtmlTestComponent />);
const container = getByTestId("container");
const test = new ElementAssertion(container);

expect(() => test.toContainHTML(123 as unknown as string))
.toThrowError(Error)
.toHaveMessage(".toContainHTML() expects a string value, got number");
});
});

context("when an empty string is passed", () => {
it("throws an error", () => {
const { getByTestId } = render(<ContainHtmlTestComponent />);
const container = getByTestId("container");
const test = new ElementAssertion(container);

expect(() => test.toContainHTML(""))
.toThrowError(Error)
.toHaveMessage(".toContainHTML() expects a non-empty string");
});
});
});
});
12 changes: 12 additions & 0 deletions packages/dom/test/unit/lib/fixtures/containHtmlTestComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ReactElement } from "react";

export function ContainHtmlTestComponent(): ReactElement {
return (
<div data-testid="container">
<span data-testid="child-span">{"Hello World"}</span>
<div className="nested">
<p>{"Nested content"}</p>
</div>
</div>
);
}
Loading