diff --git a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-chromium-linux.png b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-chromium-linux.png index e5cb6bd82..93a7ba081 100644 Binary files a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-chromium-linux.png and b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-chromium-linux.png differ diff --git a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-firefox-linux.png b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-firefox-linux.png index f59ae110a..20c362d92 100644 Binary files a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-firefox-linux.png and b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-firefox-linux.png differ diff --git a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-webkit-linux.png b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-webkit-linux.png index edcb72780..76f48ddd2 100644 Binary files a/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-webkit-linux.png and b/e2e/visual/empty-ui.spec.js-snapshots/empty-playground-1-webkit-linux.png differ diff --git a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-chromium-linux.png b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-chromium-linux.png index 82a27fed2..6447d9bcf 100644 Binary files a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-chromium-linux.png and b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-chromium-linux.png differ diff --git a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-firefox-linux.png b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-firefox-linux.png index a4690d464..d12171a1b 100644 Binary files a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-firefox-linux.png and b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-firefox-linux.png differ diff --git a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-webkit-linux.png b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-webkit-linux.png index 11703e652..200125316 100644 Binary files a/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-webkit-linux.png and b/e2e/visual/groups-ui.spec.js-snapshots/groups-playground-1-webkit-linux.png differ diff --git a/package-lock.json b/package-lock.json index 8f0dd24c5..59a6a7cef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,6 +26,7 @@ "@svgr/rollup": "^8.1.0", "@svgr/webpack": "^8.1.0", "@testing-library/preact": "^3.2.3", + "@testing-library/user-event": "^14.5.2", "@types/chai": "^4.3.19", "@types/mocha": "^10.0.8", "@types/node": "^22.7.0", @@ -6059,6 +6060,20 @@ "preact": ">=10 || ^10.0.0-alpha.0 || ^10.0.0-beta.0" } }, + "node_modules/@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "peerDependencies": { + "@testing-library/dom": ">=7.21.4" + } + }, "node_modules/@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", @@ -17203,7 +17218,9 @@ "license": "MIT" }, "node_modules/preact": { - "version": "10.5.14", + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.1.tgz", + "integrity": "sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==", "license": "MIT", "funding": { "type": "opencollective", @@ -25123,6 +25140,13 @@ "@testing-library/dom": "^8.11.1" } }, + "@testing-library/user-event": { + "version": "14.5.2", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.5.2.tgz", + "integrity": "sha512-YAh82Wh4TIrxYLmfGcixwD18oIjyC1pFQC2Y01F2lzV2HTMiYrI0nze0FD0ocB//CKS/7jIUgae+adPqxK5yCQ==", + "dev": true, + "requires": {} + }, "@tootallnate/quickjs-emscripten": { "version": "0.23.0", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", @@ -32808,7 +32832,9 @@ "dev": true }, "preact": { - "version": "10.5.14" + "version": "10.15.1", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.15.1.tgz", + "integrity": "sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==" }, "prelude-ls": { "version": "1.2.1", diff --git a/package.json b/package.json index 9a64bf438..7d0332526 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ "@svgr/rollup": "^8.1.0", "@svgr/webpack": "^8.1.0", "@testing-library/preact": "^3.2.3", + "@testing-library/user-event": "^14.5.2", "@types/chai": "^4.3.19", "@types/mocha": "^10.0.8", "@types/node": "^22.7.0", diff --git a/packages/form-js-editor/src/features/palette/components/Palette.js b/packages/form-js-editor/src/features/palette/components/Palette.js index 9a175854c..5f5bee950 100644 --- a/packages/form-js-editor/src/features/palette/components/Palette.js +++ b/packages/form-js-editor/src/features/palette/components/Palette.js @@ -51,6 +51,7 @@ export function Palette(props) { const [searchTerm, setSearchTerm] = useState(''); + /** @type {import("preact").RefObject} */ const inputRef = useRef(); const groups = groupEntries(paletteEntries); diff --git a/packages/form-js-editor/src/features/properties-panel/entries/DefaultValueEntry.js b/packages/form-js-editor/src/features/properties-panel/entries/DefaultValueEntry.js index ff93c718b..a5db2312f 100644 --- a/packages/form-js-editor/src/features/properties-panel/entries/DefaultValueEntry.js +++ b/packages/form-js-editor/src/features/properties-panel/entries/DefaultValueEntry.js @@ -16,7 +16,7 @@ import { useService } from '../hooks'; import { countDecimals, INPUTS, isValidNumber, OPTIONS_INPUTS } from '../Util'; import { useCallback } from 'preact/hooks'; -export const EMPTY_OPTION = null; +export const EMPTY_OPTION = ''; export function DefaultValueEntry(props) { const { editField, field } = props; diff --git a/packages/form-js-editor/src/render/components/FormEditor.js b/packages/form-js-editor/src/render/components/FormEditor.js index cf7daeda1..271e18e17 100644 --- a/packages/form-js-editor/src/render/components/FormEditor.js +++ b/packages/form-js-editor/src/render/components/FormEditor.js @@ -87,6 +87,7 @@ function Element(props) { const { id, type, showOutline } = field; + /** @type {import("preact").RefObject} */ const ref = useRef(); const [hovered, setHovered] = useState(false); diff --git a/packages/form-js-editor/test/helper/index.js b/packages/form-js-editor/test/helper/index.js index c9b9322b5..818cae9c0 100644 --- a/packages/form-js-editor/test/helper/index.js +++ b/packages/form-js-editor/test/helper/index.js @@ -4,7 +4,7 @@ import { FormEditorContext } from '../../src/render/context'; import { createMockInjector } from './mocks'; -import { act } from 'preact/test-utils'; +import { act } from '@testing-library/preact/pure'; import TestContainer from 'mocha-test-container-support'; diff --git a/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js b/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js index 0b66e8e6f..c9a9eba25 100644 --- a/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js +++ b/packages/form-js-viewer/src/features/repeatRender/RepeatRenderManager.js @@ -216,7 +216,7 @@ export class RepeatRenderManager { * @param {Object} props.itemValue * @param {Object} props.parentExpressionContextInfo * @param {Object} props.repeaterField - * @param {Function} props.RowsRenderer + * @param {import('preact').FunctionComponent} props.RowsRenderer * @param {Object} props.indexes * @param {Function} props.onDeleteItem * @param {boolean} props.showRemove diff --git a/packages/form-js-viewer/src/render/components/form-fields/Checklist.js b/packages/form-js-viewer/src/render/components/form-fields/Checklist.js index 8db1ae068..2c2639723 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Checklist.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Checklist.js @@ -21,6 +21,7 @@ export function Checklist(props) { const { description, label, validate = {} } = field; + /** @type {import("preact").RefObject} */ const outerDivRef = useRef(); const { required } = validate; diff --git a/packages/form-js-viewer/src/render/components/form-fields/Datetime.js b/packages/form-js-viewer/src/render/components/form-fields/Datetime.js index d1b819d94..cc35ded2f 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Datetime.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Datetime.js @@ -46,6 +46,8 @@ export function Datetime(props) { const { required } = validate; const { formId } = useContext(FormContext); + + /** @type {import("preact").RefObject} */ const dateTimeGroupRef = useRef(); const [dateTime, setDateTime] = useState(getNullDateTime()); diff --git a/packages/form-js-viewer/src/render/components/form-fields/Number.js b/packages/form-js-viewer/src/render/components/form-fields/Number.js index c547c09df..5df21c78a 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Number.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Number.js @@ -26,6 +26,7 @@ export function Numberfield(props) { const { required } = validate; + /** @type {import("preact").RefObject} */ const inputRef = useRef(); const [cachedValue, setCachedValue] = useState(value); diff --git a/packages/form-js-viewer/src/render/components/form-fields/Radio.js b/packages/form-js-viewer/src/render/components/form-fields/Radio.js index 5d9552088..6d40da142 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Radio.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Radio.js @@ -21,6 +21,7 @@ export function Radio(props) { const { description, label, validate = {} } = field; + /** @type {import("preact").RefObject} */ const outerDivRef = useRef(); const { required } = validate; diff --git a/packages/form-js-viewer/src/render/components/form-fields/Table.js b/packages/form-js-viewer/src/render/components/form-fields/Table.js index 3e64b9881..640f3bcc3 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Table.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Table.js @@ -41,8 +41,7 @@ export function Table(props) { const { field } = props; const { columns = [], columnsExpression, dataSource = '', rowCount, id, label } = field; - /** @type {[(null|Sorting), import("preact/hooks").StateUpdater]} */ - const [sortBy, setSortBy] = useState(null); + const [sortBy, setSortBy] = useState(/** @type {Sorting | null} */ null); const evaluatedColumns = useEvaluatedColumns(columnsExpression || '', columns); const columnKeys = evaluatedColumns.map(({ key }) => key); const evaluatedDataSource = useExpressionEvaluation(dataSource); diff --git a/packages/form-js-viewer/src/render/components/form-fields/Taglist.js b/packages/form-js-viewer/src/render/components/form-fields/Taglist.js index f88e85e74..f3dba43fc 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/Taglist.js +++ b/packages/form-js-viewer/src/render/components/form-fields/Taglist.js @@ -34,7 +34,11 @@ export function Taglist(props) { const [filter, setFilter] = useState(''); const [isDropdownExpanded, setIsDropdownExpanded] = useState(false); const [isEscapeClosed, setIsEscapeClose] = useState(false); + + /** @type {import("preact").RefObject} */ const focusScopeRef = useRef(); + + /** @type {import("preact").RefObject} */ const inputRef = useRef(); const eventBus = useService('eventBus'); diff --git a/packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js b/packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js index a6978fd79..b062e2f91 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js +++ b/packages/form-js-viewer/src/render/components/form-fields/parts/Datepicker.js @@ -24,7 +24,10 @@ export function Datepicker(props) { setDate, } = props; + /** @type {import("preact").RefObject} */ const dateInputRef = useRef(); + + /** @type {import("preact").RefObject} */ const focusScopeRef = useRef(); const [flatpickrInstance, setFlatpickrInstance] = useState(null); diff --git a/packages/form-js-viewer/src/render/components/form-fields/parts/DropdownList.js b/packages/form-js-viewer/src/render/components/form-fields/parts/DropdownList.js index 9b2bd04cc..60e1e87aa 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/parts/DropdownList.js +++ b/packages/form-js-viewer/src/render/components/form-fields/parts/DropdownList.js @@ -19,7 +19,11 @@ export function DropdownList(props) { const [mouseControl, setMouseControl] = useState(false); const [focusedValueIndex, setFocusedValueIndex] = useState(initialFocusIndex); const [smoothScrolling, setSmoothScrolling] = useState(false); + + /** @type {import("preact").RefObject} */ const dropdownContainer = useRef(); + + /** @type {import("preact").RefObject<{ x: number, y: number }>} */ const mouseScreenPos = useRef(); const focusedItem = useMemo(() => (values.length ? values[focusedValueIndex] : null), [focusedValueIndex, values]); diff --git a/packages/form-js-viewer/src/render/components/form-fields/parts/SearchableSelect.js b/packages/form-js-viewer/src/render/components/form-fields/parts/SearchableSelect.js index 450136c6e..3417f33d5 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/parts/SearchableSelect.js +++ b/packages/form-js-viewer/src/render/components/form-fields/parts/SearchableSelect.js @@ -17,6 +17,8 @@ export function SearchableSelect(props) { const [isDropdownExpanded, setIsDropdownExpanded] = useState(false); const [isFilterActive, setIsFilterActive] = useState(true); const [isEscapeClosed, setIsEscapeClose] = useState(false); + + /** @type {import("preact").RefObject} */ const searchbarRef = useRef(); const eventBus = useService('eventBus'); diff --git a/packages/form-js-viewer/src/render/components/form-fields/parts/SimpleSelect.js b/packages/form-js-viewer/src/render/components/form-fields/parts/SimpleSelect.js index 292edaced..37134cc73 100644 --- a/packages/form-js-viewer/src/render/components/form-fields/parts/SimpleSelect.js +++ b/packages/form-js-viewer/src/render/components/form-fields/parts/SimpleSelect.js @@ -15,6 +15,8 @@ export function SimpleSelect(props) { const [isDropdownExpanded, setIsDropdownExpanded] = useState(false); const selectRef = useRef(); + + /** @type {import("preact").RefObject} */ const inputRef = useRef(); const { loadState, options } = useOptionsAsync(field); diff --git a/packages/form-js-viewer/src/render/hooks/useDeepCompareMemoize.js b/packages/form-js-viewer/src/render/hooks/useDeepCompareMemoize.js index fd5f028b5..8200438e9 100644 --- a/packages/form-js-viewer/src/render/hooks/useDeepCompareMemoize.js +++ b/packages/form-js-viewer/src/render/hooks/useDeepCompareMemoize.js @@ -9,6 +9,7 @@ import isEqual from 'lodash/isEqual'; * @returns {T} - Returns the current state. */ export function useDeepCompareMemoize(value) { + /** @type {import("preact").RefObject} */ const ref = useRef(); if (!isEqual(value, ref.current)) { diff --git a/packages/form-js-viewer/test/spec/Form.spec.js b/packages/form-js-viewer/test/spec/Form.spec.js index de5c24a8e..5417cd7da 100644 --- a/packages/form-js-viewer/test/spec/Form.spec.js +++ b/packages/form-js-viewer/test/spec/Form.spec.js @@ -1,4 +1,5 @@ import { act, fireEvent, screen, waitFor } from '@testing-library/preact/pure'; +import userEvent from '@testing-library/user-event'; import { createForm, Form, schemaVersion } from '../../src'; @@ -666,12 +667,11 @@ describe('Form', function () { const elements = container.querySelector('.fjs-element').querySelectorAll('.fjs-element'); const element = elements[index]; const focusTarget = element.querySelector(selector); + const formRoot = container.querySelector('.fjs-form'); // when - await act(() => { - fireEvent.focus(focusTarget); - fireEvent.blur(focusTarget); - }); + await userEvent.click(focusTarget); + await userEvent.click(formRoot); // then expect(focusSpy).to.have.been.calledWithMatch({ formField }); diff --git a/packages/form-js-viewer/test/spec/render/components/FormField.spec.js b/packages/form-js-viewer/test/spec/render/components/FormField.spec.js index e9bbb0986..608e3ab7a 100644 --- a/packages/form-js-viewer/test/spec/render/components/FormField.spec.js +++ b/packages/form-js-viewer/test/spec/render/components/FormField.spec.js @@ -1,4 +1,5 @@ import { fireEvent, render } from '@testing-library/preact/pure'; +import userEvent from '@testing-library/user-event'; import { classes } from 'min-dom'; @@ -266,8 +267,8 @@ describe('FormField', function () { }); describe('eager validation', function () { - it('should trigger validation on blur', function () { - // when + it('should trigger validation on blur', async function () { + // given const setStateSpy = sinon.spy(); const { container } = createFormField({ field: { @@ -277,15 +278,17 @@ describe('FormField', function () { validationErrors: ['validation-error'], }); - // then const formField = container.querySelector('.fjs-form-field'); expect(formField).to.exist; const input = container.querySelector('input[type="text"]'); expect(setStateSpy).not.to.have.been.called; + // when + await userEvent.click(input); + await userEvent.tab(); + // then - fireEvent.blur(input); expect(setStateSpy).to.have.been.calledWith({ errors: { Creditor_ID: ['validation-error'], diff --git a/packages/form-js-viewer/test/spec/render/components/form-fields/Datetime.spec.js b/packages/form-js-viewer/test/spec/render/components/form-fields/Datetime.spec.js index e88f4722c..0f05ce213 100644 --- a/packages/form-js-viewer/test/spec/render/components/form-fields/Datetime.spec.js +++ b/packages/form-js-viewer/test/spec/render/components/form-fields/Datetime.spec.js @@ -1,4 +1,5 @@ -import { fireEvent, render } from '@testing-library/preact/pure'; +import { render } from '@testing-library/preact/pure'; +import userEvent from '@testing-library/user-event'; import { Datetime } from '../../../../../src/render/components/form-fields/Datetime'; @@ -113,7 +114,7 @@ describe('Datetime', function () { }); describe('change handling', function () { - it('should change date (keyboard)', function () { + it('should change date (keyboard)', async function () { // given const onChangeSpy = spy(); @@ -124,9 +125,9 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - - fireEvent.input(dateInput, { target: { value: '01/01/2000' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.type(dateInput, '01/01/2000'); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -134,7 +135,7 @@ describe('Datetime', function () { }); }); - it('should change date (mouse)', function () { + it('should change date (mouse)', async function () { // given const onChangeSpy = spy(); @@ -145,10 +146,10 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const firstDayNode = container.querySelectorAll('.flatpickr-day')[0]; - fireEvent.click(firstDayNode); + await userEvent.click(firstDayNode); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -156,7 +157,7 @@ describe('Datetime', function () { }); }); - it('should clear date', function () { + it('should clear date', async function () { // given const onChangeSpy = spy(); @@ -168,8 +169,8 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.input(dateInput, { target: { value: '' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -179,7 +180,7 @@ describe('Datetime', function () { }); describe('interaction', function () { - it('should navigate to next month and select date', function () { + it('should navigate to next month and select date', async function () { // given const onChangeSpy = spy(); @@ -190,13 +191,13 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const nextMonthButton = container.querySelector('.flatpickr-next-month'); - fireEvent.click(nextMonthButton); + await userEvent.click(nextMonthButton); const firstDayNode = container.querySelectorAll('.flatpickr-day')[0]; - fireEvent.click(firstDayNode); + await userEvent.click(firstDayNode); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -204,7 +205,7 @@ describe('Datetime', function () { }); }); - it('should navigate to previous month and select date', function () { + it('should navigate to previous month and select date', async function () { // given const onChangeSpy = spy(); @@ -215,13 +216,13 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const prevMonthButton = container.querySelector('.flatpickr-prev-month'); - fireEvent.click(prevMonthButton); + await userEvent.click(prevMonthButton); const firstDayNode = container.querySelectorAll('.flatpickr-day')[0]; - fireEvent.click(firstDayNode); + await userEvent.click(firstDayNode); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -229,7 +230,7 @@ describe('Datetime', function () { }); }); - it('should navigate to specific month and select date', function () { + it('should navigate to specific month and select date', async function () { // given const onChangeSpy = spy(); @@ -240,13 +241,13 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const monthSelect = container.querySelector('.flatpickr-monthDropdown-months'); - fireEvent.change(monthSelect, { target: { value: 0 } }); + await userEvent.selectOptions(monthSelect, '0'); const firstDayNode = container.querySelectorAll('.flatpickr-day')[0]; - fireEvent.click(firstDayNode); + await userEvent.click(firstDayNode); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -256,7 +257,7 @@ describe('Datetime', function () { }); describe('configuration', function () { - it('should disable past dates', function () { + it('should disable past dates', async function () { // given const { container } = createDatetime({ value: '1996-11-13', @@ -268,7 +269,7 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const previousMonthButton = container.querySelector('.flatpickr-prev-month'); @@ -278,7 +279,7 @@ describe('Datetime', function () { }); }); - it('should disable dates prior to 1900', function () { + it('should disable dates prior to 1900', async function () { // given const { container } = createDatetime({ value: '1900-01-01', @@ -290,7 +291,7 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.focus(dateInput); + await userEvent.click(dateInput); const previousMonthButton = container.querySelector('.flatpickr-prev-month'); @@ -421,12 +422,12 @@ describe('Datetime', function () { expect(dropdown).to.not.exist; }); - it('should render on input focus', function () { + it('should render on input focus', async function () { // when const { container } = createDatetime({ field: timeField }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -447,12 +448,12 @@ describe('Datetime', function () { expect(midItem).to.equal(focusedItem); }); - it('should render custom increment', function () { + it('should render custom increment', async function () { // when const { container } = createDatetime({ field: { ...timeField, timeInterval: 30 } }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -468,12 +469,12 @@ describe('Datetime', function () { expect(secondItem.innerText).to.equal('12:30 AM'); }); - it('should default to 15 increment with invalid intervals', function () { + it('should default to 15 increment with invalid intervals', async function () { // when const { container } = createDatetime({ field: { ...timeField, timeInterval: -72 } }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -489,12 +490,12 @@ describe('Datetime', function () { expect(secondItem.innerText).to.equal('12:15 AM'); }); - it('should default to 15 increment with no interval', function () { + it('should default to 15 increment with no interval', async function () { // when const { container } = createDatetime({ field: { ...timeField, timeInterval: undefined } }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -510,12 +511,12 @@ describe('Datetime', function () { expect(secondItem.innerText).to.equal('12:15 AM'); }); - it('should render 24h', function () { + it('should render 24h', async function () { // when const { container } = createDatetime({ field: { ...timeField, use24h: true } }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -531,24 +532,24 @@ describe('Datetime', function () { expect(secondItem.innerText).to.equal('00:15'); }); - it('should not render for 1m increments', function () { + it('should not render for 1m increments', async function () { // when const { container } = createDatetime({ field: { ...timeField, timeInterval: 1 } }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); expect(dropdown).to.not.exist; }); - it('should focus current value on open', function () { + it('should focus current value on open', async function () { // when const { container } = createDatetime({ field: { ...timeField, use24h: true }, value: '11:00' }); const timeInput = container.querySelector('input[type="text"]'); - fireEvent.focus(timeInput); + await userEvent.click(timeInput); // then const dropdown = container.querySelector('.fjs-dropdownlist'); @@ -559,7 +560,7 @@ describe('Datetime', function () { }); describe('change handling', function () { - it('should change time (24h)', function () { + it('should change time (24h)', async function () { // given const onChangeSpy = spy(); @@ -572,8 +573,9 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.input(dateInput, { target: { value: '13:00' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.type(dateInput, '13:00'); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -581,7 +583,7 @@ describe('Datetime', function () { }); }); - it('should change time (AM/PM)', function () { + it('should change time (AM/PM)', async function () { // given const onChangeSpy = spy(); @@ -594,8 +596,9 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.input(dateInput, { target: { value: '1PM' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.type(dateInput, '1PM'); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -603,7 +606,7 @@ describe('Datetime', function () { }); }); - it('should clear time', function () { + it('should clear time', async function () { // given const onChangeSpy = spy(); @@ -616,8 +619,8 @@ describe('Datetime', function () { // when const dateInput = container.querySelector('input[type="text"]'); - fireEvent.input(dateInput, { target: { value: '' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -751,14 +754,14 @@ describe('Datetime', function () { expect(timeInput.value).to.be.equal('10:00'); }); - it('should display an error state if only date is set', function () { + it('should display an error state if only date is set', async function () { // given const { container } = createDatetime({ field: datetimeField }); const dateInput = container.querySelectorAll('input[type="text"]')[0]; // when - fireEvent.input(dateInput, { target: { value: '01/01/2000' } }); - fireEvent.blur(dateInput); + await userEvent.type(dateInput, '01/01/2000'); + await userEvent.tab(); // then const errorGroup = container.querySelector('.fjs-form-field-error'); @@ -770,7 +773,7 @@ describe('Datetime', function () { expect(errorItem.innerText).to.equal('Date and time must both be entered.'); }); - it('should display an error state if only time is set', function () { + it('should display an error state if only time is set', async function () { // given const { container } = createDatetime({ field: datetimeField }); @@ -779,8 +782,8 @@ describe('Datetime', function () { const timeInput = container.querySelectorAll('input[type="text"]')[1]; // when - fireEvent.input(timeInput, { target: { value: '10:00' } }); - fireEvent.blur(timeInput); + await userEvent.type(timeInput, '10:00'); + await userEvent.tab(); // then const errorGroup = container.querySelector('.fjs-form-field-error'); @@ -792,7 +795,7 @@ describe('Datetime', function () { }); describe('change handling', function () { - it('should change date', function () { + it('should change date', async function () { // given const onChangeSpy = spy(); @@ -805,8 +808,9 @@ describe('Datetime', function () { // when const dateInput = container.querySelectorAll('input[type="text"]')[0]; - fireEvent.input(dateInput, { target: { value: '01/01/2000' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.type(dateInput, '01/01/2000'); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -814,7 +818,7 @@ describe('Datetime', function () { }); }); - it('should change time', function () { + it('should change time', async function () { // given const onChangeSpy = spy(); @@ -827,8 +831,9 @@ describe('Datetime', function () { // when const timeInput = container.querySelectorAll('input[type="text"]')[1]; - fireEvent.input(timeInput, { target: { value: '12:00' } }); - fireEvent.blur(timeInput); + await userEvent.clear(timeInput); + await userEvent.type(timeInput, '12:00'); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -836,7 +841,7 @@ describe('Datetime', function () { }); }); - it('should clear from date', function () { + it('should clear from date', async function () { // given const onChangeSpy = spy(); @@ -849,8 +854,8 @@ describe('Datetime', function () { // when const dateInput = container.querySelectorAll('input[type="text"]')[0]; - fireEvent.input(dateInput, { target: { value: '' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -858,7 +863,7 @@ describe('Datetime', function () { }); }); - it('should clear from time', function () { + it('should clear from time', async function () { // given const onChangeSpy = spy(); @@ -871,8 +876,8 @@ describe('Datetime', function () { // when const dateInput = container.querySelectorAll('input[type="text"]')[1]; - fireEvent.input(dateInput, { target: { value: '' } }); - fireEvent.blur(dateInput); + await userEvent.clear(dateInput); + await userEvent.tab(); // then expect(onChangeSpy).to.have.been.calledWithMatch({ diff --git a/packages/form-js-viewer/test/spec/render/components/form-fields/ExpressionField.spec.js b/packages/form-js-viewer/test/spec/render/components/form-fields/ExpressionField.spec.js index b16399a5a..835812905 100644 --- a/packages/form-js-viewer/test/spec/render/components/form-fields/ExpressionField.spec.js +++ b/packages/form-js-viewer/test/spec/render/components/form-fields/ExpressionField.spec.js @@ -1,10 +1,9 @@ -import { render } from '@testing-library/preact/pure'; +import { render, act } from '@testing-library/preact/pure'; import { ExpressionField } from '../../../../../src/render/components/form-fields/ExpressionField'; import { MockFormContext } from '../helper'; import { EventBusMock } from '../helper/mocks'; -import { act } from 'preact/test-utils'; import { createFormContainer } from '../../../../TestHelper'; diff --git a/packages/form-js-viewer/test/spec/render/components/form-fields/Select.spec.js b/packages/form-js-viewer/test/spec/render/components/form-fields/Select.spec.js index e044b0da4..f873a7375 100644 --- a/packages/form-js-viewer/test/spec/render/components/form-fields/Select.spec.js +++ b/packages/form-js-viewer/test/spec/render/components/form-fields/Select.spec.js @@ -1,4 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/preact/pure'; +import userEvent from '@testing-library/user-event'; import { Select } from '../../../../../src/render/components/form-fields/Select'; @@ -194,40 +195,40 @@ describe('Select', function () { expect(description.textContent).to.equal('foo'); }); - it('should render dropdown when focused', function () { + it('should render dropdown when focused', async function () { // when const { container } = createSelect(); const select = container.querySelector('.fjs-input-group'); // then - let selectAnchor = container.querySelector('.fjs-select-anchor'); + const selectAnchor = container.querySelector('.fjs-select-anchor'); expect(selectAnchor).to.exist; let dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.not.exist; - fireEvent.focus(select); + await userEvent.click(select); dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; }); - it('should close dropdown on blur', function () { + it('should close dropdown on blur', async function () { // given const { container } = createSelect(); const select = container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); + await userEvent.click(select); // assume let dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; // and when - fireEvent.blur(select); + await userEvent.tab(); // then dropdownList = container.querySelector('.fjs-dropdownlist'); @@ -270,7 +271,7 @@ describe('Select', function () { }); describe('interaction (static data)', function () { - it('should set value through dropdown', function () { + it('should set value through dropdown', async function () { // given const onChangeSpy = spy(); @@ -282,10 +283,9 @@ describe('Select', function () { const select = container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); - + await userEvent.click(select); const germanSelector = container.querySelector('.fjs-dropdownlist .fjs-dropdownlist-item'); - fireEvent.mouseDown(germanSelector); + await userEvent.click(germanSelector); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -316,7 +316,7 @@ describe('Select', function () { }); describe('interaction (dynamic data, valuesKey)', function () { - it('should set value through dropdown', function () { + it('should set value through dropdown', async function () { // given const onChangeSpy = spy(); @@ -330,11 +330,9 @@ describe('Select', function () { const select = container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); - + await userEvent.click(select); const germanSelector = container.querySelector('.fjs-dropdownlist .fjs-dropdownlist-item'); - - fireEvent.mouseDown(germanSelector); + await userEvent.click(germanSelector); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -365,7 +363,7 @@ describe('Select', function () { }); describe('interaction (dynamic data, valuesExpression)', function () { - it('should set value through dropdown', function () { + it('should set value through dropdown', async function () { // given const onChangeSpy = spy(); @@ -387,11 +385,10 @@ describe('Select', function () { const select = container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); + await userEvent.click(select); const germanSelector = container.querySelector('.fjs-dropdownlist .fjs-dropdownlist-item'); - - fireEvent.mouseDown(germanSelector); + await userEvent.click(germanSelector); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -399,7 +396,7 @@ describe('Select', function () { }); }); - it('should render options from values expression', function () { + it('should render options from values expression', async function () { // given const onChangeSpy = spy(); @@ -421,13 +418,13 @@ describe('Select', function () { const select = container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); + await userEvent.click(select); // then expect(getSelectValues(container)).to.eql(['Value 1', 'Value 2', 'Value 3', 'Value 4']); }); - it('should update options when evaluation changed', function () { + it('should update options when evaluation changed', async function () { // given const onChangeSpy = spy(); @@ -449,7 +446,7 @@ describe('Select', function () { const select = result.container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); + await userEvent.click(select); // assume expect(getSelectValues(result.container)).to.eql(['Value 1', 'Value 2', 'Value 3', 'Value 4']); @@ -474,7 +471,7 @@ describe('Select', function () { expect(getSelectValues(result.container)).to.eql(['Value 1', 'Value 2', 'Value 3', 'Value 4', 'Value 5']); }); - it('should update options - roundtrip', function () { + it('should update options - roundtrip', async function () { // given const onChangeSpy = spy(); @@ -496,7 +493,7 @@ describe('Select', function () { const select = result.container.querySelector('.fjs-input-group'); // when - fireEvent.focus(select); + await userEvent.click(select); // assume expect(getSelectValues(result.container)).to.eql(['Value 1', 'Value 2', 'Value 3', 'Value 4']); @@ -747,7 +744,7 @@ describe('Select', function () { expect(filter.value).to.equal('English'); }); - it('should render dropdown when focused', function () { + it('should render dropdown when focused', async function () { // when const { container } = createSelect({ field: { ...defaultField, searchable: true } }); @@ -760,13 +757,13 @@ describe('Select', function () { let dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.not.exist; - fireEvent.focus(filterInput); + await userEvent.click(filterInput); dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; }); - it('should filter dropdown', function () { + it('should filter dropdown', async function () { // when const eventBusFireSpy = spy(); const eventBus = { @@ -777,7 +774,7 @@ describe('Select', function () { const { container } = createSelect({ field, services: { eventBus } }); const filterInput = container.querySelector('input[type="text"]'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); @@ -785,7 +782,7 @@ describe('Select', function () { let listItems = dropdownList.querySelectorAll('.fjs-dropdownlist-item'); expect(listItems.length).to.equal(2); - fireEvent.input(filterInput, { target: { value: 'Ger' } }); + await userEvent.type(filterInput, 'Ger'); listItems = dropdownList.querySelectorAll('.fjs-dropdownlist-item'); expect(listItems.length).to.equal(1); @@ -798,7 +795,7 @@ describe('Select', function () { }); describe('interaction', function () { - it('should set value through dropdown', function () { + it('should set value through dropdown', async function () { // given const onChangeSpy = spy(); @@ -811,10 +808,9 @@ describe('Select', function () { const filterInput = container.querySelector('input[type="text"]'); // when - fireEvent.focus(filterInput); - + await userEvent.click(filterInput); const germanSelector = container.querySelector('.fjs-dropdownlist .fjs-dropdownlist-item'); - fireEvent.mouseDown(germanSelector); + await userEvent.click(germanSelector); // then expect(onChangeSpy).to.have.been.calledWithMatch({ diff --git a/packages/form-js-viewer/test/spec/render/components/form-fields/Taglist.spec.js b/packages/form-js-viewer/test/spec/render/components/form-fields/Taglist.spec.js index 2e46996a4..9f55b46ea 100644 --- a/packages/form-js-viewer/test/spec/render/components/form-fields/Taglist.spec.js +++ b/packages/form-js-viewer/test/spec/render/components/form-fields/Taglist.spec.js @@ -1,4 +1,5 @@ import { fireEvent, render, screen } from '@testing-library/preact/pure'; +import userEvent from '@testing-library/user-event'; import { Taglist } from '../../../../../src/render/components/form-fields/Taglist'; @@ -183,7 +184,7 @@ describe('Taglist', function () { expect(getTagValues(result.container)).to.eql(['Value 1', 'Value 5']); }); - it('should render dropdown when filter focused', function () { + it('should render dropdown when filter focused', async function () { // when const { container } = createTaglist({ value: ['tag1', 'tag2', 'tag3'], @@ -192,7 +193,7 @@ describe('Taglist', function () { const filterInput = container.querySelector('input[type="text"]'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); // then const taglistAnchor = container.querySelector('.fjs-taglist-anchor'); @@ -296,7 +297,7 @@ describe('Taglist', function () { describe('interaction', function () { describe('tag deletion', function () { - it('should work via mouse', function () { + it('should work via mouse', async function () { // given const onChangeSpy = spy(); @@ -308,7 +309,7 @@ describe('Taglist', function () { // when const removeButton = container.querySelectorAll('.fjs-taglist-tag-remove')[1]; - fireEvent.click(removeButton); + await userEvent.click(removeButton); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -376,7 +377,7 @@ describe('Taglist', function () { }); describe('filtering', function () { - it('should filter dropdown', function () { + it('should filter dropdown', async function () { // given const eventBusFireSpy = spy(); const eventBus = { @@ -391,21 +392,22 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; expect(dropdownList.children.length).to.equal(8); // then - fireEvent.input(filterInput, { target: { value: '4' } }); + await userEvent.type(filterInput, '4'); expect(dropdownList.children.length).to.equal(1); expect(eventBusFireSpy).to.have.been.calledWith('formField.search', { formField: defaultField, value: '4', }); - fireEvent.input(filterInput, { target: { value: 'Tag' } }); + await userEvent.clear(filterInput); + await userEvent.type(filterInput, 'Tag'); expect(dropdownList.children.length).to.equal(8); expect(eventBusFireSpy).to.have.been.calledWith('formField.search', { formField: defaultField, @@ -413,7 +415,7 @@ describe('Taglist', function () { }); }); - it('should filter dropdown case insensitively', function () { + it('should filter dropdown case insensitively', async function () { const { container } = createTaglist({ onChange: () => {}, value: ['tag1', 'tag2', 'tag3'], @@ -421,22 +423,24 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; - fireEvent.input(filterInput, { target: { value: 'Tag' } }); + await userEvent.type(filterInput, 'Tag'); expect(dropdownList.children.length).to.equal(8); // then - fireEvent.input(filterInput, { target: { value: 'TAG' } }); + await userEvent.clear(filterInput); + await userEvent.type(filterInput, 'TAG'); expect(dropdownList.children.length).to.equal(8); - fireEvent.input(filterInput, { target: { value: 'tAg' } }); + await userEvent.clear(filterInput); + await userEvent.type(filterInput, 'tAg'); expect(dropdownList.children.length).to.equal(8); }); - it('should filter dropdown for dynamic data', function () { + it('should filter dropdown for dynamic data', async function () { // given const onChangeSpy = spy(); @@ -449,17 +453,18 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; expect(dropdownList.children.length).to.equal(2); // then - fireEvent.input(filterInput, { target: { value: '4' } }); + await userEvent.type(filterInput, '4'); expect(dropdownList.children.length).to.equal(1); - fireEvent.input(filterInput, { target: { value: 'dyna' } }); + await userEvent.clear(filterInput); + await userEvent.type(filterInput, 'dyna'); expect(dropdownList.children.length).to.equal(2); }); }); @@ -467,7 +472,7 @@ describe('Taglist', function () { describe('dropdown', function () { describe('items', function () { - it('should not render invalid items', function () { + it('should not render invalid items', async function () { // when const { container } = createTaglist({ onchange: () => {}, @@ -486,8 +491,7 @@ describe('Taglist', function () { // then const filterInput = container.querySelector('input[type="text"]'); - - fireEvent.focus(filterInput); + await userEvent.click(filterInput); // then const taglistAnchor = container.querySelector('.fjs-taglist-anchor'); @@ -502,7 +506,7 @@ describe('Taglist', function () { }); describe('filtering', function () { - it('should render no results state', function () { + it('should render no results state', async function () { // given const onChangeSpy = spy(); @@ -513,14 +517,14 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; expect(dropdownList.children.length).to.equal(8); // then - fireEvent.input(filterInput, { target: { value: 'iahdisdisad' } }); + await userEvent.type(filterInput, 'iahdisdisad'); expect(dropdownList.children.length).to.equal(1); const noResults = dropdownList.querySelector('.fjs-dropdownlist-empty'); @@ -528,7 +532,7 @@ describe('Taglist', function () { expect(noResults.innerText).to.equal('No results'); }); - it('should render all selected state', function () { + it('should render all selected state', async function () { // given const onChangeSpy = spy(); @@ -539,7 +543,7 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); expect(dropdownList).to.exist; @@ -554,7 +558,7 @@ describe('Taglist', function () { }); describe('navigation', function () { - it('should work via keyboard', function () { + it('should work via keyboard', async function () { // given const onChangeSpy = spy(); @@ -565,7 +569,7 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); @@ -573,19 +577,21 @@ describe('Taglist', function () { let focusedItem = dropdownList.querySelector('.fjs-dropdownlist-item.focused'); expect(focusedItem.innerText).to.equal('Tag4'); - fireEvent.keyDown(filterInput, { key: 'ArrowDown', code: 'ArrowDown' }); - fireEvent.keyDown(filterInput, { key: 'ArrowDown', code: 'ArrowDown' }); + await userEvent.keyboard('{arrowdown}{arrowdown}'); + // fireEvent.keyDown(filterInput, { key: 'ArrowDown', code: 'ArrowDown' }); + // fireEvent.keyDown(filterInput, { key: 'ArrowDown', code: 'ArrowDown' }); focusedItem = dropdownList.querySelector('.fjs-dropdownlist-item.focused'); expect(focusedItem.innerText).to.equal('Tag6'); - fireEvent.keyDown(filterInput, { key: 'ArrowUp', code: 'ArrowUp' }); + await userEvent.keyboard('{arrowup}'); + // fireEvent.keyDown(filterInput, { key: 'ArrowUp', code: 'ArrowUp' }); focusedItem = dropdownList.querySelector('.fjs-dropdownlist-item.focused'); expect(focusedItem.innerText).to.equal('Tag5'); }); - it('should work via mouse', function () { + it('should work via mouse', async function () { const onChangeSpy = spy(); const { container } = createTaglist({ @@ -595,7 +601,7 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const dropdownList = container.querySelector('.fjs-dropdownlist'); @@ -634,7 +640,7 @@ describe('Taglist', function () { }); describe('selection', function () { - it('should work via mouse', function () { + it('should work via mouse', async function () { // given const onChangeSpy = spy(); @@ -645,10 +651,10 @@ describe('Taglist', function () { // when const filterInput = container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); + await userEvent.click(filterInput); const focusedItem = container.querySelector('.fjs-dropdownlist-item.focused'); - fireEvent.mouseDown(focusedItem); + await userEvent.click(focusedItem); // then expect(onChangeSpy).to.have.been.calledWithMatch({ @@ -656,7 +662,7 @@ describe('Taglist', function () { }); }); - it('should work via keyboard', function () { + it('should work via keyboard', async function () { // given const onChangeSpy = spy(); @@ -667,8 +673,8 @@ describe('Taglist', function () { // when const filterInput = taglist.container.querySelector('.fjs-taglist-input'); - fireEvent.focus(filterInput); - fireEvent.keyDown(filterInput, { key: 'Enter', code: 'Enter' }); + await userEvent.click(filterInput); + await userEvent.keyboard('{enter}'); // then expect(onChangeSpy).to.have.been.calledWithMatch({