Skip to content

Commit 3483511

Browse files
committed
Add tests for losing focus in a combobox
Unfortunately this wouldn't have detected the bug that I fixed in my previous commits, since those were related to adding an event listener to viewport size changes (which is mocked in tests), but having these shouldn't do any harm.
1 parent 6baad36 commit 3483511

File tree

4 files changed

+46
-1
lines changed

4 files changed

+46
-1
lines changed

src/app/components/client/ComboBox.test.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,20 @@ it("shows suggestions when typing", async () => {
4545
expect(suggestions).toBeInTheDocument();
4646
});
4747

48+
it("does not lose focus while typing", async () => {
49+
const user = userEvent.setup();
50+
const ComposedTextComboBox = composeStory(TextComboBoxRequired, Meta);
51+
render(<ComposedTextComboBox />);
52+
53+
const comboBox = screen.getByRole("combobox");
54+
await user.click(comboBox);
55+
expect(comboBox).toHaveFocus();
56+
await user.keyboard("T");
57+
expect(comboBox).toHaveFocus();
58+
await user.keyboard("u");
59+
expect(comboBox).toHaveFocus();
60+
});
61+
4862
it("hides suggestions when clearing the input field", async () => {
4963
const user = userEvent.setup();
5064
const ComposedTextComboBox = composeStory(TextComboBoxRequired, Meta);

src/app/components/client/LocationAutocompleteInput.test.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,22 @@ it("suggests locations after typing", async () => {
3434
expect(suggestions[1]).toHaveTextContent("Tucson AZ, USA");
3535
expect(inputField).toHaveValue("Tu");
3636
});
37+
38+
it("does not lose focus while typing", async () => {
39+
const user = userEvent.setup();
40+
const LocationAutocompleteInput = composeStory(
41+
LocationAutocompleteInputStory,
42+
Meta,
43+
);
44+
render(<LocationAutocompleteInput />);
45+
46+
expect(screen.queryByRole("listbox")).toBeNull();
47+
48+
const inputField = screen.getByLabelText("Location (demo)");
49+
await user.click(inputField);
50+
expect(inputField).toHaveFocus();
51+
await user.keyboard("T");
52+
expect(inputField).toHaveFocus();
53+
await user.keyboard("u");
54+
expect(inputField).toHaveFocus();
55+
});

src/app/components/client/Popover.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function Popover({ children, offset, state, ...props }: PopoverProps) {
3333
<Overlay>
3434
{/* FocusScope is a utility component that traps keyboard focus within its child elements.
3535
When used in a dialog, it ensures that focus never leaves the dialog until it’s closed. */}
36-
{/* We've disabled autoFocus so the popover doesn’t steal or re-trap focus
36+
{/* We've disabled autoFocus so the popover doesn’t steal or re-trap focus
3737
For more details see MNTOR-4523 */}
3838
<FocusScope contain restoreFocus autoFocus={false}>
3939
<div {...underlayProps} className={styles.underlay} />

src/app/components/client/stories/ComboBox.stories.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
import type { Meta, StoryObj } from "@storybook/nextjs";
6+
import { useArgs } from "storybook/preview-api";
67

78
import { ComboBox } from "../ComboBox";
89
import { Item } from "react-stately";
@@ -22,6 +23,17 @@ const items: Array<ItemObject> = [
2223
const meta: Meta<typeof ComboBox> = {
2324
title: "Design Systems/Atoms/ComboBox",
2425
component: ComboBox,
26+
render: (args) => {
27+
const [{ inputValue }, updateArgs] = useArgs();
28+
29+
return (
30+
<ComboBox
31+
{...args}
32+
inputValue={inputValue}
33+
onInputChange={(newValue) => updateArgs({ inputValue: newValue })}
34+
/>
35+
);
36+
},
2537
};
2638
export default meta;
2739
type Story = StoryObj<typeof ComboBox>;

0 commit comments

Comments
 (0)