This is an automated email from the ASF dual-hosted git repository.

sadpandajoe pushed a commit to branch test/dashboard-tabs-reveal-query
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 1ff35a26c891f530fff8a4dc5098b8ac94f5e6a5
Author: Joe Li <[email protected]>
AuthorDate: Fri Sep 25 15:58:46 2026 -0700

    test(dashboard): cover tab switching visibility and hidden chart updates
    
    Adds regression coverage for dashboard tabs:
    - Switching tabs selects the clicked tab, exposes only its panel, and 
renders its content as visible
    - A chart hidden in an inactive tab skips prop updates and adopts them once 
revealed
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../components/gridComponents/Chart/Chart.test.tsx | 16 +++++++
 .../components/gridComponents/Tabs/Tabs.test.tsx   | 52 ++++++++++++++++++++++
 2 files changed, 68 insertions(+)

diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.test.tsx
 
b/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.test.tsx
index a8870bcc30c..afc8d505404 100644
--- 
a/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.test.tsx
+++ 
b/superset-frontend/src/dashboard/components/gridComponents/Chart/Chart.test.tsx
@@ -892,3 +892,19 @@ test('Existing expand/collapse behavior continues to 
work', () => {
     restore();
   }
 });
+
+test('a hidden chart does not adopt a prop update, and adopts it once 
revealed', () => {
+  const { rerender } = setup({ isComponentVisible: false, isInView: false });
+  expect(capturedChartContainerProps.isInView).toBe(false);
+
+  // The parent passes an updated prop while the chart is still hidden: the
+  // memoized export bails out, so the prop update never reaches
+  // ChartContainer while the tab is hidden. Store-driven updates (such as a
+  // query trigger read via useSelector) are not gated by this memo.
+  rerender(<Chart {...props} isComponentVisible={false} isInView />);
+  expect(capturedChartContainerProps.isInView).toBe(false);
+
+  // Revealing the tab lets the chart re-render and adopt the pending update.
+  rerender(<Chart {...props} isComponentVisible isInView />);
+  expect(capturedChartContainerProps.isInView).toBe(true);
+});
diff --git 
a/superset-frontend/src/dashboard/components/gridComponents/Tabs/Tabs.test.tsx 
b/superset-frontend/src/dashboard/components/gridComponents/Tabs/Tabs.test.tsx
index 0d31b9b3514..c3270b46e8a 100644
--- 
a/superset-frontend/src/dashboard/components/gridComponents/Tabs/Tabs.test.tsx
+++ 
b/superset-frontend/src/dashboard/components/gridComponents/Tabs/Tabs.test.tsx
@@ -265,6 +265,58 @@ test('Switching tabs', async () => {
   expect(props.onChangeTab).toHaveBeenCalled();
 });
 
+test('Switching tabs shows the newly selected tab content and hides the 
previous one', async () => {
+  const props = createProps();
+  render(<Tabs {...props} />, {
+    useRedux: true,
+    useDnd: true,
+  });
+  const [firstTabId, , thirdTabId] = props.component.children;
+
+  // The first tab starts selected and its panel is the only one exposed
+  // to the accessibility tree.
+  let tabs = screen.getAllByRole('tab');
+  expect(tabs[0]).toHaveAttribute('aria-selected', 'true');
+  expect(tabs[2]).toHaveAttribute('aria-selected', 'false');
+  expect(screen.getByRole('tabpanel').id).toContain(firstTabId);
+
+  await userEvent.click(tabs[2]);
+
+  // After switching, the clicked tab is selected and its content panel
+  // becomes the only one exposed to the accessibility tree...
+  tabs = screen.getAllByRole('tab');
+  expect(tabs[2]).toHaveAttribute('aria-selected', 'true');
+  expect(tabs[0]).toHaveAttribute('aria-selected', 'false');
+  expect(screen.getByRole('tabpanel').id).toContain(thirdTabId);
+
+  // ...while the previously active tab's panel is hidden from it.
+  const firstPanel = screen
+    .getAllByRole('tabpanel', { hidden: true })
+    .find(panel => panel.id.includes(firstTabId));
+  expect(firstPanel).toHaveAttribute('aria-hidden', 'true');
+
+  // The selected tab's content is the one rendered as visible, which is what
+  // lets its charts pick up updates once revealed.
+  const lastContentPropsFor = (tabId: string) =>
+    (DashboardComponent as unknown as jest.Mock).mock.calls
+      .map(
+        call =>
+          call[0] as {
+            id: string;
+            renderType: string;
+            isComponentVisible?: boolean;
+          },
+      )
+      .filter(
+        componentProps =>
+          componentProps.renderType === RENDER_TAB_CONTENT &&
+          componentProps.id === tabId,
+      )
+      .at(-1);
+  expect(lastContentPropsFor(thirdTabId)?.isComponentVisible).toBe(true);
+  expect(lastContentPropsFor(firstTabId)?.isComponentVisible).not.toBe(true);
+});
+
 test.each([false, true])(
   'A childless TABS component does not register an active tab (editMode=%s)',
   editMode => {

Reply via email to