Skip to content

Commit 975c8b2

Browse files
authored
feat(dom): DOM - toHaveAttibute (#131)
1 parent 7701ff6 commit 975c8b2

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

packages/dom/src/lib/ElementAssertion.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,42 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
3030
invertedError,
3131
});
3232
}
33+
34+
/**
35+
* Check if the element has a specific attribute.
36+
*
37+
* @param name - The attribute name.
38+
* @param expectedValue - The expected attribute value (Optional).
39+
* @returns the assertion instance.
40+
*/
41+
public toHaveAttribute(name: string, expectedValue?: string): this {
42+
const hasAttribute = this.actual.hasAttribute(name);
43+
const receivedValue = this.actual.getAttribute(name);
44+
const isExpectedValuePresent = expectedValue !== undefined;
45+
46+
const error = new AssertionError({
47+
actual: receivedValue,
48+
expected: expectedValue,
49+
message: isExpectedValuePresent
50+
? `Expected to have attribute "${name}" with value "${expectedValue}", but received "${receivedValue}"`
51+
: `Expected to have attribute "${name}"`,
52+
});
53+
54+
const invertedError = new AssertionError({
55+
actual: receivedValue,
56+
expected: expectedValue,
57+
message: isExpectedValuePresent
58+
? `Expected to NOT have attribute "${name}" with value "${expectedValue}", but received "${receivedValue}"`
59+
: `Expected to NOT have attribute "${name}"`,
60+
});
61+
62+
return this.execute({
63+
assertWhen: (isExpectedValuePresent
64+
? hasAttribute && receivedValue === expectedValue
65+
: hasAttribute),
66+
error,
67+
invertedError,
68+
});
69+
}
70+
3371
}

packages/dom/test/unit/lib/ElementAssertion.test.tsx

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ function TestComponent(): ReactElement {
1212
);
1313
}
1414

15+
function TestComponentElement(): ReactElement {
16+
return (
17+
<button role="button" type="submit" className="btn primary" disabled>
18+
click me
19+
</button>
20+
);
21+
}
22+
1523
describe("[Unit] ElementAssertion.test.ts", () => {
1624
describe(".toBeInTheDocument", () => {
1725
context("when the element is in the document", () => {
@@ -42,4 +50,63 @@ describe("[Unit] ElementAssertion.test.ts", () => {
4250
});
4351
});
4452
});
53+
54+
describe(".toHaveAttribute", () => {
55+
context("when the element has the attribute with the expected value", () => {
56+
it("returns the assertion instance", async () => {
57+
const { findByRole } = render(<TestComponentElement />);
58+
const button = await findByRole("button", { name: "click me" });
59+
const test = new ElementAssertion(button);
60+
61+
expect(test.toHaveAttribute("type", "submit")).toBeEqual(test);
62+
63+
expect(() => test.not.toHaveAttribute("type", "submit"))
64+
.toThrowError(AssertionError)
65+
.toHaveMessage("Expected to NOT have attribute \"type\" with value \"submit\", but received \"submit\"");
66+
});
67+
});
68+
69+
context("when the element has the attribute with a not expected value", () => {
70+
it("throws an assertion error", async () => {
71+
const { findByRole } = render(<TestComponentElement />);
72+
const button = await findByRole("button", { name: "click me" });
73+
const test = new ElementAssertion(button);
74+
75+
expect(() => test.toHaveAttribute("type", "different value"))
76+
.toThrowError(AssertionError)
77+
.toHaveMessage("Expected to have attribute \"type\" with value \"different value\", but received \"submit\"",
78+
);
79+
80+
expect(test.not.toHaveAttribute("type", "different value")).toBeEqual(test);
81+
});
82+
});
83+
84+
context("when the element has the attribute without checking value", () => {
85+
it("returns the assertion instance", async () => {
86+
const { findByRole } = render(<TestComponentElement />);
87+
const button = await findByRole("button", { name: "click me" });
88+
const test = new ElementAssertion(button);
89+
90+
expect(test.toHaveAttribute("disabled")).toBeEqual(test);
91+
92+
expect(() => test.not.toHaveAttribute("disabled"))
93+
.toThrowError(AssertionError)
94+
.toHaveMessage("Expected to NOT have attribute \"disabled\"");
95+
});
96+
});
97+
98+
context("when the element does not have the attribute", () => {
99+
it("throws an assertion error", async () => {
100+
const { findByRole } = render(<TestComponentElement />);
101+
const button = await findByRole("button", { name: "click me" });
102+
const test = new ElementAssertion(button);
103+
104+
expect(() => test.toHaveAttribute("non-existent"))
105+
.toThrowError(AssertionError)
106+
.toHaveMessage("Expected to have attribute \"non-existent\"");
107+
108+
expect(test.not.toHaveAttribute("non-existent")).toBeEqual(test);
109+
});
110+
});
111+
});
45112
});

0 commit comments

Comments
 (0)