diff --git a/packages/kbn-test-jest-helpers2/index.ts b/packages/kbn-test-jest-helpers2/index.ts index 9cd76405a01b..7e514b179b9c 100644 --- a/packages/kbn-test-jest-helpers2/index.ts +++ b/packages/kbn-test-jest-helpers2/index.ts @@ -6,4 +6,4 @@ * Side Public License, v 1. */ -export * from './src/enzyme_helpers'; +export * from './src/rtl_helpers'; diff --git a/packages/kbn-test-jest-helpers2/src/enzyme_helpers.tsx b/packages/kbn-test-jest-helpers2/src/enzyme_helpers.tsx deleted file mode 100644 index 9f4e691600c0..000000000000 --- a/packages/kbn-test-jest-helpers2/src/enzyme_helpers.tsx +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -/** - * Components using the @kbn/i18n module require access to the intl context. - * This is not available when mounting single components in Enzyme. - * These helper functions aim to address that and wrap a valid, - * intl context around them. - */ - -import { I18nProvider, InjectedIntl, intlShape, __IntlProvider } from '@kbn/i18n-react'; -import { mount, ReactWrapper, render, shallow } from 'enzyme'; -import React, { ComponentType, ReactElement, ValidationMap } from 'react'; -import { act as reactAct } from 'react-dom/test-utils'; - -// Use fake component to extract `intl` property to use in tests. -const { intl } = ( - mount( - -
-
- ).find('IntlProvider') as ReactWrapper<{}, {}, __IntlProvider> -) - .instance() - .getChildContext(); - -function getOptions(context = {}, childContextTypes = {}, props = {}) { - return { - context: { - ...context, - intl, - }, - childContextTypes: { - ...childContextTypes, - intl: intlShape, - }, - ...props, - }; -} - -/** - * When using @kbn/i18n `injectI18n` on components, props.intl is required. - */ -// This function is exported solely to fix the types output in TS 4.5.2, likely a bug -// Otherwise, InjectedIntl is missing from the output -export function nodeWithIntlProp( - node: ReactElement -): ReactElement { - return React.cloneElement(node, { intl }); -} - -/** - * Creates the wrapper instance using shallow with provided intl object into context - * - * @param node The React element or cheerio wrapper - * @param options properties to pass into shallow wrapper - * @return The wrapper instance around the rendered output with intl object in context - */ -export function shallowWithIntl( - node: ReactElement, - { - context, - childContextTypes, - ...props - }: { - context?: any; - childContextTypes?: ValidationMap; - } = {} -) { - const options = getOptions(context, childContextTypes, props); - - return shallow(nodeWithIntlProp(node), options); -} - -/** - * Creates the wrapper instance using mount with provided intl object into context - * - * @param node The React element or cheerio wrapper - * @param options properties to pass into mount wrapper - * @return The wrapper instance around the rendered output with intl object in context - */ -export function mountWithIntl( - node: ReactElement, - { - context, - childContextTypes, - ...props - }: { - attachTo?: HTMLElement; - context?: any; - childContextTypes?: ValidationMap; - wrappingComponent?: ComponentType | undefined; - wrappingComponentProps?: {} | undefined; - } = {} -) { - const options = getOptions(context, childContextTypes, props); - - return mount(nodeWithIntlProp(node), options); -} - -/** - * Creates the wrapper instance using render with provided intl object into context - * - * @param node The React element or cheerio wrapper - * @param options properties to pass into render wrapper - * @return The wrapper instance around the rendered output with intl object in context - */ -export function renderWithIntl( - node: ReactElement, - { - context, - childContextTypes, - ...props - }: { - context?: any; - childContextTypes?: ValidationMap; - } = {} -): any { - const options = getOptions(context, childContextTypes, props); - - return render(nodeWithIntlProp(node), options); -} - -/** - * A wrapper object to provide access to the state of a hook under test and to - * enable interaction with that hook. - */ -interface ReactHookWrapper { - /* Ensures that async React operations have settled before and after the - * given actor callback is called. The actor callback arguments provide easy - * access to the last hook value and allow for updating the arguments passed - * to the hook body to trigger reevaluation. - */ - act: (actor: (lastHookValue: HookValue, setArgs: (args: Args) => void) => void) => void; - /* The enzyme wrapper around the test component. */ - component: ReactWrapper; - /* The most recent value return the by test harness of the hook. */ - getLastHookValue: () => HookValue; - /* The jest Mock function that receives the hook values for introspection. */ - hookValueCallback: jest.Mock; -} - -/** - * Allows for execution of hooks inside of a test component which records the - * returned values. - * - * @param body A function that calls the hook and returns data derived from it - * @param WrapperComponent A component that, if provided, will be wrapped - * around the test component. This can be useful to provide context values. - * @return {ReactHookWrapper} An object providing access to the hook state and - * functions to interact with it. - */ -export const mountHook = ( - body: (args: Args) => HookValue, - WrapperComponent?: React.ComponentType, - initialArgs: Args = {} as Args -): ReactHookWrapper => { - const hookValueCallback = jest.fn(); - let component!: ReactWrapper; - - const act: ReactHookWrapper['act'] = (actor) => { - reactAct(() => { - actor(getLastHookValue(), (args: Args) => component.setProps(args)); - component.update(); - }); - }; - - const getLastHookValue = () => { - const calls = hookValueCallback.mock.calls; - if (calls.length <= 0) { - throw Error('No recent hook value present.'); - } - return calls[calls.length - 1][0]; - }; - - const HookComponent = (props: Args) => { - hookValueCallback(body(props)); - return null; - }; - const TestComponent: React.FunctionComponent = (args) => - WrapperComponent ? ( - - - - ) : ( - - ); - - reactAct(() => { - component = mount(); - }); - - return { - act, - component, - getLastHookValue, - hookValueCallback, - }; -}; - -export function shallowWithI18nProvider(child: ReactElement) { - const wrapped = shallow({child}); - const name = typeof child.type === 'string' ? child.type : child.type.name; - return wrapped.find(name).dive(); -} - -export function mountWithI18nProvider(child: ReactElement) { - const wrapped = mount({child}); - const name = typeof child.type === 'string' ? child.type : child.type.name; - return wrapped.find(name); -} diff --git a/packages/kbn-test-jest-helpers2/src/rtl_helpers.tsx b/packages/kbn-test-jest-helpers2/src/rtl_helpers.tsx new file mode 100644 index 000000000000..0d586f2cbaef --- /dev/null +++ b/packages/kbn-test-jest-helpers2/src/rtl_helpers.tsx @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { screen, within } from '@testing-library/react'; + +export const getButtonGroupInputValue = (testId: string) => () => { + const buttonGroup = screen.getByTestId(testId); + const options = within(buttonGroup).getAllByRole('radio'); + const checkedOption = options.find((option) => option.getAttribute('checked') === ''); + if (checkedOption == null) { + throw new Error(`No checked option found in button group ${testId}`); + } + return checkedOption.nextSibling; +}; diff --git a/packages/kbn-test-jest-helpers2/tsconfig.json b/packages/kbn-test-jest-helpers2/tsconfig.json index 99630e68c5b9..9f1c443c02ee 100644 --- a/packages/kbn-test-jest-helpers2/tsconfig.json +++ b/packages/kbn-test-jest-helpers2/tsconfig.json @@ -8,11 +8,7 @@ "**/*.ts", "**/*.tsx", ], - "kbn_references": [ - "@kbn/i18n-react", - "@kbn/axe-config", - "@kbn/shared-ux-router", - ], + "kbn_references": [], "exclude": [ "target/**/*", ], diff --git a/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.test.tsx b/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.test.tsx index 682a21501dd7..cd50d2963315 100644 --- a/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.test.tsx +++ b/x-pack/plugins/lens/public/visualizations/datatable/components/toolbar.test.tsx @@ -6,7 +6,7 @@ */ import React from 'react'; -import { getButtonGroupInputValue } from '@kbn/rtl-eui'; +import { getButtonGroupInputValue } from '@kbn/test-jest-helpers2'; import { DataTableToolbar } from './toolbar'; import { DatatableVisualizationState } from '../visualization'; import { FramePublicAPI, VisualizationToolbarProps } from '../../../types'; @@ -55,16 +55,6 @@ describe('datatable toolbar', () => { userEvent.click(screen.getByRole('button', { name: /visual options/i })); }; - const getButtonGroupInputValue = (testId: string) => () => { - const buttonGroup = screen.getByTestId(testId); - const options = within(buttonGroup).getAllByRole('radio'); - const checkedOption = options.find((option) => option.getAttribute('checked') === ''); - if (checkedOption == null) { - throw new Error(`No checked option found in button group ${testId}`); - } - return checkedOption.nextSibling; - }; - const selectOptionFromButtonGroup = (testId: string) => (optionName: string | RegExp) => { const buttonGroup = screen.getByTestId(testId); const option = within(buttonGroup).getByRole('radio', { name: optionName }); @@ -81,7 +71,6 @@ describe('datatable toolbar', () => { return { ...rtlRender, - togglePopover, getRowHeightValue: getButtonGroupInputValue(ROW_HEIGHT_SETTINGS_TEST_ID), getRowHeightCustomValue: () => getNumberInput(ROW_HEIGHT_SETTINGS_TEST_ID), diff --git a/x-pack/plugins/lens/tsconfig.json b/x-pack/plugins/lens/tsconfig.json index dd714b72c998..f6aa6bec0284 100644 --- a/x-pack/plugins/lens/tsconfig.json +++ b/x-pack/plugins/lens/tsconfig.json @@ -97,7 +97,8 @@ "@kbn/shared-ux-button-toolbar", "@kbn/cell-actions", "@kbn/calculate-width-from-char-count", - "@kbn/discover-utils" + "@kbn/discover-utils", + "@kbn/test-jest-helpers2" ], "exclude": [ "target/**/*"