@@ -259,5 +259,91 @@ test.describe('Search', { tag: '@search' }, () => {
259259 expect ( rowCount ) . toBeGreaterThan ( 0 ) ;
260260 } ) ;
261261 } ) ;
262+
263+ test ( 'Histogram drag-to-zoom preserves custom SELECT columns' , async ( {
264+ page,
265+ } ) => {
266+ const CUSTOM_SELECT =
267+ 'Timestamp, ServiceName, Body as message, SeverityText' ;
268+
269+ await test . step ( 'Perform initial search' , async ( ) => {
270+ await expect ( page . locator ( '[data-testid="search-form"]' ) ) . toBeVisible ( ) ;
271+ await page . locator ( '[data-testid="search-submit-button"]' ) . click ( ) ;
272+ await page . waitForLoadState ( 'networkidle' ) ;
273+ } ) ;
274+
275+ await test . step ( 'Setup custom SELECT columns' , async ( ) => {
276+ // The SELECT field is the first CodeMirror editor (index 0)
277+ const selectEditor = page . locator ( '.cm-content' ) . first ( ) ;
278+ await expect ( selectEditor ) . toBeVisible ( ) ;
279+
280+ // Select all and replace with custom columns
281+ await selectEditor . click ( { clickCount : 3 } ) ;
282+ await page . keyboard . type ( CUSTOM_SELECT ) ;
283+ } ) ;
284+
285+ await test . step ( 'Search with custom columns and wait for histogram' , async ( ) => {
286+ await page . locator ( '[data-testid="search-submit-button"]' ) . click ( ) ;
287+ await page . waitForLoadState ( 'networkidle' ) ;
288+
289+ // Wait for histogram to render with data
290+ await expect (
291+ page . locator ( '.recharts-responsive-container' ) . first ( ) ,
292+ ) . toBeVisible ( ) ;
293+ } ) ;
294+
295+ await test . step ( 'Drag on histogram to select time range' , async ( ) => {
296+ const chartSurface = page . locator ( '.recharts-surface' ) . first ( ) ;
297+ await expect ( chartSurface ) . toBeVisible ( ) ;
298+
299+ const box = await chartSurface . boundingBox ( ) ;
300+ expect ( box ) . toBeTruthy ( ) ;
301+
302+ // Drag from 25% to 75% of chart width to zoom into a time range
303+ const startX = box ! . x + box ! . width * 0.25 ;
304+ const endX = box ! . x + box ! . width * 0.75 ;
305+ const y = box ! . y + box ! . height / 2 ;
306+
307+ await page . mouse . move ( startX , y ) ;
308+ await page . mouse . down ( ) ;
309+ await page . mouse . move ( endX , y , { steps : 10 } ) ;
310+ await page . mouse . up ( ) ;
311+
312+ // Wait for the zoom operation to complete
313+ await page . waitForLoadState ( 'networkidle' ) ;
314+ } ) ;
315+
316+ await test . step ( 'Verify custom SELECT columns are preserved' , async ( ) => {
317+ // Check URL parameters
318+ const url = page . url ( ) ;
319+ expect ( url , 'URL should contain select parameter' ) . toContain ( 'select=' ) ;
320+ expect ( url , 'URL should contain alias "message"' ) . toContain ( 'message' ) ;
321+
322+ // Verify SELECT editor content
323+ const selectEditor = page . locator ( '.cm-content' ) . first ( ) ;
324+ await expect ( selectEditor ) . toBeVisible ( ) ;
325+ const selectValue = await selectEditor . textContent ( ) ;
326+
327+ expect ( selectValue , 'SELECT should contain alias' ) . toContain (
328+ 'Body as message' ,
329+ ) ;
330+ expect ( selectValue , 'SELECT should contain SeverityText' ) . toContain (
331+ 'SeverityText' ,
332+ ) ;
333+ } ) ;
334+
335+ await test . step ( 'Verify search results are still displayed' , async ( ) => {
336+ const searchResultsTable = page . locator (
337+ '[data-testid="search-results-table"]' ,
338+ ) ;
339+ await expect (
340+ searchResultsTable ,
341+ 'Search results table should be visible' ,
342+ ) . toBeVisible ( ) ;
343+
344+ const rowCount = await searchResultsTable . locator ( 'tr' ) . count ( ) ;
345+ expect ( rowCount , 'Should have search results' ) . toBeGreaterThan ( 0 ) ;
346+ } ) ;
347+ } ) ;
262348 } ) ;
263349} ) ;
0 commit comments