Skip to content

Commit cb481ee

Browse files
committed
Create to haveFocus assertion and tests
1 parent 62d5350 commit cb481ee

File tree

3 files changed

+71
-0
lines changed

3 files changed

+71
-0
lines changed

packages/dom/src/lib/ElementAssertion.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,34 @@ export class ElementAssertion<T extends Element> extends Assertion<T> {
142142
);
143143
}
144144

145+
/**
146+
* Check if the provided element is currently focused in the document.
147+
*
148+
* @returns The assertion instance.
149+
*/
150+
public toHaveFocus(): this {
151+
152+
const hasFocus = this.actual === document.activeElement;
153+
154+
const error = new AssertionError({
155+
actual: this.actual,
156+
expected: document.activeElement,
157+
message: "Expected the element to have focus.",
158+
});
159+
160+
const invertedError = new AssertionError({
161+
actual: this.actual,
162+
expected: document.activeElement,
163+
message: "Expected the element not to have focus.",
164+
});
165+
166+
return this.execute({
167+
assertWhen: hasFocus,
168+
error,
169+
invertedError,
170+
});
171+
}
172+
145173
private getClassList(): string[] {
146174
return this.actual.className.split(/\s+/).filter(Boolean);
147175
}

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

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { render } from "@testing-library/react";
33

44
import { ElementAssertion } from "../../../src/lib/ElementAssertion";
55

6+
import { FocusTestComponent } from "./fixtures/focusTestComponent";
67
import { HaveClassTestComponent } from "./fixtures/haveClassTestComponent";
78
import { NestedElementsTestComponent } from "./fixtures/nestedElementsTestComponent";
89
import { SimpleTestComponent } from "./fixtures/simpleTestComponent";
@@ -265,4 +266,36 @@ describe("[Unit] ElementAssertion.test.ts", () => {
265266
});
266267
});
267268

269+
describe(".toHaveFocus", () => {
270+
context("when the element has focus", () => {
271+
it("returns the assertion instance", () => {
272+
const { getByTestId } = render(<FocusTestComponent />);
273+
const input1 = getByTestId("input1");
274+
input1.focus();
275+
const test = new ElementAssertion(input1);
276+
277+
expect(test.toHaveFocus()).toBeEqual(test);
278+
279+
expect(() => test.not.toHaveFocus())
280+
.toThrowError(AssertionError)
281+
.toHaveMessage("Expected the element not to have focus.");
282+
});
283+
});
284+
285+
context("when the element does not have focus", () => {
286+
it("throws an assertion error", () => {
287+
const { getByTestId } = render(<FocusTestComponent />);
288+
const input1 = getByTestId("input1");
289+
const input2 = getByTestId("input2");
290+
input1.focus();
291+
const test = new ElementAssertion(input2);
292+
293+
expect(() => test.toHaveFocus())
294+
.toThrowError(AssertionError)
295+
.toHaveMessage("Expected the element to have focus.");
296+
297+
expect(test.not.toHaveFocus()).toBeEqual(test);
298+
});
299+
});
300+
});
268301
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { ReactElement } from "react";
2+
3+
export function FocusTestComponent(): ReactElement {
4+
return (
5+
<div>
6+
<input data-testid="input1" />
7+
<input data-testid="input2" />
8+
</div>
9+
);
10+
}

0 commit comments

Comments
 (0)