-
Notifications
You must be signed in to change notification settings - Fork 349
Fix bug where loading saved search from another page #1563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
72a3442
e77bf87
9dc8619
eaee985
2e34da9
7c1c27f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@hyperdx/app": patch | ||
| --- | ||
|
|
||
| Fix bug where loading saved search from another page might use default values instead |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| import { SearchPage } from '../../page-objects/SearchPage'; | ||
| import { expect, test } from '../../utils/base-test'; | ||
|
|
||
|
|
@@ -185,4 +185,178 @@ | |
| }); | ||
| }, | ||
| ); | ||
|
|
||
| test( | ||
| 'should load saved search when navigating from another page', | ||
| { tag: '@full-stack' }, | ||
| async ({ page }) => { | ||
| /** | ||
| * This test verifies the fix for the issue where saved searches would not | ||
| * load properly when users navigate to them from another page (e.g., service map). | ||
| * | ||
| * Test flow: | ||
| * 1. Create a saved search with custom configuration (WHERE and ORDER BY) | ||
| * 2. Navigate to a different page (service map) | ||
| * 3. Navigate to the saved search URL | ||
| * 4. Verify saved search loaded correctly with all configuration restored | ||
| */ | ||
|
|
||
| let savedSearchUrl: string; | ||
| const customOrderBy = 'ServiceName ASC'; | ||
|
|
||
| await test.step('Create a saved search with custom WHERE and ORDER BY', async () => { | ||
| // Set up a custom search with WHERE clause | ||
| // Use SeverityText which is a valid column in the demo data | ||
| await searchPage.performSearch('SeverityText:info'); | ||
|
|
||
| // Set custom ORDER BY | ||
| await searchPage.setCustomOrderBy(customOrderBy); | ||
|
|
||
| // Submit the search to ensure configuration is applied | ||
| await searchPage.submitButton.click(); | ||
|
Check failure on line 216 in packages/app/tests/e2e/features/search/saved-search.spec.ts
|
||
| await searchPage.table.waitForRowsToPopulate(); | ||
|
|
||
| // Save the search | ||
| await searchPage.openSaveSearchModal(); | ||
| await searchPage.savedSearchModal.saveSearch( | ||
| 'Info Logs Navigation Test', | ||
| ); | ||
|
|
||
| // Wait for save to complete and URL to change | ||
| await expect(searchPage.savedSearchModal.container).toBeHidden(); | ||
| await page.waitForURL(/\/search\/[a-f0-9]+/, { timeout: 5000 }); | ||
|
|
||
| // Capture the saved search URL (without query params) | ||
| savedSearchUrl = page.url().split('?')[0]; | ||
| }); | ||
|
|
||
| await test.step('Navigate to a different page (service map)', async () => { | ||
| // Navigate to service map page | ||
| await page.goto('/service-map'); | ||
|
|
||
| // Wait for service map page to load | ||
| await expect(page.getByTestId('service-map-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Navigate to saved search from service map', async () => { | ||
| // Navigate directly to the saved search URL (simulating clicking a link) | ||
| await page.goto(savedSearchUrl); | ||
|
|
||
| // Wait for the search page to load | ||
| await expect(page.getByTestId('search-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Verify saved search loaded and executed automatically', async () => { | ||
| // Verify the WHERE clause is populated | ||
| const whereInput = searchPage.input; | ||
| await expect(whereInput).toHaveValue('SeverityText:info'); | ||
|
|
||
| // Verify ORDER BY is restored | ||
| const orderByEditor = searchPage.getOrderByEditor(); | ||
| const orderByContent = await orderByEditor.textContent(); | ||
| expect(orderByContent).toContain('ServiceName ASC'); | ||
|
|
||
| // Verify search results are visible (search executed automatically) | ||
| await searchPage.table.waitForRowsToPopulate(); | ||
| const rowCount = await searchPage.table.getRows().count(); | ||
| expect(rowCount).toBeGreaterThan(0); | ||
|
|
||
| // Verify the search actually ran (not just showing cached results) | ||
| const resultsTable = searchPage.getSearchResultsTable(); | ||
| await expect(resultsTable).toBeVisible(); | ||
| }); | ||
| }, | ||
| ); | ||
|
|
||
| test( | ||
| 'should preserve custom SELECT when loading saved search from another page', | ||
| { tag: '@full-stack' }, | ||
| async ({ page }) => { | ||
| /** | ||
| * This test specifically verifies that custom SELECT statements are preserved | ||
| * when navigating to a saved search from another page. | ||
| */ | ||
|
|
||
| let savedSearchUrl: string; | ||
| const customSelect = | ||
| 'Timestamp, Body, upper(ServiceName) as service_name'; | ||
|
|
||
| await test.step('Create saved search with custom SELECT', async () => { | ||
| await searchPage.setCustomSELECT(customSelect); | ||
| await searchPage.performSearch('ServiceName:frontend'); | ||
| await searchPage.openSaveSearchModal(); | ||
| await searchPage.savedSearchModal.saveSearch( | ||
| 'Custom Select Navigation Test', | ||
| ); | ||
|
|
||
| await expect(searchPage.savedSearchModal.container).toBeHidden(); | ||
| await page.waitForURL(/\/search\/[a-f0-9]+/, { timeout: 5000 }); | ||
|
|
||
| savedSearchUrl = page.url().split('?')[0]; | ||
| }); | ||
|
|
||
| await test.step('Navigate to dashboards page', async () => { | ||
| await page.goto('/dashboards'); | ||
| await expect(page.getByTestId('dashboard-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Navigate back to saved search', async () => { | ||
| await page.goto(savedSearchUrl); | ||
| await expect(page.getByTestId('search-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Verify custom SELECT is preserved', async () => { | ||
| // Wait for results to load | ||
| await searchPage.table.waitForRowsToPopulate(); | ||
|
|
||
| // Verify SELECT content | ||
| const selectEditor = searchPage.getSELECTEditor(); | ||
| const selectContent = await selectEditor.textContent(); | ||
|
|
||
| expect(selectContent).toContain('upper(ServiceName) as service_name'); | ||
| expect(selectContent).toContain('Timestamp, Body'); | ||
| }); | ||
| }, | ||
| ); | ||
|
|
||
| test( | ||
| 'should handle navigation via browser back button', | ||
| { tag: '@full-stack' }, | ||
| async ({ page }) => { | ||
| /** | ||
| * This test verifies that using browser back/forward navigation | ||
| * properly loads saved searches. | ||
| */ | ||
|
|
||
| await test.step('Create and save a search', async () => { | ||
| await searchPage.performSearch('SeverityText:error'); | ||
| await searchPage.openSaveSearchModal(); | ||
| await searchPage.savedSearchModal.saveSearch('Browser Navigation Test'); | ||
|
|
||
| await expect(searchPage.savedSearchModal.container).toBeHidden(); | ||
| await page.waitForURL(/\/search\/[a-f0-9]+/, { timeout: 5000 }); | ||
| }); | ||
|
|
||
| await test.step('Navigate to sessions page', async () => { | ||
| await page.goto('/sessions'); | ||
| await expect(page.getByTestId('sessions-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Use browser back button', async () => { | ||
| await page.goBack(); | ||
| await expect(page.getByTestId('search-page')).toBeVisible(); | ||
| }); | ||
|
|
||
| await test.step('Verify saved search loads correctly after back navigation', async () => { | ||
| // Verify WHERE clause | ||
| const whereInput = searchPage.input; | ||
| await expect(whereInput).toHaveValue('SeverityText:error'); | ||
|
|
||
| // Verify results load | ||
| await searchPage.table.waitForRowsToPopulate(); | ||
| const rowCount = await searchPage.table.getRows().count(); | ||
| expect(rowCount).toBeGreaterThan(0); | ||
| }); | ||
| }, | ||
| ); | ||
| }); | ||
Uh oh!
There was an error while loading. Please reload this page.