From 35fceb1f9006d386550db42185109daf96a96c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matuzal=C3=A9m=20Teles?= Date: Mon, 23 Oct 2023 19:04:57 -0500 Subject: [PATCH 1/2] chore(@clayui/core): add the basic rendering test suite --- packages/clay-core/src/table/Body.tsx | 16 +- .../src/table/__tests__/BasicRendering.tsx | 182 +++++++ .../__snapshots__/BasicRendering.tsx.snap | 501 ++++++++++++++++++ packages/clay-core/stories/Table.stories.tsx | 4 +- 4 files changed, 695 insertions(+), 8 deletions(-) create mode 100644 packages/clay-core/src/table/__tests__/BasicRendering.tsx create mode 100644 packages/clay-core/src/table/__tests__/__snapshots__/BasicRendering.tsx.snap diff --git a/packages/clay-core/src/table/Body.tsx b/packages/clay-core/src/table/Body.tsx index c3c176c2aa..36d3f481fa 100644 --- a/packages/clay-core/src/table/Body.tsx +++ b/packages/clay-core/src/table/Body.tsx @@ -86,13 +86,15 @@ function BodyInner>( itemContainer={useCallback( ({children, item, keyValue}: ItemProps) => - React.cloneElement(children, { - _expandable: item._expandable, - _index: item._index, - _level: item._level, - _size: item._size, - keyValue, - }), + item + ? React.cloneElement(children, { + _expandable: item._expandable, + _index: item._index, + _level: item._level, + _size: item._size, + keyValue, + }) + : children, [] )} items={items} diff --git a/packages/clay-core/src/table/__tests__/BasicRendering.tsx b/packages/clay-core/src/table/__tests__/BasicRendering.tsx new file mode 100644 index 0000000000..28ce85542a --- /dev/null +++ b/packages/clay-core/src/table/__tests__/BasicRendering.tsx @@ -0,0 +1,182 @@ +/** + * SPDX-FileCopyrightText: © 2023 Liferay, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ + +import {cleanup, render} from '@testing-library/react'; +import React from 'react'; + +import {Body, Cell, Head, Row, Table} from '../../'; + +describe('Table basic rendering', () => { + afterEach(cleanup); + + it('render static content', () => { + const {container} = render( + + + Name + Type + + + + + Foo + Foo + + + Bar + Bar + + + Baz + Baz + + +
+ ); + + expect(container).toMatchSnapshot(); + }); + + it('render dynamic content', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + {id: 1, name: 'Foo', type: 'Foo'}, + {id: 2, name: 'Bar', type: 'Bar'}, + {id: 3, name: 'Baz', type: 'Baz'}, + ]; + + const {container} = render( + + + {(column) => {column.name}} + + + + {(row) => ( + + {/** @ts-ignore */} + {(column) => {row[column.id]}} + + )} + +
+ ); + + expect(container).toMatchSnapshot(); + }); + + it('render with sort column', () => { + const {container} = render( + + + + Name + + + Type + + + + + + Foo + Foo + + + Bar + Bar + + + Baz + Baz + + +
+ ); + + expect(container).toMatchSnapshot(); + }); + + it('render with treegrid', () => { + const columns = [ + { + id: 'name', + name: 'Name', + }, + { + id: 'type', + name: 'Type', + }, + ]; + + const {container} = render( + + + {(column) => {column.name}} + + + + {(row) => ( + + {row['name']} + {row['type']} + + )} + +
+ ); + + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/clay-core/src/table/__tests__/__snapshots__/BasicRendering.tsx.snap b/packages/clay-core/src/table/__tests__/__snapshots__/BasicRendering.tsx.snap new file mode 100644 index 0000000000..e225ee51e0 --- /dev/null +++ b/packages/clay-core/src/table/__tests__/__snapshots__/BasicRendering.tsx.snap @@ -0,0 +1,501 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Table basic rendering render dynamic content 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type +
+ Foo + + Foo +
+ Bar + + Bar +
+ Baz + + Baz +
+
+
+`; + +exports[`Table basic rendering render static content 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + +
+ Name + + Type +
+ Foo + + Foo +
+ Bar + + Bar +
+ Baz + + Baz +
+
+
+`; + +exports[`Table basic rendering render with sort column 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + Name + + + + + + Type + + +
+ Foo + + Foo +
+ Bar + + Bar +
+ Baz + + Baz +
+
+
+`; + +exports[`Table basic rendering render with treegrid 1`] = ` +
+
+ + + + + + + + + + + + + + + + + + + + + +
+
+
+ Name +
+
+
+ Type +
+
+
+ Folder A +
+
+
+ Folder +
+
+
+ Folder C +
+
+
+ Folder +
+
+
+`; diff --git a/packages/clay-core/stories/Table.stories.tsx b/packages/clay-core/stories/Table.stories.tsx index b4638da000..a2e619c358 100644 --- a/packages/clay-core/stories/Table.stories.tsx +++ b/packages/clay-core/stories/Table.stories.tsx @@ -142,7 +142,9 @@ export const Sorting = () => { }; export const Treegrid = () => { - const [expandedKeys, setExpandedKeys] = useState(new Set([2, 3])); + const [expandedKeys, setExpandedKeys] = useState>( + new Set([2, 3]) + ); const columns = [ { From 2f9545fc21bd0860d7a1a23a8a46b205b4fe882c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matuzal=C3=A9m=20Teles?= Date: Tue, 24 Oct 2023 21:14:30 -0500 Subject: [PATCH 2/2] chore(@clayui/core): adds IncrementalInteractions test suite --- jest.config.js | 1 + package.json | 2 +- .../__tests__/IncrementalInteractions.tsx | 540 ++++++++++++++++++ scripts/jest-setup.ts | 6 + yarn.lock | 162 ++++-- 5 files changed, 677 insertions(+), 34 deletions(-) create mode 100644 packages/clay-core/src/table/__tests__/IncrementalInteractions.tsx create mode 100644 scripts/jest-setup.ts diff --git a/jest.config.js b/jest.config.js index a4f6c6311f..7ff4b4f847 100644 --- a/jest.config.js +++ b/jest.config.js @@ -245,6 +245,7 @@ module.exports = { moduleFileExtensions: ['ts', 'tsx', 'js', 'json'], resolver: `${__dirname}/scripts/jest-clay-lerna-resolver`, setupFiles: [`${__dirname}/scripts/setupTests.ts`, 'raf/polyfill'], + setupFilesAfterEnv: [`${__dirname}/scripts/jest-setup.ts`], testEnvironment: 'jsdom', testMatch: [ `${process.cwd()}/**/__tests__/**/*.[jt]s?(x)`, diff --git a/package.json b/package.json index de38adb6b6..1750b4c674 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@storybook/preset-scss": "^1.0.3", "@storybook/react": "^6.5.10", "@testing-library/dom": "^8.9.0", - "@testing-library/jest-dom": "^5.14.1", + "@testing-library/jest-dom": "5", "@testing-library/react": "^12.1.2", "@testing-library/user-event": "^13.2.1", "@types/d3": "^5.7.2", diff --git a/packages/clay-core/src/table/__tests__/IncrementalInteractions.tsx b/packages/clay-core/src/table/__tests__/IncrementalInteractions.tsx new file mode 100644 index 0000000000..6248967eb5 --- /dev/null +++ b/packages/clay-core/src/table/__tests__/IncrementalInteractions.tsx @@ -0,0 +1,540 @@ +/** + * SPDX-FileCopyrightText: © 2023 Liferay, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ + +import {cleanup, render} from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React, {useCallback, useMemo, useState} from 'react'; + +import {Body, Cell, Head, Row, Table} from '../../'; + +type Sorting = { + column: React.Key; + direction: 'ascending' | 'descending'; +}; + +describe('Picker incremental interactions', () => { + afterEach(cleanup); + + it('clicking on the column does the sorting', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + function ColumnSorting() { + const [sort, setSort] = useState(null); + const [items, setItems] = useState([ + {id: 1, name: 'Foo', type: 'Foo'}, + {id: 2, name: 'Bar', type: 'Bar'}, + {id: 3, name: 'Baz', type: 'Baz'}, + ]); + + const onSortChange = useCallback((sort: Sorting | null) => { + if (sort) { + setItems((items) => + items.sort((a, b) => { + let cmp = new Intl.Collator('en', { + numeric: true, + }).compare( + // @ts-ignore + a[sort.column], + // @ts-ignore + b[sort.column] + ); + + if (sort.direction === 'descending') { + cmp *= -1; + } + + return cmp; + }) + ); + } + + setSort(sort); + }, []); + + return ( + + + {(column) => ( + + {column.name} + + )} + + + + {(row) => ( + + {/** @ts-ignore */} + {(column) => {row[column.id]}} + + )} + +
+ ); + } + + const {getAllByRole} = render(); + + const [name, type] = getAllByRole('columnheader'); + + expect(name!.getAttribute('aria-sort')).toBe('none'); + expect(type!.getAttribute('aria-sort')).toBe('none'); + + const [row1Col1, , row2Col1, , row3Col1] = getAllByRole('cell'); + + expect(row1Col1!.textContent).toBe('Foo'); + expect(row2Col1!.textContent).toBe('Bar'); + expect(row3Col1!.textContent).toBe('Baz'); + + userEvent.click(name!); + + expect(name!.getAttribute('aria-sort')).toBe('ascending'); + expect(type!.getAttribute('aria-sort')).toBe('none'); + + const [newRow1Col1, , newRow2Col1, , newRow3Col1] = + getAllByRole('cell'); + + expect(newRow1Col1!.textContent).toBe('Bar'); + expect(newRow2Col1!.textContent).toBe('Baz'); + expect(newRow3Col1!.textContent).toBe('Foo'); + }); + + it('clicking again on the header column with sorting reverses the ordering', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + {id: 1, name: 'Foo', type: 'Foo'}, + {id: 2, name: 'Bar', type: 'Bar'}, + {id: 3, name: 'Baz', type: 'Baz'}, + ]; + + function ColumnSorting() { + const [sort, setSort] = useState({ + column: 'name', + direction: 'ascending', + }); + + const filteredItems = useMemo(() => { + if (!sort) { + return items; + } + + return items.sort((a, b) => { + let cmp = new Intl.Collator('en', {numeric: true}).compare( + // @ts-ignore + a[sort.column], + // @ts-ignore + b[sort.column] + ); + + if (sort.direction === 'descending') { + cmp *= -1; + } + + return cmp; + }); + }, [sort]); + + return ( + + + {(column) => ( + + {column.name} + + )} + + + + {(row) => ( + + {/** @ts-ignore */} + {(column) => {row[column.id]}} + + )} + +
+ ); + } + + const {getAllByRole} = render(); + + const [name, type] = getAllByRole('columnheader'); + + expect(name!.getAttribute('aria-sort')).toBe('ascending'); + expect(type!.getAttribute('aria-sort')).toBe('none'); + + const [row1Col1, , row2Col1, , row3Col1] = getAllByRole('cell'); + + expect(row1Col1!.textContent).toBe('Bar'); + expect(row2Col1!.textContent).toBe('Baz'); + expect(row3Col1!.textContent).toBe('Foo'); + + userEvent.click(name!); + + expect(name!.getAttribute('aria-sort')).toBe('descending'); + expect(type!.getAttribute('aria-sort')).toBe('none'); + + const [newRow1Col1, , newRow2Col1, , newRow3Col1] = + getAllByRole('cell'); + + expect(newRow1Col1!.textContent).toBe('Foo'); + expect(newRow2Col1!.textContent).toBe('Baz'); + expect(newRow3Col1!.textContent).toBe('Bar'); + }); + + it('clicking on a new header column will reset the order of the previous column', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + {id: 1, name: 'Foo', type: 'PNG'}, + {id: 2, name: 'Bar', type: 'Files'}, + {id: 3, name: 'Baz', type: 'Folder'}, + ]; + + function ColumnSorting() { + const [sort, setSort] = useState({ + column: 'name', + direction: 'ascending', + }); + + const filteredItems = useMemo(() => { + if (!sort) { + return items; + } + + return items.sort((a, b) => { + let cmp = new Intl.Collator('en', {numeric: true}).compare( + // @ts-ignore + a[sort.column], + // @ts-ignore + b[sort.column] + ); + + if (sort.direction === 'descending') { + cmp *= -1; + } + + return cmp; + }); + }, [sort]); + + return ( + + + {(column) => ( + + {column.name} + + )} + + + + {(row) => ( + + {/** @ts-ignore */} + {(column) => {row[column.id]}} + + )} + +
+ ); + } + + const {getAllByRole} = render(); + + const [name, type] = getAllByRole('columnheader'); + + expect(name!.getAttribute('aria-sort')).toBe('ascending'); + expect(type!.getAttribute('aria-sort')).toBe('none'); + + const [row1Col1, , row2Col1, , row3Col1] = getAllByRole('cell'); + + expect(row1Col1!.textContent).toBe('Bar'); + expect(row2Col1!.textContent).toBe('Baz'); + expect(row3Col1!.textContent).toBe('Foo'); + + userEvent.click(type!); + + expect(name!.getAttribute('aria-sort')).toBe('none'); + expect(type!.getAttribute('aria-sort')).toBe('ascending'); + + const [, newRow1Col2, , newRow2Col2, , newRow3Col2] = + getAllByRole('cell'); + + expect(newRow1Col2!.textContent).toBe('Files'); + expect(newRow2Col2!.textContent).toBe('Folder'); + expect(newRow3Col2!.textContent).toBe('PNG'); + }); + + describe('tree grid', () => { + it('pressing tab will move the focus to the first row', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + { + id: 1, + name: 'Foo', + type: 'PNG', + }, + {id: 2, name: 'Bar', type: 'Files'}, + { + children: [ + {id: 4, name: 'Bar', type: 'Vector'}, + {id: 5, name: 'Foo', type: 'Files'}, + ], + id: 3, + name: 'Baz', + type: 'Folder', + }, + ]; + + const {getAllByRole} = render( + + + {(column) => {column.name}} + + + + {(row) => ( + + {(column) => ( + + {/** @ts-ignore */} + {row[column.id]} + + )} + + )} + +
+ ); + + const [, firstRow] = getAllByRole('row'); + + expect(document.activeElement).not.toEqual(firstRow); + + userEvent.tab(); + + expect(firstRow).toHaveFocus(); + }); + + it('pressing tab again will move the focus to the next element outside the table', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + { + id: 1, + name: 'Foo', + type: 'PNG', + }, + {id: 2, name: 'Bar', type: 'Files'}, + { + children: [ + {id: 4, name: 'Bar', type: 'Vector'}, + {id: 5, name: 'Foo', type: 'Files'}, + ], + id: 3, + name: 'Baz', + type: 'Folder', + }, + ]; + + const {getAllByRole} = render( + + + {(column) => {column.name}} + + + + {(row) => ( + + {(column) => ( + + {/** @ts-ignore */} + {row[column.id]} + + )} + + )} + +
+ ); + + const [, firstRow] = getAllByRole('row'); + + expect(document.activeElement).not.toEqual(firstRow); + + userEvent.tab(); + + expect(firstRow).toHaveFocus(); + + userEvent.tab(); + + expect(document.body).toHaveFocus(); + }); + + describe('keyboard interaction on row', () => { + it('pressing the down arrow key moves focus to the row below', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + { + id: 1, + name: 'Foo', + type: 'PNG', + }, + {id: 2, name: 'Bar', type: 'Files'}, + { + children: [ + {id: 4, name: 'Bar', type: 'Vector'}, + {id: 5, name: 'Foo', type: 'Files'}, + ], + id: 3, + name: 'Baz', + type: 'Folder', + }, + ]; + + const {getAllByRole} = render( + + + {(column) => ( + {column.name} + )} + + + + {(row) => ( + + {(column) => ( + + {/** @ts-ignore */} + {row[column.id]} + + )} + + )} + +
+ ); + + const [, firstRow, secondRow] = getAllByRole('row'); + + expect(document.activeElement).not.toEqual(firstRow); + + userEvent.tab(); + + expect(firstRow).toHaveFocus(); + + userEvent.keyboard('{ArrowDown/}'); + + expect(secondRow).toHaveFocus(); + }); + + it('pressing the up arrow key moves focus to the row above', () => { + const columns = [ + {id: 'name', name: 'Name'}, + {id: 'type', name: 'Type'}, + ]; + + const items = [ + { + id: 1, + name: 'Foo', + type: 'PNG', + }, + {id: 2, name: 'Bar', type: 'Files'}, + { + children: [ + {id: 4, name: 'Bar', type: 'Vector'}, + {id: 5, name: 'Foo', type: 'Files'}, + ], + id: 3, + name: 'Baz', + type: 'Folder', + }, + ]; + + const {getAllByRole} = render( + + + {(column) => ( + {column.name} + )} + + + + {(row) => ( + + {(column) => ( + + {/** @ts-ignore */} + {row[column.id]} + + )} + + )} + +
+ ); + + const [, firstRow, secondRow] = getAllByRole('row'); + + expect(document.activeElement).not.toEqual(firstRow); + + userEvent.tab(); + + expect(firstRow).toHaveFocus(); + + userEvent.keyboard('{ArrowDown/}'); + + expect(secondRow).toHaveFocus(); + + userEvent.keyboard('{ArrowUp/}'); + + expect(firstRow).toHaveFocus(); + }); + + it('press the left arrow key to collpase the node with expandable', () => {}); + + it('pressing the left arrow key moves the focus to the row on the level above', () => {}); + + it('pressing the right arrow key expands the node if the node has children', () => {}); + + it('pressing the right arrow key moves the focus to the first cell', () => {}); + }); + + describe('keyboard interaction on cell', () => { + it('pressing the up arrow key moves the focus to the cell above', () => {}); + + it('pressing the down arrow key moves focus to the cell below', () => {}); + + it('pressing the right arrow key moves focus to the cell to the right', () => {}); + + it('pressing the left arrow key moves the focus to the right cell', () => {}); + + it('pressing the left arrow key in the first cell moves the focus to the row', () => {}); + }); + }); +}); diff --git a/scripts/jest-setup.ts b/scripts/jest-setup.ts new file mode 100644 index 0000000000..baec39c78a --- /dev/null +++ b/scripts/jest-setup.ts @@ -0,0 +1,6 @@ +/** + * SPDX-FileCopyrightText: © 2023 Liferay, Inc. + * SPDX-License-Identifier: BSD-3-Clause + */ + +import '@testing-library/jest-dom'; diff --git a/yarn.lock b/yarn.lock index ad90fecf2d..b0d3f81ca0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.0.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28" + integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg== + "@algolia/autocomplete-core@1.9.3": version "1.9.3" resolved "https://registry.yarnpkg.com/@algolia/autocomplete-core/-/autocomplete-core-1.9.3.tgz#1d56482a768c33aae0868c8533049e02e8961be7" @@ -1830,6 +1835,13 @@ "@types/node" "*" jest-mock "^27.5.1" +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + "@jest/fake-timers@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" @@ -1896,6 +1908,13 @@ dependencies: "@sinclair/typebox" "^0.25.16" +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + "@jest/source-map@^27.5.1": version "27.5.1" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" @@ -2011,6 +2030,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -2769,6 +2800,11 @@ resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + "@sindresorhus/is@^0.14.0": version "0.14.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" @@ -3953,16 +3989,16 @@ lz-string "^1.4.4" pretty-format "^27.0.2" -"@testing-library/jest-dom@^5.14.1": - version "5.14.1" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.14.1.tgz#8501e16f1e55a55d675fe73eecee32cdaddb9766" - integrity sha512-dfB7HVIgTNCxH22M1+KU6viG5of2ldoA5ly8Ar8xkezKHKXjRvznCdbMbqjYGgO2xjRbwnR+rR8MLUIqF3kKbQ== +"@testing-library/jest-dom@5": + version "5.17.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz#5e97c8f9a15ccf4656da00fecab505728de81e0c" + integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== dependencies: + "@adobe/css-tools" "^4.0.1" "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^4.2.2" + aria-query "^5.0.0" chalk "^3.0.0" - css "^3.0.0" css.escape "^1.5.1" dom-accessibility-api "^0.5.6" lodash "^4.17.15" @@ -4489,12 +4525,12 @@ "@types/istanbul-lib-report" "*" "@types/jest@*": - version "27.0.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.0.2.tgz#ac383c4d4aaddd29bbf2b916d8d105c304a5fcd7" - integrity sha512-4dRxkS/AFX0c5XW6IPMNOydLn2tEhNhJV7DnYK+0bjoJZ+QTmfucBlihX7aoEsh/ocYtkLC73UbnBXBXIxsULA== + version "29.5.6" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.6.tgz#f4cf7ef1b5b0bfc1aa744e41b24d9cc52533130b" + integrity sha512-/t9NnzkOpXb4Nfvg17ieHE6EeSjDS2SGSpNYfoLbUAeL/EOueU/RSdOWFpfQTXBEM7BguYW1XQ0EbM+6RlIh6w== dependencies: - jest-diff "^27.0.0" - pretty-format "^27.0.0" + expect "^29.0.0" + pretty-format "^29.0.0" "@types/jest@^26.0.0": version "26.0.24" @@ -4741,9 +4777,9 @@ integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== "@types/testing-library__jest-dom@^5.9.1": - version "5.14.1" - resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.1.tgz#014162a5cee6571819d48e999980694e2f657c3c" - integrity sha512-Gk9vaXfbzc5zCXI9eYE9BI5BNHEp4D3FWjgqBE/ePGYElLAP+KvxBcsdkwfIVvezs605oiyd/VrpiHe3Oeg+Aw== + version "5.14.9" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466" + integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== dependencies: "@types/jest" "*" @@ -8845,15 +8881,6 @@ css@^2.0.0: source-map-resolve "^0.5.2" urix "^0.1.0" -css@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" - integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== - dependencies: - inherits "^2.0.4" - source-map "^0.6.1" - source-map-resolve "^0.6.0" - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -9776,6 +9803,11 @@ diff-sequences@^27.5.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + diff@^1.0.4: version "1.4.0" resolved "https://registry.yarnpkg.com/diff/-/diff-1.4.0.tgz#7f28d2eb9ee7b15a97efd89ce63dcfdaa3ccbabf" @@ -11054,6 +11086,17 @@ expect@^27.5.1: jest-matcher-utils "^27.5.1" jest-message-util "^27.5.1" +expect@^29.0.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + exponential-backoff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" @@ -15126,7 +15169,7 @@ jest-diff@^26.0.0: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-diff@^27.0.0, jest-diff@^27.5.1: +jest-diff@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== @@ -15136,6 +15179,16 @@ jest-diff@^27.0.0, jest-diff@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + jest-docblock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" @@ -15202,6 +15255,11 @@ jest-get-type@^27.5.1: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + jest-haste-map@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" @@ -15284,6 +15342,16 @@ jest-matcher-utils@^27.5.1: jest-get-type "^27.5.1" pretty-format "^27.5.1" +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + jest-message-util@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" @@ -15299,6 +15367,21 @@ jest-message-util@^27.5.1: slash "^3.0.0" stack-utils "^2.0.3" +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + jest-mock@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" @@ -15482,6 +15565,18 @@ jest-util@^28.0.0: graceful-fs "^4.2.9" picomatch "^2.2.3" +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + jest-validate@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" @@ -20674,7 +20769,7 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: +pretty-format@^27.0.2, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== @@ -20683,6 +20778,15 @@ pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -23136,14 +23240,6 @@ source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: source-map-url "^0.4.0" urix "^0.1.0" -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - source-map-support@^0.5.16, source-map-support@^0.5.17, source-map-support@^0.5.19, source-map-support@^0.5.6, source-map-support@~0.5.10, source-map-support@~0.5.12, source-map-support@~0.5.20: version "0.5.20" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"