From 1261345b81ea12346ed405bc30429564a06e2b99 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 11 Apr 2023 10:51:54 +0100 Subject: [PATCH] Chore: Upgrade to react 18 (#64428) * update react 18 related deps * fix some types * make sure we're on react-router-dom >= 5.3.3 * Use new root API * Remove StrictMode for now - react 18 double rendering causes issues * fix + ignore some @grafana/ui types * fix some more types * use renderHook from @testing-library/react in almost all cases * fix storybook types * rewrite useDashboardSave to not use useEffect * make props optional * only render if props are provided * add correct type for useCallback * make resourcepicker tests more robust * fix ModalManager rendering * fix some more unit tests * store the click coordinates in a ref as setState is NOT synchronous * fix remaining e2e tests * rewrite dashboardpage tests to avoid act warnings * undo lint ignores * fix ExpanderCell types * set SymbolCell type correctly * fix QueryAndExpressionsStep * looks like the types were actually wrong instead :D * undo this for now... * remove spinner waits * more robust tests * rewrite errorboundary test to not explicitly count the number of renders * make urlParam expect async * increase timeout in waitFor * revert ExplorePage test changes * Update public/app/features/dashboard/containers/DashboardPage.test.tsx Co-authored-by: Alex Khomenko * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko * Update public/app/features/dashboard/containers/PublicDashboardPage.test.tsx Co-authored-by: Alex Khomenko * skip fakeTimer test, ignore table types for now + other review comments * update package peerDeps * small tweak to resourcepicker test * update lockfile... * increase timeout in sharepublicdashboard tests * ensure ExplorePaneContainer passes correct queries to initializeExplore * fix LokiContextUI test * fix unit tests * make importDashboard flow more consistent * wait for dashboard name before continuing * more test fixes * readd dashboard name to variable e2e tests * wait for switches to be enabled before clicking * fix modal rendering * don't use @testing-library/dom directly * quick fix for rendering of panels in firefox * make PromQueryField test more robust * don't wait for chartData - in react 18 this can happen before the wait code even gets executed --------- Co-authored-by: kay delaney Co-authored-by: Alex Khomenko --- .github/renovate.json5 | 10 - ...ook-addon-docs-npm-6.5.16-56ecbd77e7.patch | 14 + ...act-split-pane-npm-0.1.92-93dbf51dff.patch | 12 + ...g_a_row_with_a_non_repeating_panel.spec.ts | 2 + .../new-constant-variable.spec.ts | 4 +- .../new-custom-variable.spec.ts | 3 + .../new-datasource-variable.spec.ts | 2 + .../new-interval-variable.spec.ts | 2 + .../new-query-variable.spec.ts | 4 + .../new-text-box-variable.spec.ts | 2 + .../trace-view-scrolling.spec.ts | 4 +- package.json | 24 +- packages/grafana-data/package.json | 19 +- .../grafana-e2e/src/flows/configurePanel.ts | 3 - .../grafana-e2e/src/flows/importDashboard.ts | 7 +- packages/grafana-runtime/package.json | 17 +- .../usePluginInteractionReporter.test.tsx | 2 +- packages/grafana-ui/package.json | 23 +- .../src/components/Dropdown/Dropdown.tsx | 2 +- .../ErrorBoundary/ErrorBoundary.test.tsx | 6 +- .../InteractiveTable/ExpanderCell.tsx | 2 +- .../src/components/Logs/LogRowContext.tsx | 3 +- .../src/components/Menu/MenuItem.test.tsx | 3 +- .../src/components/Menu/hooks.test.tsx | 4 +- .../src/components/Segment/Segment.tsx | 3 +- .../src/components/Segment/SegmentAsync.tsx | 3 +- .../src/components/Slider/HandleTooltip.tsx | 3 +- .../src/components/Slider/RangeSlider.tsx | 2 +- .../grafana-ui/src/components/Table/utils.ts | 4 + .../src/themes/ThemeContext.test.tsx | 3 +- packages/grafana-ui/src/utils/reactUtils.ts | 4 +- .../internal/input-datasource/package.json | 8 +- public/app/AppWrapper.tsx | 70 ++-- public/app/angular/services/ng_react.ts | 29 +- public/app/app.ts | 8 +- public/app/core/services/ModalManager.ts | 9 +- .../alerting/NotificationsListPage.tsx | 2 +- .../features/alerting/TestRuleResult.test.tsx | 10 +- .../alerting/unified/Receivers.test.tsx | 27 +- .../notification-policies/Modals.tsx | 6 +- .../hooks/useAlertManagerSourceName.test.tsx | 2 +- .../hooks/useExternalAMSelector.test.tsx | 93 ++--- .../unified/hooks/useIsRuleEditable.test.tsx | 2 +- .../AnnotationsSettings.test.tsx | 3 +- .../DashboardSettings/LinksSettings.test.tsx | 3 +- .../VersionsSettings.test.tsx | 3 +- .../SharePublicDashboard.test.tsx | 33 +- .../containers/DashboardPage.test.tsx | 338 ++++++++-------- .../containers/PublicDashboardPage.test.tsx | 280 ++++++-------- .../dashboard/dashgrid/DashboardGrid.test.tsx | 3 +- .../dashboard/dashgrid/DashboardPanel.tsx | 4 +- .../dashboard/dashgrid/LazyLoader.tsx | 4 +- .../components/DataSourceTestingStatus.tsx | 2 +- .../features/explore/ExplorePaneContainer.tsx | 4 +- .../TraceView/useChildrenState.test.ts | 2 +- .../explore/TraceView/useDetailState.test.ts | 2 +- .../TraceView/useHoverIndentGuide.test.ts | 2 +- .../explore/TraceView/useSearch.test.ts | 2 +- .../explore/TraceView/useViewRange.test.ts | 2 +- .../features/explore/spec/helper/setup.tsx | 3 +- public/app/features/explore/state/query.ts | 3 +- .../LibraryPanelsSearch.test.tsx | 3 +- .../logs/components/LogRowContext.tsx | 6 +- .../features/playlist/PlaylistForm.test.tsx | 3 +- .../profile/UserProfileEditPage.test.tsx | 3 +- .../search/page/components/columns.tsx | 8 +- .../MetricsQueryEditor/dataHooks.test.ts | 70 ++-- .../components/QueryEditor/QueryEditor.tsx | 2 +- .../ResourcePicker/ResourcePicker.test.tsx | 26 +- .../VariableEditor/VariableEditor.tsx | 4 +- .../azuremonitor/utils/useAsyncState.test.ts | 25 +- .../azuremonitor/utils/useLastError.test.ts | 2 +- .../datasource/cloudwatch/hooks.test.ts | 82 ++-- .../useMigratedMetricsQuery.test.ts | 2 +- .../elasticsearch/hooks/useFields.test.tsx | 2 +- .../elasticsearch/hooks/useNextId.test.tsx | 2 +- .../VisualInfluxQLEditor/Editor.test.tsx | 10 +- .../components/useShadowedState.test.ts | 2 +- .../influxdb/components/useUniqueId.test.ts | 2 +- .../loki/components/LokiContextUi.test.tsx | 5 +- .../parca/QueryEditor/QueryEditor.test.tsx | 3 +- .../phlare/QueryEditor/QueryEditor.test.tsx | 3 +- .../components/PromQueryField.test.tsx | 8 +- .../querybuilder/shared/hooks/useFlag.test.ts | 2 +- .../datasource/zipkin/QueryField.test.tsx | 32 +- .../components/FlameGraph/FlameGraph.test.tsx | 3 +- public/app/plugins/panel/graph/graph.ts | 13 +- .../plugins/panel/nodeGraph/layout.test.ts | 2 +- yarn.lock | 361 +++++++++--------- 89 files changed, 921 insertions(+), 920 deletions(-) create mode 100644 .yarn/patches/@storybook-addon-docs-npm-6.5.16-56ecbd77e7.patch create mode 100644 .yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch diff --git a/.github/renovate.json5 b/.github/renovate.json5 index a652df0a8ad..83033b38060 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -22,16 +22,6 @@ "@sentry/browser", "@sentry/types", "@sentry/utils", - - // dep updates blocked by React 18 - "@testing-library/dom", - "@testing-library/react", - "@types/react", - "@types/react-dom", - "@types/react-test-renderer", - "react", - "react-dom", - "react-test-renderer" ], "includePaths": ["package.json", "packages/**"], "ignorePaths": ["packages/grafana-toolkit/package.json", "emails/**", "plugins-bundled/**", "**/mocks/**"], diff --git a/.yarn/patches/@storybook-addon-docs-npm-6.5.16-56ecbd77e7.patch b/.yarn/patches/@storybook-addon-docs-npm-6.5.16-56ecbd77e7.patch new file mode 100644 index 00000000000..5fc706f7d5d --- /dev/null +++ b/.yarn/patches/@storybook-addon-docs-npm-6.5.16-56ecbd77e7.patch @@ -0,0 +1,14 @@ +diff --git a/dist/ts3.9/blocks/DocsContainer.d.ts b/dist/ts3.9/blocks/DocsContainer.d.ts +index be330e44bebb02eaf2c92d365d4e7dc1da452465..6c8b1d42bea2e184456e2757eb2ee20076ba43b3 100644 +--- a/dist/ts3.9/blocks/DocsContainer.d.ts ++++ b/dist/ts3.9/blocks/DocsContainer.d.ts +@@ -1,7 +1,8 @@ +-import { FunctionComponent } from 'react'; ++import { FunctionComponent, ReactNode } from 'react'; + import { AnyFramework } from '@storybook/csf'; + import { DocsContextProps } from './DocsContext'; + export interface DocsContainerProps { + context: DocsContextProps; ++ children?: ReactNode; + } + export declare const DocsContainer: FunctionComponent; diff --git a/.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch b/.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch new file mode 100644 index 00000000000..1ea29362cf1 --- /dev/null +++ b/.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch @@ -0,0 +1,12 @@ +diff --git a/index.d.ts b/index.d.ts +index d116f54d6da12d24b48e24ff3636c9066059aa58..93290945d8b1818cab893d6466179b33869a47b9 100644 +--- a/index.d.ts ++++ b/index.d.ts +@@ -25,6 +25,7 @@ export type SplitPaneProps = { + pane2Style?: React.CSSProperties; + resizerClassName?: string; + step?: number; ++ children?: React.ReactNode; + }; + + export type SplitPaneState = { diff --git a/e2e/dashboards-suite/Repeating_a_row_with_a_non_repeating_panel.spec.ts b/e2e/dashboards-suite/Repeating_a_row_with_a_non_repeating_panel.spec.ts index c47eb7fd096..0b44c94cf85 100644 --- a/e2e/dashboards-suite/Repeating_a_row_with_a_non_repeating_panel.spec.ts +++ b/e2e/dashboards-suite/Repeating_a_row_with_a_non_repeating_panel.spec.ts @@ -1,5 +1,6 @@ import { e2e } from '@grafana/e2e'; const PAGE_UNDER_TEST = 'k3PEoCpnk/repeating-a-row-with-a-non-repeating-panel-and-horizontal-repeating-panel'; +const DASHBOARD_NAME = 'Repeating a row with a non-repeating panel and horizontal repeating panel'; describe('Repeating a row with repeated panels and a non-repeating panel', () => { beforeEach(() => { @@ -8,6 +9,7 @@ describe('Repeating a row with repeated panels and a non-repeating panel', () => it('should be able to collapse and expand a repeated row without losing panels', () => { e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); const panelsToCheck = [ 'Row 2 non-repeating panel', diff --git a/e2e/dashboards-suite/new-constant-variable.spec.ts b/e2e/dashboards-suite/new-constant-variable.spec.ts index bdb990828ed..c595e49c692 100644 --- a/e2e/dashboards-suite/new-constant-variable.spec.ts +++ b/e2e/dashboards-suite/new-constant-variable.spec.ts @@ -2,11 +2,13 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; describe('Variables - Constant', () => { it('can add a new constant variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "Constant" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); @@ -15,8 +17,8 @@ describe('Variables - Constant', () => { e2e().get('input').type('Constant{enter}'); }); e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur(); - e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur(); e2e.pages.Dashboard.Settings.Variables.Edit.ConstantVariable.constantOptionsQueryInputV2().type('pesto').blur(); + e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur(); e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(0).should('have.text', 'pesto'); diff --git a/e2e/dashboards-suite/new-custom-variable.spec.ts b/e2e/dashboards-suite/new-custom-variable.spec.ts index 1ed710f11d3..79b8a139a28 100644 --- a/e2e/dashboards-suite/new-custom-variable.spec.ts +++ b/e2e/dashboards-suite/new-custom-variable.spec.ts @@ -2,6 +2,7 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; function fillInCustomVariable(name: string, label: string, value: string) { e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => { @@ -23,6 +24,7 @@ describe('Variables - Custom', () => { it('can add a custom template variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "Custom" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); @@ -50,6 +52,7 @@ describe('Variables - Custom', () => { it('can add a custom template variable with labels', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "Custom" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); diff --git a/e2e/dashboards-suite/new-datasource-variable.spec.ts b/e2e/dashboards-suite/new-datasource-variable.spec.ts index 8d9bdfb4ea3..27aaa3c15fd 100644 --- a/e2e/dashboards-suite/new-datasource-variable.spec.ts +++ b/e2e/dashboards-suite/new-datasource-variable.spec.ts @@ -2,11 +2,13 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; describe('Variables - Datasource', () => { it('can add a new datasource variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "Datasource" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); diff --git a/e2e/dashboards-suite/new-interval-variable.spec.ts b/e2e/dashboards-suite/new-interval-variable.spec.ts index c55fb7b0796..6e4eeda55af 100644 --- a/e2e/dashboards-suite/new-interval-variable.spec.ts +++ b/e2e/dashboards-suite/new-interval-variable.spec.ts @@ -2,6 +2,7 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; function assertPreviewValues(expectedValues: string[]) { for (const expected of expectedValues) { @@ -14,6 +15,7 @@ describe('Variables - Interval', () => { it('can add a new interval variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "Interval" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); diff --git a/e2e/dashboards-suite/new-query-variable.spec.ts b/e2e/dashboards-suite/new-query-variable.spec.ts index 2dfc095d9bc..307f3da7b6c 100644 --- a/e2e/dashboards-suite/new-query-variable.spec.ts +++ b/e2e/dashboards-suite/new-query-variable.spec.ts @@ -2,11 +2,13 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables'; +const DASHBOARD_NAME = 'Templating - Nested Template Variables'; describe('Variables - Query - Add variable', () => { it('query variable should be default and default fields should be correct', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click(); @@ -77,6 +79,7 @@ describe('Variables - Query - Add variable', () => { it('adding a single value query variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click(); @@ -132,6 +135,7 @@ describe('Variables - Query - Add variable', () => { it('adding a multi value query variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); e2e.pages.Dashboard.Settings.Variables.List.newButton().should('be.visible').click(); diff --git a/e2e/dashboards-suite/new-text-box-variable.spec.ts b/e2e/dashboards-suite/new-text-box-variable.spec.ts index f07385729d2..9bd24f16157 100644 --- a/e2e/dashboards-suite/new-text-box-variable.spec.ts +++ b/e2e/dashboards-suite/new-text-box-variable.spec.ts @@ -2,11 +2,13 @@ import { e2e } from '@grafana/e2e'; import { GrafanaBootConfig } from '@grafana/runtime'; const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output'; +const DASHBOARD_NAME = 'Test variable output'; describe('Variables - Text box', () => { it('can add a new text box variable', () => { e2e.flows.login('admin', 'admin'); e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=templating` }); + e2e().contains(DASHBOARD_NAME).should('be.visible'); // Create a new "text box" variable e2e.components.CallToActionCard.buttonV2('Add variable').click(); diff --git a/e2e/various-suite/trace-view-scrolling.spec.ts b/e2e/various-suite/trace-view-scrolling.spec.ts index 3342281afe5..5fd3cfdae0f 100644 --- a/e2e/various-suite/trace-view-scrolling.spec.ts +++ b/e2e/various-suite/trace-view-scrolling.spec.ts @@ -29,7 +29,9 @@ describe('Trace view', () => { e2e.pages.Explore.General.scrollView().children('.scrollbar-view').scrollTo('center'); // After scrolling we should load more spans - e2e.components.TraceViewer.spanBar().its('length').should('be.gt', oldLength); + e2e.components.TraceViewer.spanBar().should(($span) => { + expect($span.length).to.be.gt(oldLength); + }); }); }); }); diff --git a/package.json b/package.json index 1e8cf53df28..d266f25c225 100644 --- a/package.json +++ b/package.json @@ -114,10 +114,9 @@ "@rtsao/plugin-proposal-class-properties": "7.0.1-patch.1", "@swc/core": "1.3.38", "@swc/helpers": "0.4.14", - "@testing-library/dom": "8.20.0", + "@testing-library/dom": "9.0.1", "@testing-library/jest-dom": "5.16.5", - "@testing-library/react": "12.1.4", - "@testing-library/react-hooks": "8.0.1", + "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", "@types/angular": "1.8.4", "@types/angular-route": "1.7.2", @@ -146,15 +145,15 @@ "@types/papaparse": "5.3.7", "@types/pluralize": "^0.0.29", "@types/prismjs": "1.26.0", - "@types/react": "17.0.42", + "@types/react": "18.0.28", "@types/react-beautiful-dnd": "13.1.3", - "@types/react-dom": "17.0.14", + "@types/react-dom": "18.0.11", "@types/react-grid-layout": "1.3.2", "@types/react-highlight-words": "0.16.4", "@types/react-redux": "7.1.25", "@types/react-router-dom": "5.3.3", "@types/react-table": "7.7.14", - "@types/react-test-renderer": "17.0.1", + "@types/react-test-renderer": "18.0.0", "@types/react-transition-group": "4.4.5", "@types/react-virtualized-auto-sizer": "1.0.1", "@types/react-window": "1.8.5", @@ -226,7 +225,7 @@ "react-refresh": "0.14.0", "react-select-event": "5.5.1", "react-simple-compat": "1.2.3", - "react-test-renderer": "17.0.2", + "react-test-renderer": "18.2.0", "redux-mock-store": "1.5.4", "rimraf": "4.4.0", "rudder-sdk-js": "2.25.0", @@ -294,6 +293,7 @@ "@sentry/browser": "6.19.7", "@sentry/types": "6.19.7", "@sentry/utils": "6.19.7", + "@testing-library/react-hooks": "^8.0.1", "@types/react-resizable": "3.0.3", "@types/webpack-env": "1.18.0", "@visx/event": "3.0.1", @@ -366,11 +366,11 @@ "rc-time-picker": "3.7.3", "rc-tree": "5.7.2", "re-resizable": "6.9.9", - "react": "17.0.2", + "react": "18.2.0", "react-awesome-query-builder": "5.4.0", "react-beautiful-dnd": "13.1.1", "react-diff-viewer": "^3.1.1", - "react-dom": "17.0.2", + "react-dom": "18.2.0", "react-draggable": "4.4.5", "react-dropzone": "^14.2.3", "react-enable": "^3.1.0", @@ -385,7 +385,7 @@ "react-redux": "7.2.6", "react-resizable": "3.0.4", "react-reverse-portal": "2.1.1", - "react-router-dom": "^5.2.0", + "react-router-dom": "5.3.3", "react-select": "5.7.0", "react-split-pane": "0.1.92", "react-table": "7.8.0", @@ -437,7 +437,9 @@ "@storybook/manager-webpack5/webpack": "5.76.0", "ngtemplate-loader/loader-utils": "^2.0.0", "trim": "0.0.3", - "slate-dev-environment@^0.2.2": "patch:slate-dev-environment@npm:0.2.5#.yarn/patches/slate-dev-environment-npm-0.2.5-9aeb7da7b5.patch" + "slate-dev-environment@^0.2.2": "patch:slate-dev-environment@npm:0.2.5#.yarn/patches/slate-dev-environment-npm-0.2.5-9aeb7da7b5.patch", + "react-split-pane@0.1.92": "patch:react-split-pane@npm:0.1.92#.yarn/patches/react-split-pane-npm-0.1.92-93dbf51dff.patch", + "@storybook/addon-docs@6.5.16": "patch:@storybook/addon-docs@npm:6.5.16#.yarn/patches/@storybook-addon-docs-npm-6.5.16-56ecbd77e7.patch" }, "workspaces": { "packages": [ diff --git a/packages/grafana-data/package.json b/packages/grafana-data/package.json index 70497f3d1ed..7032827909b 100644 --- a/packages/grafana-data/package.json +++ b/packages/grafana-data/package.json @@ -63,10 +63,9 @@ "@rollup/plugin-commonjs": "23.0.2", "@rollup/plugin-json": "5.0.1", "@rollup/plugin-node-resolve": "15.0.1", - "@testing-library/dom": "8.20.0", + "@testing-library/dom": "9.0.1", "@testing-library/jest-dom": "5.16.5", - "@testing-library/react": "12.1.4", - "@testing-library/react-hooks": "8.0.1", + "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", "@types/dompurify": "^2", "@types/history": "4.7.11", @@ -76,15 +75,15 @@ "@types/marked": "4.0.8", "@types/node": "18.14.6", "@types/papaparse": "5.3.7", - "@types/react": "17.0.42", - "@types/react-dom": "17.0.14", + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11", "@types/sinon": "10.0.13", "@types/testing-library__jest-dom": "5.14.5", "@types/tinycolor2": "1.4.3", "esbuild": "0.16.17", - "react": "17.0.2", - "react-dom": "17.0.2", - "react-test-renderer": "17.0.2", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-test-renderer": "18.2.0", "rimraf": "4.4.0", "rollup": "2.79.1", "rollup-plugin-dts": "^5.0.0", @@ -94,7 +93,7 @@ "typescript": "4.8.4" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" } } diff --git a/packages/grafana-e2e/src/flows/configurePanel.ts b/packages/grafana-e2e/src/flows/configurePanel.ts index 7181c06fa05..a121376a98a 100644 --- a/packages/grafana-e2e/src/flows/configurePanel.ts +++ b/packages/grafana-e2e/src/flows/configurePanel.ts @@ -141,7 +141,6 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC if (queriesForm) { queriesForm(fullConfig); - e2e().wait('@chartData'); // Wait for a possible complex visualization to render (or something related, as this isn't necessary on the dashboard page) // Can't assert that its HTML changed because a new query could produce the same results @@ -158,8 +157,6 @@ export const configurePanel = (config: PartialAddPanelConfig | PartialEditPanelC // Avoid annotations flakiness e2e.components.RefreshPicker.runButtonV2().first().click({ force: true }); - e2e().wait('@chartData'); - // Wait for RxJS e2e().wait(500); diff --git a/packages/grafana-e2e/src/flows/importDashboard.ts b/packages/grafana-e2e/src/flows/importDashboard.ts index d3b01c2be6b..2d9edeee690 100644 --- a/packages/grafana-e2e/src/flows/importDashboard.ts +++ b/packages/grafana-e2e/src/flows/importDashboard.ts @@ -20,10 +20,9 @@ export const importDashboard = (dashboardToImport: Dashboard, queryTimeout?: num e2e().visit(fromBaseUrl('/dashboard/import')); // Note: normally we'd use 'click' and then 'type' here, but the json object is so big that using 'val' is much faster - e2e.components.DashboardImportPage.textarea() - .should('be.visible') - .click() - .invoke('val', JSON.stringify(dashboardToImport)); + e2e.components.DashboardImportPage.textarea().should('be.visible'); + e2e.components.DashboardImportPage.textarea().click(); + e2e.components.DashboardImportPage.textarea().invoke('val', JSON.stringify(dashboardToImport)); e2e.components.DashboardImportPage.submit().should('be.visible').click(); e2e.components.ImportDashboardForm.name().should('be.visible').click().clear().type(dashboardToImport.title); e2e.components.ImportDashboardForm.submit().should('be.visible').click(); diff --git a/packages/grafana-runtime/package.json b/packages/grafana-runtime/package.json index 67798bf4475..e7ba8738b6c 100644 --- a/packages/grafana-runtime/package.json +++ b/packages/grafana-runtime/package.json @@ -52,21 +52,20 @@ "@grafana/tsconfig": "^1.2.0-rc1", "@rollup/plugin-commonjs": "23.0.2", "@rollup/plugin-node-resolve": "15.0.1", - "@testing-library/dom": "8.20.0", - "@testing-library/react": "12.1.4", - "@testing-library/react-hooks": "8.0.1", + "@testing-library/dom": "9.0.1", + "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", "@types/angular": "1.8.4", "@types/history": "4.7.11", "@types/jest": "29.2.3", "@types/lodash": "4.14.191", - "@types/react": "17.0.42", - "@types/react-dom": "17.0.14", + "@types/react": "18.0.28", + "@types/react-dom": "18.0.11", "@types/systemjs": "^0.20.6", "esbuild": "0.16.17", "lodash": "4.17.21", - "react": "17.0.2", - "react-dom": "17.0.2", + "react": "18.2.0", + "react-dom": "18.2.0", "rimraf": "4.4.0", "rollup": "2.79.1", "rollup-plugin-dts": "^5.0.0", @@ -77,7 +76,7 @@ "typescript": "4.8.4" }, "peerDependencies": { - "react": "17.0.2", - "react-dom": "17.0.2" + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" } } diff --git a/packages/grafana-runtime/src/analytics/plugins/usePluginInteractionReporter.test.tsx b/packages/grafana-runtime/src/analytics/plugins/usePluginInteractionReporter.test.tsx index 75b52e2cf59..40c2a65bdc9 100644 --- a/packages/grafana-runtime/src/analytics/plugins/usePluginInteractionReporter.test.tsx +++ b/packages/grafana-runtime/src/analytics/plugins/usePluginInteractionReporter.test.tsx @@ -1,4 +1,4 @@ -import { renderHook } from '@testing-library/react-hooks'; +import { renderHook } from '@testing-library/react'; import React from 'react'; import { diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 09febdfebd2..9185bda19ca 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -97,7 +97,7 @@ "react-inlinesvg": "3.0.2", "react-popper": "2.3.0", "react-popper-tooltip": "4.4.2", - "react-router-dom": "^5.2.0", + "react-router-dom": "5.3.3", "react-select": "5.7.0", "react-select-event": "^5.1.0", "react-table": "7.8.0", @@ -134,10 +134,9 @@ "@storybook/preset-scss": "1.0.3", "@storybook/react": "6.5.16", "@storybook/theming": "6.5.16", - "@testing-library/dom": "8.20.0", + "@testing-library/dom": "9.0.1", "@testing-library/jest-dom": "5.16.5", - "@testing-library/react": "12.1.4", - "@testing-library/react-hooks": "8.0.1", + "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", "@types/common-tags": "^1.8.0", "@types/d3": "7.4.0", @@ -149,15 +148,15 @@ "@types/mock-raf": "1.0.3", "@types/node": "18.14.6", "@types/prismjs": "1.26.0", - "@types/react": "17.0.42", + "@types/react": "18.0.28", "@types/react-beautiful-dnd": "13.1.3", "@types/react-calendar": "3.9.0", "@types/react-color": "3.0.6", - "@types/react-dom": "17.0.14", + "@types/react-dom": "18.0.11", "@types/react-highlight-words": "0.16.4", "@types/react-router-dom": "5.3.3", "@types/react-table": "7.7.14", - "@types/react-test-renderer": "17.0.1", + "@types/react-test-renderer": "18.0.0", "@types/react-transition-group": "4.4.5", "@types/react-window": "1.8.5", "@types/slate": "0.47.11", @@ -173,9 +172,9 @@ "expose-loader": "4.0.0", "mock-raf": "1.0.1", "process": "^0.11.10", - "react": "17.0.2", - "react-dom": "17.0.2", - "react-test-renderer": "17.0.2", + "react": "18.2.0", + "react-dom": "18.2.0", + "react-test-renderer": "18.2.0", "rimraf": "4.4.0", "rollup": "2.79.1", "rollup-plugin-dts": "^5.0.0", @@ -190,7 +189,7 @@ "webpack": "5.76.0" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0", - "react-dom": "^16.8.0 || ^17.0.0" + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" } } diff --git a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx index 21f1e28ed8c..3db8ed9c69f 100644 --- a/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx +++ b/packages/grafana-ui/src/components/Dropdown/Dropdown.tsx @@ -71,7 +71,7 @@ export const Dropdown = React.memo(({ children, overlay, placement, offset, onVi timeout={{ appear: animationDuration, exit: 0, enter: 0 }} classNames={animationStyles} > -
{ReactUtils.renderOrCallToRender(overlay)}
+
{ReactUtils.renderOrCallToRender(overlay, {})}
diff --git a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx index 72eb6d9084b..df5241e46de 100644 --- a/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx +++ b/packages/grafana-ui/src/components/ErrorBoundary/ErrorBoundary.test.tsx @@ -57,7 +57,7 @@ describe('ErrorBoundary', () => { expect((faro.api.pushError as jest.Mock).mock.calls[0][0]).toBe(problem); }); - it('should recover when when recover props change', async () => { + it('should rerender when recover props change', async () => { const problem = new Error('things went terribly wrong'); let renderCount = 0; @@ -75,6 +75,8 @@ describe('ErrorBoundary', () => { ); await screen.findByText(problem.message); + expect(renderCount).toBeGreaterThan(0); + const oldRenderCount = renderCount; rerender( @@ -89,6 +91,6 @@ describe('ErrorBoundary', () => { ); - expect(renderCount).toBe(2); + expect(renderCount).toBeGreaterThan(oldRenderCount); }); }); diff --git a/packages/grafana-ui/src/components/InteractiveTable/ExpanderCell.tsx b/packages/grafana-ui/src/components/InteractiveTable/ExpanderCell.tsx index 69873f54e13..607b032878b 100644 --- a/packages/grafana-ui/src/components/InteractiveTable/ExpanderCell.tsx +++ b/packages/grafana-ui/src/components/InteractiveTable/ExpanderCell.tsx @@ -10,7 +10,7 @@ const expanderContainerStyles = css` height: 100%; `; -export function ExpanderCell({ row, __rowID }: CellProps & { __rowID: string }) { +export function ExpanderCell({ row, __rowID }: CellProps) { return (
{ + const message = typeof item === 'string' ? item : item.message ?? ''; return (
- {typeof item === 'string' && textUtil.hasAnsiCodes(item) ? : item} + {textUtil.hasAnsiCodes(message) ? : message}
); }} diff --git a/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx b/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx index 5371d1c7674..0a9c729903a 100644 --- a/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx +++ b/packages/grafana-ui/src/components/Menu/MenuItem.test.tsx @@ -1,5 +1,4 @@ -import { fireEvent } from '@testing-library/dom'; -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen } from '@testing-library/react'; import React from 'react'; import { selectors } from '@grafana/e2e-selectors'; diff --git a/packages/grafana-ui/src/components/Menu/hooks.test.tsx b/packages/grafana-ui/src/components/Menu/hooks.test.tsx index 94b007a4ab7..254f41c7a8a 100644 --- a/packages/grafana-ui/src/components/Menu/hooks.test.tsx +++ b/packages/grafana-ui/src/components/Menu/hooks.test.tsx @@ -1,6 +1,4 @@ -import { fireEvent } from '@testing-library/dom'; -import { render, screen } from '@testing-library/react'; -import { act, renderHook } from '@testing-library/react-hooks'; +import { act, fireEvent, render, renderHook, screen } from '@testing-library/react'; import React, { createRef, KeyboardEvent, RefObject } from 'react'; import { useMenuFocus } from './hooks'; diff --git a/packages/grafana-ui/src/components/Segment/Segment.tsx b/packages/grafana-ui/src/components/Segment/Segment.tsx index fd8401c6c82..9f25ceb6243 100644 --- a/packages/grafana-ui/src/components/Segment/Segment.tsx +++ b/packages/grafana-ui/src/components/Segment/Segment.tsx @@ -40,6 +40,7 @@ export function Segment({ if (!expanded) { const label = isObject(value) ? value.label : value; + const labelAsString = label != null ? String(label) : undefined; return (