From 7ec2ef1bfed039228b466eb717196a459e7b7989 Mon Sep 17 00:00:00 2001 From: James Cocker Date: Tue, 9 Dec 2025 11:07:46 +0000 Subject: [PATCH 1/7] Added functionality however resizeObserver is getting old state Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.tsx | 66 ++++++++++++++++++- .../CollapsibleSideBar.module.css | 1 - 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx index 8edd3351..637eaffd 100644 --- a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx +++ b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx @@ -5,7 +5,7 @@ */ 'use client'; -import { useMemo, useState } from 'react'; +import { useEffect, useMemo, useRef, useState } from 'react'; import { HeaderMenuButton, SideNavItems, Search, Button, InlineNotification } from '@carbon/react'; import { Add } from '@carbon/icons-react'; import styles from '@/styles/test-runs/saved-queries/CollapsibleSideBar.module.css'; @@ -57,12 +57,35 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS // State to hold the data of the item currently being dragged for the DragOverlay const [activeQuery, setActiveQuery] = useState(null); + const [sideNavExpandedHeight, setSideNavExpandedHeight] = useState(0); + // const [isObservingMainContentElement, setIsObservingMainContentElement] = useState(false); + const [mainContentElement, setMainContentElement] = useState(null); + // let mainContentElement: Element | null = null; + const maxNumberOfSavedQueriesToNotResizeFor = 9; // Does not include default query. + // const resizeObserver = useRef(null); + // Isolate user-sortable queries from the default query const sortableQueries = useMemo( () => savedQueries.filter((query) => query.createdAt !== defaultQuery.createdAt), [savedQueries, defaultQuery] ); + const updateSideNavHeight = () => { + // Only dynamically change the height when there are enough saved queries to warrent it (due to flickering caused by flipping the heights around). + console.log(filteredSortableQueries.length + " " + maxNumberOfSavedQueriesToNotResizeFor + " " + mainContentElement); + if (filteredSortableQueries.length > maxNumberOfSavedQueriesToNotResizeFor && mainContentElement) { + + // As the mainContent for the test runs details is also flex, we must set this height to 0, wait a short while, then set the height of this element to the main content minus an offset. + setSideNavExpandedHeight(0); + setTimeout(() => { + if (mainContentElement) { // The line below seems to need mainContentElement checked inside the setTimeout(). + const newHeight = mainContentElement.clientHeight - 50; + setSideNavExpandedHeight(newHeight); + } + }, 1); + } + }; + const sensors = useSensors( useSensor(PointerSensor), useSensor(TouchSensor), @@ -148,6 +171,46 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS return sortableQueries; }, [searchTerm, sortableQueries]); + useEffect(() => { + updateSideNavHeight(); + }, [filteredSortableQueries]) + + // Grab the main content element on page load. + useEffect(() => { + setMainContentElement(document.querySelector('.TestRunsPage_mainContent__Ftan5')); + // mainContentElement = document.querySelector('.TestRunsPage_mainContent__Ftan5'); + }, []); + + useEffect(() => { + // Initial update + updateSideNavHeight(); + + if (filteredSortableQueries.length <= maxNumberOfSavedQueriesToNotResizeFor) { + // Default constianer to a calculated height. + // + 3 for the Title, search bar and saved query rows, * 50(px) for each row. + setSideNavExpandedHeight((maxNumberOfSavedQueriesToNotResizeFor + 3) * 50); + } + + // Add event listener for main content resize. + const resizeObserver = new ResizeObserver(entries => { + if (entries[0]) { // Check if there's a valid entry. + updateSideNavHeight(); + } + }); + + if (mainContentElement) { + console.log("Making new reseizer") + resizeObserver.observe(mainContentElement); + } + + // Cleanup function to remove the event listener when the component unmounts + return () => { + if (mainContentElement) { + resizeObserver.unobserve(mainContentElement); + } + }; + }, [mainContentElement]) + return (
diff --git a/galasa-ui/src/styles/test-runs/saved-queries/CollapsibleSideBar.module.css b/galasa-ui/src/styles/test-runs/saved-queries/CollapsibleSideBar.module.css index 1ff3e9d7..b2944dca 100644 --- a/galasa-ui/src/styles/test-runs/saved-queries/CollapsibleSideBar.module.css +++ b/galasa-ui/src/styles/test-runs/saved-queries/CollapsibleSideBar.module.css @@ -36,7 +36,6 @@ max-width: 360px; background-color: var(--cds-layer); border-right: 1px solid var(--cds-border-subtle); - height: 800px; overflow-y: auto; overflow-x: hidden; } From 94255f57cc462b43be0eaa58ee786386343e06c9 Mon Sep 17 00:00:00 2001 From: James Cocker Date: Tue, 9 Dec 2025 12:32:51 +0000 Subject: [PATCH 2/7] Remove max elements to ignore height resizing Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.tsx | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx index 637eaffd..0fd8588b 100644 --- a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx +++ b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx @@ -5,7 +5,7 @@ */ 'use client'; -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useState } from 'react'; import { HeaderMenuButton, SideNavItems, Search, Button, InlineNotification } from '@carbon/react'; import { Add } from '@carbon/icons-react'; import styles from '@/styles/test-runs/saved-queries/CollapsibleSideBar.module.css'; @@ -58,11 +58,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const [activeQuery, setActiveQuery] = useState(null); const [sideNavExpandedHeight, setSideNavExpandedHeight] = useState(0); - // const [isObservingMainContentElement, setIsObservingMainContentElement] = useState(false); const [mainContentElement, setMainContentElement] = useState(null); - // let mainContentElement: Element | null = null; - const maxNumberOfSavedQueriesToNotResizeFor = 9; // Does not include default query. - // const resizeObserver = useRef(null); // Isolate user-sortable queries from the default query const sortableQueries = useMemo( @@ -72,8 +68,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const updateSideNavHeight = () => { // Only dynamically change the height when there are enough saved queries to warrent it (due to flickering caused by flipping the heights around). - console.log(filteredSortableQueries.length + " " + maxNumberOfSavedQueriesToNotResizeFor + " " + mainContentElement); - if (filteredSortableQueries.length > maxNumberOfSavedQueriesToNotResizeFor && mainContentElement) { + if (mainContentElement) { // As the mainContent for the test runs details is also flex, we must set this height to 0, wait a short while, then set the height of this element to the main content minus an offset. setSideNavExpandedHeight(0); @@ -82,7 +77,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const newHeight = mainContentElement.clientHeight - 50; setSideNavExpandedHeight(newHeight); } - }, 1); + }, 0); } }; @@ -178,19 +173,12 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS // Grab the main content element on page load. useEffect(() => { setMainContentElement(document.querySelector('.TestRunsPage_mainContent__Ftan5')); - // mainContentElement = document.querySelector('.TestRunsPage_mainContent__Ftan5'); }, []); useEffect(() => { // Initial update updateSideNavHeight(); - if (filteredSortableQueries.length <= maxNumberOfSavedQueriesToNotResizeFor) { - // Default constianer to a calculated height. - // + 3 for the Title, search bar and saved query rows, * 50(px) for each row. - setSideNavExpandedHeight((maxNumberOfSavedQueriesToNotResizeFor + 3) * 50); - } - // Add event listener for main content resize. const resizeObserver = new ResizeObserver(entries => { if (entries[0]) { // Check if there's a valid entry. @@ -199,8 +187,9 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS }); if (mainContentElement) { - console.log("Making new reseizer") resizeObserver.observe(mainContentElement); + } else { + setSideNavExpandedHeight(800); } // Cleanup function to remove the event listener when the component unmounts From 760b9b8bca1e624a5d4a6248d7b35351862b665c Mon Sep 17 00:00:00 2001 From: James Cocker Date: Tue, 9 Dec 2025 12:39:52 +0000 Subject: [PATCH 3/7] Remove updating height on filtered query change and small formatting + comment changes Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.tsx | 16 ++++++---------- .../src/styles/test-runs/TestRunsPage.module.css | 1 - 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx index 0fd8588b..18f7fe2b 100644 --- a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx +++ b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx @@ -67,13 +67,12 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS ); const updateSideNavHeight = () => { - // Only dynamically change the height when there are enough saved queries to warrent it (due to flickering caused by flipping the heights around). if (mainContentElement) { - // As the mainContent for the test runs details is also flex, we must set this height to 0, wait a short while, then set the height of this element to the main content minus an offset. setSideNavExpandedHeight(0); setTimeout(() => { - if (mainContentElement) { // The line below seems to need mainContentElement checked inside the setTimeout(). + // The .clientHeight seems to need mainContentElement checked inside the setTimeout(). + if (mainContentElement) { const newHeight = mainContentElement.clientHeight - 50; setSideNavExpandedHeight(newHeight); } @@ -166,10 +165,6 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS return sortableQueries; }, [searchTerm, sortableQueries]); - useEffect(() => { - updateSideNavHeight(); - }, [filteredSortableQueries]) - // Grab the main content element on page load. useEffect(() => { setMainContentElement(document.querySelector('.TestRunsPage_mainContent__Ftan5')); @@ -180,8 +175,9 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS updateSideNavHeight(); // Add event listener for main content resize. - const resizeObserver = new ResizeObserver(entries => { - if (entries[0]) { // Check if there's a valid entry. + const resizeObserver = new ResizeObserver((entries) => { + // Check if there's a valid entry. + if (entries[0]) { updateSideNavHeight(); } }); @@ -198,7 +194,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS resizeObserver.unobserve(mainContentElement); } }; - }, [mainContentElement]) + }, [mainContentElement]); return (
diff --git a/galasa-ui/src/styles/test-runs/TestRunsPage.module.css b/galasa-ui/src/styles/test-runs/TestRunsPage.module.css index 3b1af1d1..2ef84079 100644 --- a/galasa-ui/src/styles/test-runs/TestRunsPage.module.css +++ b/galasa-ui/src/styles/test-runs/TestRunsPage.module.css @@ -410,4 +410,3 @@ inset: 0; z-index: 1; } - From 35516401c5233a378ec34df31337a7b9b7ebcfbe Mon Sep 17 00:00:00 2001 From: James Cocker Date: Tue, 9 Dec 2025 12:50:02 +0000 Subject: [PATCH 4/7] Add a minimum value for the side nav, instead of 0, to reduce flickering effect Signed-off-by: James Cocker --- .../test-runs/saved-queries/CollapsibleSideBar.tsx | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx index 18f7fe2b..94665940 100644 --- a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx +++ b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx @@ -6,9 +6,10 @@ 'use client'; import { useEffect, useMemo, useState } from 'react'; -import { HeaderMenuButton, SideNavItems, Search, Button, InlineNotification } from '@carbon/react'; +import { HeaderMenuButton, Search, Button, InlineNotification } from '@carbon/react'; import { Add } from '@carbon/icons-react'; import styles from '@/styles/test-runs/saved-queries/CollapsibleSideBar.module.css'; +import testRunsPageStyles from '@/styles/test-runs/TestRunsPage.module.css'; import { arrayMove, SortableContext, @@ -59,6 +60,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const [sideNavExpandedHeight, setSideNavExpandedHeight] = useState(0); const [mainContentElement, setMainContentElement] = useState(null); + const SIDE_NAV_MIN_HEIGHT = 700; // Isolate user-sortable queries from the default query const sortableQueries = useMemo( @@ -68,8 +70,8 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const updateSideNavHeight = () => { if (mainContentElement) { - // As the mainContent for the test runs details is also flex, we must set this height to 0, wait a short while, then set the height of this element to the main content minus an offset. - setSideNavExpandedHeight(0); + // As the mainContent for the test runs details is also flex, we must set this height to a minimum (700), wait a short while, then set the height of this element to the main content minus an offset. + setSideNavExpandedHeight(SIDE_NAV_MIN_HEIGHT); setTimeout(() => { // The .clientHeight seems to need mainContentElement checked inside the setTimeout(). if (mainContentElement) { @@ -167,7 +169,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS // Grab the main content element on page load. useEffect(() => { - setMainContentElement(document.querySelector('.TestRunsPage_mainContent__Ftan5')); + setMainContentElement(document.querySelector('.' + testRunsPageStyles.mainContent)); }, []); useEffect(() => { From a8e77463773e491c58582380423de0d9ef6fd498 Mon Sep 17 00:00:00 2001 From: James Cocker Date: Thu, 11 Dec 2025 12:03:34 +0000 Subject: [PATCH 5/7] New tests working, some old tests are broken Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.test.tsx | 141 +++++++++++++++++- 1 file changed, 139 insertions(+), 2 deletions(-) diff --git a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx index 1e30e472..feb6dcd7 100644 --- a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx +++ b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx @@ -3,9 +3,9 @@ * * SPDX-License-Identifier: EPL-2.0 */ -import React from 'react'; +import React, { act } from 'react'; import '@testing-library/jest-dom'; -import { fireEvent, render, screen } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import CollapsibleSideBar from '@/components/test-runs/saved-queries/CollapsibleSideBar'; import { useSavedQueries } from '@/contexts/SavedQueriesContext'; import { useTestRunsQueryParams } from '@/contexts/TestRunsQueryParamsContext'; @@ -22,6 +22,9 @@ const mockQueries = [ { createdAt: '2023-01-02T00:00:00Z', title: 'Test Run 2', url: '' }, { createdAt: '2023-01-03T00:00:00Z', title: 'Test Run 3', url: '' }, ]; +let resizeObserverMock: jest.Mock; +let mockObserve: jest.Mock; +let mockUnobserve: jest.Mock; // Mock child components jest.mock('@/components/test-runs/saved-queries/QueryItem', () => ({ @@ -40,6 +43,10 @@ jest.mock('@/contexts/TestRunsQueryParamsContext', () => ({ useTestRunsQueryParams: jest.fn(), })); +jest.mock('@/styles/test-runs/TestRunsPage.module.css', () => ({ + mainContent: "TestRunsPage_mainContent__Ftan5" +})); + // Mock the DndContext to capture the onDragEnd function for testing let capturedOnDragEnd: (event: any) => void; jest.mock('@dnd-kit/core', () => ({ @@ -83,6 +90,19 @@ beforeEach(() => { defaultQuery: mockQueries[0], setSavedQueries: mockSetSavedQueries, })); + + resizeObserverMock = jest.fn().mockImplementation(() => { + mockObserve = jest.fn(); + mockUnobserve = jest.fn(); + const mockDisconnect = jest.fn(); + + return { + observe: mockObserve, + unobserve: mockUnobserve, + disconnect: mockDisconnect, + }; + }); + window.ResizeObserver = resizeObserverMock; }); describe('CollapsibleSideBar', () => { @@ -336,4 +356,121 @@ describe('CollapsibleSideBar', () => { expect(mockSetSavedQueries).not.toHaveBeenCalled(); }); }); + + describe('updating side nav height', () => { + test('should not observe the main content if main content not loaded', async () => { + await act(async () => { + render(); + }) + + expect(mockObserve).toHaveBeenCalledTimes(0); + }); + + test('should observe the main content if main content rendered', async () => { + const mainContentElement = document.createElement('div'); + mainContentElement.className = "TestRunsPage_mainContent__Ftan5"; + document.body.appendChild(mainContentElement); + + render(); + + const sidebar = screen.getByLabelText('Saved Queries Sidebar'); + + await waitFor(() => { + expect(mockObserve).toHaveBeenCalledTimes(1); + + if (sidebar) { + expect(sidebar.style.height).toBe("-50px"); + } else { + fail('could not find sidebar'); + + } + + document.body.innerHTML = ''; + }); + }); + + // const sidebar = screen.getByLabelText('Saved Queries Sidebar'); + // const headerButton = screen.getByRole('button', { name: 'Saved Queries' }); + + // // Click the header button to expand the sidebar + // fireEvent.click(headerButton); + + // // Simulate the mainContentElement resizing + // const mainContentElement = screen.getByRole('main'); + // fireEvent.resize(mainContentElement, { clientHeight: 1500 }); + + // // Assert that the side nav height is updated correctly + // expect(CollapsibleSideBar.).toHaveBeenCalled(); + // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(700); + // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(1500 - 50); + + + // it('should observe the mainContentElement and update side nav height on resize', () => { + // // Insert test data into savedQueries + // const savedQueries = [ + // { createdAt: '2023-01-01T00:00:00Z', title: 'Test Run 1', url: '' }, + // { createdAt: '2023-01-02T00:00:00Z', title: 'Test Run 2', url: '' }, + // { createdAt: '2023-01-03T00:00:00Z', title: 'Test Run 3', url: '' }, + // ]; + + // // Render the CollapsibleSideBar component with the test data + // render(); + + // // Simulate the mainContentElement resizing + // const mainContentElement = screen.getByRole('main'); + // fireEvent.resize(mainContentElement, { clientHeight: 1500 }); + + // // Assert that the side nav height is updated correctly + // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(700); + // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(1500 - 50); + // }); + + // it('should not update side nav height if mainContentElement is null', () => { + // // Render the CollapsibleSideBar component without mainContentElement + // render(); + + // // Simulate the mainContentElement being null + // const mainContentElement = screen.getByRole('main', { hidden: true }); + + // // Assert that the side nav height is not updated + // expect(CollapsibleSideBar.setSideNavExpandedHeight).not.toHaveBeenCalled(); + // }); + + }); }); + +// describe('Resizable height', () => { +// jest.mock('@/components/test-runs/saved-queries/CollapsibleSideBar', () => ({ +// ...jest.requireActual('@/components/test-runs/saved-queries/CollapsibleSideBar'), +// setSideNavExpandedHeight: jest.fn(), +// setMainContentElement: jest.fn(), +// })); + +// beforeEach(() => { +// setSideNavExpandedHeight.mockReset(); +// setMainContentElement.mockReset(); +// }); + +// it('should update side nav height correctly', () => { +// const mockMainContentElement = { clientHeight: 1200 }; +// setMainContentElement.mockReturnValueOnce(mockMainContentElement); + +// act(() => { +// CollapsibleSideBar.updateSideNavHeight(); +// }); + +// expect(setSideNavExpandedHeight).toHaveBeenCalledWith(700); +// expect(setSideNavExpandedHeight).toHaveBeenCalledWith(mockMainContentElement.clientHeight - 50); +// }); + +// it('should not update side nav height if mainContentElement is null', () => { +// setMainContentElement.mockReturnValueOnce(null); + +// act(() => { +// CollapsibleSideBar.updateSideNavHeight(); +// }); + +// expect(setSideNavExpandedHeight).not.toHaveBeenCalled(); +// }); + +// }) From c228db0480b1de4e46fad5a29a5682035516eb85 Mon Sep 17 00:00:00 2001 From: James Cocker Date: Thu, 11 Dec 2025 12:26:11 +0000 Subject: [PATCH 6/7] Fixed failing tests, added comments and improved readability Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.test.tsx | 107 ++---------------- 1 file changed, 11 insertions(+), 96 deletions(-) diff --git a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx index feb6dcd7..116ec220 100644 --- a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx +++ b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: EPL-2.0 */ -import React, { act } from 'react'; +import React from 'react'; import '@testing-library/jest-dom'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import CollapsibleSideBar from '@/components/test-runs/saved-queries/CollapsibleSideBar'; @@ -43,8 +43,11 @@ jest.mock('@/contexts/TestRunsQueryParamsContext', () => ({ useTestRunsQueryParams: jest.fn(), })); +// Stylesheet seems to somehow override CollapsibleSideBar.module.css, so the extra necessary items have been added in here. jest.mock('@/styles/test-runs/TestRunsPage.module.css', () => ({ - mainContent: "TestRunsPage_mainContent__Ftan5" + mainContent: 'TestRunsPage_mainContent__Ftan5', + sideNavCollapsed: 'sideNavCollapsed', + sideNavExpanded: 'sideNavExpanded', })); // Mock the DndContext to capture the onDragEnd function for testing @@ -359,16 +362,13 @@ describe('CollapsibleSideBar', () => { describe('updating side nav height', () => { test('should not observe the main content if main content not loaded', async () => { - await act(async () => { - render(); - }) - - expect(mockObserve).toHaveBeenCalledTimes(0); + render(); + expect(mockObserve).toHaveBeenCalledTimes(0); }); - test('should observe the main content if main content rendered', async () => { + test('should observe the main content if main content rendered, and set to height of main content -50px', async () => { const mainContentElement = document.createElement('div'); - mainContentElement.className = "TestRunsPage_mainContent__Ftan5"; + mainContentElement.className = 'TestRunsPage_mainContent__Ftan5'; document.body.appendChild(mainContentElement); render(); @@ -379,98 +379,13 @@ describe('CollapsibleSideBar', () => { expect(mockObserve).toHaveBeenCalledTimes(1); if (sidebar) { - expect(sidebar.style.height).toBe("-50px"); + expect(sidebar.style.height).toBe('-50px'); } else { fail('could not find sidebar'); - } - + document.body.innerHTML = ''; }); }); - - // const sidebar = screen.getByLabelText('Saved Queries Sidebar'); - // const headerButton = screen.getByRole('button', { name: 'Saved Queries' }); - - // // Click the header button to expand the sidebar - // fireEvent.click(headerButton); - - // // Simulate the mainContentElement resizing - // const mainContentElement = screen.getByRole('main'); - // fireEvent.resize(mainContentElement, { clientHeight: 1500 }); - - // // Assert that the side nav height is updated correctly - // expect(CollapsibleSideBar.).toHaveBeenCalled(); - // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(700); - // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(1500 - 50); - - - // it('should observe the mainContentElement and update side nav height on resize', () => { - // // Insert test data into savedQueries - // const savedQueries = [ - // { createdAt: '2023-01-01T00:00:00Z', title: 'Test Run 1', url: '' }, - // { createdAt: '2023-01-02T00:00:00Z', title: 'Test Run 2', url: '' }, - // { createdAt: '2023-01-03T00:00:00Z', title: 'Test Run 3', url: '' }, - // ]; - - // // Render the CollapsibleSideBar component with the test data - // render(); - - // // Simulate the mainContentElement resizing - // const mainContentElement = screen.getByRole('main'); - // fireEvent.resize(mainContentElement, { clientHeight: 1500 }); - - // // Assert that the side nav height is updated correctly - // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(700); - // expect(CollapsibleSideBar.setSideNavExpandedHeight).toHaveBeenCalledWith(1500 - 50); - // }); - - // it('should not update side nav height if mainContentElement is null', () => { - // // Render the CollapsibleSideBar component without mainContentElement - // render(); - - // // Simulate the mainContentElement being null - // const mainContentElement = screen.getByRole('main', { hidden: true }); - - // // Assert that the side nav height is not updated - // expect(CollapsibleSideBar.setSideNavExpandedHeight).not.toHaveBeenCalled(); - // }); - }); }); - -// describe('Resizable height', () => { -// jest.mock('@/components/test-runs/saved-queries/CollapsibleSideBar', () => ({ -// ...jest.requireActual('@/components/test-runs/saved-queries/CollapsibleSideBar'), -// setSideNavExpandedHeight: jest.fn(), -// setMainContentElement: jest.fn(), -// })); - -// beforeEach(() => { -// setSideNavExpandedHeight.mockReset(); -// setMainContentElement.mockReset(); -// }); - -// it('should update side nav height correctly', () => { -// const mockMainContentElement = { clientHeight: 1200 }; -// setMainContentElement.mockReturnValueOnce(mockMainContentElement); - -// act(() => { -// CollapsibleSideBar.updateSideNavHeight(); -// }); - -// expect(setSideNavExpandedHeight).toHaveBeenCalledWith(700); -// expect(setSideNavExpandedHeight).toHaveBeenCalledWith(mockMainContentElement.clientHeight - 50); -// }); - -// it('should not update side nav height if mainContentElement is null', () => { -// setMainContentElement.mockReturnValueOnce(null); - -// act(() => { -// CollapsibleSideBar.updateSideNavHeight(); -// }); - -// expect(setSideNavExpandedHeight).not.toHaveBeenCalled(); -// }); - -// }) From 9f7d72ccfc56a32079ea0551fe314d22011e760c Mon Sep 17 00:00:00 2001 From: James Cocker Date: Thu, 11 Dec 2025 13:55:06 +0000 Subject: [PATCH 7/7] Minor refactoring of implementation and removed styles mock in test Signed-off-by: James Cocker --- .../saved-queries/CollapsibleSideBar.tsx | 33 ++++++++++--------- .../saved-queries/CollapsibleSideBar.test.tsx | 9 +---- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx index 94665940..ac592332 100644 --- a/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx +++ b/galasa-ui/src/components/test-runs/saved-queries/CollapsibleSideBar.tsx @@ -60,7 +60,8 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS const [sideNavExpandedHeight, setSideNavExpandedHeight] = useState(0); const [mainContentElement, setMainContentElement] = useState(null); - const SIDE_NAV_MIN_HEIGHT = 700; + const SIDE_NAV_MIN_HEIGHT_PIXELS = 700; + const SIDE_NAV_HEIGHT_IF_NOT_RESIZABLE_PIXELS = 850; // Isolate user-sortable queries from the default query const sortableQueries = useMemo( @@ -68,20 +69,6 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS [savedQueries, defaultQuery] ); - const updateSideNavHeight = () => { - if (mainContentElement) { - // As the mainContent for the test runs details is also flex, we must set this height to a minimum (700), wait a short while, then set the height of this element to the main content minus an offset. - setSideNavExpandedHeight(SIDE_NAV_MIN_HEIGHT); - setTimeout(() => { - // The .clientHeight seems to need mainContentElement checked inside the setTimeout(). - if (mainContentElement) { - const newHeight = mainContentElement.clientHeight - 50; - setSideNavExpandedHeight(newHeight); - } - }, 0); - } - }; - const sensors = useSensors( useSensor(PointerSensor), useSensor(TouchSensor), @@ -173,6 +160,20 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS }, []); useEffect(() => { + const updateSideNavHeight = () => { + if (mainContentElement) { + // As the mainContent for the test runs details is also flex, we must set this height to a minimum, wait a short while, then set the height of this element to the main content minus an offset. + setSideNavExpandedHeight(SIDE_NAV_MIN_HEIGHT_PIXELS); + setTimeout(() => { + // The .clientHeight seems to need mainContentElement checked inside the setTimeout(). + if (mainContentElement) { + const newHeight = mainContentElement.clientHeight - 50; + setSideNavExpandedHeight(newHeight); + } + }, 0); + } + }; + // Initial update updateSideNavHeight(); @@ -187,7 +188,7 @@ export default function CollapsibleSideBar({ handleEditQueryName }: CollapsibleS if (mainContentElement) { resizeObserver.observe(mainContentElement); } else { - setSideNavExpandedHeight(800); + setSideNavExpandedHeight(SIDE_NAV_HEIGHT_IF_NOT_RESIZABLE_PIXELS); } // Cleanup function to remove the event listener when the component unmounts diff --git a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx index 116ec220..6cdd91db 100644 --- a/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx +++ b/galasa-ui/src/tests/components/test-runs/saved-queries/CollapsibleSideBar.test.tsx @@ -43,13 +43,6 @@ jest.mock('@/contexts/TestRunsQueryParamsContext', () => ({ useTestRunsQueryParams: jest.fn(), })); -// Stylesheet seems to somehow override CollapsibleSideBar.module.css, so the extra necessary items have been added in here. -jest.mock('@/styles/test-runs/TestRunsPage.module.css', () => ({ - mainContent: 'TestRunsPage_mainContent__Ftan5', - sideNavCollapsed: 'sideNavCollapsed', - sideNavExpanded: 'sideNavExpanded', -})); - // Mock the DndContext to capture the onDragEnd function for testing let capturedOnDragEnd: (event: any) => void; jest.mock('@dnd-kit/core', () => ({ @@ -368,7 +361,7 @@ describe('CollapsibleSideBar', () => { test('should observe the main content if main content rendered, and set to height of main content -50px', async () => { const mainContentElement = document.createElement('div'); - mainContentElement.className = 'TestRunsPage_mainContent__Ftan5'; + mainContentElement.className = 'mainContent'; document.body.appendChild(mainContentElement); render();