test: e2e- sortorder-testcases (#7445)

### **PR Type**
Tests, Enhancement


___

### **Description**
- Add case-insensitive search helper methods

- Implement log count ordering verification

- Refactor tests to use new page-object methods

- Add 15-minute relative time selector helper


___

### **Changes diagram**

```mermaid
flowchart LR
  A["LogsPage page object"]
  B["playwright tests"]
  A -- "add search & ordering methods" --> B
  B -- "invoke helpers in specs" --> C["Improved test coverage"]
```


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>logsPage.js</strong><dd><code>Add log ordering and
ignore-case helpers</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

tests/ui-testing/pages/logsPage.js

<li>Added locators for query editor and refresh button<br> <li>
Implemented verifyLogCountOrdering (asc/desc)<br> <li> Added
searchWithStringMatchIgnoreCase method<br> <li> Added
setDateTimeTo15Minutes helper


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/7445/files#diff-6af0f73f0523e6fccd38532cb454dc58c4ef1fe4ef5bc5a135ef3f0ee5371ef6">+74/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Tests</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>logsqueries.spec.js</strong><dd><code>Use new page
helpers in specs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></summary>
<hr>

tests/ui-testing/playwright-tests/logsqueries.spec.js

<li>Refactored string-match tests to use page methods<br> <li> Replaced
inline date-time selection with helper<br> <li> Added test for logcount
ordering verification<br> <li> Cleaned up test formatting and timeouts


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/7445/files#diff-aee28776157572aac692a692c53f8d5aebfe8d01d1a7addf14f3a3f92c35b3a5">+24/-50</a>&nbsp;
</td>

</tr>
</table></td></tr></tr></tbody></table>

___

> <details> <summary> Need help?</summary><li>Type <code>/help how to
...</code> in the comments thread for any questions about PR-Agent
usage.</li><li>Check out the <a
href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a>
for more information.</li></details>
This commit is contained in:
Neha P
2025-07-03 17:30:27 +05:30
committed by GitHub
parent 471f6ee7a0
commit efd2bab4a7
2 changed files with 96 additions and 50 deletions
+74
View File
@@ -60,6 +60,11 @@ export class LogsPage {
this.partitionActiveIndicator = page.locator('[data-test="logs-search-partition-active"]');
this.resultText = '[data-test="logs-search-search-result"]';
// String match ignore case locators
this.logsSearchBarQueryEditor = '[data-test="logs-search-bar-query-editor"]';
this.searchBarRefreshButton = '[data-cy="search-bar-refresh-button"] > .q-btn__content';
this.logTableColumnSource = '[data-test="log-table-column-0-source"]';
}
async selectOrganization() {
@@ -752,5 +757,74 @@ async pageNotVisible() {
await expect(fastRewindElement).not.toBeVisible();
}
async verifyLogCountOrdering(orderType) {
// Type and execute the query
const query = orderType === 'desc'
? `SELECT MAX(_timestamp) as ts, count(_timestamp) as logcount,kubernetes_container_name FROM 'e2e_automate' where log is not null GROUP BY kubernetes_container_name order by logcount desc`
: `SELECT MAX(_timestamp) as ts, count(_timestamp) as logcount,kubernetes_container_name FROM 'e2e_automate' where log is not null GROUP BY kubernetes_container_name order by logcount asc`;
await this.clearAndFillQueryEditor(query);
await this.page.waitForTimeout(2000);
// Enable SQL mode if not already enabled
const sqlModeSwitch = this.page.getByRole('switch', { name: 'SQL Mode' });
const isSqlEnabled = await sqlModeSwitch.isChecked();
if (!isSqlEnabled) {
await sqlModeSwitch.click();
await this.page.waitForTimeout(1000);
}
// Run the query
await this.page.locator("[data-test='logs-search-bar-refresh-btn']").click({ force: true });
await this.page.waitForTimeout(2000);
// Get all table rows and verify order
const rows = await this.page.locator('[data-test^="logs-search-result-detail-"]').all();
let previousValue = orderType === 'desc' ? Number.MAX_SAFE_INTEGER : Number.MIN_SAFE_INTEGER;
for (const row of rows) {
const sourceCell = await row.locator('[data-test^="log-table-column-"][data-test$="-source"]').textContent();
try {
const logcountMatch = sourceCell.match(/logcount":(\d+)/);
const currentValue = logcountMatch ? parseInt(logcountMatch[1]) : 0;
if (orderType === 'desc') {
expect(currentValue).toBeLessThanOrEqual(previousValue);
} else {
expect(currentValue).toBeGreaterThanOrEqual(previousValue);
}
previousValue = currentValue;
} catch (error) {
console.error('Error parsing cell content:', sourceCell);
throw error;
}
}
// Verify we have results
expect(rows.length).toBeGreaterThan(0);
}
async verifyLogCountOrderingDescending() {
await this.verifyLogCountOrdering('desc');
}
async verifyLogCountOrderingAscending() {
await this.verifyLogCountOrdering('asc');
}
// String match ignore case methods
async searchWithStringMatchIgnoreCase(searchText) {
await this.page.locator(this.logsSearchBarQueryEditor).click();
await this.page.keyboard.press(process.platform === "darwin" ? "Meta+A" : "Control+A");
await this.page.keyboard.press("Backspace");
await this.page.keyboard.type(`str_match_ignore_case('${searchText}')`);
await this.page.locator(this.searchBarRefreshButton).click();
await this.page.waitForTimeout(3000);
await expect(this.page.locator(this.logTableColumnSource)).toBeVisible();
}
async setDateTimeTo15Minutes() {
await this.page.locator(this.dateTimeButton).click();
await this.page.locator('[data-test="date-time-relative-15-m-btn"] > .q-btn__content > .block').click();
}
}
@@ -99,17 +99,15 @@ test.describe("Logs Queries testcases", () => {
await page.waitForTimeout(3000);
await page.locator('[data-test="log-table-column-0-source"]').click();
await page.locator(':nth-child(1) > [data-test="log-details-include-exclude-field-btn"] > .q-btn__content > .q-icon').click(); await page.locator(
'[data-test="log-details-include-field-btn"]').click(); await page.locator(
'[data-test="close-dialog"] > .q-btn__content').click(); await page.locator(
'[data-test="logs-search-saved-views-btn"] > .q-btn-dropdown--current > .q-btn__content > :nth-child(1)').click(); await page.locator(
'[data-test="add-alert-name-input"]').fill("e2etimestamp"); await page.locator(
'[data-test="saved-view-dialog-save-btn"] > .q-btn__content').click(); await page.locator(
'[data-test="logs-search-saved-views-btn"] > .q-btn-dropdown__arrow-container > .q-btn__content > .q-icon').click(); await page.locator(
'.q-item__label').getByText(/timestamp/).first().click({ force: true });
await page.waitForTimeout(
3000);
await page.locator(':nth-child(1) > [data-test="log-details-include-exclude-field-btn"] > .q-btn__content > .q-icon').click();
await page.locator('[data-test="log-details-include-field-btn"]').click();
await page.locator('[data-test="close-dialog"] > .q-btn__content').click();
await page.locator('[data-test="logs-search-saved-views-btn"] > .q-btn-dropdown--current > .q-btn__content > :nth-child(1)').click();
await page.locator('[data-test="add-alert-name-input"]').fill("e2etimestamp");
await page.locator('[data-test="saved-view-dialog-save-btn"] > .q-btn__content').click();
await page.locator('[data-test="logs-search-saved-views-btn"] > .q-btn-dropdown__arrow-container > .q-btn__content > .q-icon').click();
await page.locator('.q-item__label').getByText(/timestamp/).first().click({ force: true });
await page.waitForTimeout(3000);
await page.locator('[data-test="logs-search-saved-views-btn"]').getByLabel('Expand').click();
await page.locator('[data-test="log-search-saved-view-field-search-input"]').click();
await page.locator('[data-test="log-search-saved-view-field-search-input"]').fill('e2e');
@@ -120,7 +118,6 @@ test.describe("Logs Queries testcases", () => {
// await page.locator('[data-test="logs-search-saved-views-btn"]').getByLabel('Expand').click();
await page.getByText('delete').click();
await page.locator('[data-test="confirm-button"]').click();
});
test("should redirect to logs after clicking on stream explorer via stream page", async ({ page }) => {
@@ -287,7 +284,7 @@ test.describe("Logs Queries testcases", () => {
const targetElement = page.locator('[data-test="logs-search-subfield-add-kubernetes_pod_name-ziox-ingester-0"]').getByText('ziox-ingester-');
await expect(targetElement).toBeVisible(); // Assertion to ensure visibility
await targetElement.click()
})
});
test("should display results in selected time", async ({
page,
@@ -299,46 +296,13 @@ test.describe("Logs Queries testcases", () => {
});
test("should display results if stringmatch ignorecase lowercase added in log query search", async ({ page }) => {
// Type the value of a variable into an input field
await page.locator('[data-test="date-time-btn"]').click({ force: true });
await page.locator('[data-test="date-time-relative-15-m-btn"] > .q-btn__content > .block').click({ force: true });
// Ensure the query editor is visible and clickable before typing
const queryEditor = page.locator('[data-test="logs-search-bar-query-editor"]');
await expect(queryEditor).toBeVisible();
await queryEditor.click();
await page.keyboard.type("str_match_ignore_case(kubernetes_container_name, 'ziox')");
await page.waitForTimeout(4000);
// Ensure the refresh button is visible and clickable before clicking
const refreshButton = page.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content');
await expect(refreshButton).toBeVisible();
await refreshButton.click({ force: true });
// Verify that the expected log table column is visible
await expect(page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
await logsPage.setDateTimeTo15Minutes();
await logsPage.searchWithStringMatchIgnoreCase('ziox');
});
test("should display results if stringmatch ignorecase uppercase added in log query search", async ({ page }) => {
// Type the value of a variable into an input field
await page.locator('[data-test="date-time-btn"]').click({ force: true });
await page.locator('[data-test="date-time-relative-15-m-btn"] > .q-btn__content > .block').click({ force: true });
// Ensure the query editor is visible and clickable before typing
const queryEditor = page.locator('[data-test="logs-search-bar-query-editor"]');
await expect(queryEditor).toBeVisible();
await queryEditor.click();
await page.keyboard.type("str_match_ignore_case(kubernetes_container_name, 'Ziox')");
await page.waitForTimeout(4000);
// Ensure the refresh button is visible and clickable before clicking
const refreshButton = page.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content');
await expect(refreshButton).toBeVisible();
await refreshButton.click({ force: true });
// Verify that the expected log table column is visible
await expect(page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
await logsPage.setDateTimeTo15Minutes();
await logsPage.searchWithStringMatchIgnoreCase('Ziox');
});
test("should trigger search results when pressing Cmd+Enter or Ctrl+Enter", async ({ page }) => {
@@ -356,4 +320,12 @@ test.describe("Logs Queries testcases", () => {
test("should execute SQL query with keyboard shortcut (Cmd+Enter or Ctrl+Enter)", async ({ page }) => {
await logsPage.executeQueryWithKeyboardShortcutWithSQLMode();
});
test("should verify logcount ordering in ascending and descending order", async ({ page }) => {
// Verify descending order
await logsPage.verifyLogCountOrderingDescending();
// Verify ascending order
await logsPage.verifyLogCountOrderingAscending();
});
})