Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
af2817e
add proper keyboard navigation to combobox
LFDanLu Apr 27, 2026
4e1c651
mutiple select for combobox, api rename for consitency, table keyboar…
LFDanLu Apr 27, 2026
d828424
add tests for deselect
LFDanLu Apr 27, 2026
9cc80d8
get rid of timer warnings cuz user gives a default if not provided
LFDanLu Apr 27, 2026
2556c18
change getters into method calls for consistency
LFDanLu Apr 27, 2026
0f0bd7d
update instances of old getters to new function calls
LFDanLu Apr 27, 2026
c694bb4
update instances of old getters to new function calls
LFDanLu Apr 27, 2026
c9125d3
switch to dom testing library
LFDanLu Apr 27, 2026
1beb706
support missing RTL for expand and keyboard nav
LFDanLu Apr 28, 2026
59994d3
standardize indexOrText option naming
LFDanLu Apr 28, 2026
c86baaf
throw when attempting to interact with disabled rows and make error m…
LFDanLu Apr 28, 2026
53187c3
update readmes and docs to reflect change to testing-library/dom
LFDanLu Apr 28, 2026
8a871db
more audit items
LFDanLu Apr 28, 2026
a20ca65
add tests to cover error messages
LFDanLu Apr 28, 2026
348c5f7
cleanup todos that we are punting on/not doing
LFDanLu Apr 29, 2026
3c4d45e
add grid navigation to listbox test util and fix browser tests
LFDanLu Apr 29, 2026
b1ca6f4
add grid nav to gridlist too
LFDanLu Apr 29, 2026
226f5d9
add browser tests for each pattern to make sure utils work with it
LFDanLu Apr 30, 2026
3e45ed4
adding midding dialog testing pages to RAC
LFDanLu Apr 30, 2026
1687d0d
add rough skills for the test utils
LFDanLu Apr 30, 2026
3e6d64a
forgot to save
LFDanLu Apr 30, 2026
1dc99d1
improvements to skill guidence and utils from attempt to use skill to…
LFDanLu Apr 30, 2026
3fac945
more improvements from second pass
LFDanLu May 1, 2026
bc32b85
add getter for table footer
LFDanLu May 1, 2026
cf0038a
Merge branch 'main' of github.com:adobe/react-spectrum into test-util…
LFDanLu May 1, 2026
b513616
Merge branch 'main' of github.com:adobe/react-spectrum into test-util…
LFDanLu May 8, 2026
ed0919b
formatting
LFDanLu May 8, 2026
ed6c99c
update getter naming
LFDanLu May 8, 2026
10870bf
update table util for rowgroups and table footer, update formatTarget…
LFDanLu May 8, 2026
c109290
formatting
LFDanLu May 9, 2026
6d01a4c
fix test from bad merge
LFDanLu May 9, 2026
41fb378
add missing aria labels to browser tests
LFDanLu May 9, 2026
38ec8e2
how did this not auto format
LFDanLu May 9, 2026
76f1397
get rid of extraneous typing
LFDanLu May 11, 2026
79e5d22
Merge branch 'main' of github.com:adobe/react-spectrum into test-util…
LFDanLu May 12, 2026
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
2 changes: 1 addition & 1 deletion packages/@adobe/react-spectrum/docs/combobox/ComboBox.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,7 @@ it('ComboBox can select an option via keyboard', async function () {
expect(comboboxTester.listbox).toBeInTheDocument();

let options = comboboxTester.options();
await comboboxTester.selectOption({option: options[0]});
await comboboxTester.toggleOptionSelection({option: options[0]});
expect(comboboxTester.combobox.value).toBe('One');
expect(comboboxTester.listbox).not.toBeInTheDocument();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/@adobe/react-spectrum/docs/menu/MenuTrigger.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ it('Menu can open its submenu via keyboard', async function () {
let submenuTester = await menuTester.openSubmenu({submenuTrigger: 'Share…'});
expect(submenuTester.menu).toBeInTheDocument();

await submenuTester.selectOption({option: submenuTester.options()[0]});
await submenuTester.toggleOptionSelection({option: submenuTester.options()[0]});
expect(submenuTester.menu).not.toBeInTheDocument();
expect(menuTester.menu).not.toBeInTheDocument();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/@adobe/react-spectrum/docs/picker/Picker.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -603,7 +603,7 @@ it('Picker can select an option via keyboard', async function () {
let trigger = selectTester.trigger;
expect(trigger).toHaveTextContent('Select…');

await selectTester.selectOption({option: 'Cat'});
await selectTester.toggleOptionSelection({option: 'Cat'});
expect(trigger).toHaveTextContent('Cat');
});
```
Expand Down
4 changes: 2 additions & 2 deletions packages/@adobe/react-spectrum/test/combobox/ComboBox.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,7 @@ describe('ComboBox', function () {
expect(comboboxTester.combobox).not.toHaveAttribute('aria-activedescendant');

let options = comboboxTester.options();
await comboboxTester.selectOption({option: options[0]});
await comboboxTester.toggleOptionSelection({option: options[0]});

expect(comboboxTester.combobox.value).toBe('One');

Expand Down Expand Up @@ -876,7 +876,7 @@ describe('ComboBox', function () {
expect(combobox.value).toBe('Tw');
expect(comboboxTester.options().length).toBe(1);

await comboboxTester.selectOption({option: 'Two'});
await comboboxTester.toggleOptionSelection({option: 'Two'});
expect(comboboxTester.listbox).toBeFalsy();
expect(combobox.value).toBe('Two');
// selectionManager.select from useSingleSelectListState always calls onSelectionChange even if the key is the same
Expand Down
8 changes: 4 additions & 4 deletions packages/@adobe/react-spectrum/test/menu/MenuTrigger.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ describe('MenuTrigger', function () {
expect(onSelect).toBeCalledTimes(0);
}

await menuTester.selectOption({option: 'Foo', menuSelectionMode: 'single', closesOnSelect: false});
await menuTester.toggleOptionSelection({option: 'Foo', menuSelectionMode: 'single', closesOnSelect: false});

if (Component === MenuTrigger) {
expect(onSelectionChange).toBeCalledTimes(1);
Expand Down Expand Up @@ -269,7 +269,7 @@ describe('MenuTrigger', function () {
expect(onOpenChange).toBeCalledTimes(1);
expect(onSelectionChange).toBeCalledTimes(0);
menuTester.setInteractionType('keyboard');
await menuTester.selectOption({option: 'Foo', menuSelectionMode: 'single', closesOnSelect: false});
await menuTester.toggleOptionSelection({option: 'Foo', menuSelectionMode: 'single', closesOnSelect: false});

expect(menuTester.menu).toBeInTheDocument();
expect(menuTester.trigger).toHaveAttribute('aria-expanded', 'true');
Expand All @@ -288,10 +288,10 @@ describe('MenuTrigger', function () {
expect(onOpenChange).toBeCalledTimes(1);
expect(onSelectionChange).toBeCalledTimes(0);

await menuTester.selectOption({option: 'Foo', menuSelectionMode: 'multiple', keyboardActivation: 'Space'});
await menuTester.toggleOptionSelection({option: 'Foo', menuSelectionMode: 'multiple', keyboardActivation: 'Space'});
expect(onSelectionChange).toBeCalledTimes(1);
expect(onSelectionChange.mock.calls[0][0].has('Foo')).toBeTruthy();
await menuTester.selectOption({option: 'Bar', menuSelectionMode: 'multiple', keyboardActivation: 'Space'});
await menuTester.toggleOptionSelection({option: 'Bar', menuSelectionMode: 'multiple', keyboardActivation: 'Space'});
expect(onSelectionChange).toBeCalledTimes(2);
expect(onSelectionChange.mock.calls[1][0].has('Bar')).toBeTruthy();

Expand Down
26 changes: 13 additions & 13 deletions packages/@adobe/react-spectrum/test/picker/Picker.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ describe('Picker', function () {

expect(document.activeElement).toBe(listbox);

await selectTester.selectOption({option: 'Three'});
await selectTester.toggleOptionSelection({option: 'Three'});
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('three');

Expand Down Expand Up @@ -982,19 +982,19 @@ describe('Picker', function () {

expect(document.activeElement).toBe(listbox);

await selectTester.selectOption({option: 'Empty'});
await selectTester.toggleOptionSelection({option: 'Empty'});
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('');
expect(document.activeElement).toBe(picker);
expect(picker).toHaveTextContent('Empty');

await selectTester.selectOption({option: 'Zero'});
await selectTester.toggleOptionSelection({option: 'Zero'});
expect(onSelectionChange).toHaveBeenCalledTimes(2);
expect(onSelectionChange).toHaveBeenLastCalledWith('0');
expect(document.activeElement).toBe(picker);
expect(picker).toHaveTextContent('Zero');

await selectTester.selectOption({option: 'False'});
await selectTester.toggleOptionSelection({option: 'False'});
expect(onSelectionChange).toHaveBeenCalledTimes(3);
expect(onSelectionChange).toHaveBeenLastCalledWith('false');
expect(document.activeElement).toBe(picker);
Expand Down Expand Up @@ -1071,7 +1071,7 @@ describe('Picker', function () {
expect(items[1]).toHaveTextContent('Two');
expect(items[2]).toHaveTextContent('Three');

await selectTester.selectOption({option: 'Two'});
await selectTester.toggleOptionSelection({option: 'Two'});

expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('two');
Expand Down Expand Up @@ -1152,7 +1152,7 @@ describe('Picker', function () {
expect(items[1]).toHaveTextContent('Two');
expect(items[2]).toHaveTextContent('Three');

await selectTester.selectOption({option: 'Three'});
await selectTester.toggleOptionSelection({option: 'Three'});
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onOpenChangeSpy).toHaveBeenCalledTimes(2);

Expand Down Expand Up @@ -1509,7 +1509,7 @@ describe('Picker', function () {
let items = selectTester.options();
expect(document.activeElement).toBe(items[1]);

await selectTester.selectOption({option: 'Two'});
await selectTester.toggleOptionSelection({option: 'Two'});
expect(onSelectionChange).not.toHaveBeenCalled();

expect(document.activeElement).toBe(picker);
Expand Down Expand Up @@ -2092,7 +2092,7 @@ describe('Picker', function () {
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Constraints not satisfied');
expect(document.activeElement).toBe(picker);

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');
});

Expand Down Expand Up @@ -2120,7 +2120,7 @@ describe('Picker', function () {
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Invalid value');
expect(document.activeElement).toBe(picker);

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');
});

Expand Down Expand Up @@ -2160,7 +2160,7 @@ describe('Picker', function () {
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Invalid value.');
expect(input.validity.valid).toBe(false);

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');
expect(input.validity.valid).toBe(true);
});
Expand Down Expand Up @@ -2211,7 +2211,7 @@ describe('Picker', function () {
expect(picker).toHaveAttribute('aria-describedby');
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Constraints not satisfied');

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');

await user.click(getByTestId('reset'));
Expand Down Expand Up @@ -2239,7 +2239,7 @@ describe('Picker', function () {
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Invalid value');
expect(input.validity.valid).toBe(true);

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');
});

Expand All @@ -2260,7 +2260,7 @@ describe('Picker', function () {
expect(picker).toHaveAttribute('aria-describedby');
expect(document.getElementById(picker.getAttribute('aria-describedby'))).toHaveTextContent('Invalid value');

await selectTester.selectOption({option: 'One'});
await selectTester.toggleOptionSelection({option: 'One'});
expect(picker).not.toHaveAttribute('aria-describedby');
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ describe('Picker/Select ', function () {
);

let selectTester = testUtilUser.createTester('Select', {root: screen.getByTestId('test')});
await selectTester.selectOption({option: 'Three'});
await selectTester.toggleOptionSelection({option: 'Three'});
expect(selectTester.trigger).toHaveTextContent('Three');
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('three');
Expand All @@ -139,7 +139,7 @@ describe('Picker/Select ', function () {
);

let selectTester = testUtilUser.createTester('Select', {root: screen.getByTestId('test')});
await selectTester.selectOption({option: 'Cat'});
await selectTester.toggleOptionSelection({option: 'Cat'});
expect(selectTester.trigger).toHaveTextContent('Cat');
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('cat');
Expand Down Expand Up @@ -218,7 +218,7 @@ describe('Picker/Select ', function () {
);

let selectTester = testUtilUser.createTester('Select', {root: screen.getByTestId('test')});
await selectTester.selectOption({option: 'Three'});
await selectTester.toggleOptionSelection({option: 'Three'});
expect(selectTester.trigger).toHaveTextContent('Three');
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('three');
Expand All @@ -244,7 +244,7 @@ describe('Picker/Select ', function () {
);

let selectTester = testUtilUser.createTester('Select', {root: screen.getAllByTestId('test')[0]});
await selectTester.selectOption({option: 'Cat'});
await selectTester.toggleOptionSelection({option: 'Cat'});
expect(selectTester.trigger).toHaveTextContent('Cat');
expect(onSelectionChange).toHaveBeenCalledTimes(1);
expect(onSelectionChange).toHaveBeenLastCalledWith('cat');
Expand Down
18 changes: 9 additions & 9 deletions packages/@react-aria/test-utils/src/checkboxgroup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ export class CheckboxGroupTester {

let checkbox;
if (typeof checkboxIndexOrText === 'number') {
checkbox = this.checkboxes[checkboxIndexOrText];
checkbox = this.checkboxes()[checkboxIndexOrText];
} else if (typeof checkboxIndexOrText === 'string') {
let label = within(this.checkboxgroup).getByText(checkboxIndexOrText);
let label = within(this.checkboxgroup()).getByText(checkboxIndexOrText);

// Label may wrap the checkbox, or the actual label may be a sibling span, or the checkbox div could have the label within it
if (label) {
Expand All @@ -83,7 +83,7 @@ export class CheckboxGroupTester {

private async keyboardNavigateToCheckbox(opts: {checkbox: HTMLElement}) {
let {checkbox} = opts;
let checkboxes = this.checkboxes;
let checkboxes = this.checkboxes();
checkboxes = checkboxes.filter(checkbox => !(checkbox.hasAttribute('disabled') || checkbox.getAttribute('aria-disabled') === 'true'));
if (checkboxes.length === 0) {
throw new Error('Checkbox group doesnt have any non-disabled checkboxes. Please double check your checkbox group.');
Expand All @@ -94,7 +94,7 @@ export class CheckboxGroupTester {
throw new Error('Checkbox provided is not in the checkbox group.');
}

if (!this.checkboxgroup.contains(document.activeElement)) {
if (!this.checkboxgroup().contains(document.activeElement)) {
Comment thread
snowystinger marked this conversation as resolved.
Outdated
act(() => checkboxes[0].focus());
}

Expand Down Expand Up @@ -138,21 +138,21 @@ export class CheckboxGroupTester {
/**
* Returns the checkboxgroup.
*/
get checkboxgroup(): HTMLElement {
checkboxgroup(): HTMLElement {
return this._checkboxgroup;
}

/**
* Returns the checkboxes.
*/
get checkboxes(): HTMLElement[] {
return within(this.checkboxgroup).queryAllByRole('checkbox');
checkboxes(): HTMLElement[] {
return within(this.checkboxgroup()).queryAllByRole('checkbox');
}

/**
* Returns the currently selected checkboxes in the checkboxgroup if any.
*/
get selectedCheckboxes(): HTMLElement[] {
return this.checkboxes.filter(checkbox => (checkbox as HTMLInputElement).checked || checkbox.getAttribute('aria-checked') === 'true');
selectedCheckboxes(): HTMLElement[] {
return this.checkboxes().filter(checkbox => (checkbox as HTMLInputElement).checked || checkbox.getAttribute('aria-checked') === 'true');
}
}
Loading