Files
openobserve/tests/ui-testing/playwright-tests/Logs/logsqueries.spec.js
T
Shrinath RaoandClaude Opus 4.7 e2813291ce test: stabilise alpha1 e2e tests via UI org-switch (#11528)
## Summary

Stabilises alpha1 cloud E2E tests across the Logs-Core shard. Fixes a
UI/API org mismatch root cause, adds env-aware query execution helpers,
and brings all 10 changed spec files into POM compliance.

## Root cause (original)

After Dex login, the Pinia store binds all API calls to the user's
*default* org. The URL `?org_identifier=...` alone does not update the
store. Ingestion went to the `.env` org while UI searches went to the
user's default org → empty results → cascading test failures.

## Changes

### Alpha1 environment / authentication
- **`global-setup-alpha1.js`** — switches active org via the navbar
dropdown after Dex login so the Pinia store adopts the correct org;
`context.storageState` captures the result for all test contexts
- **`playwright-alpha1.config.js`** — `ORGNAME` sourced purely from
`.env`; cloud-config override removed
- **`loginPage.login()` / `unflattened.spec.js`** — include
`?org_identifier=${ORGNAME}` in SPA navigation to prevent defaulting to
`_meta`
- **`unflattened.js openStreamDetail()`** — replaced broken
stream-name-text click with `Stream Detail` action button + Schema-tab
visibility wait

### Auto-run query handling (`auto_query_enabled` flag)
- **`logsPage.js`** — added `runQueryAfterModeChange()`: on alpha1
(`auto_query_enabled=true`) waits for the in-flight auto-query to
complete; on local triggers a fresh query. Fixes
`@interestingFieldsCRUD` and `@quickModeResults` tests that were passing
on alpha1 but failing locally because the old fix clicked Refresh
mid-auto-run (hitting Cancel)
- **`logsQueryPage.js`** — null-guard `textContent()` return in
`_toggleAutoRun()` (`|| ''`) to satisfy Playwright's `string | null`
type contract

### Merge conflict resolution
- **`logsPage.js enableQuickModeIfDisabled()`** — kept HEAD's version
that defines `quickModeIndicator` at the top of the function (used in
the retry loop); discarded main's version that opened the utilities menu
before the variable was defined

### POM compliance (Sentinel audit)
Added three new POM methods to **`logsPage.js`**:
- `watchForNotification(timeout)` — returns a promise for pre-action
race-condition-safe notification watching
- `expectNotificationContainsText(text)` — notification text assertion
- `waitForNotificationWithText(text, timeout)` — notification waiter
with text filter

Removed raw locators from spec files:
- **`logspage.spec.js`** — notification race pattern →
`watchForNotification()` + `expectNotificationContainsText()`; 5-line
raw histogram toggle block → `ensureHistogramState(true)` (POM method
already existed)
- **`logsqueries.spec.js`** —
`pm.logsPage.page.waitForSelector('.q-notification__message:has-text(...)')`
→ `waitForNotificationWithText()`
- **`jobSearch.spec.js`** — added `testLogger` import; replaced 14×
`console.log` with `testLogger.info`; raw Monaco editor locators (lines
158–168) → `logsPage.waitForQueryEditorVisible()` +
`logsPage.getQueryEditorText()` (both already in POM)

### Tags
- **`jobSearch.spec.js`** — all 8 tests now tagged: `@jobSearch,
@P0/@P1` with functional sub-tags (`@smoke`, `@crud`, `@validation`)
- **`logshistogram.spec.js`** — all 5 tests now include `@P1`

## Results

- All `logsquickmode.spec.js` tests pass on both local and alpha1
- Zero Sentinel critical issues remaining across all 10 changed spec
files
- Remaining warnings (old-style auth in `jobSearch.spec.js` /
`pagination.spec.js`, `pm.logsPage.page.reload()` in
`logsquickmode.spec.js`) are pre-existing tech debt deferred to a
separate PR

## Test plan

- [ ] Run `logsquickmode.spec.js` locally and on alpha1 — both should
pass
- [ ] Run full Logs-Core shard on alpha1: `npx playwright test --config
playwright-alpha1.config.js
playwright-tests/Logs/{join,logspage,logsquickmode,pagination,unflattened,logshistogram,jobSearch,logsqueries,logsAnalyzeDimensions}.spec.js`
- [ ] Verify global setup logs: `Switching active org to: <ORGNAME>` →
`Org switch complete`
- [ ] Confirm no `console.log` output in `jobSearch.spec.js` test run
(all replaced by `testLogger`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-07 16:19:54 +00:00

514 lines
22 KiB
JavaScript

const { test, expect, navigateToBase } = require('../utils/enhanced-baseFixtures.js');
const testLogger = require('../utils/test-logger.js');
const PageManager = require('../../pages/page-manager.js');
const logData = require("../../fixtures/log.json");
const { ingestTestData } = require('../utils/data-ingestion.js');
async function applyQueryButton(pm) {
const search = pm.page.waitForResponse(logData.applyQuery);
// Strategic 1000ms wait for query button DOM stabilization - this is functionally necessary
await pm.page.waitForTimeout(1000);
await pm.logsPage.clickRefreshButton();
await expect.poll(async () => (await search).status()).toBe(200);
}
function removeUTFCharacters(text) {
// Remove UTF characters using regular expression
return text.replace(/[^\x00-\x7F]/g, " ");
}
test.describe("Logs Queries testcases", () => {
test.describe.configure({ mode: 'parallel' });
let pm; // Page Manager instance
test.beforeEach(async ({ page }, testInfo) => {
// Initialize test setup
testLogger.testStart(testInfo.title, testInfo.file);
// Navigate to base URL with authentication
await navigateToBase(page);
pm = new PageManager(page);
// Strategic post-authentication stabilization wait - this is functionally necessary
await page.waitForTimeout(1000);
// Data ingestion for logs queries testing (preserve exact logic)
await ingestTestData(page);
// Strategic wait for data ingestion completion - this is functionally necessary
await page.waitForTimeout(1000);
// Navigate to logs page and setup for queries testing
await page.goto(
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
);
await pm.logsPage.selectStream("e2e_automate");
await applyQueryButton(pm);
testLogger.info('Logs queries test setup completed');
});
test.afterEach(async ({ page }) => {
try {
// await pm.commonActions.flipStreaming();
testLogger.info('Streaming flipped after test');
} catch (error) {
testLogger.warn('Streaming flip failed', { error: error.message });
}
});
test("should display quick mode toggle button", {
tag: ['@quickModeLogs', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing quick mode toggle button visibility');
await pm.logsPage.expectQuickModeToggleVisible();
testLogger.info('Quick mode toggle visibility test completed');
});
test.skip("should add timestamp to editor save this view and switch", {
tag: ['@timestampViewLogs', '@all', '@logs']
}, async ({ page }) => {
await pm.logsPage.waitForTimeout(3000);
await pm.logsPage.clickLogTableColumnSource();
await pm.logsPage.clickIncludeExcludeFieldButton();
await pm.logsPage.clickIncludeFieldButton();
await pm.logsPage.clickCloseDialog();
await pm.logsPage.clickSavedViewsButton();
await pm.logsPage.fillSavedViewName("e2etimestamp");
await pm.logsPage.clickSavedViewDialogSaveContent();
await pm.logsPage.clickSavedViewArrow();
await pm.logsPage.clickSavedViewByLabel(/timestamp/);
await pm.logsPage.waitForTimeout(3000);
await pm.logsPage.clickSavedViewsExpand();
await pm.logsPage.clickSavedViewSearchInput();
await pm.logsPage.fillSavedViewSearchInput('e2e');
await pm.logsPage.clickSavedViewByTitle('e2etimestamp');
await pm.logsPage.clickSavedViewsExpand();
await pm.logsPage.clickSavedViewSearchInput();
await pm.logsPage.clickSavedViewByTitle('e2etimestamp');
await pm.logsPage.clickDeleteButton();
await pm.logsPage.clickConfirmButton();
});
test("should create saved view and delete it", {
tag: ['@streamExplorer', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing saved view creation and deletion functionality');
// Generate a random saved view name
const randomSavedViewName = `streamslog${Math.random().toString(36).substring(2, 10)}`;
// Interactions with the page
await pm.logsPage.clickRefreshButton();
await pm.logsPage.clickSavedViewsExpand();
await pm.logsPage.clickSaveViewButton();
await pm.logsPage.fillSavedViewName(randomSavedViewName); // Use the random name
await pm.logsPage.clickSavedViewDialogSave();
// Wait for the success toast message to appear briefly after save
try {
await pm.logsPage.waitForNotificationWithText('View created successfully', 3000);
testLogger.info('Success toast validated: View created successfully');
} catch (error) {
testLogger.info('View creation toast may have appeared and disappeared quickly - continuing with test');
}
// Strategic 2000ms wait for saved view creation - this is functionally necessary
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickStreamsMenuItem();
await pm.logsPage.clickSearchStreamInput();
await pm.logsPage.fillSearchStreamInput('e2e');
// Strategic 500ms wait for stream search DOM stabilization - this is functionally necessary
await pm.logsPage.waitForTimeout(500);
await pm.logsPage.clickExploreButton();
// Strategic 2000ms wait for navigation to stream explorer - this is functionally necessary
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.waitForSavedViewsButton();
await pm.logsPage.clickSavedViewsExpand();
await pm.logsPage.clickSavedViewSearchInput();
await pm.logsPage.fillSavedViewSearchInput(randomSavedViewName); // Use the random name here
// Strategic 1000ms wait for saved view search results - this is functionally necessary
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.waitForSavedViewText(randomSavedViewName);
await pm.logsPage.clickSavedViewByText(randomSavedViewName);
// Wait for saved view to be applied and page to settle before re-expanding
await page.waitForLoadState('domcontentloaded');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickSavedViewsExpand();
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.clickSavedViewSearchInput();
await pm.logsPage.clickSavedViewByTitle(randomSavedViewName); // Use the random name here
// Wait for UI to stabilize before attempting deletion
await pm.logsPage.waitForTimeout(1000);
// Delete the saved view
await pm.logsPage.clickDeleteSavedViewButton(randomSavedViewName);
await pm.logsPage.waitForTimeout(500);
await pm.logsPage.clickConfirmButton(); // Confirm deletion
testLogger.info(`Successfully deleted saved view: ${randomSavedViewName}`);
testLogger.info('Saved view creation and deletion test completed');
});
test("should reset the editor on clicking reset filter button", {
tag: ['@resetFilters', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing reset filter button functionality');
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditorTextbox();
await pm.logsPage.typeInQueryEditor("match_all_raw_ignore_case('provide_credentials')");
await pm.logsPage.waitForSearchBarRefreshButton();
await pm.logsPage.clickRefreshButton();
await pm.logsPage.clickResetFiltersButton();
await pm.logsPage.waitForQueryEditorTextbox();
await pm.logsPage.expectQueryEditorEmpty();
testLogger.info('Reset filter button test completed');
});
test("should add invalid query and display error", {
tag: ['@invalidQueryLogs', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing invalid query error handling');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor("kubernetes");
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickSearchBarRefreshButton();
await pm.logsPage.expectErrorMessageVisible();
testLogger.info('Invalid query error handling test completed');
});
test("should not display error if match all case added in log query search", {
tag: ['@matchAllLogs', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing match_all query functionality');
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.expectQueryEditorVisible();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor("match_all('code')");
await pm.logsPage.expectSearchBarRefreshButtonVisible();
await pm.logsPage.clickSearchBarRefreshButton();
await pm.logsPage.expectLogTableColumnSourceVisible();
testLogger.info('Match_all query functionality test completed');
});
// Duplicate test - kept in logspage.spec.js
// test("should display error when save function is clicked without any VRL function", {
// tag: ['@functionValidation', '@all', '@logs']
// }, async ({ page }) => {
// testLogger.info('Testing VRL function save validation without function definition');
// await pm.logsPage.clickFunctionDropdownSave();
// await pm.logsPage.expectWarningNoFunctionDefinition();
//
// testLogger.info('VRL function save validation test completed');
// });
// Duplicate test - kept in logspage.spec.js
// test("should display click save directly while creating a function", {
// tag: ['@functionSaveValidation', '@all', '@logs']
// }, async ({ page }) => {
// testLogger.info('Testing function save validation when clicking save directly');
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.toggleVrlEditor();
// await pm.logsPage.clickVrlEditor();
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.clickFunctionDropdownSave();
// await pm.logsPage.clickSavedViewDialogSave();
// await pm.logsPage.expectFunctionNameNotValid();
//
// testLogger.info('Function save validation test completed');
// });
// Duplicate test - kept in logspage.spec.js
// test("should display error on adding only blank spaces under function name", {
// tag: ['@functionNameValidation', '@all', '@logs']
// }, async ({ page }) => {
// testLogger.info('Testing function name validation with blank spaces');
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.toggleVrlEditor();
// await pm.logsPage.clickVrlEditor();
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.clickFunctionDropdownSave();
// await pm.logsPage.fillSavedFunctionNameInput(' ');
// await pm.logsPage.clickSavedViewDialogSave();
// await pm.logsPage.expectFunctionNameNotValid();
//
// testLogger.info('Function name blank spaces validation test completed');
// });
// Duplicate test - kept in logspage.spec.js
// test("should display error on adding invalid characters under function name", {
// tag: ['@functionNameValidation', '@all', '@logs']
// }, async ({ page }) => {
// testLogger.info('Testing function name validation with invalid characters');
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.toggleVrlEditor();
// await pm.logsPage.clickVrlEditor();
// await pm.logsPage.waitForTimeout(1000);
// await pm.logsPage.clickFunctionDropdownSave();
// await pm.logsPage.fillSavedFunctionNameInput('e2e@@@');
// await pm.logsPage.clickSavedViewDialogSave();
// await pm.logsPage.expectFunctionNameNotValid();
//
// testLogger.info('Function name invalid characters validation test completed');
// });
test("should display added function on switching between tabs and again navigate to log", {
tag: ['@functionPersistence', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing function persistence across tab navigation');
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.toggleVrlEditor();
await pm.logsPage.clickVrlEditor();
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.clickRefreshButton();
await pm.logsPage.clickMenuLinkMetricsItem();
await pm.logsPage.clickMenuLinkLogsItem();
await pm.logsPage.clickMenuLinkLogsItem();
await pm.logsPage.expectPageContainsText(".a=2");
testLogger.info('Function persistence test completed');
});
test("should display bar chart when histogram toggle is on", {
tag: ['@histogramBarChart', '@histogram', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing bar chart display with histogram toggle');
// Ensure histogram is ON before testing bar chart
const isHistogramOn = await pm.logsPage.isHistogramOn();
if (!isHistogramOn) {
await pm.logsPage.toggleHistogram();
await pm.logsPage.waitForTimeout(1000);
}
await pm.logsPage.clickLogSearchIndexListFieldSearchInput();
await pm.logsPage.fillLogSearchIndexListFieldSearchInput('code');
await pm.logsPage.waitForTimeout(4000);
await pm.logsPage.clickExpandCode();
await pm.logsPage.waitForTimeout(4000);
// Click refresh and wait for actual results (not just DOM ready — AJAX search on alpha1 can be slow)
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForSearchResults();
// Toggle SQL mode and refresh
await pm.logsPage.clickSQLModeToggle();
await pm.logsPage.clickRefreshButton();
// clickBarChartCanvas includes networkidle wait + retry — more reliable than a static timeout
await pm.logsPage.clickBarChartCanvas();
// Toggle SQL mode off and refresh
await pm.logsPage.clickSQLModeToggle();
await pm.logsPage.clickRefreshButton();
// clickBarChartCanvas includes networkidle wait + retry
await pm.logsPage.clickBarChartCanvas();
await pm.logsPage.clickHistogramToggleDiv();
testLogger.info('Histogram bar chart display test completed');
});
test("should display search around in histogram mode", {
tag: ['@searchAroundHistogram', '@histogram', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing search around functionality in histogram mode');
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.clickLogTableColumnSource();
await pm.logsPage.clickLogsDetailTableSearchAroundBtn();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectLogTableColumnSourceVisible();
testLogger.info('Search around histogram mode test completed');
});
test.skip("should display results for search around after adding function", async ({ page }) => {
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.toggleVrlEditor();
await pm.logsPage.clickVrlEditor();
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.clickRefreshButton();
await pm.logsPage.clickLogTableColumn3Source();
await pm.logsPage.clickLogsDetailTableSearchAroundBtn();
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.expectLogTableColumnSourceVisible();
});
test("should display search around in SQL mode", {
tag: ['@searchAroundSQL', '@sqlMode', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing search around functionality in SQL mode');
await pm.logsPage.waitForTimeout(1000);
await pm.logsPage.clickSQLModeToggle();
await pm.logsPage.clickLogTableColumnSource();
await pm.logsPage.clickLogsDetailTableSearchAroundBtn();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectLogTableColumnSourceVisible();
testLogger.info('Search around SQL mode test completed');
});
test("should display results for search around with limit query", {
tag: ['@searchAroundLimit', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing search around functionality with limit query');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor("match_all('code') limit 5");
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickSQLModeToggle();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickLogTableColumnSource();
await pm.logsPage.clickLogsDetailTableSearchAroundBtn();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectLogTableColumnSourceVisible();
testLogger.info('Search around with limit query test completed');
});
test("should not display pagination for limit query", {
tag: ['@paginationLimit', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing pagination behavior with limit query');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor("match_all('code') limit 5");
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickSQLModeToggle();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectPaginationNotVisible();
testLogger.info('Pagination limit query test completed');
});
test("should not display pagination for SQL limit query", {
tag: ['@paginationSQLLimit', '@sqlMode', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing pagination behavior with SQL limit query');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor('SELECT * FROM "e2e_automate" ORDER BY _timestamp DESC limit 5');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectPaginationNotVisible();
testLogger.info('Pagination SQL limit query test completed');
});
test("should not display pagination for SQL group/order/limit query", {
tag: ['@paginationSQLGroupOrder', '@sqlMode', '@all', '@logs']
}, async ({ page }) => {
testLogger.info('Testing pagination behavior with SQL group/order/limit query');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.clickRelative15MinButton();
await pm.logsPage.clickQueryEditor();
await pm.logsPage.typeInQueryEditor('SELECT * FROM "e2e_automate" WHERE code < 400 GROUP BY code ORDER BY count(*) DESC LIMIT 5');
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.expectPaginationNotVisible();
testLogger.info('Pagination SQL group/order/limit query test completed');
});
test("should reset pagination to page 1 after running query again", {
tag: ['@pagination', '@logs', '@all']
}, async ({ page }) => {
testLogger.info('Testing pagination reset behavior after re-running query');
// Set up conditions to ensure we have enough data for pagination
await pm.logsPage.waitForTimeout(2000);
await pm.logsPage.clickDateTimeButton();
await pm.logsPage.waitForTimeout(1000);
// Use wider time range to capture ingested data
const selectedRange = await pm.logsPage.clickWideRelativeTimeRangeOrFallback();
testLogger.info(`Set time range to ${selectedRange} to capture ingested data`);
// Run initial query to get results
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForTimeout(3000);
// Pagination should exist after ingesting data - expect it to be visible
await pm.logsPage.expectResultPaginationVisible();
testLogger.info('Pagination controls found, proceeding with test');
// Get available page count using POM
const pageCount = await pm.logsPage.getPaginationPageCount();
testLogger.info(`Found ${pageCount} page buttons`);
// Navigate to page 4 using POM
testLogger.info('Navigating to page 4');
await pm.logsPage.clickPaginationPage(4);
await pm.logsPage.waitForTimeout(2000);
// Verify we're on page 4 using POM
await pm.logsPage.waitForTimeout(3000);
const page4Classes = await pm.logsPage.getPaginationPageClasses(4);
testLogger.info(`Page 4 button classes: ${page4Classes}`);
// Run query again while on page 4
testLogger.info('Running query again while on page 4');
await pm.logsPage.clickRefreshButton();
await pm.logsPage.waitForTimeout(3000);
// Verify pagination resets to page 1 using POM
await pm.logsPage.waitForTimeout(2000);
const page4ClassesAfter = await pm.logsPage.getPaginationPageClasses(4).catch(() => null);
const page1ClassesAfter = await pm.logsPage.getPaginationPageClasses(1).catch(() => null);
testLogger.info(`After query - Page 1 classes: ${page1ClassesAfter}`);
testLogger.info(`After query - Page 4 classes: ${page4ClassesAfter}`);
// Check pagination state using POM methods
const isStillOnPage4 = await pm.logsPage.isPaginationPageActive(4).catch(() => false);
const isBackToPage1 = await pm.logsPage.isPaginationPageActive(1).catch(() => false);
if (isStillOnPage4) {
testLogger.error('🐛 BUG DETECTED: Pagination stayed on page 4 instead of resetting to page 1');
expect(isStillOnPage4).toBeFalsy();
} else if (isBackToPage1) {
testLogger.info('✅ Pagination correctly reset to page 1 after re-running query');
expect(isBackToPage1).toBeTruthy();
} else {
testLogger.info('Using fallback method to check pagination state');
const activePage = await pm.logsPage.getActivePaginationPageText();
testLogger.info(`Active page (fallback): ${activePage}`);
if (activePage === '4') {
testLogger.error('🐛 BUG DETECTED: Pagination stayed on page 4 (fallback method)');
expect(activePage).toBe('1');
} else {
testLogger.info('✅ Pagination appears to have reset correctly (fallback method)');
}
}
testLogger.info('Pagination reset behavior test completed');
});
});