This is an automated email from the ASF dual-hosted git repository. rusackas pushed a commit to branch chore/lint-cleanup-tech-debt-4 in repository https://gitbox.apache.org/repos/asf/superset.git
commit 84890b924b928c7bdbde14948e95f4d2f5643d6a Author: Evan Rusackas <[email protected]> AuthorDate: Wed Feb 11 00:43:24 2026 -0800 chore(lint): add jest/expect-expect rule for test assertions - Add jest/expect-expect rule to oxlint.json with error level - Configure assertFunctionNames to recognize custom assertion helpers: - expect* (glob pattern for all expect-prefixed helpers) - runTimezoneTest (time comparison tests) - compareURI (explore utils tests) - test*WithInitialValues (truncation hook tests) Fixed tests that were missing explicit assertions: - ModalTrigger.test.tsx: add assertion for tooltip render - ChartDataProvider.test.tsx: add assertion for loading state - SuperChart.test.tsx: add eslint-disable for skipped test - Markdown.test.tsx: add assertions for error handling and resize - UploadDataModal.test.tsx: add assertion for schema population - AnnotationLayerList.test.tsx: add assertion for bulk select - CssTemplateList.test.tsx: add assertion for bulk select - ChartCreation.test.tsx: add assertions for URL parameter tests - sqlLab.test.ts: add assertion for empty refresh queries Co-Authored-By: Claude Opus 4.5 <[email protected]> --- superset-frontend/oxlint.json | 14 +++++++++++++- .../src/components/ModalTrigger/ModalTrigger.test.tsx | 2 +- .../test/chart/components/ChartDataProvider.test.tsx | 2 +- .../test/chart/components/SuperChart.test.tsx | 2 +- superset-frontend/src/SqlLab/reducers/sqlLab.test.ts | 3 +++ .../components/gridComponents/Markdown/Markdown.test.tsx | 8 ++++++++ .../databases/UploadDataModel/UploadDataModal.test.tsx | 6 ++++-- .../pages/AnnotationLayerList/AnnotationLayerList.test.tsx | 2 +- .../src/pages/ChartCreation/ChartCreation.test.tsx | 4 ++-- .../src/pages/CssTemplateList/CssTemplateList.test.tsx | 2 +- 10 files changed, 35 insertions(+), 10 deletions(-) diff --git a/superset-frontend/oxlint.json b/superset-frontend/oxlint.json index 81b7523dce5..fe2360b2219 100644 --- a/superset-frontend/oxlint.json +++ b/superset-frontend/oxlint.json @@ -262,7 +262,19 @@ // === Jest rules === "jest/consistent-test-it": ["error", { "fn": "test" }], "jest/no-focused-tests": "error", - "jest/no-disabled-tests": "error" + "jest/no-disabled-tests": "error", + "jest/expect-expect": [ + "error", + { + "assertFunctionNames": [ + "expect", + "expect*", + "runTimezoneTest", + "compareURI", + "test*WithInitialValues" + ] + } + ] }, "ignorePatterns": [ "packages/generator-superset/**/*", diff --git a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx index 87eb2eec7f1..aa61ef85c4d 100644 --- a/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx +++ b/superset-frontend/packages/superset-ui-core/src/components/ModalTrigger/ModalTrigger.test.tsx @@ -61,7 +61,7 @@ test('should render a tooltip on hover', async () => { render(<ModalTrigger {...tooltipProps} />); await userEvent.hover(screen.getByRole('button')); - await screen.findByRole('tooltip'); + expect(await screen.findByRole('tooltip')).toBeInTheDocument(); }); test('should not render a modal before click', () => { diff --git a/superset-frontend/packages/superset-ui-core/test/chart/components/ChartDataProvider.test.tsx b/superset-frontend/packages/superset-ui-core/test/chart/components/ChartDataProvider.test.tsx index 3745c0b746d..906bb8ad019 100644 --- a/superset-frontend/packages/superset-ui-core/test/chart/components/ChartDataProvider.test.tsx +++ b/superset-frontend/packages/superset-ui-core/test/chart/components/ChartDataProvider.test.tsx @@ -231,7 +231,7 @@ describe('ChartDataProvider', () => { mockLoadDatasource.mockImplementation(() => new Promise(() => {})); setup(); - await screen.findByRole('status'); + expect(await screen.findByRole('status')).toBeInTheDocument(); }); test('shows payload when loaded', async () => { diff --git a/superset-frontend/packages/superset-ui-core/test/chart/components/SuperChart.test.tsx b/superset-frontend/packages/superset-ui-core/test/chart/components/SuperChart.test.tsx index db41f084cb5..86203ed8643 100644 --- a/superset-frontend/packages/superset-ui-core/test/chart/components/SuperChart.test.tsx +++ b/superset-frontend/packages/superset-ui-core/test/chart/components/SuperChart.test.tsx @@ -276,7 +276,7 @@ describe('SuperChart', () => { }; // Update the resize observer trigger to ensure it's called after component mount - /* oxlint-disable-next-line jest/no-disabled-tests */ + /* oxlint-disable-next-line jest/no-disabled-tests, jest/expect-expect -- skipped test */ test.skip('works when width and height are percent', async () => { const { container } = render( <SuperChart diff --git a/superset-frontend/src/SqlLab/reducers/sqlLab.test.ts b/superset-frontend/src/SqlLab/reducers/sqlLab.test.ts index 93b25a71203..eacbe65ea83 100644 --- a/superset-frontend/src/SqlLab/reducers/sqlLab.test.ts +++ b/superset-frontend/src/SqlLab/reducers/sqlLab.test.ts @@ -575,7 +575,10 @@ describe('sqlLabReducer', () => { expect(newState.queries.def).toBe(completedQuery); }); test('should refresh queries when polling returns empty', () => { + const prevQueries = newState.queries; newState = sqlLabReducer(newState, actions.refreshQueries({})); + // Empty refresh should preserve existing queries + expect(newState.queries).toBe(prevQueries); }); test('should set state to fetching when sync query succeeds without results', () => { const syncQuery = { diff --git a/superset-frontend/src/dashboard/components/gridComponents/Markdown/Markdown.test.tsx b/superset-frontend/src/dashboard/components/gridComponents/Markdown/Markdown.test.tsx index 74183fcf239..4794cba0fd6 100644 --- a/superset-frontend/src/dashboard/components/gridComponents/Markdown/Markdown.test.tsx +++ b/superset-frontend/src/dashboard/components/gridComponents/Markdown/Markdown.test.tsx @@ -281,6 +281,9 @@ test('should handle markdown errors gracefully', async () => { await new Promise(resolve => setTimeout(resolve, 100)); }); + + // Verify component still renders after error events + expect(screen.getByTestId('dashboard-markdown-editor')).toBeInTheDocument(); }); test('should resize editor when width changes', async () => { @@ -307,6 +310,11 @@ test('should resize editor when width changes', async () => { await new Promise(resolve => setTimeout(resolve, 100)); }); + + // Verify component still renders after resize + expect( + screen.getByTestId('dashboard-component-chart-holder'), + ).toBeInTheDocument(); }); test('should update content when undo/redo changes occur', async () => { diff --git a/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx b/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx index 0796de19398..a4bf245f271 100644 --- a/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx +++ b/superset-frontend/src/features/databases/UploadDataModel/UploadDataModal.test.tsx @@ -412,8 +412,10 @@ describe('UploadDataModal - Database and Schema Population', () => { await userEvent.click(selectDatabase); await userEvent.click(screen.getByText('database2')); await userEvent.click(selectSchema); - await waitFor(() => screen.getAllByText('schema1')); - await waitFor(() => screen.getAllByText('schema2')); + await waitFor(() => { + expect(screen.getAllByText('schema1')).not.toHaveLength(0); + expect(screen.getAllByText('schema2')).not.toHaveLength(0); + }); }, 60000); }); diff --git a/superset-frontend/src/pages/AnnotationLayerList/AnnotationLayerList.test.tsx b/superset-frontend/src/pages/AnnotationLayerList/AnnotationLayerList.test.tsx index b8260d3ff3f..ecc32e2c614 100644 --- a/superset-frontend/src/pages/AnnotationLayerList/AnnotationLayerList.test.tsx +++ b/superset-frontend/src/pages/AnnotationLayerList/AnnotationLayerList.test.tsx @@ -205,6 +205,6 @@ describe('AnnotationLayersList', () => { fireEvent.click(bulkSelectButton); // Wait for bulk select mode to be enabled - await screen.findByText('0 Selected'); + expect(await screen.findByText('0 Selected')).toBeInTheDocument(); }, 30000); }); diff --git a/superset-frontend/src/pages/ChartCreation/ChartCreation.test.tsx b/superset-frontend/src/pages/ChartCreation/ChartCreation.test.tsx index 4d8311548ac..58fb5fad213 100644 --- a/superset-frontend/src/pages/ChartCreation/ChartCreation.test.tsx +++ b/superset-frontend/src/pages/ChartCreation/ChartCreation.test.tsx @@ -260,7 +260,7 @@ test('handles special characters in dataset name from URL parameter', async () = await renderComponent(); - await screen.findByText('flightsÆ test'); + expect(await screen.findByText('flightsÆ test')).toBeInTheDocument(); Object.defineProperty(window, 'location', { value: originalLocation, @@ -294,7 +294,7 @@ test('pre-selects the dataset from URL parameter and shows it in dropdown', asyn await renderComponent(); - await screen.findByText('flights'); + expect(await screen.findByText('flights')).toBeInTheDocument(); Object.defineProperty(window, 'location', { value: originalLocation, diff --git a/superset-frontend/src/pages/CssTemplateList/CssTemplateList.test.tsx b/superset-frontend/src/pages/CssTemplateList/CssTemplateList.test.tsx index 418c2da1216..f47434443f3 100644 --- a/superset-frontend/src/pages/CssTemplateList/CssTemplateList.test.tsx +++ b/superset-frontend/src/pages/CssTemplateList/CssTemplateList.test.tsx @@ -196,6 +196,6 @@ describe('CssTemplatesList', () => { fireEvent.click(bulkSelectButton); // Wait for bulk select mode to be enabled - await screen.findByText('0 Selected'); + expect(await screen.findByText('0 Selected')).toBeInTheDocument(); }, 30000); });
