diff --git a/__mocks__/domPolyfills.js b/__mocks__/domPolyfills.js
new file mode 100644
index 00000000..9679ae30
--- /dev/null
+++ b/__mocks__/domPolyfills.js
@@ -0,0 +1,26 @@
+/* eslint-disable */
+
+// Polyfill for Element.prototype.getRootNode (missing in older jsdom)
+if (!Element.prototype.getRootNode) {
+ Element.prototype.getRootNode = function (options) {
+ var node = this;
+ while (node.parentNode) {
+ node = node.parentNode;
+ }
+ return node;
+ };
+}
+
+// Polyfill for Element.prototype.closest (missing in older jsdom)
+if (!Element.prototype.closest) {
+ Element.prototype.closest = function (selector) {
+ var el = this;
+ while (el) {
+ if (el.matches && el.matches(selector)) {
+ return el;
+ }
+ el = el.parentElement;
+ }
+ return null;
+ };
+}
diff --git a/before-tests.js b/before-tests.js
index aeea426c..99bb8288 100644
--- a/before-tests.js
+++ b/before-tests.js
@@ -1,9 +1,34 @@
/* eslint-env node */
-import { configure } from 'enzyme';
-import * as Adapter from 'enzyme-adapter-react-16';
-
import 'url-search-params-polyfill';
-// http://airbnb.io/enzyme/docs/installation/index.html#working-with-react-16
-configure({ adapter: new Adapter() });
+// Suppress act() warnings only for async markdown rendering (SyncMarkdownView /
+// QuickStartMarkdownView). Other act warnings still surface so new tests stay honest.
+const originalError = console.error;
+
+const isMarkdownActWarning = (...args) => {
+ const message = args
+ .map((a) => {
+ if (typeof a === 'string') {
+ return a;
+ }
+ if (a instanceof Error && typeof a.message === 'string') {
+ return a.message;
+ }
+ return '';
+ })
+ .join('\n');
+ if (!message.includes('was not wrapped in act(')) {
+ return false;
+ }
+ return (
+ message.includes('SyncMarkdownView') || message.includes('QuickStartMarkdownView')
+ );
+};
+
+console.error = (...args) => {
+ if (isMarkdownActWarning(...args)) {
+ return;
+ }
+ originalError.call(console, ...args);
+};
diff --git a/jest-setup-framework.js b/jest-setup-framework.js
new file mode 100644
index 00000000..09326480
--- /dev/null
+++ b/jest-setup-framework.js
@@ -0,0 +1 @@
+require('@testing-library/jest-dom');
diff --git a/package.json b/package.json
index 564baeb7..e090f746 100644
--- a/package.json
+++ b/package.json
@@ -102,7 +102,8 @@
"./__mocks__/serverFlags.js",
"./__mocks__/mutationObserver.js",
"./__mocks__/websocket.js",
- "./before-tests.js"
+ "./before-tests.js",
+ "./__mocks__/domPolyfills.js"
],
"coverageDirectory": "__coverage__",
"coverageReporters": [
@@ -115,7 +116,8 @@
"src/**/*.{js,jsx,ts,tsx}",
"!**/node_modules/**"
],
- "resolver": "./jest-resolver.js"
+ "resolver": "./jest-resolver.js",
+ "setupTestFrameworkScriptFile": "./jest-setup-framework.js"
},
"engines": {
"node": ">=18.0.0"
diff --git a/packages/module/package.json b/packages/module/package.json
index 93a5c4e7..f3803074 100644
--- a/packages/module/package.json
+++ b/packages/module/package.json
@@ -66,10 +66,9 @@
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^11.1.0",
+ "@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^13.4.0",
"@types/dompurify": "^3.0.5",
- "@types/enzyme": "^3.10.7",
- "@types/enzyme-adapter-react-16": "^1.0.6",
"@types/history": "^4.7.8",
"@types/node": "^14.14.35",
"@types/react": "^18.2.79",
@@ -77,9 +76,6 @@
"clean-css-cli": "^4.3.0",
"concat-files": "^0.1.1",
"dart-sass": "^1.25.0",
- "enzyme": "^3.7.0",
- "enzyme-adapter-react-16": "^1.15.5",
- "enzyme-to-json": "^3.6.1",
"monaco-editor": "0.34.1",
"node-sass-glob-importer": "^5.3.2",
"prettier": "^2.8.8",
diff --git a/packages/module/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx b/packages/module/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx
index f727f517..bbd534d1 100644
--- a/packages/module/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx
+++ b/packages/module/src/ConsoleShared/src/components/markdown-extensions/__tests__/MarkdownCopyClipboard.spec.tsx
@@ -1,24 +1,38 @@
-import { shallow } from 'enzyme';
-import MarkdownCopyClipboard, { CopyClipboard } from '../MarkdownCopyClipboard';
+import { render } from '@testing-library/react';
+import {
+ QuickStartContext,
+ QuickStartContextDefaults,
+} from '@quickstarts/utils/quick-start-context';
+import MarkdownCopyClipboard from '../MarkdownCopyClipboard';
+import { MARKDOWN_COPY_BUTTON_ID } from '../const';
import { htmlDocumentForCopyClipboard } from './test-data';
+const contextValues = {
+ ...QuickStartContextDefaults,
+ getResource: (key: string) => key,
+};
+
describe('MarkdownCopyClipboard', () => {
beforeAll(() => {
document.body.innerHTML = htmlDocumentForCopyClipboard;
});
+
it('should render null if no element is found', () => {
- const wrapper = shallow(
- ,
+ const { container } = render(
+
+
+ ,
);
- expect(wrapper.isEmptyRender()).toBe(true);
- expect(wrapper.find(CopyClipboard).exists()).toBe(false);
+ expect(container.firstChild).toBeNull();
});
- it('should render null if no element is found', () => {
- const wrapper = shallow(
- ,
+ it('should render copy targets when rootSelector matches buttons in the document', () => {
+ render(
+
+
+ ,
);
- expect(wrapper.isEmptyRender()).toBe(false);
- expect(wrapper.find(CopyClipboard).exists()).toBe(true);
+ const elements = document.querySelectorAll(`#copy-markdown-1 [${MARKDOWN_COPY_BUTTON_ID}]`);
+ expect(elements).toHaveLength(2);
});
});
diff --git a/packages/module/src/catalog/__tests__/QuickStartCatalog.spec.tsx b/packages/module/src/catalog/__tests__/QuickStartCatalog.spec.tsx
index 52517168..1a7f4006 100644
--- a/packages/module/src/catalog/__tests__/QuickStartCatalog.spec.tsx
+++ b/packages/module/src/catalog/__tests__/QuickStartCatalog.spec.tsx
@@ -1,34 +1,39 @@
-import { Gallery, Card } from '@patternfly/react-core';
-import { shallow } from 'enzyme';
-import { EmptyBox } from '@console/internal/components/utils';
+import { render, screen, waitFor } from '@testing-library/react';
import { getQuickStarts } from '../../data/test-utils';
-import { QuickStartCatalogPage } from '../../QuickStartCatalogPage';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import QuickStartCatalog from '../QuickStartCatalog';
-jest.mock('@console/shared', () => {
- const ActualShared = require.requireActual('@console/shared');
- return {
- ...ActualShared,
- useQueryParams: () => new Map(),
- };
-});
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ allQuickStartStates: {},
+ getResource: (key: string) => key,
+};
+
+const renderWithContext = (props: any) =>
+ render(
+
+
+ ,
+ );
describe('QuickStartCatalog', () => {
- it('should load an emptybox if no QS exist', () => {
- const QuickStartCatalogProps = { quickStarts: [], onClick: jest.fn() };
- const QuickStartCatalogWrapper = shallow();
- expect(QuickStartCatalogWrapper.find(EmptyBox).exists()).toBeTruthy();
+ it('should render an empty state if no QS exist', () => {
+ renderWithContext({ quickStarts: [] });
+ // When no quickstarts, the catalog renders no cards
+ expect(screen.queryByRole('article')).not.toBeInTheDocument();
});
- it('should load a gallery if QS exist', () => {
- const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
- const QuickStartCatalogWrapper = shallow();
- expect(QuickStartCatalogWrapper.find(Gallery).exists()).toBeTruthy();
- });
- xit('should load galleryItems equal to the number of QS', () => {
- const QuickStartCatalogProps = { quickStarts: getQuickStarts(), onClick: jest.fn() };
- const QuickStartCatalogWrapper = shallow();
- const galleryItems = QuickStartCatalogWrapper.find(Card);
- expect(galleryItems.exists()).toBeTruthy();
- expect(galleryItems.length).toEqual(getQuickStarts().length);
+
+ it('should load a gallery if QS exist', async () => {
+ const quickStarts = getQuickStarts();
+ renderWithContext({ quickStarts });
+ // Each tile exposes the quick start display name as the title control (link-styled button)
+ await waitFor(() => {
+ quickStarts.forEach((qs) => {
+ expect(
+ screen.getByRole('button', { name: qs.spec.displayName }),
+ ).toBeInTheDocument();
+ });
+ });
});
});
diff --git a/packages/module/src/catalog/__tests__/QuickStartTile.spec.tsx b/packages/module/src/catalog/__tests__/QuickStartTile.spec.tsx
index 885fcf22..02059579 100644
--- a/packages/module/src/catalog/__tests__/QuickStartTile.spec.tsx
+++ b/packages/module/src/catalog/__tests__/QuickStartTile.spec.tsx
@@ -1,37 +1,56 @@
-import { Card } from '@patternfly/react-core';
-import { shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { getQuickStarts } from '../../data/test-utils';
import { QuickStartStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import QuickStartTile from '../QuickStartTile';
-describe('QuickStartTile', () => {
- const quickstarts = getQuickStarts();
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ setActiveQuickStart: jest.fn(),
+ getResource: (key: string) => key,
+};
+
+const quickstarts = getQuickStarts();
- it('should load proper catalog tile without featured property', () => {
- const wrapper = shallow(
- ,
- );
- const catalogTile = wrapper.find(Card);
- expect(catalogTile.exists()).toBeTruthy();
- expect(catalogTile.hasClass('pf-m-current')).toBe(false);
+const renderWithContext = (props: any) =>
+ render(
+
+
+ ,
+ );
+
+describe('QuickStartTile', () => {
+ it('should load proper catalog tile without featured property', async () => {
+ const quickStart = quickstarts[0];
+ renderWithContext({
+ quickStart,
+ status: QuickStartStatus.NOT_STARTED,
+ onClick: jest.fn(),
+ isActive: false,
+ });
+ await waitFor(() => {
+ expect(
+ screen.getByRole('button', { name: quickStart.spec.displayName }),
+ ).toBeInTheDocument();
+ });
+ // Status label is omitted for not-started tiles
+ expect(screen.queryByText('In progress')).not.toBeInTheDocument();
});
- it('should load proper catalog tile with featured property', () => {
- const wrapper = shallow(
- ,
- );
- const catalogTile = wrapper.find(Card);
- expect(catalogTile.exists()).toBeTruthy();
- expect(catalogTile.hasClass('pf-m-current')).toBe(true);
+ it('should load proper catalog tile with featured property', async () => {
+ const quickStart = quickstarts[1];
+ renderWithContext({
+ quickStart,
+ status: QuickStartStatus.IN_PROGRESS,
+ onClick: jest.fn(),
+ isActive: true,
+ });
+ await waitFor(() => {
+ expect(
+ screen.getByRole('button', { name: quickStart.spec.displayName }),
+ ).toBeInTheDocument();
+ });
+ expect(screen.getByText('In progress')).toBeInTheDocument();
});
});
diff --git a/packages/module/src/catalog/__tests__/QuickStartTileDescription.spec.tsx b/packages/module/src/catalog/__tests__/QuickStartTileDescription.spec.tsx
index 004f19e0..67cb1f73 100644
--- a/packages/module/src/catalog/__tests__/QuickStartTileDescription.spec.tsx
+++ b/packages/module/src/catalog/__tests__/QuickStartTileDescription.spec.tsx
@@ -1,43 +1,44 @@
-import { Popover } from '@patternfly/react-core';
-import { shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { getQuickStarts } from '../../data/test-utils';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import QuickStartTileDescription from '../QuickStartTileDescription';
-jest.mock('react', () => {
- const ActualReact = require.requireActual('react');
- return {
- ...ActualReact,
- useContext: () => jest.fn(),
- };
-});
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ startQuickStart: jest.fn(),
+ restartQuickStart: jest.fn(),
+ getResource: (key: string) => key,
+};
-xdescribe('QuickStartCatalog', () => {
- beforeEach(() => {
- spyOn(React, 'useContext').and.returnValue({
- activeQuickStartID: '',
- startQuickStart: () => {},
- restartQuickStart: () => {},
- getResource: (key) => `quickstart~${key}`,
- });
- });
+const renderWithContext = (props: any) =>
+ render(
+
+
+ ,
+ );
- it('should show prerequisites only if provided', () => {
- // this quick start does not have prereqs
+describe('QuickStartTileDescription', () => {
+ it('should show prerequisites only if provided', async () => {
const quickStart = getQuickStarts()[0].spec;
- const QuickStartTileDescriptionWrapper = shallow(
- ,
- );
- expect(QuickStartTileDescriptionWrapper.find(Text)).toHaveLength(0);
+ renderWithContext({ description: quickStart.description });
+ await waitFor(() => {
+ expect(
+ screen.queryByRole('button', { name: 'Show prerequisites' }),
+ ).not.toBeInTheDocument();
+ });
});
- it('shoould render prerequisites inside a popover', () => {
+ it('should render prerequisites trigger when prerequisite list is non-empty', async () => {
const quickStart = getQuickStarts()[2].spec;
- const QuickStartTileDescriptionWrapper = shallow(
- ,
- );
- expect(QuickStartTileDescriptionWrapper.find(Popover)).toHaveLength(1);
+ renderWithContext({
+ description: quickStart.description,
+ prerequisites: quickStart.prerequisites,
+ });
+ await waitFor(() => {
+ expect(
+ screen.getByRole('button', { name: 'Show prerequisites' }),
+ ).toBeInTheDocument();
+ });
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartConclusion.spec.tsx b/packages/module/src/controller/__tests__/QuickStartConclusion.spec.tsx
index 08eb34e3..85746c68 100644
--- a/packages/module/src/controller/__tests__/QuickStartConclusion.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartConclusion.spec.tsx
@@ -1,25 +1,19 @@
-import { ComponentProps } from 'react';
-import { Button } from '@patternfly/react-core';
-import { ShallowWrapper, shallow } from 'enzyme';
+import { render, waitFor } from '@testing-library/react';
import { allQuickStarts } from '../../data/quick-start-test-data';
-import QuickStartMarkdownView from '../../QuickStartMarkdownView';
import { QuickStartTaskStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import { getQuickStartByName } from '../../utils/quick-start-utils';
import QuickStartConclusion from '../QuickStartConclusion';
-jest.mock('react', () => {
- const ActualReact = require.requireActual('react');
- return {
- ...ActualReact,
- useContext: () => jest.fn(),
- };
-});
-
-const i18nNS = 'quickstart';
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ startQuickStart: jest.fn(),
+ restartQuickStart: jest.fn(),
+ getResource: (key: string) => key,
+};
-type QuickStartConclusionProps = ComponentProps;
-let wrapper: ShallowWrapper;
-const props: QuickStartConclusionProps = {
+const defaultProps = {
tasks: getQuickStartByName('explore-pipelines', allQuickStarts).spec.tasks,
allTaskStatuses: [
QuickStartTaskStatus.SUCCESS,
@@ -31,52 +25,56 @@ const props: QuickStartConclusionProps = {
onQuickStartChange: jest.fn(),
};
-xdescribe('QuickStartConclusion', () => {
+const renderWithContext = (props = {}) =>
+ render(
+
+
+ ,
+ );
+
+describe('QuickStartConclusion', () => {
beforeEach(() => {
- spyOn(React, 'useContext').and.returnValue({
- activeQuickStartID: '',
- startQuickStart: () => {},
- restartQuickStart: () => {},
- getResource: (key) => `quickstart~${key}`,
- });
- wrapper = shallow();
+ jest.clearAllMocks();
});
- it('should render conclusion if there are no failed tasks', () => {
- expect(wrapper.find(QuickStartMarkdownView).first().props().content).toEqual('conclusion');
+ it('should render conclusion if there are no failed tasks', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/conclusion/);
+ });
});
- it('should render link for next quick start if nextQuickStart prop is available and there are no failed tasks', () => {
- wrapper = shallow(
- ,
- );
- expect(wrapper.find(Button).at(0).props().children).toEqual(
- `${i18nNS}~Start Installing the Pipelines Operator quick start`,
- );
+ it('should render link for next quick start if nextQuickStart prop is available and there are no failed tasks', async () => {
+ renderWithContext({
+ nextQuickStarts: [getQuickStartByName('explore-pipelines', allQuickStarts)],
+ });
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(
+ /Start Installing the Pipelines Operator quick start/,
+ );
+ });
});
- it('should not render link for next quick start if nextQuickStart props is not available', () => {
- expect(wrapper.find(Button).length).toBe(0);
+ it('should not render link for next quick start if nextQuickStart props is not available', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/conclusion/);
+ });
+ expect(document.body.textContent).not.toMatch(/Start .* quick start/);
});
- it('should not render conclusion, link for next quick start and should render message for retrying if there are failed tasks', () => {
- wrapper = shallow(
- ,
- );
- expect(wrapper.find(QuickStartMarkdownView).first().props().content).toEqual(
- `${i18nNS}~One or more verifications did not pass during this quick start. Revisit the tasks or the help links, and then try again.`,
- );
- expect(wrapper.find(Button).length).toBe(0);
+ it('should not render conclusion and should render message for retrying if there are failed tasks', async () => {
+ renderWithContext({
+ nextQuickStarts: [getQuickStartByName('explore-pipelines', allQuickStarts)],
+ allTaskStatuses: [
+ QuickStartTaskStatus.FAILED,
+ QuickStartTaskStatus.SUCCESS,
+ QuickStartTaskStatus.SUCCESS,
+ ],
+ });
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/One or more verifications did not pass/);
+ });
+ expect(document.body.textContent).not.toMatch(/Start .* quick start/);
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartContent.spec.tsx b/packages/module/src/controller/__tests__/QuickStartContent.spec.tsx
index 2b81ecd5..e433caa2 100644
--- a/packages/module/src/controller/__tests__/QuickStartContent.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartContent.spec.tsx
@@ -1,52 +1,71 @@
-import { ComponentProps } from 'react';
-import { ShallowWrapper, shallow } from 'enzyme';
+import { render, waitFor } from '@testing-library/react';
import { allQuickStarts } from '../../data/quick-start-test-data';
import { QuickStartTaskStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import { getQuickStartByName } from '../../utils/quick-start-utils';
-import QuickStartConclusion from '../QuickStartConclusion';
import QuickStartContent from '../QuickStartContent';
-import QuickStartIntroduction from '../QuickStartIntroduction';
-import QuickStartTasks from '../QuickStartTasks';
-type QuickStartContentProps = ComponentProps;
+const contextValues = {
+ ...QuickStartContextDefaults,
+ getResource: (key: string) => key,
+};
-let wrapper: ShallowWrapper;
+const quickStart = getQuickStartByName('explore-serverless', allQuickStarts);
+const totalTasks = quickStart.spec.tasks.length;
-const props: QuickStartContentProps = {
- quickStart: getQuickStartByName('explore-serverless', allQuickStarts),
- allTaskStatuses: [
- QuickStartTaskStatus.INIT,
- QuickStartTaskStatus.INIT,
- QuickStartTaskStatus.INIT,
- ],
+const defaultProps = {
+ quickStart,
+ allTaskStatuses: [QuickStartTaskStatus.INIT, QuickStartTaskStatus.INIT],
taskNumber: -1,
onTaskReview: jest.fn(),
onTaskSelect: jest.fn(),
onQuickStartChange: jest.fn(),
};
+const renderWithContext = (props = {}) =>
+ render(
+
+
+ ,
+ );
+
describe('QuickStartContent', () => {
beforeEach(() => {
- wrapper = shallow();
+ jest.clearAllMocks();
});
- it('should render QuickStartIntroduction when the tour status is Not Started', () => {
- expect(wrapper.find(QuickStartIntroduction).length).toBe(1);
- expect(wrapper.find(QuickStartTasks).length).toBe(0);
- expect(wrapper.find(QuickStartConclusion).length).toBe(0);
+ it('should render QuickStartIntroduction when the tour status is Not Started', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(
+ new RegExp(`In this quick start, you will complete ${totalTasks} task`),
+ );
+ });
+ expect(document.body.textContent).not.toMatch(/Your Serverless Operator is ready/);
});
- it('should render QuickStartTasks when the tour is In Progress', () => {
- wrapper = shallow();
- expect(wrapper.find(QuickStartIntroduction).length).toBe(0);
- expect(wrapper.find(QuickStartTasks).length).toBe(1);
- expect(wrapper.find(QuickStartConclusion).length).toBe(0);
+ it('should render QuickStartTasks when the tour is In Progress', async () => {
+ // taskNumber is 0-based index into spec.tasks; first task visible and active when non-INIT
+ renderWithContext({
+ taskNumber: 0,
+ allTaskStatuses: [QuickStartTaskStatus.VISITED, QuickStartTaskStatus.INIT],
+ });
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/Install the OpenShift Serverless Operator/);
+ });
+ expect(document.body.textContent).not.toMatch(
+ new RegExp(`In this quick start, you will complete ${totalTasks} task`),
+ );
});
- it('should render QuickStartConclusion when the tour is Complete', () => {
- wrapper = shallow();
- expect(wrapper.find(QuickStartIntroduction).length).toBe(0);
- expect(wrapper.find(QuickStartTasks).length).toBe(0);
- expect(wrapper.find(QuickStartConclusion).length).toBe(1);
+ it('should render QuickStartConclusion when the tour is Complete', async () => {
+ renderWithContext({ taskNumber: totalTasks });
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/Your Serverless Operator is ready/);
+ });
+ // Conclusion still lists task headers; intro copy is not shown
+ expect(document.body.textContent).not.toMatch(
+ /In this quick start, you will complete \d+ task/,
+ );
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartFooter.spec.tsx b/packages/module/src/controller/__tests__/QuickStartFooter.spec.tsx
index 80b938d1..855b1114 100644
--- a/packages/module/src/controller/__tests__/QuickStartFooter.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartFooter.spec.tsx
@@ -1,103 +1,87 @@
-import * as React from 'react';
-import { Button } from '@patternfly/react-core';
-import { shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { QuickStartStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import QuickStartFooter from '../QuickStartFooter';
-jest.mock('react', () => {
- const ActualReact = require.requireActual('react');
- return {
- ...ActualReact,
- useContext: () => jest.fn(),
- };
-});
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ startQuickStart: jest.fn(),
+ restartQuickStart: jest.fn(),
+ getResource: (key: string) => key,
+};
-describe('QuickStartFooter', () => {
- type QuickStartFooterProps = React.ComponentProps;
- let quickStartFooterProps: QuickStartFooterProps;
- beforeEach(() => {
- spyOn(React, 'useContext').and.returnValue({
- activeQuickStartID: '',
- startQuickStart: () => {},
- restartQuickStart: () => {},
- getResource: (key) => `quickstart~${key}`,
- });
- });
+const renderWithContext = (props: any) =>
+ render(
+
+
+ ,
+ );
- it('should load Start button for not started tours', () => {
- quickStartFooterProps = {
+describe('QuickStartFooter', () => {
+ it('should load Start button for not started tours', async () => {
+ renderWithContext({
status: QuickStartStatus.NOT_STARTED,
footerClass: 'test',
quickStartId: 'test-quickstart',
- onNext: () => null,
- onBack: () => null,
+ onNext: jest.fn(),
+ onBack: jest.fn(),
totalTasks: 4,
taskNumber: -1,
- };
-
- const quickStartFooterWrapper = shallow();
- const footerButtons = quickStartFooterWrapper.find(Button);
- expect(footerButtons.exists()).toBeTruthy();
- expect(footerButtons.length).toEqual(1);
- expect(footerButtons.at(0).childAt(0).text()).toBe('quickstart~Start');
+ });
+ await waitFor(() => {
+ expect(screen.getByRole('button', { name: 'Start' })).toBeInTheDocument();
+ });
+ expect(screen.queryByRole('button', { name: 'Back' })).not.toBeInTheDocument();
});
- it('should load Continue and Restart buttons for in progress tours at into page', () => {
- quickStartFooterProps = {
+ it('should load Continue and Restart buttons for in progress tours at intro page', async () => {
+ renderWithContext({
status: QuickStartStatus.IN_PROGRESS,
footerClass: 'test',
quickStartId: 'test-quickstart',
- onNext: () => null,
- onBack: () => null,
+ onNext: jest.fn(),
+ onBack: jest.fn(),
totalTasks: 4,
taskNumber: -1,
- };
-
- const quickStartFooterWrapper = shallow();
- const footerButtons = quickStartFooterWrapper.find(Button);
- expect(footerButtons.exists()).toBeTruthy();
- expect(footerButtons.length).toEqual(2);
- expect(footerButtons.at(0).childAt(0).text()).toBe('quickstart~Continue');
- expect(footerButtons.at(1).childAt(0).text()).toBe('quickstart~Restart');
+ });
+ await waitFor(() => {
+ expect(screen.getByRole('button', { name: 'Continue' })).toBeInTheDocument();
+ });
+ expect(screen.getByRole('button', { name: 'Restart' })).toBeInTheDocument();
});
- it('should load Next and Back buttons, and Restart link for in progress tours in task page', () => {
- quickStartFooterProps = {
+ it('should load Next, Back, and Restart buttons for in progress tours in task page', async () => {
+ renderWithContext({
status: QuickStartStatus.IN_PROGRESS,
footerClass: 'test',
quickStartId: 'test-quickstart',
- onNext: () => null,
- onBack: () => null,
+ onNext: jest.fn(),
+ onBack: jest.fn(),
totalTasks: 4,
taskNumber: 2,
- };
-
- const quickStartFooterWrapper = shallow();
- const footerButtons = quickStartFooterWrapper.find(Button);
- expect(footerButtons.exists()).toBeTruthy();
- expect(footerButtons.length).toEqual(3);
- expect(footerButtons.at(0).childAt(0).text()).toBe('quickstart~Next');
- expect(footerButtons.at(1).childAt(0).text()).toBe('quickstart~Back');
- expect(footerButtons.at(2).childAt(0).text()).toBe('quickstart~Restart');
+ });
+ await waitFor(() => {
+ expect(screen.getByRole('button', { name: 'Next' })).toBeInTheDocument();
+ });
+ expect(screen.getByRole('button', { name: 'Back' })).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: 'Restart' })).toBeInTheDocument();
});
- it('should load Close, Back and Restart buttons for completed tours in conclusion page', () => {
- quickStartFooterProps = {
+ it('should load Close, Back and Restart buttons for completed tours in conclusion page', async () => {
+ renderWithContext({
status: QuickStartStatus.COMPLETE,
footerClass: 'test',
quickStartId: 'test-quickstart',
- onNext: () => null,
- onBack: () => null,
+ onNext: jest.fn(),
+ onBack: jest.fn(),
totalTasks: 4,
taskNumber: 4,
- };
-
- const quickStartFooterWrapper = shallow();
- const footerButtons = quickStartFooterWrapper.find(Button);
- expect(footerButtons.exists()).toBeTruthy();
- expect(footerButtons.length).toEqual(3);
- expect(footerButtons.at(0).childAt(0).text()).toBe('quickstart~Close');
- expect(footerButtons.at(1).childAt(0).text()).toBe('quickstart~Back');
- expect(footerButtons.at(2).childAt(0).text()).toBe('quickstart~Restart');
+ });
+ await waitFor(() => {
+ expect(screen.getByRole('button', { name: 'Close' })).toBeInTheDocument();
+ });
+ expect(screen.getByRole('button', { name: 'Back' })).toBeInTheDocument();
+ expect(screen.getByRole('button', { name: 'Restart' })).toBeInTheDocument();
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartTaskHeader.spec.tsx b/packages/module/src/controller/__tests__/QuickStartTaskHeader.spec.tsx
index e344d612..d28a21cd 100644
--- a/packages/module/src/controller/__tests__/QuickStartTaskHeader.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartTaskHeader.spec.tsx
@@ -1,43 +1,47 @@
-import { ComponentProps } from 'react';
-import { Title, WizardNavItem } from '@patternfly/react-core';
-import { ShallowWrapper, shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { QuickStartTaskStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import QuickStartTaskHeader from '../QuickStartTaskHeader';
-type QuickStartTaskHeaderProps = ComponentProps;
-let wrapper: ShallowWrapper;
-const props: QuickStartTaskHeaderProps = {
+const contextValues = {
+ ...QuickStartContextDefaults,
+ getResource: (key: string) => key,
+};
+
+const defaultProps = {
title: 'title',
taskIndex: 1,
subtitle: 'subtitle',
taskStatus: QuickStartTaskStatus.INIT,
- size: 'lg',
+ size: 'lg' as const,
isActiveTask: true,
onTaskSelect: jest.fn(),
};
+const renderWithContext = (props = {}) =>
+ render(
+
+
+ ,
+ );
+
describe('QuickStartTaskHeader', () => {
- beforeEach(() => {
- // DOMPurify.addHook = jest.fn();
- wrapper = shallow();
+ it('should render subtitle for active task', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ expect(
+ screen.getByRole('button', {
+ name: new RegExp(`${defaultProps.title}.*${defaultProps.subtitle}`),
+ }),
+ ).toBeInTheDocument();
+ });
});
- it('should render subtitle for active task', () => {
- expect(wrapper.find(WizardNavItem).dive().find(Title).length).toBe(1);
- expect(
- wrapper.find(WizardNavItem).dive().find('[data-test-id="quick-start-task-subtitle"]').props()
- .children,
- ).toEqual(props.subtitle);
- });
- it('should not render subtitle if task is not active', () => {
- wrapper = shallow();
- expect(wrapper.find(WizardNavItem).dive().find(Title).length).toBe(1);
- expect(
- wrapper
- .find(WizardNavItem)
- .dive()
- .find('[data-test-id="quick-start-task-subtitle"]')
- .exists(),
- ).toBe(false);
+ it('should not render subtitle if task is not active', async () => {
+ renderWithContext({ isActiveTask: false });
+ await waitFor(() => {
+ expect(screen.getByRole('button', { name: defaultProps.title })).toBeInTheDocument();
+ });
+ expect(screen.queryByText(defaultProps.subtitle)).not.toBeInTheDocument();
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartTaskReview.spec.tsx b/packages/module/src/controller/__tests__/QuickStartTaskReview.spec.tsx
index 48c91328..125c9ba5 100644
--- a/packages/module/src/controller/__tests__/QuickStartTaskReview.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartTaskReview.spec.tsx
@@ -1,42 +1,57 @@
-import { Alert } from '@patternfly/react-core';
-import { ShallowWrapper, shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { allQuickStarts } from '../../data/quick-start-test-data';
-import QuickStartMarkdownView from '../../QuickStartMarkdownView';
import { QuickStartTaskStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import { getQuickStartByName } from '../../utils/quick-start-utils';
import QuickStartTaskReview from '../QuickStartTaskReview';
-import { ComponentProps } from 'react';
-type QuickStartTaskReviewProps = ComponentProps;
-let wrapper: ShallowWrapper;
-const props: QuickStartTaskReviewProps = {
- review: getQuickStartByName('explore-serverless', allQuickStarts).spec.tasks[0].review,
+const contextValues = {
+ ...QuickStartContextDefaults,
+ getResource: (key: string) => key,
+};
+
+const review = getQuickStartByName('explore-serverless', allQuickStarts).spec.tasks[0].review;
+
+const defaultProps = {
+ review,
taskStatus: QuickStartTaskStatus.REVIEW,
onTaskReview: jest.fn(),
};
-describe('QuickStartTaskReview', () => {
- it('should render alert with info variant when task status is review', () => {
- wrapper = shallow();
- expect(wrapper.find(Alert).props().variant).toBe('info');
- });
+const renderWithContext = (props = {}) =>
+ render(
+
+
+ ,
+ );
- it('should render alert with success variant when task status is success', () => {
- props.taskStatus = QuickStartTaskStatus.SUCCESS;
- wrapper = shallow();
- expect(wrapper.find(Alert).props().variant).toBe('success');
+describe('QuickStartTaskReview', () => {
+ it('should render review prompt with yes/no while task is in review', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ expect(screen.getByRole('alert')).toBeInTheDocument();
+ });
+ expect(screen.getByText('Check your work')).toBeInTheDocument();
+ expect(screen.getByRole('radio', { name: 'Yes' })).not.toBeChecked();
+ expect(screen.getByRole('radio', { name: 'No' })).not.toBeChecked();
});
- it('should render alert with danger variant when task status is failed', () => {
- props.taskStatus = QuickStartTaskStatus.FAILED;
- wrapper = shallow();
- expect(wrapper.find(Alert).props().variant).toBe('danger');
+ it('should mark Yes selected when task status is success', async () => {
+ renderWithContext({ taskStatus: QuickStartTaskStatus.SUCCESS });
+ await waitFor(() => {
+ expect(screen.getByRole('radio', { name: 'Yes' })).toBeChecked();
+ });
+ expect(screen.getByRole('radio', { name: 'No' })).not.toBeChecked();
});
- it('should render task help in markdown when task status is failed', () => {
- wrapper = shallow();
- expect(wrapper.find(QuickStartMarkdownView).at(1).props().content).toEqual(
- props.review.failedTaskHelp,
- );
+ it('should mark No selected and show failed-task help when task status is failed', async () => {
+ renderWithContext({ taskStatus: QuickStartTaskStatus.FAILED });
+ await waitFor(() => {
+ expect(screen.getByRole('radio', { name: 'No' })).toBeChecked();
+ });
+ expect(screen.getByRole('radio', { name: 'Yes' })).not.toBeChecked();
+ await waitFor(() => {
+ expect(document.body.textContent).toMatch(/This task is incomplete/);
+ });
});
});
diff --git a/packages/module/src/controller/__tests__/QuickStartTasks.spec.tsx b/packages/module/src/controller/__tests__/QuickStartTasks.spec.tsx
index cc8f6b21..649f3a4d 100644
--- a/packages/module/src/controller/__tests__/QuickStartTasks.spec.tsx
+++ b/packages/module/src/controller/__tests__/QuickStartTasks.spec.tsx
@@ -1,25 +1,22 @@
-import * as React from 'react';
-import { ShallowWrapper, shallow } from 'enzyme';
+import { render, screen, waitFor } from '@testing-library/react';
import { allQuickStarts } from '../../data/quick-start-test-data';
-import QuickStartMarkdownView from '../../QuickStartMarkdownView';
import { QuickStartTaskStatus } from '../../utils/quick-start-types';
+import { QuickStartContext, QuickStartContextDefaults } from '../../utils/quick-start-context';
import { getQuickStartByName } from '../../utils/quick-start-utils';
-import TaskHeader from '../QuickStartTaskHeader';
-import QuickStartTaskReview from '../QuickStartTaskReview';
-import QuickStartTask from '../QuickStartTasks';
+import QuickStartTasks from '../QuickStartTasks';
-jest.mock('react', () => {
- const ActualReact = require.requireActual('react');
- return {
- ...ActualReact,
- useContext: () => jest.fn(),
- };
-});
+const contextValues = {
+ ...QuickStartContextDefaults,
+ activeQuickStartID: '',
+ startQuickStart: jest.fn(),
+ restartQuickStart: jest.fn(),
+ getResource: (key: string) => key,
+};
+
+const tasks = getQuickStartByName('monitor-sampleapp', allQuickStarts).spec.tasks;
-type QuickStartTaskProps = React.ComponentProps;
-let wrapper: ShallowWrapper;
-const props: QuickStartTaskProps = {
- tasks: getQuickStartByName('monitor-sampleapp', allQuickStarts).spec.tasks,
+const defaultProps = {
+ tasks,
allTaskStatuses: [
QuickStartTaskStatus.SUCCESS,
QuickStartTaskStatus.INIT,
@@ -30,49 +27,54 @@ const props: QuickStartTaskProps = {
onTaskSelect: jest.fn(),
};
+const renderWithContext = (props = {}) =>
+ render(
+
+
+ ,
+ );
+
describe('QuickStartTasks', () => {
beforeEach(() => {
- spyOn(React, 'useContext').and.returnValue({
- activeQuickStartID: '',
- startQuickStart: () => {},
- restartQuickStart: () => {},
- getResource: (key) => `quickstart~${key}`,
- });
- wrapper = shallow();
+ jest.clearAllMocks();
});
- it('should render correct number of tasks based on currentTaskIndex', () => {
- expect(wrapper.find(TaskHeader).length).toBe(1);
+ it('should render correct number of tasks based on currentTaskIndex', async () => {
+ renderWithContext();
+ await waitFor(() => {
+ // Only non-INIT tasks are rendered; first task is SUCCESS so it shows
+ const taskHeaders = screen.getAllByRole('listitem');
+ expect(taskHeaders).toHaveLength(1);
+ });
});
- it('should render SyncMarkdownView with description if a task is active', () => {
- wrapper = shallow(
- ,
- );
- expect(wrapper.find(QuickStartMarkdownView).at(0).props().content).toEqual(
- props.tasks[2].description,
- );
+ it('should render description if a task is active', async () => {
+ renderWithContext({
+ allTaskStatuses: [
+ QuickStartTaskStatus.SUCCESS,
+ QuickStartTaskStatus.FAILED,
+ QuickStartTaskStatus.VISITED,
+ ],
+ taskNumber: 2,
+ });
+ await waitFor(() => {
+ // All 3 tasks are non-INIT, so all render
+ const taskHeaders = screen.getAllByRole('listitem');
+ expect(taskHeaders).toHaveLength(3);
+ });
});
- it('should render review when task is active and in Review state', () => {
- wrapper = shallow(
- ,
- );
- expect(wrapper.find(QuickStartTaskReview).exists()).toBe(true);
+ it('should render review when task is active and in Review state', async () => {
+ renderWithContext({
+ allTaskStatuses: [
+ QuickStartTaskStatus.SUCCESS,
+ QuickStartTaskStatus.REVIEW,
+ QuickStartTaskStatus.INIT,
+ ],
+ });
+ await waitFor(() => {
+ // "Check your work" is the alert title for QuickStartTaskReview
+ expect(screen.getByText('Check your work')).toBeInTheDocument();
+ });
});
});
diff --git a/test-setup.js b/test-setup.js
index 82edfc9e..41b3e374 100644
--- a/test-setup.js
+++ b/test-setup.js
@@ -1,4 +1,2 @@
-import { configure } from 'enzyme';
-import Adapter from 'enzyme-adapter-react-16';
-
-configure({ adapter: new Adapter() });
+// This file is intentionally left minimal.
+// enzyme setup has been removed in favor of @testing-library/react.
diff --git a/yarn.lock b/yarn.lock
index b90f479d..ac8cbdc0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -5,6 +5,13 @@ __metadata:
version: 8
cacheKey: 10c0
+"@adobe/css-tools@npm:^4.4.0":
+ version: 4.4.4
+ resolution: "@adobe/css-tools@npm:4.4.4"
+ checksum: 10c0/8f3e6cfaa5e6286e6f05de01d91d060425be2ebaef490881f5fe6da8bbdb336835c5d373ea337b0c3b0a1af4be048ba18780f0f6021d30809b4545922a7e13d9
+ languageName: node
+ linkType: hard
+
"@ampproject/remapping@npm:^2.2.0":
version: 2.3.0
resolution: "@ampproject/remapping@npm:2.3.0"
@@ -2596,10 +2603,9 @@ __metadata:
"@rollup/plugin-commonjs": "npm:^17.0.0"
"@rollup/plugin-json": "npm:^4.1.0"
"@rollup/plugin-node-resolve": "npm:^11.1.0"
+ "@testing-library/jest-dom": "npm:^6.9.1"
"@testing-library/react": "npm:^13.4.0"
"@types/dompurify": "npm:^3.0.5"
- "@types/enzyme": "npm:^3.10.7"
- "@types/enzyme-adapter-react-16": "npm:^1.0.6"
"@types/history": "npm:^4.7.8"
"@types/node": "npm:^14.14.35"
"@types/react": "npm:^18.2.79"
@@ -2608,9 +2614,6 @@ __metadata:
concat-files: "npm:^0.1.1"
dart-sass: "npm:^1.25.0"
dompurify: "npm:^3.3.2"
- enzyme: "npm:^3.7.0"
- enzyme-adapter-react-16: "npm:^1.15.5"
- enzyme-to-json: "npm:^3.6.1"
history: "npm:^5.0.0"
monaco-editor: "npm:0.34.1"
node-sass-glob-importer: "npm:^5.3.2"
@@ -2901,6 +2904,20 @@ __metadata:
languageName: node
linkType: hard
+"@testing-library/jest-dom@npm:^6.9.1":
+ version: 6.9.1
+ resolution: "@testing-library/jest-dom@npm:6.9.1"
+ dependencies:
+ "@adobe/css-tools": "npm:^4.4.0"
+ aria-query: "npm:^5.0.0"
+ css.escape: "npm:^1.5.1"
+ dom-accessibility-api: "npm:^0.6.3"
+ picocolors: "npm:^1.1.1"
+ redent: "npm:^3.0.0"
+ checksum: 10c0/4291ebd2f0f38d14cefac142c56c337941775a5807e2a3d6f1a14c2fbd6be76a18e498ed189e95bedc97d9e8cf1738049bc76c85b5bc5e23fae7c9e10f7b3a12
+ languageName: node
+ linkType: hard
+
"@testing-library/react@npm:^13.4.0":
version: 13.4.0
resolution: "@testing-library/react@npm:13.4.0"
@@ -2955,15 +2972,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/cheerio@npm:*, @types/cheerio@npm:^0.22.22":
- version: 0.22.30
- resolution: "@types/cheerio@npm:0.22.30"
- dependencies:
- "@types/node": "npm:*"
- checksum: 10c0/b5ade8b6936a176a7dcbc8b5ca458d8c349f97ebaebc7a897df09aa3ffb7e9194c39e494feb786c1d34143dcbabbc0247b7f71bf20a5173c5366dd0a362b2436
- languageName: node
- linkType: hard
-
"@types/connect-history-api-fallback@npm:^1.5.4":
version: 1.5.4
resolution: "@types/connect-history-api-fallback@npm:1.5.4"
@@ -3061,25 +3069,6 @@ __metadata:
languageName: node
linkType: hard
-"@types/enzyme-adapter-react-16@npm:^1.0.6":
- version: 1.0.6
- resolution: "@types/enzyme-adapter-react-16@npm:1.0.6"
- dependencies:
- "@types/enzyme": "npm:*"
- checksum: 10c0/032bde12b93b0c1215213e8a87defe916cfa6d5508d8480de933c224ebc9f3346c67a6cd6494ee83b6b8c53eeef499838002156e87f4d865cd933509ec0d3a89
- languageName: node
- linkType: hard
-
-"@types/enzyme@npm:*, @types/enzyme@npm:^3.10.7":
- version: 3.10.9
- resolution: "@types/enzyme@npm:3.10.9"
- dependencies:
- "@types/cheerio": "npm:*"
- "@types/react": "npm:*"
- checksum: 10c0/29f8de84a4bcbc8e4b22913fa5ee05958f6dd53ec597096459fcc3b0fb24c7b322e3250bc81408be31c3466c2637eb7a36d973fa4e5d7548c9d0225c9bc2fcbf
- languageName: node
- linkType: hard
-
"@types/eslint-scope@npm:^3.7.7":
version: 3.7.7
resolution: "@types/eslint-scope@npm:3.7.7"
@@ -4548,6 +4537,13 @@ __metadata:
languageName: node
linkType: hard
+"aria-query@npm:^5.0.0":
+ version: 5.3.2
+ resolution: "aria-query@npm:5.3.2"
+ checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e
+ languageName: node
+ linkType: hard
+
"arr-diff@npm:^2.0.0":
version: 2.0.0
resolution: "arr-diff@npm:2.0.0"
@@ -4677,19 +4673,6 @@ __metadata:
languageName: node
linkType: hard
-"array.prototype.filter@npm:^1.0.0":
- version: 1.0.0
- resolution: "array.prototype.filter@npm:1.0.0"
- dependencies:
- call-bind: "npm:^1.0.2"
- define-properties: "npm:^1.1.3"
- es-abstract: "npm:^1.18.0"
- es-array-method-boxes-properly: "npm:^1.0.0"
- is-string: "npm:^1.0.5"
- checksum: 10c0/67c971f61527c47da77ad26ef2bb06a1bb71f62032598fd5566cf2adf13bf24f140eefbb1ee8d1987a4e869699b6b20387f9bc109ff245e7a491593e656cce49
- languageName: node
- linkType: hard
-
"array.prototype.find@npm:^2.1.1":
version: 2.1.1
resolution: "array.prototype.find@npm:2.1.1"
@@ -4700,7 +4683,7 @@ __metadata:
languageName: node
linkType: hard
-"array.prototype.flat@npm:^1.2.3, array.prototype.flat@npm:^1.3.1":
+"array.prototype.flat@npm:^1.3.1":
version: 1.3.1
resolution: "array.prototype.flat@npm:1.3.1"
dependencies:
@@ -6250,19 +6233,6 @@ __metadata:
languageName: node
linkType: hard
-"cheerio-select@npm:^1.5.0":
- version: 1.5.0
- resolution: "cheerio-select@npm:1.5.0"
- dependencies:
- css-select: "npm:^4.1.3"
- css-what: "npm:^5.0.1"
- domelementtype: "npm:^2.2.0"
- domhandler: "npm:^4.2.0"
- domutils: "npm:^2.7.0"
- checksum: 10c0/851c8f9bb74823e63547ad5a39b7e301aac88950081ecf5a253e0a8c47a813f7f3428903d35c6ad78a0518b0e9c31dd0c863296f60ab4d53363612c564f863c3
- languageName: node
- linkType: hard
-
"cheerio-select@npm:^2.1.0":
version: 2.1.0
resolution: "cheerio-select@npm:2.1.0"
@@ -6296,21 +6266,6 @@ __metadata:
languageName: node
linkType: hard
-"cheerio@npm:^1.0.0-rc.3":
- version: 1.0.0-rc.10
- resolution: "cheerio@npm:1.0.0-rc.10"
- dependencies:
- cheerio-select: "npm:^1.5.0"
- dom-serializer: "npm:^1.3.2"
- domhandler: "npm:^4.2.0"
- htmlparser2: "npm:^6.1.0"
- parse5: "npm:^6.0.1"
- parse5-htmlparser2-tree-adapter: "npm:^6.0.1"
- tslib: "npm:^2.2.0"
- checksum: 10c0/2bb0fae8b1941949f506ddc4df75e3c2d0e5cc6c05478f918dd64a4d2c5282ec84b243890f6a809052a8eb6214641084922c07f726b5287b5dba114b10e52cb9
- languageName: node
- linkType: hard
-
"chokidar@npm:4.0.0":
version: 4.0.0
resolution: "chokidar@npm:4.0.0"
@@ -7408,7 +7363,7 @@ __metadata:
languageName: node
linkType: hard
-"css-what@npm:^5.0.0, css-what@npm:^5.0.1":
+"css-what@npm:^5.0.0":
version: 5.0.1
resolution: "css-what@npm:5.0.1"
checksum: 10c0/a1bec4996f51e416a28efe3b003a7fd33ff0d6a91cb97be483c647df1c499e0ae6a84849c01ae87a323fc45fdb77509da773dc9a8ebab652f0a81ac47ebbf80c
@@ -7422,6 +7377,13 @@ __metadata:
languageName: node
linkType: hard
+"css.escape@npm:^1.5.1":
+ version: 1.5.1
+ resolution: "css.escape@npm:1.5.1"
+ checksum: 10c0/5e09035e5bf6c2c422b40c6df2eb1529657a17df37fda5d0433d722609527ab98090baf25b13970ca754079a0f3161dd3dfc0e743563ded8cfa0749d861c1525
+ languageName: node
+ linkType: hard
+
"cssesc@npm:^3.0.0":
version: 3.0.0
resolution: "cssesc@npm:3.0.0"
@@ -8096,13 +8058,6 @@ __metadata:
languageName: node
linkType: hard
-"discontinuous-range@npm:1.0.0":
- version: 1.0.0
- resolution: "discontinuous-range@npm:1.0.0"
- checksum: 10c0/487b105f83c1cc528e25e65d3c4b73958ec79769b7bd0e264414702a23a7e2b282c72982b4bef4af29fcab53f47816c3f0a5c40d85a99a490f4bc35b83dc00f8
- languageName: node
- linkType: hard
-
"dns-packet@npm:^5.2.2":
version: 5.6.0
resolution: "dns-packet@npm:5.6.0"
@@ -8137,6 +8092,13 @@ __metadata:
languageName: node
linkType: hard
+"dom-accessibility-api@npm:^0.6.3":
+ version: 0.6.3
+ resolution: "dom-accessibility-api@npm:0.6.3"
+ checksum: 10c0/10bee5aa514b2a9a37c87cd81268db607a2e933a050074abc2f6fa3da9080ebed206a320cbc123567f2c3087d22292853bdfdceaffdd4334ffe2af9510b29360
+ languageName: node
+ linkType: hard
+
"dom-converter@npm:^0.2.0":
version: 0.2.0
resolution: "dom-converter@npm:0.2.0"
@@ -8146,7 +8108,7 @@ __metadata:
languageName: node
linkType: hard
-"dom-serializer@npm:^1.0.1, dom-serializer@npm:^1.3.2":
+"dom-serializer@npm:^1.0.1":
version: 1.3.2
resolution: "dom-serializer@npm:1.3.2"
dependencies:
@@ -8221,7 +8183,7 @@ __metadata:
languageName: node
linkType: hard
-"domutils@npm:^2.5.2, domutils@npm:^2.6.0, domutils@npm:^2.7.0":
+"domutils@npm:^2.5.2, domutils@npm:^2.6.0":
version: 2.7.0
resolution: "domutils@npm:2.7.0"
dependencies:
@@ -8490,7 +8452,7 @@ __metadata:
languageName: node
linkType: hard
-"enzyme-adapter-react-16@npm:^1.15.5, enzyme-adapter-react-16@npm:^1.15.6":
+"enzyme-adapter-react-16@npm:^1.15.6":
version: 1.15.6
resolution: "enzyme-adapter-react-16@npm:1.15.6"
dependencies:
@@ -8528,7 +8490,7 @@ __metadata:
languageName: node
linkType: hard
-"enzyme-shallow-equal@npm:^1.0.1, enzyme-shallow-equal@npm:^1.0.4":
+"enzyme-shallow-equal@npm:^1.0.4":
version: 1.0.4
resolution: "enzyme-shallow-equal@npm:1.0.4"
dependencies:
@@ -8538,49 +8500,6 @@ __metadata:
languageName: node
linkType: hard
-"enzyme-to-json@npm:^3.6.1":
- version: 3.6.2
- resolution: "enzyme-to-json@npm:3.6.2"
- dependencies:
- "@types/cheerio": "npm:^0.22.22"
- lodash: "npm:^4.17.21"
- react-is: "npm:^16.12.0"
- peerDependencies:
- enzyme: ^3.4.0
- checksum: 10c0/90fba5bbcfda37f456d483a46d7a077123fb65f74e59bab1e137e30c84f5b3149114efae7f9736f7ea49dd9171299645816bc5f6649b16a19d47c8bd1d6d8065
- languageName: node
- linkType: hard
-
-"enzyme@npm:^3.7.0":
- version: 3.11.0
- resolution: "enzyme@npm:3.11.0"
- dependencies:
- array.prototype.flat: "npm:^1.2.3"
- cheerio: "npm:^1.0.0-rc.3"
- enzyme-shallow-equal: "npm:^1.0.1"
- function.prototype.name: "npm:^1.1.2"
- has: "npm:^1.0.3"
- html-element-map: "npm:^1.2.0"
- is-boolean-object: "npm:^1.0.1"
- is-callable: "npm:^1.1.5"
- is-number-object: "npm:^1.0.4"
- is-regex: "npm:^1.0.5"
- is-string: "npm:^1.0.5"
- is-subset: "npm:^0.1.1"
- lodash.escape: "npm:^4.0.1"
- lodash.isequal: "npm:^4.5.0"
- object-inspect: "npm:^1.7.0"
- object-is: "npm:^1.0.2"
- object.assign: "npm:^4.1.0"
- object.entries: "npm:^1.1.1"
- object.values: "npm:^1.1.1"
- raf: "npm:^3.4.1"
- rst-selector-parser: "npm:^2.2.3"
- string.prototype.trim: "npm:^1.2.1"
- checksum: 10c0/14081671ed77924026036ed4edb1168cdac826aadd1ab2c77a5b7fdda625589dc5a4062cd0c65ec88add3ea3f7c0ebcbf3178bcf84b43335a175d8c71a016809
- languageName: node
- linkType: hard
-
"eol@npm:^0.9.1":
version: 0.9.1
resolution: "eol@npm:0.9.1"
@@ -8629,7 +8548,7 @@ __metadata:
languageName: node
linkType: hard
-"es-abstract@npm:^1.17.4, es-abstract@npm:^1.18.0, es-abstract@npm:^1.19.0, es-abstract@npm:^1.20.4":
+"es-abstract@npm:^1.17.4, es-abstract@npm:^1.19.0, es-abstract@npm:^1.20.4":
version: 1.21.2
resolution: "es-abstract@npm:1.21.2"
dependencies:
@@ -8671,13 +8590,6 @@ __metadata:
languageName: node
linkType: hard
-"es-array-method-boxes-properly@npm:^1.0.0":
- version: 1.0.0
- resolution: "es-array-method-boxes-properly@npm:1.0.0"
- checksum: 10c0/4b7617d3fbd460d6f051f684ceca6cf7e88e6724671d9480388d3ecdd72119ddaa46ca31f2c69c5426a82e4b3091c1e81867c71dcdc453565cd90005ff2c382d
- languageName: node
- linkType: hard
-
"es-define-property@npm:^1.0.1":
version: 1.0.1
resolution: "es-define-property@npm:1.0.1"
@@ -11620,16 +11532,6 @@ __metadata:
languageName: node
linkType: hard
-"html-element-map@npm:^1.2.0":
- version: 1.3.1
- resolution: "html-element-map@npm:1.3.1"
- dependencies:
- array.prototype.filter: "npm:^1.0.0"
- call-bind: "npm:^1.0.2"
- checksum: 10c0/5ae8b37546601864eb41363a05871a896df36e59714607b1386a114d45f1c6b6cd1633d6fb09e09e5ee0f1c909d6b9c1bbca831333b8eef936312f61b1b5ecb8
- languageName: node
- linkType: hard
-
"html-encoding-sniffer@npm:^1.0.1":
version: 1.0.2
resolution: "html-encoding-sniffer@npm:1.0.2"
@@ -12430,7 +12332,7 @@ __metadata:
languageName: node
linkType: hard
-"is-boolean-object@npm:^1.0.1, is-boolean-object@npm:^1.1.0":
+"is-boolean-object@npm:^1.1.0":
version: 1.1.1
resolution: "is-boolean-object@npm:1.1.1"
dependencies:
@@ -12462,7 +12364,7 @@ __metadata:
languageName: node
linkType: hard
-"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.1.5, is-callable@npm:^1.2.7":
+"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7":
version: 1.2.7
resolution: "is-callable@npm:1.2.7"
checksum: 10c0/ceebaeb9d92e8adee604076971dd6000d38d6afc40bb843ea8e45c5579b57671c3f3b50d7f04869618242c6cee08d1b67806a8cb8edaaaf7c0748b3720d6066f
@@ -12924,7 +12826,7 @@ __metadata:
languageName: node
linkType: hard
-"is-regex@npm:^1.0.5, is-regex@npm:^1.1.0, is-regex@npm:^1.1.4":
+"is-regex@npm:^1.1.0, is-regex@npm:^1.1.4":
version: 1.1.4
resolution: "is-regex@npm:1.1.4"
dependencies:
@@ -12987,13 +12889,6 @@ __metadata:
languageName: node
linkType: hard
-"is-subset@npm:^0.1.1":
- version: 0.1.1
- resolution: "is-subset@npm:0.1.1"
- checksum: 10c0/d8125598ab9077a76684e18726fb915f5cea7a7358ed0c6ff723f4484d71a0a9981ee5aae06c44de99cfdef0fefce37438c6257ab129e53c82045ea0c2acdebf
- languageName: node
- linkType: hard
-
"is-symbol@npm:^1.0.2, is-symbol@npm:^1.0.3":
version: 1.0.4
resolution: "is-symbol@npm:1.0.4"
@@ -14569,27 +14464,6 @@ __metadata:
languageName: node
linkType: hard
-"lodash.escape@npm:^4.0.1":
- version: 4.0.1
- resolution: "lodash.escape@npm:4.0.1"
- checksum: 10c0/90ade409cec05b6869090476952fdfb84d4d87b1ff4a0e03ebd590f980d9a1248d93ba14579f10d80c6429e4d6af13ba137c28db64cae6dadb71442e54a3ad2b
- languageName: node
- linkType: hard
-
-"lodash.flattendeep@npm:^4.4.0":
- version: 4.4.0
- resolution: "lodash.flattendeep@npm:4.4.0"
- checksum: 10c0/83cb80754b921fb4ed2c222b91a82b2524f3bdc60c3ae91e00688bd4bf1bcc28b8a2cc250e11fdc1b6da3a2de09e57008e13f15a209cafdd4f9163d047f97544
- languageName: node
- linkType: hard
-
-"lodash.isequal@npm:^4.5.0":
- version: 4.5.0
- resolution: "lodash.isequal@npm:4.5.0"
- checksum: 10c0/dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f
- languageName: node
- linkType: hard
-
"lodash.merge@npm:^4.6.2":
version: 4.6.2
resolution: "lodash.merge@npm:4.6.2"
@@ -15624,13 +15498,6 @@ __metadata:
languageName: node
linkType: hard
-"moo@npm:^0.5.0":
- version: 0.5.1
- resolution: "moo@npm:0.5.1"
- checksum: 10c0/2a4f2557463c3a71cf5bf06362d13ed3de065fa366e72dbc8ae1af500b7077a3d66e5c893ce24d643a81dcbf46f966f45e749ab303ccc0c56fbce3c15e941b34
- languageName: node
- linkType: hard
-
"morgan@npm:^1.6.1":
version: 1.10.0
resolution: "morgan@npm:1.10.0"
@@ -15783,23 +15650,6 @@ __metadata:
languageName: node
linkType: hard
-"nearley@npm:^2.7.10":
- version: 2.20.1
- resolution: "nearley@npm:2.20.1"
- dependencies:
- commander: "npm:^2.19.0"
- moo: "npm:^0.5.0"
- railroad-diagrams: "npm:^1.0.0"
- randexp: "npm:0.4.6"
- bin:
- nearley-railroad: bin/nearley-railroad.js
- nearley-test: bin/nearley-test.js
- nearley-unparse: bin/nearley-unparse.js
- nearleyc: bin/nearleyc.js
- checksum: 10c0/d25e1fd40b19c53a0ada6a688670f4a39063fd9553ab62885e81a82927d51572ce47193b946afa3d85efa608ba2c68f433c421f69b854bfb7f599eacb5fae37e
- languageName: node
- linkType: hard
-
"negotiator@npm:0.6.3":
version: 0.6.3
resolution: "negotiator@npm:0.6.3"
@@ -16176,7 +16026,7 @@ __metadata:
languageName: node
linkType: hard
-"object-inspect@npm:^1.12.3, object-inspect@npm:^1.7.0, object-inspect@npm:^1.9.0":
+"object-inspect@npm:^1.12.3, object-inspect@npm:^1.9.0":
version: 1.12.3
resolution: "object-inspect@npm:1.12.3"
checksum: 10c0/752bb5f4dc595e214157ea8f442adb77bdb850ace762b078d151d8b6486331ab12364997a89ee6509be1023b15adf2b3774437a7105f8a5043dfda11ed622411
@@ -16190,7 +16040,7 @@ __metadata:
languageName: node
linkType: hard
-"object-is@npm:^1.0.2, object-is@npm:^1.1.2, object-is@npm:^1.1.5":
+"object-is@npm:^1.1.2, object-is@npm:^1.1.5":
version: 1.1.5
resolution: "object-is@npm:1.1.5"
dependencies:
@@ -16228,7 +16078,7 @@ __metadata:
languageName: node
linkType: hard
-"object.entries@npm:^1.1.1, object.entries@npm:^1.1.2, object.entries@npm:^1.1.5, object.entries@npm:^1.1.6":
+"object.entries@npm:^1.1.2, object.entries@npm:^1.1.5, object.entries@npm:^1.1.6":
version: 1.1.6
resolution: "object.entries@npm:1.1.6"
dependencies:
@@ -16279,7 +16129,7 @@ __metadata:
languageName: node
linkType: hard
-"object.values@npm:^1.1.1, object.values@npm:^1.1.2, object.values@npm:^1.1.6":
+"object.values@npm:^1.1.2, object.values@npm:^1.1.6":
version: 1.1.6
resolution: "object.values@npm:1.1.6"
dependencies:
@@ -16858,15 +16708,6 @@ __metadata:
languageName: node
linkType: hard
-"parse5-htmlparser2-tree-adapter@npm:^6.0.1":
- version: 6.0.1
- resolution: "parse5-htmlparser2-tree-adapter@npm:6.0.1"
- dependencies:
- parse5: "npm:^6.0.1"
- checksum: 10c0/dfa5960e2aaf125707e19a4b1bc333de49232eba5a6ffffb95d313a7d6087c3b7a274b58bee8d3bd41bdf150638815d1d601a42bbf2a0345208c3c35b1279556
- languageName: node
- linkType: hard
-
"parse5-htmlparser2-tree-adapter@npm:^7.0.0":
version: 7.1.0
resolution: "parse5-htmlparser2-tree-adapter@npm:7.1.0"
@@ -16886,7 +16727,7 @@ __metadata:
languageName: node
linkType: hard
-"parse5@npm:6.0.1, parse5@npm:^6.0.1":
+"parse5@npm:6.0.1":
version: 6.0.1
resolution: "parse5@npm:6.0.1"
checksum: 10c0/595821edc094ecbcfb9ddcb46a3e1fe3a718540f8320eff08b8cf6742a5114cce2d46d45f95c26191c11b184dcaf4e2960abcd9c5ed9eb9393ac9a37efcfdecb
@@ -17866,32 +17707,6 @@ __metadata:
languageName: node
linkType: hard
-"raf@npm:^3.4.1":
- version: 3.4.1
- resolution: "raf@npm:3.4.1"
- dependencies:
- performance-now: "npm:^2.1.0"
- checksum: 10c0/337f0853c9e6a77647b0f499beedafea5d6facfb9f2d488a624f88b03df2be72b8a0e7f9118a3ff811377d534912039a3311815700d2b6d2313f82f736f9eb6e
- languageName: node
- linkType: hard
-
-"railroad-diagrams@npm:^1.0.0":
- version: 1.0.0
- resolution: "railroad-diagrams@npm:1.0.0"
- checksum: 10c0/81bf8f86870a69fb9ed243102db9ad6416d09c4cb83964490d44717690e07dd982f671503236a1f8af28f4cb79d5d7a87613930f10ac08defa845ceb6764e364
- languageName: node
- linkType: hard
-
-"randexp@npm:0.4.6":
- version: 0.4.6
- resolution: "randexp@npm:0.4.6"
- dependencies:
- discontinuous-range: "npm:1.0.0"
- ret: "npm:~0.1.10"
- checksum: 10c0/14ee14b6d7f5ce69609b51cc914fb7a7c82ad337820a141c5f762c5ad1fe868f5191ea6e82359aee019b625ee1359486628fa833909d12c3b5dd9571908c3345
- languageName: node
- linkType: hard
-
"randomatic@npm:^3.0.0":
version: 3.1.1
resolution: "randomatic@npm:3.1.1"
@@ -18080,7 +17895,7 @@ __metadata:
languageName: node
linkType: hard
-"react-is@npm:^16.12.0, react-is@npm:^16.13.1, react-is@npm:^16.8.6":
+"react-is@npm:^16.13.1, react-is@npm:^16.8.6":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
@@ -18295,6 +18110,16 @@ __metadata:
languageName: node
linkType: hard
+"redent@npm:^3.0.0":
+ version: 3.0.0
+ resolution: "redent@npm:3.0.0"
+ dependencies:
+ indent-string: "npm:^4.0.0"
+ strip-indent: "npm:^3.0.0"
+ checksum: 10c0/d64a6b5c0b50eb3ddce3ab770f866658a2b9998c678f797919ceb1b586bab9259b311407280bd80b804e2a7c7539b19238ae6a2a20c843f1a7fcff21d48c2eae
+ languageName: node
+ linkType: hard
+
"reduce-flatten@npm:^1.0.1":
version: 1.0.1
resolution: "reduce-flatten@npm:1.0.1"
@@ -19102,16 +18927,6 @@ __metadata:
languageName: node
linkType: hard
-"rst-selector-parser@npm:^2.2.3":
- version: 2.2.3
- resolution: "rst-selector-parser@npm:2.2.3"
- dependencies:
- lodash.flattendeep: "npm:^4.4.0"
- nearley: "npm:^2.7.10"
- checksum: 10c0/b631aca2cb451fbde8d78dbc9a9479f20f1f40565cd8eb63773cb6e2a395ed87b392291986b84c2c7da68b70084e3469fbe958261300a10dff41c87fa3bc58aa
- languageName: node
- linkType: hard
-
"rsvp@npm:^3.3.3":
version: 3.6.2
resolution: "rsvp@npm:3.6.2"
@@ -20548,7 +20363,7 @@ __metadata:
languageName: node
linkType: hard
-"string.prototype.trim@npm:^1.2.1, string.prototype.trim@npm:^1.2.7":
+"string.prototype.trim@npm:^1.2.7":
version: 1.2.7
resolution: "string.prototype.trim@npm:1.2.7"
dependencies:
@@ -21485,7 +21300,7 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.2.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0":
+"tslib@npm:^2.0.1, tslib@npm:^2.0.3, tslib@npm:^2.1.0, tslib@npm:^2.4.0, tslib@npm:^2.5.0":
version: 2.5.2
resolution: "tslib@npm:2.5.2"
checksum: 10c0/34fa100454708fa8acb7afc2b07d80e0332081e2075ddd912ba959af3b24f969663dac6d602961e57371dc05683badb83b3186ada92c4631ec777e02e3aab608