Files
graylog2-server/graylog2-web-interface/test/helpers/selectEvent.ts
Dennis Oelkers 9dd1a00330 Upgrade @testing-library/user-event from v13 to v14 (#25248)
* Upgrade @testing-library/user-event from v13 to v14

Migrate all test files to the v14 API:
- Add `await` to all userEvent calls (v14 returns promises)
- Replace `paste(element, text)` with `paste(text)` or fireEvent
- Replace `{selectall}` in type() with clear() + type()
- Remove `{ ctrlKey: true }` from click(), use keyboard modifiers
- Remove redundant act() wrappers (v14 handles act internally)
- Add `userEvent.setup({ advanceTimers })` for fake timer tests
- Use fireEvent.change() for number/spinbutton controlled inputs
- Fix selectEvent.ts fake timer detection for Jest 30

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Remove unused fireEvent import in InputSetupWizard.StartInput.test

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* Fix lint errors from user-event v14 upgrade

- Fix import group ordering in AggregationWizard test files
- Move setupUser definition before first usage in SavedSearchForm.test
- Add eslint-disable for intentional fireEvent usage on controlled inputs
- Fix eslint issues in selectEvent helper and rename createUser to setup

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Linus Pahl <linus.pahl@graylog.com>
2026-03-10 13:49:16 +01:00

92 lines
3.2 KiB
TypeScript

/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import userEvent from '@testing-library/user-event';
import * as selectEvent from 'react-select-event';
import { screen, within } from 'wrappedTestingLibrary';
/*
* This file contains helper methods, which replace the `react-select-event` methods.
* They are useful when interacting with the `react-select` select component.
*/
const setup = () => {
// clock property is set by @sinonjs/fake-timers when jest.useFakeTimers() is active
if ('clock' in setTimeout) {
return userEvent.setup({ advanceTimers: jest.advanceTimersByTime });
}
return userEvent.setup();
};
const clearAll = async (container: HTMLElement, selectClassName: string) => {
// eslint-disable-next-line testing-library/no-node-access
const clearIcons = container.querySelectorAll(`.${selectClassName} svg[aria-hidden="true"]`);
await setup().click(clearIcons[clearIcons.length - 1]);
};
const customCreate = (element: HTMLElement, option: string) =>
selectEvent.create(element, option, { container: document.body });
const customSelect = (element: HTMLElement, optionOrOptions: string | Array<string> | RegExp) =>
selectEvent.select(element, optionOrOptions, { container: document.body });
const findSelectInput = (name: string, config?: { container: HTMLElement }) => {
const queryRoot = config?.container ? within(config.container) : screen;
// eslint-disable-next-line testing-library/prefer-screen-queries
return queryRoot.findByRole('combobox', { name: new RegExp(name, 'i') });
};
const assertOptionExists = async (
selectName: string,
optionName: (string | RegExp) | Array<string | RegExp>,
config?: { container: HTMLElement },
) => {
const input = await findSelectInput(selectName, config);
selectEvent.openMenu(input);
const optionNames = Array.isArray(optionName) ? optionName : [optionName];
return Promise.all(optionNames.map((name) => screen.findByRole('option', { name: new RegExp(name, 'i') })));
};
// The select name should ideally be the HTML label. If there is no label, you can use the placeholder text.
const chooseOption = async (
selectName: string,
optionName: (string | RegExp) | Array<string | RegExp>,
config?: { container: HTMLElement },
) => {
const input = await findSelectInput(selectName, config);
const optionNames = Array.isArray(optionName) ? optionName : [optionName];
const user = setup();
for (const name of optionNames) {
// eslint-disable-next-line no-await-in-loop
await user.type(input, `${name}{enter}`);
}
};
export default {
clearAll,
openMenu: selectEvent.openMenu,
create: customCreate,
select: customSelect,
chooseOption,
findSelectInput,
assertOptionExists,
};