mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 08:09:27 +00:00
test: Logs Page Major Overhaul (#7490)
### **User description** Updated logs page, Updated playwright yml file, Updated all files containing references of logs page, added folder structure to logs, updated locators for failing test cases ___ ### **PR Type** Tests, Enhancement ___ ### **Description** - Introduce `LogsPage` POM class with locators and methods - Refactor log specs to use new POM classes - Add `LogsQueryPage` for query filtering logic - Rename `selectStream` helper across tests ___ ### **Changes diagram** ```mermaid flowchart LR A["LogsPage POM"] --> B["logspage.spec.js"] A --> C["logsqueries.spec.js"] A --> D["logshistogram.spec.js"] A --> E["logsQueryPage POM"] F["Stream Helper"] --> G["indexquery.spec.js"] ``` ___ ### **Changes walkthrough** 📝 <table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>2 files</summary><table> <tr> <td><strong>logsPage.js</strong><dd><code>Add comprehensive `LogsPage` POM class</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-8045b343491d8943869c1af74cdafab204dc49c02a70294417e73f47d35e0b59">+1563/-0</a></td> </tr> <tr> <td><strong>logsQueryPage.js</strong><dd><code>Add `LogsQueryPage` for query filter tests</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-d4b122abaad43a49fa5d670610274e876342177176360077492e2e094dbc2cba">[link]</a> </td> </tr> </table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>7 files</summary><table> <tr> <td><strong>logspage.spec.js</strong><dd><code>Add `logspage.spec.js` using `LogsPage` POM</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-b1a64252adae01c5e8f7e758e3c820f5476260f60c44a4a57b4f15a05a59a85a">+509/-0</a> </td> </tr> <tr> <td><strong>logsqueries.spec.js</strong><dd><code>Refactor `logsqueries.spec.js` to use `LogsPage`</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-c2055f6cef1580b15c5f94f5c8c2e496a6e921332b48bad943bb7c0630846a65">+136/-127</a></td> </tr> <tr> <td><strong>logshistogram.spec.js</strong><dd><code>Refactor `logshistogram.spec.js` for POM usage</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-d01da1c5a03b1d1c1c74e11f6e4ebe879def1ce87e407aa9a1afc8473040f4bc">+74/-63</a> </td> </tr> <tr> <td><strong>indexquery.spec.js</strong><dd><code>Rename and use `selectStream` helper</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-0fdb3410e34d127b97b20feda5f1c5f244f23af2d2d88c331ab753a1f434d3b1">+2/-2</a> </td> </tr> <tr> <td><strong>region.spec.js</strong><dd><code>Rename `selectStream` in region tests</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-b90cf78e7ef83f1fa7e5b8ebb9639604d26888afaa0b2083381de89131063ec8">+2/-2</a> </td> </tr> <tr> <td><strong>enrichment.spec.js</strong><dd><code>Update import path to `logsPages/logsPage.js`</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-1c26b9ac51f49e25aa8fe1ad6ae5376da50d27be032579c4194b62e5e798a76b">+3/-3</a> </td> </tr> <tr> <td><strong>sanity.spec.js</strong><dd><code>Update `LogsPage` import and stream selection</code> </dd></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-53b3ede269fef5199fbaea935f79134b50ba4db51edc517e4b1701f2cbcc5130">+2/-2</a> </td> </tr> </table></details></td></tr><tr><td><strong>Additional files</strong></td><td><details><summary>23 files</summary><table> <tr> <td><strong>playwright.yml</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-7afcd2d8f7b49bda74843f209eefb7b2da45f7e7803bf2e4bd636699b76aa2d3">+4/-4</a> </td> </tr> <tr> <td><strong>logsPage.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-6af0f73f0523e6fccd38532cb454dc58c4ef1fe4ef5bc5a135ef3f0ee5371ef6">+0/-830</a> </td> </tr> <tr> <td><strong>streamsPage.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-792df584eb1625d35fd1e33a5a37aa3ada28f15ec1e77a1921f1c56e50bf70d2">+1/-1</a> </td> </tr> <tr> <td><strong>logsquickmode.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-81f2f36450c07435f1b0f3c33462c7dac98c0798250913ae5ed928f57ad82cdf">+58/-92</a> </td> </tr> <tr> <td><strong>changeOrg.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-607c77ca637716a5b8d37ec25dbaf7dc91cddd7d981b72f9c460f54498d14351">+1/-1</a> </td> </tr> <tr> <td><strong>dashboard-folder.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-bdb8f953e350e378f4196ea1b74fa60961dbe7e87ea34b77e551e77983ab0360">+1/-1</a> </td> </tr> <tr> <td><strong>dashboardtype.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-40ee9b1480e11efe6a8fcbdd9c28e2881ef564783b43e12aaa86f2b3cc7d8bc6">+2/-2</a> </td> </tr> <tr> <td><strong>visualization-vrl.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-4bfe28b08994ca0333edbe51bc99d3ddf05525387e90932d88681028e1947db4">+2/-2</a> </td> </tr> <tr> <td><strong>visualize.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-d144f23552ec150db375c89e52c3a53ede9ff3fa5dcd6092694fbe0a308d22ec">+2/-2</a> </td> </tr> <tr> <td><strong>join.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-e039a16bb79192216b3fb8ecfc745db63f48c43e73a9305ed6adb54c4a9dd683">+1/-1</a> </td> </tr> <tr> <td><strong>logspage.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-950a38f6d66dbcf4f7cb39dc366ab25f533044718edee8199d7f819c5b06efe3">+0/-582</a> </td> </tr> <tr> <td><strong>multiselect-stream.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-e2eb0d6de0ad04a42b73cce92a1c86e68213fed79bd7507ea00abfe18a2633c7">+2/-2</a> </td> </tr> <tr> <td><strong>pagination.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-5e44451149ef320c6c78668ff2a42a152fdc7b0565838c8d7f7385f5d4809cb5">+1/-1</a> </td> </tr> <tr> <td><strong>pipeline-core.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-e6249b045437e7f087b825dc0ee2d8ccebed0894d10c84b7bc9b12dca7a25754">+2/-2</a> </td> </tr> <tr> <td><strong>pipelines.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-9b48f5edc53f2413789549b189d4a80f134a320dd5beebf96d738069eb43033a">+2/-2</a> </td> </tr> <tr> <td><strong>remotepipeline.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-3b5a97115bd312e7490580fa00af21077ea5050915995bd133a7f5fd913e5394">+2/-2</a> </td> </tr> <tr> <td><strong>sanity2.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-f1ab4c6d536ebc3b8ea7ff17d2954d86ef56b660dcfaa1bb39f8213a5bf92e22">+2/-2</a> </td> </tr> <tr> <td><strong>schema.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-1212ad9c33ea14a5a660923b20c162380c9d8c27ffa64993ddfc827e4d82a208">+2/-2</a> </td> </tr> <tr> <td><strong>schemaload.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-768d758450ec41815b1330503394239673698045f5c29e46fc05d7b475c037ea">+1/-1</a> </td> </tr> <tr> <td><strong>searchpartition.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-557a8fcb7159dd28b9a8fd9c0657b5882297c650ef4f22a2d2213211a42b17ea">+2/-2</a> </td> </tr> <tr> <td><strong>secondsPrecisionAdded.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-bd92ad86063b90d67a50098a8ba722ef9b232f950a7c53604ae898043af7abfb">+1/-1</a> </td> </tr> <tr> <td><strong>unflattened.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-a5e0a62966202ad510f4be2cd89e91c1d34eaf48d179e5725d532f1d7fb92b4e">+2/-2</a> </td> </tr> <tr> <td><strong>websocket.spec.js</strong></td> <td><a href="https://github.com/openobserve/openobserve/pull/7490/files#diff-1f356bcfb18ed299a284a4c81893d73612faf9bac3941430f30d7c1b2d105540">+1/-1</a> </td> </tr> </table></details></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:
@@ -122,10 +122,10 @@ jobs:
|
||||
"dashboards/visualization-vrl.spec.js",
|
||||
"enrichment.spec.js",
|
||||
"join.spec.js",
|
||||
"logshistogram.spec.js",
|
||||
"logspage.spec.js",
|
||||
"logsqueries.spec.js",
|
||||
"logsquickmode.spec.js",
|
||||
"Logs/logshistogram.spec.js",
|
||||
"Logs/logspage.spec.js",
|
||||
"Logs/logsqueries.spec.js",
|
||||
"Logs/logsquickmode.spec.js",
|
||||
"multiselect-stream.spec.js",
|
||||
"pagination.spec.js",
|
||||
"pipelines.spec.js",
|
||||
|
||||
@@ -1,830 +0,0 @@
|
||||
// logsPage.js
|
||||
import { expect } from '@playwright/test';
|
||||
const { chromium } = require('playwright');
|
||||
import { dateTimeButtonLocator, relative30SecondsButtonLocator, absoluteTabLocator, Past30SecondsValue } from '../pages/CommonLocator.js';
|
||||
import logData from '../cypress/fixtures/log.json';
|
||||
|
||||
export class LogsPage {
|
||||
constructor(page) {
|
||||
|
||||
this.page = page;
|
||||
|
||||
this.orgDropdown = '[data-test="navbar-organizations-select"]';
|
||||
this.defaultOrgOption = this.page.getByRole('option', { name: 'default', exact: true }).locator('div').nth(2);
|
||||
this.logsMenuItem = page.locator('[data-test="menu-link-\\/logs-item"]');
|
||||
this.indexDropDown = page.locator('[data-test="logs-search-index-list"]').getByText('arrow_drop_down');
|
||||
this.streamToggle = page.locator('[data-test="log-search-index-list-stream-toggle-default"] div');
|
||||
this.exploreButton = page.getByRole('button', { name: 'Explore' });
|
||||
this.timestampColumnMenu = page.locator('[data-test="log-table-column-1-_timestamp"] [data-test="table-row-expand-menu"]');
|
||||
|
||||
this.filterMessage = page.locator('div:has-text("info Adjust filter parameters and click \'Run query\'")');
|
||||
|
||||
this.dateTimeButton = dateTimeButtonLocator;
|
||||
this.relative30SecondsButton = page.locator(relative30SecondsButtonLocator);
|
||||
|
||||
this.sqlModeToggle = this.page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2)
|
||||
|
||||
this.absoluteTab = absoluteTabLocator;
|
||||
|
||||
this.homeButton = "[name ='home']";
|
||||
|
||||
|
||||
this.timeZoneDropdown = "//label[contains(@class,'timezone-select')]";
|
||||
this.timeZoneOption = (zone) => `role=option[name="${zone}"]`;
|
||||
this.dateSelector = (day) => `//div[contains(@class,'q-date__calendar-item--in')]/button/span[contains(@class,'q-btn__content')]/span[text()='${day}']`;
|
||||
this.monthSelector = (month) => `//span[text() ='${month}']`;
|
||||
this.yearSelector = (year) => `//span[text() ='${year}']`;
|
||||
this.startTimeField = "input[class = 'q-field__native q-placeholder']:nth-of-type(2)";
|
||||
this.endTimeField = "input[class = 'q-field__native q-placeholder']:nth-of-type(3)";
|
||||
this.scheduleText = "//i[text() ='schedule']/following-sibling::span";
|
||||
this.calendarDate = "//div[contains(@class,'q-date__calendar-item--in')]/button/span[contains(@class,'q-btn__content')]/span[text()='";
|
||||
this.startTimeInput = "input[class = 'q-field__native q-placeholder']:nth-child(2)";
|
||||
this.endTimeInput = "input[class = 'q-field__native q-placeholder']:nth-child(3)";
|
||||
this.timezoneSelector = "//label[contains(@class,'timezone-select')]";
|
||||
|
||||
this.streamDropdown = '[data-test="log-search-index-list-select-stream"]';
|
||||
this.queryButton = "[data-test='logs-search-bar-refresh-btn']";
|
||||
this.queryEditor = '[data-test="logs-search-bar-query-editor"]';
|
||||
this.quickModeToggle = '[data-test="logs-search-bar-quick-mode-toggle-btn"]';
|
||||
|
||||
this.profileButton = page.locator('[data-test="header-my-account-profile-icon"]');
|
||||
this.signOutButton = page.getByText('Sign Out');
|
||||
|
||||
// Search Partition locators
|
||||
this.searchPartitionButton = page.locator('[data-test="logs-search-partition-btn"]');
|
||||
this.partitionDropdown = page.locator('[data-test="logs-search-partition-dropdown"]');
|
||||
this.partitionOption = (option) => page.getByRole('option', { name: option });
|
||||
this.partitionValueInput = page.locator('[data-test="logs-search-partition-value-input"]');
|
||||
this.partitionApplyButton = page.locator('[data-test="logs-search-partition-apply-btn"]');
|
||||
this.partitionClearButton = page.locator('[data-test="logs-search-partition-clear-btn"]');
|
||||
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() {
|
||||
await this.page.locator(this.orgDropdown).getByText('arrow_drop_down').click();
|
||||
await this.defaultOrgOption.click();
|
||||
}
|
||||
|
||||
|
||||
async navigateToLogs() {
|
||||
// Click on Logs menu item
|
||||
await this.page.locator(this.homeButton).hover();
|
||||
await this.logsMenuItem.click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
// await expect(this.page.locator('[data-test="logs-search-no-stream-selected-text"]')).toContainText('info Select a stream and press \'Run query\' to continue. Additionally, you can apply additional filters and adjust the date range to enhance search.');
|
||||
}
|
||||
|
||||
async validateLogsPage() {
|
||||
await expect(this.page.locator('[data-test="logs-search-no-stream-selected-text"]')).toContainText('info Select a stream and press \'Run query\' to continue. Additionally, you can apply additional filters and adjust the date range to enhance search.');
|
||||
}
|
||||
|
||||
async logsPageDefaultMultiOrg() {
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.reload();
|
||||
await this.page.locator('[data-test="navbar-organizations-select"]').getByText('arrow_drop_down').click();
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.getByRole('option', { name: 'defaulttestmulti' }).locator('div').nth(2).click();
|
||||
}
|
||||
|
||||
async logsPageURLValidation() {
|
||||
// TODO: fix the test
|
||||
// await expect(this.page).not.toHaveURL(/default/);
|
||||
}
|
||||
|
||||
async selectIndexAndStream() {
|
||||
// Select index and stream
|
||||
await this.indexDropDown.click();
|
||||
await this.streamToggle.first().click();
|
||||
// await this.page.waitForTimeout(3000);
|
||||
await this.streamToggle.nth(2).click();
|
||||
}
|
||||
|
||||
async selectIndexAndStreamJoin() {
|
||||
await this.page.locator('[data-test="logs-search-index-list"]').getByText('arrow_drop_down').click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator('[data-test="log-search-index-list-stream-toggle-default"] div').first().click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator('[data-test="log-search-index-list-stream-toggle-e2e_automate"] div').first().click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
}
|
||||
|
||||
async selectRunQuery() {
|
||||
|
||||
await this.page.locator(this.queryButton).click();
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async setTimeToPast30Seconds() {
|
||||
// Set the time filter to the last 30 seconds
|
||||
await expect(this.page.locator(this.dateTimeButton)).toBeVisible();
|
||||
await this.page.locator(this.dateTimeButton).click();
|
||||
await this.relative30SecondsButton.click();
|
||||
|
||||
}
|
||||
|
||||
async verifyTimeSetTo30Seconds() {
|
||||
// Verify that the time filter displays "Past 30 Seconds"
|
||||
await expect(this.page.locator(this.dateTimeButton)).toContainText(Past30SecondsValue);
|
||||
}
|
||||
|
||||
async enableSQLMode() {
|
||||
await this.sqlModeToggle.click();
|
||||
}
|
||||
|
||||
async setDateTime() {
|
||||
await expect(this.page.locator(this.dateTimeButton)).toBeVisible();
|
||||
await this.page.locator(this.dateTimeButton).click();
|
||||
await this.page.locator(this.absoluteTab).click();
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
}
|
||||
|
||||
async setAbsoluteDate(year, month, day, currentMonth, currentYear) {
|
||||
// await this.page.locator(this.dateTimeButton).click();
|
||||
// await this.page.getByText(" Absolute ").click();
|
||||
|
||||
if (currentMonth.includes(month) && year === currentYear.toString()) {
|
||||
await this.page.locator(this.calendarDate + day + "']").dblclick();
|
||||
} else if (year === currentYear.toString()) {
|
||||
await this.page.getByText(currentMonth).click();
|
||||
await this.page.locator("//span[text() ='" + month + "']").click();
|
||||
await this.page.locator("//span[text() ='" + day + "']").dblclick();
|
||||
} else {
|
||||
await this.page.getByText(currentMonth).click();
|
||||
await this.page.locator("//span[text() ='" + month + "']").click();
|
||||
await this.page.locator("//span[text() ='" + currentYear + "']").click();
|
||||
await this.page.locator("//span[text() ='" + year + "']").click();
|
||||
await this.page.locator("//span[text() ='" + day + "']").dblclick();
|
||||
}
|
||||
}
|
||||
|
||||
async setStartAndEndTime(startTime, endTime) {
|
||||
await this.page.locator(this.startTimeInput).fill(startTime);
|
||||
await this.page.locator(this.endTimeInput).fill(endTime);
|
||||
}
|
||||
|
||||
async setTimeRange(startTime, endTime) {
|
||||
await this.page.locator(this.startTimeField).fill(startTime);
|
||||
await this.page.locator(this.endTimeField).fill(endTime);
|
||||
}
|
||||
|
||||
async verifySchedule(expectedTime) {
|
||||
const schedule = await this.page.locator(this.scheduleText).textContent();
|
||||
expect(schedule).toEqual(expectedTime);
|
||||
}
|
||||
|
||||
async setTimeZone(zone) {
|
||||
await this.page.locator(this.timeZoneDropdown).click();
|
||||
await this.page.getByRole(this.timeZoneOption(zone)).click();
|
||||
}
|
||||
|
||||
async changeTimeZone() {
|
||||
await this.page.locator("//label[contains(@class,'timezone-select')]").click()
|
||||
await this.page.getByRole('option', { name: 'Asia/Dubai' }).click()
|
||||
}
|
||||
|
||||
async verifyDateTime(startTime, endTime) {
|
||||
await expect(this.page.locator(this.dateTimeButton)).toContainText(`${startTime} - ${endTime}`);
|
||||
}
|
||||
|
||||
async copyShare() {
|
||||
const browser = await chromium.launch();
|
||||
|
||||
const context = await browser.newContext({
|
||||
permissions: ['clipboard-read', 'clipboard-write']
|
||||
});
|
||||
const page = await context.newPage();
|
||||
await page.locator("[title ='Share Link']").click();
|
||||
const copiedUrl = await page.evaluate(() => navigator.clipboard.readText())
|
||||
console.log(copiedUrl);
|
||||
// console.log(Copied text: ${copiedUrl})
|
||||
const newpage = await context.newPage()
|
||||
await newpage.waitForTimeout(5000)
|
||||
await newpage.goto(copiedUrl)
|
||||
console.log(newpage.url())
|
||||
expect(copiedUrl).toContain('short')
|
||||
}
|
||||
|
||||
async getScheduleText() {
|
||||
return await this.page.locator("//button[(@data-test ='date-time-btn')]/span[contains(@class,'q-btn__content')]/span").textContent();
|
||||
}
|
||||
|
||||
async selectStream(stream) {
|
||||
await this.page.waitForTimeout(4000);
|
||||
await this.page.locator(this.streamDropdown).click({ force: true });
|
||||
await this.page.locator("div.q-item").getByText(`${stream}`).first().click({ force: true });
|
||||
}
|
||||
|
||||
async applyQuery() {
|
||||
const search = this.page.waitForResponse(logData.applyQuery);
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
}
|
||||
|
||||
async applyQueryButton(expectedUrl) {
|
||||
const searchResponse = this.page.waitForResponse(expectedUrl);
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator(this.queryButton).click({ force: true });
|
||||
await expect.poll(async () => (await searchResponse).status()).toBe(200);
|
||||
}
|
||||
|
||||
async clearAndRunQuery() {
|
||||
await this.page.locator(this.queryButton).click();
|
||||
await this.page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await this.page.locator(this.queryEditor).click();
|
||||
await this.page.keyboard.press(process.platform === "darwin" ? "Meta+A" : "Control+A");
|
||||
await this.page.keyboard.press("Backspace");
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator(this.queryButton).click();
|
||||
await this.page.getByText("SQL query is missing or invalid. Please submit a valid SQL statement.").click();
|
||||
}
|
||||
|
||||
|
||||
async kubernetesContainerName() {
|
||||
await this.page.getByLabel('Expand "kubernetes_container_name"').click();
|
||||
await this.page.waitForTimeout(5000);
|
||||
await this.page.locator('[data-test="logs-search-subfield-add-kubernetes_container_name-ziox"] [data-test="log-search-subfield-list-equal-kubernetes_container_name-field-btn"]').click();
|
||||
|
||||
}
|
||||
|
||||
async kubernetesContainerNameJoin() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a join "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async kubernetesContainerNameJoinLimit() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a join "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name LIMIT 10');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
|
||||
async kubernetesContainerNameJoinLike() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a join "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name WHERE a.kubernetes_container_name LIKE "%ziox%"');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async kubernetesContainerNameLeftJoin() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a LEFT JOIN "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async kubernetesContainerNameRightJoin() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a RIGHT JOIN "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async kubernetesContainerNameFullJoin() {
|
||||
await this.page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')
|
||||
.fill('SELECT a.kubernetes_container_name , b.kubernetes_container_name FROM "default" as a FULL JOIN "e2e_automate" as b on a.kubernetes_container_name = b.kubernetes_container_name');
|
||||
await this.page.waitForTimeout(5000);
|
||||
}
|
||||
|
||||
async displayCountQuery() {
|
||||
await this.page.waitForTimeout(4000);
|
||||
await expect(this.page.getByRole('heading', { name: 'Error while fetching' })).not.toBeVisible();
|
||||
}
|
||||
|
||||
async validateResult() {
|
||||
await this.page.waitForTimeout(10000);
|
||||
await expect(this.page.locator('[data-test="logs-search-search-result"]')).toBeVisible();
|
||||
await this.page.locator('td[data-test="log-table-column-0-source"]').nth(0).click();
|
||||
await expect(this.page.locator('[data-test="log-expand-detail-key-kubernetes_container_name-text"]')).toBeVisible();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
async signOut() {
|
||||
await this.profileButton.click();
|
||||
await this.signOutButton.click();
|
||||
}
|
||||
|
||||
async displayTwoStreams() {
|
||||
await expect(this.page.locator('[data-test="logs-search-index-list"]')).toContainText('default, e2e_automate');
|
||||
}
|
||||
|
||||
async verifyQuickModeToggle() {
|
||||
await expect(this.page.locator(this.quickModeToggle)).toBeVisible();
|
||||
}
|
||||
|
||||
async clickQuickModeToggle() {
|
||||
|
||||
// Get the toggle button element
|
||||
const toggleButton = await this.page.$('[data-test="logs-search-bar-quick-mode-toggle-btn"] > .q-toggle__inner');
|
||||
// Evaluate the class attribute to determine if the toggle is in the off state
|
||||
const isSwitchedOff = await toggleButton.evaluate(node => node.classList.contains('q-toggle__inner--falsy'));
|
||||
// If the toggle is switched off, click on it to switch it on
|
||||
if (isSwitchedOff) {
|
||||
await toggleButton.click();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async clickInterestingFields() {
|
||||
|
||||
await this.page.locator('[data-cy="index-field-search-input"]').fill("kubernetes_container_name");
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.locator('[data-test="log-search-index-list-interesting-kubernetes_container_name-field-btn"]').first().click();
|
||||
await this.page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
async validateInterestingFields() {
|
||||
await expect(this.page.locator('[data-test="logs-search-bar-query-editor"]').getByText(/kubernetes_container_name/).first()).toBeVisible();
|
||||
}
|
||||
|
||||
async validateInterestingFieldsQuery() {
|
||||
await this.page.waitForSelector('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(this.page.locator('[data-test="logs-search-bar-query-editor"]').locator('text=kubernetes_container_name FROM "default"')
|
||||
).toBeVisible();
|
||||
}
|
||||
|
||||
async addRemoveInteresting() {
|
||||
|
||||
await this.page.locator('[data-cy="index-field-search-input"]').clear();
|
||||
await this.page.locator('[data-cy="index-field-search-input"]').fill("job");
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.locator('[data-test="log-search-index-list-interesting-job-field-btn"]').last().click({ force: true, });
|
||||
await this.page.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content').click({ force: true, });
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.locator('[data-test="log-search-index-list-interesting-job-field-btn"]').last().click({ force: true, });
|
||||
await this.page.waitForTimeout(2000);
|
||||
await expect(this.page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox')).not.toHaveText(/job/);
|
||||
}
|
||||
|
||||
|
||||
async setDateTimeToToday() {
|
||||
// Set up route interception and apply filters
|
||||
await this.page.route('**/api/default/_search**', (route) => route.continue());;
|
||||
|
||||
// Click on the date-time button
|
||||
await expect(this.page.locator(this.dateTimeButton)).toBeVisible();
|
||||
await this.page.locator(this.dateTimeButton).click();
|
||||
|
||||
// Select the absolute date-time tab
|
||||
await this.page.locator('[data-test="date-time-absolute-tab"]').click();
|
||||
|
||||
// Select the current date
|
||||
const date = new Date().getDate();
|
||||
await this.page.getByRole('button', { name: date.toString(), exact: true }).last().click();
|
||||
await this.page.getByRole('button', { name: date.toString(), exact: true }).last().click();
|
||||
|
||||
// Fill the start time
|
||||
const startTimeInput = this.page.locator(".startEndTime td:nth-child(1) input");
|
||||
await startTimeInput.click();
|
||||
await startTimeInput.fill("");
|
||||
await startTimeInput.type("000000");
|
||||
|
||||
// Wait briefly for UI stability
|
||||
// await this.page.waitForTimeout(2000);
|
||||
await this.page.waitForSelector('.startEndTime td:nth-child(2) input', { state: 'visible' });
|
||||
|
||||
|
||||
// Fill the end time
|
||||
const endTimeInput = this.page.locator(".startEndTime td:nth-child(2) input");
|
||||
await endTimeInput.click();
|
||||
await endTimeInput.fill("");
|
||||
await this.page.waitForTimeout(2000);
|
||||
await endTimeInput.type("235900");
|
||||
await this.page.locator('[data-test="logs-logs-toggle"]', { state: 'visible' }).click();
|
||||
await this.page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
|
||||
// Wait briefly for search results to load
|
||||
await this.page.waitForTimeout(2000);
|
||||
|
||||
// Validate the date range of the log entries
|
||||
const startDate = new Date();
|
||||
startDate.setHours(0, 0, 0);
|
||||
const endDate = new Date();
|
||||
endDate.setHours(23, 59, 59);
|
||||
|
||||
const startDateStr = `${startDate.getFullYear()}-${String(startDate.getMonth() + 1).padStart(2, "0")}-${String(startDate.getDate()).padStart(2, "0")} 00:00:00`;
|
||||
const endDateStr = `${endDate.getFullYear()}-${String(endDate.getMonth() + 1).padStart(2, "0")}-${String(endDate.getDate()).padStart(2, "0")} 23:59:59`;
|
||||
|
||||
const rows = await this.page.locator('[data-test="logs-search-result-logs-table"] tbody:nth-of-type(2) tr').all();
|
||||
|
||||
for (let i = 2; i < rows.length; i++) {
|
||||
const dateText = await rows[i].locator('td:first-child div div:nth-child(2) span span').textContent();
|
||||
if (dateText) {
|
||||
const date = new Date(dateText.trim());
|
||||
const startDate = new Date(startDateStr);
|
||||
const endDate = new Date(endDateStr);
|
||||
|
||||
// Check if the parsed date is valid
|
||||
if (isNaN(date.getTime())) {
|
||||
throw new Error(`Invalid date format: ${dateText}`);
|
||||
}
|
||||
|
||||
expect(date >= startDate && date <= endDate).toBeTruthy();
|
||||
}
|
||||
}
|
||||
|
||||
await expect(this.page.locator('[data-test="logs-search-result-logs-table"]')).toBeVisible();
|
||||
}
|
||||
|
||||
async selectStreamAndStreamTypeForLogs(stream) {
|
||||
|
||||
await this.page.locator('[data-test="log-search-index-list-select-stream"]').click();
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.locator('[data-test="log-search-index-list-select-stream"]').fill(stream);
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.waitForSelector(`[data-test="log-search-index-list-stream-toggle-${stream}"] div`, { state: "visible" });
|
||||
await this.page.waitForTimeout(2000);
|
||||
await this.page.locator(`[data-test="log-search-index-list-stream-toggle-${stream}"] div`).first().click();
|
||||
}
|
||||
|
||||
async toggleHistogram() {
|
||||
await this.page.waitForSelector('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
await this.page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"] div').nth(2).click();
|
||||
}
|
||||
|
||||
async checkErrorVisible() {
|
||||
return this.page.getByRole('heading', { name: 'Error while fetching' }).isVisible();
|
||||
}
|
||||
|
||||
async getErrorDetails() {
|
||||
return this.page.locator('[data-test="logs-search-search-result"]').getByRole('heading');
|
||||
}
|
||||
|
||||
async selectIndexStreamDefault() {
|
||||
await this.page.locator('[data-test="logs-search-index-list"]').getByText('arrow_drop_down').click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator('[data-test="log-search-index-list-stream-toggle-default"] div').first().click();
|
||||
|
||||
}
|
||||
|
||||
async selectIndexStream(streamName) {
|
||||
await this.page.locator('[data-test="logs-search-index-list"]').getByText('arrow_drop_down').click();
|
||||
await this.page.waitForTimeout(3000);
|
||||
await this.page.locator(`[data-test="log-search-index-list-stream-toggle-${streamName}"] div`).first().click();
|
||||
|
||||
}
|
||||
|
||||
async clearAndFillQueryEditor(query) {
|
||||
const editor = this.page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox');
|
||||
await editor.fill(''); // Clear the editor
|
||||
await this.page.waitForTimeout(1000); // Optional: adjust or remove as per your needs
|
||||
await editor.fill(query); // Fill with the new query
|
||||
}
|
||||
|
||||
async typeQuery(query) {
|
||||
const queryEditor = this.page.locator('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(queryEditor).toBeVisible();
|
||||
await queryEditor.click();
|
||||
await this.page.locator('[data-test="logs-search-bar-query-editor"]').locator('.cm-content').fill(query);
|
||||
await this.page.waitForTimeout(1000);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
async waitForSearchResultAndCheckText(expectedText) {
|
||||
const locator = this.page.locator('[data-test="logs-search-search-result"]').getByRole('heading');
|
||||
await locator.waitFor(); // Wait for the element to be visible
|
||||
await expect(locator).toContainText(expectedText);
|
||||
}
|
||||
|
||||
async executeQueryWithKeyboardShortcut() {
|
||||
// Press Cmd+Enter (Mac) or Ctrl+Enter (Windows/Linux)
|
||||
await this.page.keyboard.press(process.platform === "darwin" ? "Meta+Enter" : "Control+Enter");
|
||||
}
|
||||
|
||||
async executeQueryWithKeyboardShortcutTest() {
|
||||
// Set up date/time filter
|
||||
await this.page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await this.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 = this.page.locator('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(queryEditor).toBeVisible();
|
||||
await queryEditor.click();
|
||||
await this.page.keyboard.type("match_all('code')");
|
||||
|
||||
// Execute query using keyboard shortcut
|
||||
await this.executeQueryWithKeyboardShortcut();
|
||||
|
||||
// Verify that the expected log table column is visible
|
||||
await expect(this.page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
|
||||
}
|
||||
|
||||
async executeQueryWithKeyboardShortcutAfterClickingElsewhere() {
|
||||
// Set up date/time filter
|
||||
await this.page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await this.page.locator('[data-test="date-time-relative-15-m-btn"] > .q-btn__content > .block').click({ force: true });
|
||||
|
||||
// Click elsewhere on the screen first
|
||||
await this.page.locator('[data-test="logs-search-bar"]').click();
|
||||
|
||||
// Ensure the query editor is visible and clickable before typing
|
||||
const queryEditor = this.page.locator('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(queryEditor).toBeVisible();
|
||||
await queryEditor.click();
|
||||
await this.page.keyboard.type("match_all('code')");
|
||||
|
||||
// Execute query using keyboard shortcut
|
||||
await this.executeQueryWithKeyboardShortcut();
|
||||
|
||||
// Verify that the expected log table column is visible
|
||||
await expect(this.page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
|
||||
}
|
||||
|
||||
async executeQueryWithKeyboardShortcutWithDifferentQuery() {
|
||||
// Set up date/time filter
|
||||
await this.page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await this.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 = this.page.locator('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(queryEditor).toBeVisible();
|
||||
await queryEditor.click();
|
||||
await this.page.keyboard.type("str_match_ignore_case(kubernetes_container_name, 'ziox')");
|
||||
|
||||
// Execute query using keyboard shortcut
|
||||
await this.executeQueryWithKeyboardShortcut();
|
||||
|
||||
// Verify that the expected log table column is visible
|
||||
await expect(this.page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
|
||||
}
|
||||
|
||||
async executeQueryWithKeyboardShortcutWithSQLMode() {
|
||||
// Set up date/time filter
|
||||
await this.page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await this.page.locator('[data-test="date-time-relative-15-m-btn"] > .q-btn__content > .block').click({ force: true });
|
||||
|
||||
// Enable SQL mode
|
||||
await this.sqlModeToggle.click();
|
||||
|
||||
// Ensure the query editor is visible and clickable before typing
|
||||
const queryEditor = this.page.locator('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(queryEditor).toBeVisible();
|
||||
await queryEditor.click();
|
||||
await this.page.keyboard.type('SELECT COUNT(_timestamp) AS xyz, _timestamp FROM "e2e_automate" Group by _timestamp ORDER BY _timestamp DESC');
|
||||
|
||||
// Execute query using keyboard shortcut
|
||||
await this.executeQueryWithKeyboardShortcut();
|
||||
|
||||
// Verify that the expected log table column is visible
|
||||
await expect(this.page.locator('[data-test="logs-search-result-bar-chart"]')).toBeVisible();
|
||||
}
|
||||
|
||||
async executeQueryWithErrorHandling() {
|
||||
// Fill query editor with invalid query
|
||||
await this.page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox', { name: 'Editor content;Press Alt+F1' }).fill('match_all(\'invalid\')');
|
||||
|
||||
// Click refresh button and verify error
|
||||
await this.page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await this.page.locator('[data-test="logs-search-error-message"]').click();
|
||||
|
||||
// Reset filters
|
||||
await this.page.locator('[data-test="logs-search-bar-reset-filters-btn"]').click();
|
||||
|
||||
// Toggle histogram
|
||||
await this.page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"] div').first().click();
|
||||
|
||||
// Click first line and refresh
|
||||
await this.page.locator('.cm-line').first().click();
|
||||
await this.page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
|
||||
// Verify no data message
|
||||
await this.page.getByText('warning No data found for').click();
|
||||
|
||||
// Click on result detail
|
||||
await this.page.locator('[data-test="logs-search-result-detail-undefined"]').click();
|
||||
}
|
||||
|
||||
// New methods for histogram query test
|
||||
async executeHistogramQuery(query) {
|
||||
await this.page.locator('[data-test="logs-search-bar-query-editor"]').locator('.cm-content').click();
|
||||
await this.page.keyboard.type(query);
|
||||
await this.page.waitForTimeout(2000);
|
||||
}
|
||||
|
||||
async toggleHistogramAndExecute() {
|
||||
await this.page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"] div').nth(2).click();
|
||||
await this.page.waitForTimeout(1000);
|
||||
await this.page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
}
|
||||
|
||||
async verifyHistogramState() {
|
||||
const isHistogramOff = await this.page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]')
|
||||
.evaluate(el => el.getAttribute('aria-checked') === 'false');
|
||||
expect(isHistogramOff).toBeTruthy();
|
||||
}
|
||||
|
||||
async verifySearchPartitionResponse() {
|
||||
const searchPartitionPromise = this.page.waitForResponse(response =>
|
||||
response.url().includes('/api/default/_search_partition') &&
|
||||
response.request().method() === 'POST'
|
||||
);
|
||||
|
||||
const searchPartitionResponse = await searchPartitionPromise;
|
||||
const searchPartitionData = await searchPartitionResponse.json();
|
||||
|
||||
expect(searchPartitionData).toHaveProperty('partitions');
|
||||
expect(searchPartitionData).toHaveProperty('histogram_interval');
|
||||
expect(searchPartitionData).toHaveProperty('order_by', 'asc');
|
||||
|
||||
return searchPartitionData;
|
||||
}
|
||||
|
||||
async captureSearchCalls() {
|
||||
const searchCalls = [];
|
||||
this.page.on('response', async response => {
|
||||
if (response.url().includes('/api/default/_search') &&
|
||||
response.request().method() === 'POST') {
|
||||
const requestData = await response.request().postDataJSON();
|
||||
searchCalls.push({
|
||||
start_time: requestData.query.start_time,
|
||||
end_time: requestData.query.end_time,
|
||||
sql: requestData.query.sql
|
||||
});
|
||||
}
|
||||
});
|
||||
await this.page.waitForTimeout(2000);
|
||||
return searchCalls;
|
||||
}
|
||||
|
||||
async verifyStreamingModeResponse() {
|
||||
const searchPromise = this.page.waitForResponse(response =>
|
||||
response.url().includes('/api/default/_search') &&
|
||||
response.request().method() === 'POST'
|
||||
);
|
||||
|
||||
const searchResponse = await searchPromise;
|
||||
expect(searchResponse.status()).toBe(200);
|
||||
|
||||
const searchData = await searchResponse.json();
|
||||
expect(searchData).toBeDefined();
|
||||
expect(searchData.hits).toBeDefined();
|
||||
}
|
||||
|
||||
async clickExplore() {
|
||||
try {
|
||||
// Wait for the explore button to be visible and clickable
|
||||
await this.exploreButton.first().waitFor({ state: 'visible', timeout: 10000 });
|
||||
await this.exploreButton.first().waitFor({ state: 'attached', timeout: 10000 });
|
||||
|
||||
// Click the button and wait for any network requests to complete
|
||||
await Promise.all([
|
||||
this.page.waitForLoadState('networkidle'),
|
||||
this.exploreButton.first().click()
|
||||
]);
|
||||
|
||||
// Wait for the results to load
|
||||
await this.page.waitForTimeout(3000);
|
||||
} catch (error) {
|
||||
console.error('Error in clickExplore:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async openTimestampMenu() {
|
||||
try {
|
||||
// Wait for the table to be visible first
|
||||
await this.page.waitForSelector('[data-test="logs-search-result-logs-table"]', { state: 'visible', timeout: 10000 });
|
||||
|
||||
// Wait for the timestamp column to be visible
|
||||
await this.page.waitForSelector('[data-test="log-table-column-1-_timestamp"]', { state: 'visible', timeout: 10000 });
|
||||
|
||||
// Wait for the menu button to be visible and clickable
|
||||
await this.timestampColumnMenu.waitFor({ state: 'visible', timeout: 10000 });
|
||||
|
||||
// Ensure the menu button is in viewport
|
||||
await this.timestampColumnMenu.scrollIntoViewIfNeeded();
|
||||
|
||||
// Click the menu and wait for any network requests to complete
|
||||
await Promise.all([
|
||||
this.page.waitForLoadState('networkidle'),
|
||||
this.timestampColumnMenu.click({ force: true })
|
||||
]);
|
||||
|
||||
// Wait for the menu to open
|
||||
await this.page.waitForTimeout(1000);
|
||||
} catch (error) {
|
||||
console.error('Error in openTimestampMenu:', error);
|
||||
// Try alternative approach if first attempt fails
|
||||
try {
|
||||
await this.page.waitForTimeout(2000); // Give more time for the table to load
|
||||
await this.timestampColumnMenu.click({ force: true });
|
||||
await this.page.waitForTimeout(1000);
|
||||
} catch (retryError) {
|
||||
console.error('Error in openTimestampMenu retry:', retryError);
|
||||
throw retryError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async clickResultsPerPage() {
|
||||
// Click the dropdown to open the options
|
||||
await this.page.locator('[data-test="logs-search-search-result"]').getByText('arrow_drop_down').click();
|
||||
await this.page.getByText('10', { exact: true }).click();
|
||||
await this.page.waitForTimeout(2000);
|
||||
await expect(this.page.locator('[data-test="logs-search-search-result"]')).toContainText('Showing 1 to 10 out of');
|
||||
}
|
||||
|
||||
async selectResultsPerPageAndVerify(resultsPerPage, expectedText) {
|
||||
|
||||
await this.page.getByText(resultsPerPage, { exact: true }).click();
|
||||
await this.page.waitForTimeout(2000);
|
||||
await expect(this.page.locator('[data-test="logs-search-search-result"]')).toContainText(expectedText);
|
||||
}
|
||||
|
||||
async pageNotVisible() {
|
||||
|
||||
const fastRewindElement = this.page.locator('[data-test="logs-search-result-records-per-page"]').getByText('50');
|
||||
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();
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
import { expect } from '@playwright/test';
|
||||
import { LoginPage } from '../loginPage.js';
|
||||
import { LogsPage } from '../logsPage.js';
|
||||
import { LogsPage } from '../logsPages/logsPage.js';
|
||||
import { IngestionPage } from '../ingestionPage.js';
|
||||
import { ManagementPage } from '../managementPage.js';
|
||||
import { StreamPage } from '../streamPage.js';
|
||||
@@ -194,4 +194,9 @@ export class StreamsPage {
|
||||
const errorDetailsButton = this.page.locator('[data-test="logs-page-histogram-error-details-btn"]');
|
||||
await expect(errorDetailsButton).not.toBeVisible();
|
||||
}
|
||||
|
||||
// Validation method for 'No data found for histogram.'
|
||||
async expectNoDataFoundForHistogram() {
|
||||
await expect(this.page.getByText('warning No data found for histogram.')).toBeVisible();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
import { test, expect } from "../baseFixtures.js";
|
||||
import logData from "../../cypress/fixtures/log.json";
|
||||
import { LogsPage } from '../../pages/logsPages/logsPage.js';
|
||||
import logsdata from "../../../test-data/logs_data.json";
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
await page.locator('[data-cy="login-user-id"]').fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
await page.locator("label").filter({ hasText: "Password *" }).click();
|
||||
await page.locator('[data-cy="login-password"]').fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
test.describe("Logs Histogram testcases", () => {
|
||||
let logsPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(5000);
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
});
|
||||
|
||||
test("Verify error handling and no results found with histogram", {
|
||||
tag: ['@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Check if histogram is off and toggle it on if needed
|
||||
const isHistogramOn = await logsPage.isHistogramOn();
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Type invalid query and verify error
|
||||
await logsPage.typeQuery("match_all('invalid')");
|
||||
await logsPage.setDateTimeFilter();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.clickErrorMessage();
|
||||
await logsPage.clickResetFilters();
|
||||
|
||||
// Type SQL query and verify no results
|
||||
await logsPage.typeQuery("SELECT count(*) FROM 'e2e_automate' where code > 500");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickNoDataFound();
|
||||
await logsPage.clickResultDetail();
|
||||
});
|
||||
|
||||
test("Verify error handling with histogram toggle off and on", {
|
||||
tag: ['@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Check if histogram is on and toggle it off
|
||||
const isHistogramOn = await logsPage.isHistogramOn();
|
||||
if (isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Type invalid query and verify error
|
||||
await logsPage.typeQuery("match_all('invalid')");
|
||||
await logsPage.setDateTimeFilter();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.clickErrorMessage();
|
||||
await logsPage.clickResetFilters();
|
||||
|
||||
// Toggle histogram back on
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Type SQL query and verify no results
|
||||
await logsPage.typeQuery("SELECT count(*) FROM 'e2e_automate' where code > 500");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickNoDataFound();
|
||||
await logsPage.clickResultDetail();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle persistence after multiple queries", {
|
||||
tag: ['@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Start with histogram on
|
||||
const isHistogramOn = await logsPage.isHistogramOn();
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Run first query
|
||||
await logsPage.typeQuery("SELECT * FROM 'e2e_automate' LIMIT 10");
|
||||
await logsPage.setDateTimeFilter();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram off
|
||||
await logsPage.toggleHistogram();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.enableSQLMode();
|
||||
|
||||
// Run second query
|
||||
await logsPage.typeQuery("SELECT count(*) FROM 'e2e_automate'");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
|
||||
// Verify histogram stays off
|
||||
await logsPage.verifyHistogramState();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle with empty query", {
|
||||
tag: ['@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Start with histogram off
|
||||
const isHistogramOn = await logsPage.isHistogramOn();
|
||||
if (isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Clear query and refresh
|
||||
await logsPage.typeQuery("");
|
||||
await logsPage.setDateTimeFilter();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram on
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Verify histogram state
|
||||
const isHistogramOnAfterToggle = await logsPage.isHistogramOn();
|
||||
expect(isHistogramOnAfterToggle).toBeTruthy();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle with complex query", {
|
||||
tag: ['@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Start with histogram on
|
||||
const isHistogramOn = await logsPage.isHistogramOn();
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Run complex query
|
||||
await logsPage.typeQuery("SELECT * FROM 'e2e_automate' WHERE timestamp > '2024-01-01' AND code < 400 GROUP BY code ORDER BY count(*) DESC LIMIT 5");
|
||||
await logsPage.setDateTimeFilter();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram off and verify
|
||||
await logsPage.toggleHistogram();
|
||||
const isHistogramOff = await logsPage.isHistogramOn();
|
||||
expect(!isHistogramOff).toBeTruthy();
|
||||
|
||||
// Run another query and verify histogram stays off
|
||||
await logsPage.typeQuery("SELECT count(*) FROM 'e2e_automate'");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefresh();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
|
||||
const isHistogramStillOff = await logsPage.isHistogramOn();
|
||||
expect(!isHistogramStillOff).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,467 @@
|
||||
import { test, expect } from "../baseFixtures";
|
||||
import logData from "../../cypress/fixtures/log.json";
|
||||
import logsdata from "../../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
console.log("ZO_BASE_URL", process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
test.describe("Logs Page testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
// click on the run query button
|
||||
// Type the value of a variable into an input field
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
// tebefore(async function () {
|
||||
// // logData("log");
|
||||
// // const data = page;
|
||||
// // logData = data;
|
||||
|
||||
// console.log("--logData--", logData);
|
||||
// });
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000)
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
test("should click run query after SQL toggle on but without any query", {
|
||||
tag: ['@sqlQueryLogs', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.selectAllText();
|
||||
await logsPage.pressBackspace();
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.expectSQLQueryMissingError();
|
||||
});
|
||||
|
||||
test("should be able to enter valid text in VRL and run query", {
|
||||
tag: ['@vrlQueryLogs', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await applyQueryButton(page);
|
||||
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await applyQueryButton(page);
|
||||
await logsPage.expectWarningElementHidden();
|
||||
|
||||
await logsPage.clickTableRowExpandMenu();
|
||||
await logsPage.expectTextVisible(".a=2");
|
||||
await logsPage.expectLogsTableVisible();
|
||||
await logsPage.clickRefreshButton();
|
||||
});
|
||||
|
||||
test("should hide and display again after clicking the arrow", {
|
||||
tag: ['@hideAndDisplayLogs', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await logsPage.clickShowQueryToggle();
|
||||
await logsPage.clickFieldListCollapseButton();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickFieldListCollapseButton();
|
||||
await logsPage.expectIndexFieldSearchInputVisible();
|
||||
});
|
||||
|
||||
test("should verify if special characters allowed in saved views name", {
|
||||
tag: ['@savedViewsSpecialCharacters', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await logsPage.clickShowQueryToggle();
|
||||
await logsPage.clickSavedViewsButton();
|
||||
await logsPage.fillSavedViewName("e2e@@@@@");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.expectNotificationMessage("Please provide valid view name");
|
||||
});
|
||||
|
||||
test("should display error when user directly clicks on OK without adding name", {
|
||||
tag: ['@savedViewsValidation', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSaveViewButton();
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
});
|
||||
|
||||
test("should display the details of logs results on graph", {
|
||||
tag: ['@logsResultsGraph', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await applyQueryButton(page);
|
||||
await logsPage.waitForTimeout(5000);
|
||||
await logsPage.expectSearchListVisible();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickLogTableColumnSource();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickCloseDialogForce();
|
||||
await logsPage.expectSearchListVisible();
|
||||
});
|
||||
|
||||
test("should click on live mode on button and select 5 sec, switch off, and then click run query", {
|
||||
tag: ['@liveMode', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route("**/logData.ValueQuery", (route) => route.continue());
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await logsPage.clickLiveModeButton();
|
||||
await logsPage.clickLiveMode5Sec();
|
||||
await logsPage.expectNotificationMessage("Live mode is enabled");
|
||||
await logsPage.clickLiveModeButton();
|
||||
await logsPage.clickLiveMode5Sec();
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
test("should click on VRL toggle and display the field, then disable toggle and make the VRL field disappear", {
|
||||
tag: ['@vrlToggle', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.expectVrlFieldVisible();
|
||||
await logsPage.clickVrlToggle();
|
||||
await logsPage.expectFnEditorNotVisible();
|
||||
});
|
||||
|
||||
test("should switch from past 6 weeks to past 6 days on date-time UI", {
|
||||
tag: ['@dateTimeUI', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative6WeeksButton();
|
||||
await logsPage.expectTextVisible("Past 6 Weeks");
|
||||
await applyQueryButton(page);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickPast6DaysButton();
|
||||
await logsPage.expectTextVisible("Past 6 Days");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
test("should display SQL query on switching between Menu options & navigating to Logs again", {
|
||||
tag: ['@sqlQueryPersistence', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickSQLModeToggle();
|
||||
const expectedQuery = 'SELECT * FROM "e2e_automate"';
|
||||
const text = await logsPage.getQueryEditorText();
|
||||
await expect(text.replace(/\s/g, "")).toContain(expectedQuery.replace(/\s/g, ""));
|
||||
await logsPage.clickMenuLinkMetricsItem();
|
||||
await logsPage.clickMenuLinkLogsItem();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectQueryEditorContainsSelectFrom();
|
||||
});
|
||||
test("should display ingested logs - search logs, navigate on another tab, revisit logs page", {
|
||||
tag: ['@ingestedLogsPersistence', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await applyQueryButton(page);
|
||||
await logsPage.clickMenuLinkTracesItem();
|
||||
await logsPage.waitForTimeout(100);
|
||||
await logsPage.clickMenuLinkLogsItem();
|
||||
await logsPage.waitForTimeout(5000);
|
||||
await logsPage.expectBarChartVisible();
|
||||
});
|
||||
|
||||
test.skip("should redirect to logs after clicking on stream explorer via stream page", {
|
||||
tag: ['@streamExplorer', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickMenuLinkStreamsItem();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickMenuLinkStreamsItem();
|
||||
await logsPage.clickSearchStreamInput();
|
||||
await logsPage.fillSearchStreamInput("e2e");
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickExploreButton();
|
||||
await logsPage.expectUrlContainsLogs();
|
||||
});
|
||||
|
||||
test('should display error when save function is clicked without any VRL function', {
|
||||
tag: ['@functionValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.expectWarningNoFunctionDefinition();
|
||||
});
|
||||
|
||||
test('should create a function and then delete it', {
|
||||
tag: ['@functionCRUD', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.clickSavedFunctionNameInput();
|
||||
const randomString = logsPage.generateRandomString();
|
||||
const functionName = 'e2efunction_' + randomString;
|
||||
await logsPage.fillSavedFunctionNameInput(functionName);
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.clickMenuLinkPipelineItem();
|
||||
await logsPage.clickTabRealtime();
|
||||
await logsPage.clickFunctionStreamTab();
|
||||
await logsPage.clickSearchFunctionInput();
|
||||
await logsPage.fillSearchFunctionInput(randomString);
|
||||
await logsPage.clickDeleteFunctionButton();
|
||||
await logsPage.clickConfirmButton();
|
||||
});
|
||||
|
||||
test('should display click save directly while creating a function', {
|
||||
tag: ['@functionSaveValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.expectFunctionNameNotValid();
|
||||
});
|
||||
|
||||
test('should display error on adding only blank spaces under function name', {
|
||||
tag: ['@functionNameValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.fillSavedFunctionNameInput(' ');
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.expectFunctionNameNotValid();
|
||||
});
|
||||
|
||||
|
||||
test('should display error on adding invalid characters under function name', {
|
||||
tag: ['@functionNameValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickFunctionDropdownSave();
|
||||
await logsPage.fillSavedFunctionNameInput('e2e@@@');
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.expectFunctionNameNotValid();
|
||||
});
|
||||
|
||||
test('should display added function on switching between tabs and again navigate to log', {
|
||||
tag: ['@functionPersistence', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickMenuLinkMetricsItem();
|
||||
await logsPage.clickMenuLinkLogsItem();
|
||||
await logsPage.clickMenuLinkLogsItem();
|
||||
await logsPage.expectPageContainsText(".a=2");
|
||||
});
|
||||
|
||||
test('should display bar chart when histogram toggle is on', {
|
||||
tag: ['@histogramBarChart', '@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickLogSearchIndexListFieldSearchInput();
|
||||
await logsPage.fillLogSearchIndexListFieldSearchInput('code');
|
||||
await logsPage.waitForTimeout(4000);
|
||||
await logsPage.clickExpandCode();
|
||||
await logsPage.waitForTimeout(4000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickBarChartCanvas();
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickBarChartCanvas();
|
||||
await logsPage.clickHistogramToggleDiv();
|
||||
});
|
||||
|
||||
test('should display search around in histogram mode', {
|
||||
tag: ['@searchAroundHistogram', '@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickLogTableColumnSource();
|
||||
await logsPage.clickLogsDetailTableSearchAroundBtn();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
|
||||
test.skip('should display results for search around after adding function', async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickVrlEditor();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickLogTableColumn3Source();
|
||||
await logsPage.clickLogsDetailTableSearchAroundBtn();
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
test('should display search around in SQL mode', {
|
||||
tag: ['@searchAroundSQL', '@sqlMode', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickLogTableColumnSource();
|
||||
await logsPage.clickLogsDetailTableSearchAroundBtn();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
test("should display results for search around with limit query", {
|
||||
tag: ['@searchAroundLimit', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor("match_all('code') limit 5");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickLogTableColumnSource();
|
||||
await logsPage.clickLogsDetailTableSearchAroundBtn();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
test("should not display pagination for limit query", {
|
||||
tag: ['@paginationLimit', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor("match_all('code') limit 5");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectPaginationNotVisible();
|
||||
});
|
||||
|
||||
test("should not display pagination for SQL limit query", {
|
||||
tag: ['@paginationSQLLimit', '@sqlMode', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor('SELECT * FROM "e2e_automate" ORDER BY _timestamp DESC limit 5');
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectPaginationNotVisible();
|
||||
});
|
||||
|
||||
test("should not display pagination for SQL group/order/limit query", {
|
||||
tag: ['@paginationSQLGroupOrder', '@sqlMode', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor('SELECT * FROM "e2e_automate" WHERE code < 400 GROUP BY code ORDER BY count(*) DESC LIMIT 5');
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectPaginationNotVisible();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,334 @@
|
||||
import { test, expect } from "../baseFixtures";
|
||||
import logData from "../../cypress/fixtures/log.json";
|
||||
import logsdata from "../../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
test.describe("Logs Queries testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
// click on the run query button
|
||||
// Type the value of a variable into an input field
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000)
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
test("should display quick mode toggle button", {
|
||||
tag: ['@quickModeLogs', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.expectQuickModeToggleVisible();
|
||||
});
|
||||
|
||||
test.skip("should add timestamp to editor save this view and switch", {
|
||||
tag: ['@timestampViewLogs', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickLogTableColumnSource();
|
||||
await logsPage.clickIncludeExcludeFieldButton();
|
||||
await logsPage.clickIncludeFieldButton();
|
||||
await logsPage.clickCloseDialog();
|
||||
await logsPage.clickSavedViewsButton();
|
||||
await logsPage.fillSavedViewName("e2etimestamp");
|
||||
await logsPage.clickSavedViewDialogSaveContent();
|
||||
await logsPage.clickSavedViewArrow();
|
||||
await logsPage.clickSavedViewByLabel(/timestamp/);
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSavedViewSearchInput();
|
||||
await logsPage.fillSavedViewSearchInput('e2e');
|
||||
await logsPage.clickSavedViewByTitle('e2etimestamp');
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSavedViewSearchInput();
|
||||
await logsPage.clickSavedViewByTitle('e2etimestamp');
|
||||
await logsPage.clickDeleteButton();
|
||||
await logsPage.clickConfirmButton();
|
||||
});
|
||||
|
||||
test("should redirect to logs after clicking on stream explorer via stream page", {
|
||||
tag: ['@streamExplorer', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Generate a random saved view name
|
||||
const randomSavedViewName = `streamslog${Math.random().toString(36).substring(2, 10)}`;
|
||||
|
||||
// Interactions with the page
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSaveViewButton();
|
||||
await logsPage.fillSavedViewName(randomSavedViewName); // Use the random name
|
||||
await logsPage.clickSavedViewDialogSave();
|
||||
await logsPage.waitForTimeout(5000);
|
||||
await logsPage.clickStreamsMenuItem();
|
||||
await logsPage.clickSearchStreamInput();
|
||||
await logsPage.fillSearchStreamInput('e2e');
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.clickExploreButton();
|
||||
await logsPage.waitForTimeout(5000);
|
||||
await logsPage.waitForSavedViewsButton();
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSavedViewSearchInput();
|
||||
await logsPage.fillSavedViewSearchInput(randomSavedViewName); // Use the random name here
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.waitForSavedViewText(randomSavedViewName);
|
||||
await logsPage.clickSavedViewByText(randomSavedViewName);
|
||||
await logsPage.clickSavedViewsExpand();
|
||||
await logsPage.clickSavedViewSearchInput();
|
||||
await logsPage.clickSavedViewByTitle(randomSavedViewName); // Use the random name here
|
||||
|
||||
// Dynamic delete button selector using the random saved view name
|
||||
await logsPage.clickDeleteSavedViewButton(randomSavedViewName);
|
||||
await logsPage.clickConfirmButton(); // Confirm deletion
|
||||
});
|
||||
|
||||
test("should reset the editor on clicking reset filter button", {
|
||||
tag: ['@resetFilters', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditorTextbox();
|
||||
await logsPage.typeInQueryEditor("match_all_raw_ignore_case('provide_credentials')");
|
||||
await logsPage.waitForSearchBarRefreshButton();
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickResetFiltersButton();
|
||||
await logsPage.waitForQueryEditorTextbox();
|
||||
await logsPage.expectQueryEditorEmpty();
|
||||
});
|
||||
|
||||
test("should add invalid query and display error", {
|
||||
tag: ['@invalidQueryLogs', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor("kubernetes");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.expectErrorMessageVisible();
|
||||
});
|
||||
|
||||
test("should not display error if match all case added in log query search", {
|
||||
tag: ['@matchAllLogs', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickDateTimeButton();
|
||||
await logsPage.clickRelative15MinButton();
|
||||
|
||||
await logsPage.expectQueryEditorVisible();
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor("match_all('code')");
|
||||
|
||||
await logsPage.expectSearchBarRefreshButtonVisible();
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("should change stream settings and click on search stream", {
|
||||
tag: ['@streamSettings', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickStreamsMenuItem();
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickStreamsSearchStreamInput();
|
||||
await logsPage.fillStreamsSearchStreamInput("e2e_automate");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickStreamDetail();
|
||||
await logsPage.clickSchemaStreamIndexSelect();
|
||||
await logsPage.clickFullTextSearch();
|
||||
await logsPage.clickSchemaUpdateSettingsButton();
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickColAutoButton();
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickExploreTitle();
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
});
|
||||
|
||||
|
||||
test("should display error if blank spaces added under stream name and clicked create stream ", {
|
||||
tag: ['@streamValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickStreamsMenuItem();
|
||||
await logsPage.clickAddStreamButton();
|
||||
await logsPage.clickAddStreamNameInput();
|
||||
await logsPage.typeInQueryEditor(" ");
|
||||
await logsPage.clickSaveStreamButton();
|
||||
await logsPage.expectFieldRequiredVisible();
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("should display error if create stream is clicked without adding name", {
|
||||
tag: ['@streamValidation', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickStreamsMenuItem();
|
||||
await logsPage.clickAddStreamButton();
|
||||
await logsPage.waitForSaveStreamButton();
|
||||
await logsPage.scrollSaveStreamButtonIntoView();
|
||||
await logsPage.clickSaveStreamButton();
|
||||
await logsPage.expectFieldRequiredVisible();
|
||||
});
|
||||
|
||||
test("should display enter count query", {
|
||||
tag: ['@countQuery', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.clickQueryEditorTextbox();
|
||||
await logsPage.typeInQueryEditor('SELECT COUNT(_timestamp) AS xyz, _timestamp FROM "e2e_automate" Group by _timestamp ORDER BY _timestamp DESC');
|
||||
await logsPage.waitForTimeout(4000);
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.expectSearchBarRefreshButtonVisible();
|
||||
await logsPage.waitForTimeout(3000);
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.waitForTimeout(4000);
|
||||
await logsPage.expectErrorWhileFetchingNotVisible();
|
||||
await logsPage.clickBarChartCanvas();
|
||||
});
|
||||
|
||||
test("should display values API text successfully and error to not be displayed", {
|
||||
tag: ['@valuesAPI', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.fillIndexFieldSearchInput('kubernetes_pod_name');
|
||||
await logsPage.clickExpandLabel('kubernetes_pod_name');
|
||||
await logsPage.expectErrorWhileFetchingFieldValuesNotVisible();
|
||||
await logsPage.clickText('ziox-ingester-');
|
||||
await logsPage.clickRefreshButton();
|
||||
await logsPage.clickCollapseLabel('kubernetes_pod_name');
|
||||
await logsPage.clickExpandLabel('kubernetes_pod_name');
|
||||
await logsPage.expectSubfieldAddButtonVisible('kubernetes_pod_name', 'ziox-ingester-');
|
||||
await logsPage.clickSubfieldAddButton('kubernetes_pod_name', 'ziox-ingester-');
|
||||
});
|
||||
|
||||
test("should display results in selected time", {
|
||||
tag: ['@timeSelection', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
await logsPage.setDateTimeToToday();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("should display results if stringmatch ignorecase lowercase added in log query search", {
|
||||
tag: ['@stringMatchIgnoreLowerCase', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.selectStream('e2e_automate');
|
||||
await logsPage.setDateTimeTo15Minutes();
|
||||
await logsPage.searchWithStringMatchIgnoreCase('ziox');
|
||||
});
|
||||
|
||||
test("should display results if stringmatch ignorecase uppercase added in log query search", {
|
||||
tag: ['@stringMatchIgnoreUpperCase', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.selectStream('e2e_automate');
|
||||
await logsPage.setDateTimeTo15Minutes();
|
||||
await logsPage.searchWithStringMatchIgnoreCase('Ziox');
|
||||
});
|
||||
|
||||
test("should trigger search results when pressing Cmd+Enter or Ctrl+Enter", {
|
||||
tag: ['@keyboardShortcuts', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutTest();
|
||||
});
|
||||
|
||||
test("should execute query with keyboard shortcut (Cmd+Enter or Ctrl+Enter) after clicking elsewhere ", {
|
||||
tag: ['@keyboardShortcuts', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutAfterClickingElsewhere();
|
||||
});
|
||||
|
||||
test("should execute different query with keyboard shortcut (Cmd+Enter or Ctrl+Enter)", {
|
||||
tag: ['@keyboardShortcuts', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutWithDifferentQuery();
|
||||
});
|
||||
|
||||
test("should execute SQL query with keyboard shortcut (Cmd+Enter or Ctrl+Enter)", {
|
||||
tag: ['@keyboardShortcuts', '@sqlMode', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutWithSQLMode();
|
||||
});
|
||||
|
||||
test("should verify logcount ordering in ascending and descending order", {
|
||||
tag: ['@logCountOrdering', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
// Verify descending order
|
||||
await logsPage.verifyLogCountOrderingDescending();
|
||||
|
||||
// Verify ascending order
|
||||
await logsPage.verifyLogCountOrderingAscending();
|
||||
});
|
||||
})
|
||||
@@ -0,0 +1,204 @@
|
||||
import { test, expect } from "../baseFixtures";
|
||||
import logData from "../../cypress/fixtures/log.json";
|
||||
import logsdata from "../../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
console.log("ZO_BASE_URL", process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
test.describe("Logs Quickmode testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000);
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
|
||||
await applyQueryButton(page);
|
||||
|
||||
// Enable quick mode toggle if it's not already enabled
|
||||
const toggleButton = await logsPage.page.$('[data-test="logs-search-bar-quick-mode-toggle-btn"] > .q-toggle__inner');
|
||||
// Evaluate the class attribute to determine if the toggle is in the off state
|
||||
const isSwitchedOff = await toggleButton.evaluate(node => node.classList.contains('q-toggle__inner--falsy'));
|
||||
if (isSwitchedOff) {
|
||||
await toggleButton.click();
|
||||
}
|
||||
});
|
||||
test("should click on interesting fields icon and display query in editor", {
|
||||
tag: ['@interestingFieldsLogs', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_pod_id");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_pod_id");
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectInterestingFieldInEditor("kubernetes_pod_id");
|
||||
});
|
||||
test("should display quick mode toggle button", {
|
||||
tag: ['@quickModeLogs', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.expectQuickModeToggleVisible();
|
||||
});
|
||||
|
||||
test("should click on interesting fields icon in histogram mode and run query", {
|
||||
tag: ['@interestingFieldsHistogramModeLogs', '@histogram', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_pod_id");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_pod_id");
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectInterestingFieldInTable("kubernetes_pod_id");
|
||||
});
|
||||
|
||||
test("should display error on entering random text in histogram mode when quick mode is on", {
|
||||
tag: ['@errorHandlingHistogramModeLogs', '@histogram', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickQueryEditor();
|
||||
await logsPage.typeInQueryEditor("oooo");
|
||||
await logsPage.waitForTimeout(1000);
|
||||
await logsPage.waitForSearchBarRefreshButton();
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectErrorMessageVisible();
|
||||
});
|
||||
|
||||
test("should display selected interestesing field and order by - as default in editor", {
|
||||
tag: ['@interestingFieldsSqlModeLogs', '@sqlMode', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_pod_id");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_pod_id");
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.waitForQueryEditorTextbox();
|
||||
await logsPage.expectQueryEditorVisible();
|
||||
});
|
||||
|
||||
test("should adding/removing interesting field removes it from editor and results too", {
|
||||
tag: ['@interestingFieldsCRUD', '@all', '@logs']
|
||||
}, async ({ page }) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_container_name");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_container_name");
|
||||
await logsPage.fillIndexFieldSearchInput("level");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("level");
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.expectLogTableColumnSourceVisible();
|
||||
await logsPage.clickInterestingFieldButton("level");
|
||||
await logsPage.expectQueryEditorNotContainsText("level");
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.expectLogTableColumnSourceNotHaveText("source");
|
||||
});
|
||||
|
||||
test("should display order by in sql mode by default even after page reload", {
|
||||
tag: ['@sqlModeOrderBy', '@sqlMode', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_pod_id");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_pod_id");
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.page.reload();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectQueryEditorContainsText('SELECT kubernetes_pod_id FROM "e2e_automate"');
|
||||
});
|
||||
|
||||
test("should display results without adding timestamp in quick mode", {
|
||||
tag: ['@quickModeResults', '@all', '@logs']
|
||||
}, async ({
|
||||
page,
|
||||
}) => {
|
||||
await logsPage.fillIndexFieldSearchInput("kubernetes_pod_id");
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickInterestingFieldButton("kubernetes_pod_id");
|
||||
await logsPage.clickSQLModeToggle();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.clickSearchBarRefreshButton();
|
||||
await logsPage.waitForTimeout(2000);
|
||||
await logsPage.expectExactTextVisible("source");
|
||||
});
|
||||
});
|
||||
@@ -14,18 +14,22 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.ingestion();
|
||||
await streamsPage.ingestionJoin();
|
||||
await streamsPage.goToManagement();
|
||||
await page.waitForTimeout(5000);
|
||||
await page.waitForTimeout(3000); // Reduced from 5000
|
||||
await streamsPage.checkStreaming();
|
||||
});
|
||||
|
||||
test("Run query after selecting two streams after enabling streaming", async ({ page }) => {
|
||||
test("Run query after selecting two streams after enabling streaming", {
|
||||
tag: ['@streaming', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.displayTwoStreams();
|
||||
await streamsPage.selectRunQuery();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams and SQL Mode On", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams and SQL Mode On", {
|
||||
tag: ['@streaming', '@sqlMode', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
// await streamsPage.enableSQLMode();
|
||||
@@ -33,7 +37,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.displayTwoStreams();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, selecting field and SQL Mode On", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, selecting field and SQL Mode On", {
|
||||
tag: ['@streaming', '@sqlMode', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerName();
|
||||
@@ -42,26 +48,35 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join queries", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join queries", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameJoin();
|
||||
// await streamsPage.enableSQLMode();
|
||||
await streamsPage.selectRunQuery();
|
||||
await page.waitForTimeout(3000); // Wait for query results
|
||||
await streamsPage.displayCountQuery();
|
||||
await page.waitForTimeout(3000); // Wait for query results
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join limit", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join limit", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameJoinLimit();
|
||||
// await streamsPage.enableSQLMode();
|
||||
await streamsPage.selectRunQuery();
|
||||
await page.waitForTimeout(3000); // Wait for query results
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join like", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join like", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameJoinLike();
|
||||
@@ -70,7 +85,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Left join queries", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Left join queries", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameLeftJoin();
|
||||
@@ -79,7 +96,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Right join queries", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Right join queries", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameRightJoin();
|
||||
@@ -88,7 +107,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Full join queries", async ({ page }) => {
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Full join queries", {
|
||||
tag: ['@streaming', '@sqlMode', '@joins', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.kubernetesContainerNameFullJoin();
|
||||
@@ -97,7 +118,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateResult();
|
||||
});
|
||||
|
||||
test("Enable Streaming for clicking on interesting field icon and display field in editor", async ({ page }) => {
|
||||
test("Enable Streaming for clicking on interesting field icon and display field in editor", {
|
||||
tag: ['@streaming', '@interestingFields', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.enableSQLMode();
|
||||
@@ -107,7 +130,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateInterestingFields();
|
||||
});
|
||||
|
||||
test("Enable Streaming for clicking on interesting field icon and display query in editor", async ({ page }) => {
|
||||
test("Enable Streaming for clicking on interesting field icon and display query in editor", {
|
||||
tag: ['@streaming', '@interestingFields', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
await streamsPage.enableSQLMode();
|
||||
@@ -117,7 +142,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.validateInterestingFieldsQuery();
|
||||
});
|
||||
|
||||
test("Enable Streaming for Adding or removing interesting field removes it from editor and results too", async ({ page }) => {
|
||||
test("Enable Streaming for Adding or removing interesting field removes it from editor and results too", {
|
||||
tag: ['@streaming', '@interestingFields', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexAndStreamJoin();
|
||||
// await streamsPage.enableSQLMode();
|
||||
@@ -127,7 +154,9 @@ test.describe("Streaming for logs", () => {
|
||||
await streamsPage.addRemoveInteresting();
|
||||
});
|
||||
|
||||
test("Streaming enabled histogram is disabled and run query, results appear and then user switches on Histogram, getting error", async ({ page }) => {
|
||||
test("Streaming enabled histogram is disabled and run query, results appear and then user switches on Histogram, getting error", {
|
||||
tag: ['@streaming', '@histogram', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexStreamDefault();
|
||||
await streamsPage.selectRunQuery();
|
||||
@@ -145,13 +174,15 @@ test.describe("Streaming for logs", () => {
|
||||
await expect(errorDetailsButton).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("No Histogram should be displayed if Data is not available", async ({ page }) => {
|
||||
test("No Histogram should be displayed if Data is not available", {
|
||||
tag: ['@streaming', '@histogram', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
await streamsPage.navigateToLogs();
|
||||
await streamsPage.selectIndexStreamDefault();
|
||||
await streamsPage.enableSQLMode();
|
||||
await streamsPage.clearAndFillQueryEditor('SELECT count(_timestamp) FROM "default" where code = 201');
|
||||
await page.waitForTimeout(1000);
|
||||
await streamsPage.selectRunQuery();
|
||||
await streamsPage.waitForSearchResultAndCheckText('warning No data found for histogram.');
|
||||
await streamsPage.expectNoDataFoundForHistogram();
|
||||
});
|
||||
});
|
||||
@@ -26,7 +26,9 @@ test.describe("Stream name casing preservation tests", () => {
|
||||
await page.waitForTimeout(5000);
|
||||
});
|
||||
|
||||
test("should preserve stream name casing after ingestion and show in stream explorer", async ({ page }) => {
|
||||
test("should preserve stream name casing after ingestion and show in stream explorer", {
|
||||
tag: ['@streamName', '@casing', '@all', '@streams']
|
||||
}, async ({ page }) => {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const headers = getHeaders();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./baseFixtures.js";
|
||||
import { LoginPage } from '../pages/loginPage.js';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
import { IngestionPage } from '../pages/ingestionPage.js';
|
||||
import { HomePage } from "../pages/homePage.js";
|
||||
import { MetricsPage } from "../pages/metricsPage.js";
|
||||
@@ -91,10 +91,8 @@ test.describe("Change Organisation", () => {
|
||||
multiOrgIdentifier = await createOrgPage.createOrg(newOrgName);
|
||||
await ingestionPage.ingestionMultiOrg(multiOrgIdentifier);
|
||||
await homePage.homePageOrg(newOrgName);
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.navigateToLogs(multiOrgIdentifier);
|
||||
await homePage.homeURLContains(multiOrgIdentifier);
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Metrics Page default validation", async ({ page }) => {
|
||||
|
||||
@@ -39,7 +39,7 @@ test.describe("dashboard folder testcases", () => {
|
||||
await orgNavigation;
|
||||
});
|
||||
|
||||
test.skip("Should create and delete a unique folder, and verify it's deleted", async ({
|
||||
test("Should create and delete a unique folder, and verify it's deleted" ,async ({
|
||||
page,
|
||||
}) => {
|
||||
const dashboardPage = new DashboardListPage(page);
|
||||
|
||||
@@ -17,8 +17,8 @@ const randomDashboardName =
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
// Refactored test cases using Page Object Model
|
||||
|
||||
// Refactored test cases using Page Object Model
|
||||
test.describe("dashboard UI testcases", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test, expect } from "../baseFixtures";
|
||||
import LogsVisualise from "../../pages/dashboardPages/visualise";
|
||||
import { login } from "../utils/dashLogin";
|
||||
import { ingestion } from "../utils/dashIngestion";
|
||||
import LogsVisualise from "../../pages/dashboardPages/visualise.js";
|
||||
import { login } from "../utils/dashLogin.js";
|
||||
import { ingestion } from "../utils/dashIngestion.js";
|
||||
import logData from "../../cypress/fixtures/log.json";
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
@@ -25,7 +25,6 @@ test.describe("visualization VRL testcases", () => {
|
||||
);
|
||||
|
||||
const logsVisualise = new LogsVisualise(page);
|
||||
|
||||
await selectStreamAndStreamTypeForLogs(page, logData.Stream);
|
||||
await logsVisualise.logsApplyQueryButton();
|
||||
});
|
||||
@@ -421,4 +420,4 @@ test.describe("visualization VRL testcases", () => {
|
||||
// Assertion: Fail the test if an error was detected
|
||||
expect(errorDetected).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -636,4 +636,4 @@ test.describe("logs testcases", () => {
|
||||
await dashboardCreate.backToDashboardList();
|
||||
await deleteDashboard(page, randomDashboardName);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,7 @@ import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
// import { log } from "console";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import PipelinePage from "../pages/pipelinePage";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
// import { pipeline } from "stream";
|
||||
// import fs from "fs";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
@@ -59,7 +59,7 @@ async function ingestion(page) {
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
const selectStreamAndStreamTypeForLogs = async (page, stream) => {
|
||||
const selectStream = async (page, stream) => {
|
||||
await page.waitForTimeout(4000);
|
||||
await page
|
||||
.locator('[data-test="log-search-index-list-select-stream"]')
|
||||
@@ -116,7 +116,7 @@ test.describe("Enrichment data testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ async function login(page) {
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
}
|
||||
|
||||
const selectStreamAndStreamTypeForLogs = async (page, stream) => {
|
||||
const selectStream = async (page, stream) => {
|
||||
await page.waitForTimeout(4000);
|
||||
await page.locator('[data-test="log-search-index-list-select-stream"]').click({ force: true });
|
||||
await page.locator("div.q-item").getByText(`${stream}`).first().click({ force: true });
|
||||
@@ -91,7 +91,7 @@ test.describe("Compare SQL query execution times", () => {
|
||||
console.log(response);
|
||||
|
||||
await page.goto(`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`);
|
||||
await selectStreamAndStreamTypeForLogs(page, logData.Stream);
|
||||
await selectStream(page, logData.Stream);
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import { LoginPage } from '../pages/loginPage';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
import { IngestionPage } from '../pages/ingestionPage';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
@@ -1,204 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures.js";
|
||||
import logData from "../cypress/fixtures/log.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { LogsQueryPage } from '../pages/logsQueryPage.js';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
await page.locator('[data-cy="login-user-id"]').fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
await page.locator("label").filter({ hasText: "Password *" }).click();
|
||||
await page.locator('[data-cy="login-password"]').fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
test.describe("Logs Queries testcases", () => {
|
||||
let logsPage;
|
||||
let logsQueryPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(5000);
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000);
|
||||
logsPage = new LogsPage(page);
|
||||
logsQueryPage = new LogsQueryPage(page);
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
});
|
||||
|
||||
test("Verify error handling and no results found with histogram", async ({ page }) => {
|
||||
// Check if histogram is off and toggle it on if needed
|
||||
const histogramToggle = page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
const isHistogramOn = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Type invalid query and verify error
|
||||
await logsQueryPage.typeQuery("match_all('invalid')");
|
||||
await logsQueryPage.setDateTimeFilter();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.clickErrorMessage();
|
||||
await logsQueryPage.clickResetFilters();
|
||||
|
||||
// Type SQL query and verify no results
|
||||
await logsQueryPage.typeQuery("SELECT count(*) FROM 'e2e_automate' where code > 500");
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickNoDataFound();
|
||||
await logsQueryPage.clickResultDetail();
|
||||
});
|
||||
|
||||
test("Verify error handling with histogram toggle off and on", async ({ page }) => {
|
||||
// Check if histogram is on and toggle it off
|
||||
const histogramToggle = page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
const isHistogramOn = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
if (isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Type invalid query and verify error
|
||||
await logsQueryPage.typeQuery("match_all('invalid')");
|
||||
await logsQueryPage.setDateTimeFilter();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.clickErrorMessage();
|
||||
await logsQueryPage.clickResetFilters();
|
||||
|
||||
// Toggle histogram back on
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Type SQL query and verify no results
|
||||
await logsQueryPage.typeQuery("SELECT count(*) FROM 'e2e_automate' where code > 500");
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickNoDataFound();
|
||||
await logsQueryPage.clickResultDetail();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle persistence after multiple queries", async ({ page }) => {
|
||||
// Start with histogram on
|
||||
const histogramToggle = page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
const isHistogramOn = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Run first query
|
||||
await logsQueryPage.typeQuery("SELECT * FROM 'e2e_automate' LIMIT 10");
|
||||
await logsQueryPage.setDateTimeFilter();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram off
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Run second query
|
||||
await logsQueryPage.typeQuery("SELECT count(*) FROM 'e2e_automate'");
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
|
||||
// Verify histogram stays off
|
||||
const isHistogramStillOff = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'false');
|
||||
expect(isHistogramStillOff).toBeTruthy();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle with empty query", async ({ page }) => {
|
||||
// Start with histogram off
|
||||
const histogramToggle = page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
const isHistogramOn = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
if (isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Clear query and refresh
|
||||
await logsQueryPage.typeQuery("");
|
||||
await logsQueryPage.setDateTimeFilter();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram on
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Verify histogram state
|
||||
const isHistogramOnAfterToggle = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
expect(isHistogramOnAfterToggle).toBeTruthy();
|
||||
});
|
||||
|
||||
test("Verify histogram toggle with complex query", async ({ page }) => {
|
||||
// Start with histogram on
|
||||
const histogramToggle = page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"]');
|
||||
const isHistogramOn = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'true');
|
||||
if (!isHistogramOn) {
|
||||
await logsPage.toggleHistogram();
|
||||
}
|
||||
|
||||
// Run complex query
|
||||
await logsQueryPage.typeQuery("SELECT * FROM 'e2e_automate' WHERE timestamp > '2024-01-01' AND code < 400 GROUP BY code ORDER BY count(*) DESC LIMIT 5");
|
||||
await logsQueryPage.setDateTimeFilter();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
|
||||
// Toggle histogram off and verify
|
||||
await logsPage.toggleHistogram();
|
||||
const isHistogramOff = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'false');
|
||||
expect(isHistogramOff).toBeTruthy();
|
||||
|
||||
// Run another query and verify histogram stays off
|
||||
await logsQueryPage.typeQuery("SELECT count(*) FROM 'e2e_automate'");
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
await logsQueryPage.clickRefresh();
|
||||
await logsQueryPage.waitForTimeout(2000);
|
||||
|
||||
const isHistogramStillOff = await histogramToggle.evaluate(el => el.getAttribute('aria-checked') === 'false');
|
||||
expect(isHistogramStillOff).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -1,582 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
console.log("ZO_BASE_URL", process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
test.describe("Logs UI testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
// click on the run query button
|
||||
// Type the value of a variable into an input field
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
// tebefore(async function () {
|
||||
// // logData("log");
|
||||
// // const data = page;
|
||||
// // logData = data;
|
||||
|
||||
// console.log("--logData--", logData);
|
||||
// });
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000)
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
test("should click run query after SQL toggle on but without any query", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.locator('[data-test="logs-search-bar-query-editor"]').click();
|
||||
await page.keyboard.press(
|
||||
process.platform === "darwin" ? "Meta+A" : "Control+A"
|
||||
); // Select all text
|
||||
await page.keyboard.press("Backspace");
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.getByText("SQL query is missing or invalid. Please submit a valid SQL statement.").click();
|
||||
});
|
||||
|
||||
test("should be able to enter valid text in VRL and run query", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await applyQueryButton(page);
|
||||
|
||||
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await applyQueryButton(page);
|
||||
const warningElement = page.locator('text=warning Query execution');
|
||||
await expect(warningElement).toBeHidden()
|
||||
|
||||
await page
|
||||
.locator('[data-test="table-row-expand-menu"]')
|
||||
.first()
|
||||
.click({ force: true });
|
||||
await expect(page.locator("text=.a=2")).toBeVisible();
|
||||
await expect(
|
||||
page.locator('[data-test="logs-search-result-logs-table"]')
|
||||
).toBeVisible();
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
});
|
||||
|
||||
test("should hide and display again after clicking the arrow", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page
|
||||
.locator('[data-test="logs-search-bar-show-query-toggle-btn"]')
|
||||
.click({ force: true });
|
||||
await page.locator('[data-test="logs-search-field-list-collapse-btn"]').click();
|
||||
await page.waitForTimeout(1000)
|
||||
await page.locator('[data-test="logs-search-field-list-collapse-btn"]').click();
|
||||
// await page
|
||||
// .locator(".bg-primary > .q-btn__content > .q-icon")
|
||||
// .click({ force: true });
|
||||
// await page.waitForTimeout(2000);
|
||||
// await page
|
||||
// .locator(".bg-primary > .q-btn__content > .q-icon")
|
||||
// .click({ force: true });
|
||||
await expect(
|
||||
page.locator('[data-cy="index-field-search-input"]')
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should verify if special characters allowed in saved views name", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page
|
||||
.locator('[data-test="logs-search-bar-show-query-toggle-btn"]')
|
||||
.click({ force: true });
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="logs-search-saved-views-btn"] > .q-btn-dropdown--current > .q-btn__content > :nth-child(1)'
|
||||
)
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.locator('[data-test="add-alert-name-input"]').type("e2e@@@@@");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator('[data-test="saved-view-dialog-save-btn"]')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await expect(page.locator(".q-notification__message")).toContainText(
|
||||
"Please provide valid view name"
|
||||
);
|
||||
});
|
||||
|
||||
test("should display error when user directly clicks on OK without adding name", async ({
|
||||
page,
|
||||
}) => {
|
||||
// Click on the date-time button
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page
|
||||
.locator('[data-test="logs-search-saved-views-btn"]')
|
||||
.getByLabel("Expand")
|
||||
.click();
|
||||
await page
|
||||
.locator("button")
|
||||
.filter({ hasText: "savesaved_search" })
|
||||
.click();
|
||||
await page.locator('[data-test="add-alert-name-input"]');
|
||||
const saveButton = await page.locator(
|
||||
'[data-test="saved-view-dialog-save-btn"]'
|
||||
);
|
||||
await saveButton.scrollIntoViewIfNeeded();
|
||||
await saveButton.click({ force: true });
|
||||
// await expect(page.locator('.q-notification__message')).toContainText('Please provide valid view name');
|
||||
});
|
||||
|
||||
test("should display the details of logs results on graph", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({ force: true });
|
||||
await applyQueryButton(page);
|
||||
await page.waitForTimeout(5000);
|
||||
await expect(
|
||||
page.locator(".search-list > :nth-child(1) > .text-left")
|
||||
).toBeVisible();
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-test="log-table-column-0-source"]').click();
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="close-dialog"]').click({
|
||||
force: true,
|
||||
});
|
||||
await expect(
|
||||
page.locator(".search-list > :nth-child(1) > .text-left")
|
||||
).not.toBeHidden();
|
||||
});
|
||||
|
||||
test("should click on live mode on button and select 5 sec, switch off, and then click run query", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route("**/logData.ValueQuery", (route) => route.continue());
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page
|
||||
.locator(".q-pl-sm > .q-btn > .q-btn__content")
|
||||
.click({ force: true });
|
||||
await page.locator('[data-test="logs-search-bar-refresh-time-5"]').click({
|
||||
force: true,
|
||||
});
|
||||
await expect(page.locator(".q-notification__message")).toContainText(
|
||||
"Live mode is enabled"
|
||||
);
|
||||
await page
|
||||
.locator(".q-pl-sm > .q-btn > .q-btn__content")
|
||||
.click({ force: true });
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="logs-search-off-refresh-interval"] > .q-btn__content'
|
||||
)
|
||||
.click({ force: true });
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
test("should click on VRL toggle and display the field, then disable toggle and make the VRL field disappear", async ({
|
||||
page,
|
||||
}) => {
|
||||
await expect(page.locator("#fnEditor")).toBeVisible();
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="logs-search-bar-show-query-toggle-btn"] > .q-toggle__inner'
|
||||
)
|
||||
.click({ force: true });
|
||||
await expect(page.locator("#fnEditor")).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("should switch from past 6 weeks to past 6 days on date-time UI", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-w-btn"] > .q-btn__content')
|
||||
.click({ force: true });
|
||||
await expect(page.locator('[data-test="date-time-btn"]')).toContainText(
|
||||
"Past 6 Weeks"
|
||||
);
|
||||
await applyQueryButton(page);
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="date-time-relative-6-d-btn"]')
|
||||
.click({ force: true });
|
||||
await expect(page.locator('[data-test="date-time-btn"]')).toContainText(
|
||||
"Past 6 Days"
|
||||
);
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
test("should display SQL query on switching between Menu options & navigating to Logs again", async ({
|
||||
page,
|
||||
}) => {
|
||||
// Intercept the GET request, replace 'logData.ValueQuery' with your actual endpoint
|
||||
await page.route("**/logData.ValueQuery", (route) => route.continue());
|
||||
|
||||
// Click on the date-time button
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
|
||||
await page.waitForTimeout(1000);
|
||||
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
|
||||
// Assert that the SQL query is visible
|
||||
const expectedQuery =
|
||||
'SELECT * FROM "e2e_automate"';
|
||||
// const text = await page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox').textContent();
|
||||
// console.log(textval)
|
||||
const text = await page.evaluate(() => {
|
||||
const editor = document.querySelector('[data-test="logs-search-bar-query-editor"]').querySelector('.cm-content'); // Adjust selector if needed
|
||||
return editor ? editor.textContent.trim() : null;
|
||||
});
|
||||
|
||||
console.log(text);
|
||||
await expect(text.replace(/\s/g, "")).toContain(
|
||||
expectedQuery.replace(/\s/g, "")
|
||||
);
|
||||
await page.locator('[data-test="menu-link-/-item"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="menu-link-/logs-item"]')
|
||||
.click({ force: true });
|
||||
await page.waitForTimeout(2000);
|
||||
|
||||
await page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]')
|
||||
.locator(".cm-content")
|
||||
.locator(".cm-line")
|
||||
.filter({ hasText: 'SELECT * FROM "e2e_automate"' })
|
||||
.nth(0);
|
||||
});
|
||||
test("should display ingested logs - search logs, navigate on another tab, revisit logs page", async ({
|
||||
page,
|
||||
}) => {
|
||||
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 });
|
||||
await applyQueryButton(page);
|
||||
await page
|
||||
.locator('[data-test="menu-link-/traces-item"]')
|
||||
.click({ force: true });
|
||||
await page.waitForTimeout(100);
|
||||
await page
|
||||
.locator('[data-test="menu-link-/logs-item"]')
|
||||
.click({ force: true });
|
||||
await page.waitForTimeout(5000);
|
||||
const barChart = await page.locator(
|
||||
'[data-test="logs-search-result-bar-chart"]'
|
||||
);
|
||||
await expect(barChart).toBeTruthy();
|
||||
});
|
||||
|
||||
test("should redirect to logs after clicking on stream explorer via stream page", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.locator('[data-test="date-time-btn"]').click({ force: true });
|
||||
await page
|
||||
.locator('[data-test="menu-link-/streams-item"]')
|
||||
.click({ force: true });
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.locator('[data-test="menu-link-\\/streams-item"]')
|
||||
.click({ force: true });
|
||||
await page.getByPlaceholder("Search Stream").click();
|
||||
await page.getByPlaceholder("Search Stream").fill("e2e");
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.getByRole("button", { name: "Explore" })
|
||||
.first()
|
||||
.click({ force: true });
|
||||
await expect(page.url()).toContain("logs");
|
||||
});
|
||||
|
||||
test('should display error when save function is clicked without any VRL function', async ({ page }) => {
|
||||
// await page.locator('[data-test="menu-link-\\/logs-item"]').click();
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('#q-notify div').filter({ hasText: 'warningNo function definition' }).nth(3).click();
|
||||
});
|
||||
|
||||
test('should create a function and then delete it', async ({ page }) => {
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('[data-test="saved-function-name-input"]').click();
|
||||
await page.locator('[data-test="saved-function-name-input"]').fill('e2efunction');
|
||||
await page.locator('[data-test="saved-view-dialog-save-btn"]').click();
|
||||
// await page.locator('[data-test="menu-link-\\/functions-item"]').click();
|
||||
await page.locator('[data-test="menu-link-\\/pipeline-item"]').click();
|
||||
await page.locator('[data-test="tab-realtime"]').click();
|
||||
|
||||
await page.locator('[data-test="function-stream-tab"]').click();
|
||||
await page.getByPlaceholder('Search Function').click();
|
||||
await page.getByPlaceholder('Search Function').fill('e2e');
|
||||
await page.getByRole('button', { name: 'Delete Function' }).click();
|
||||
await page.locator('[data-test="confirm-button"]').click();
|
||||
});
|
||||
|
||||
test('should display click save directly while creating a function', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('[data-test="saved-view-dialog-save-btn"]').click();
|
||||
await page.getByText('Function name is not valid.').click();
|
||||
});
|
||||
|
||||
test('should display error on adding only blank spaces under function name', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('[data-test="saved-function-name-input"]').fill(' ');
|
||||
await page.locator('[data-test="saved-view-dialog-save-btn"]').click();
|
||||
await page.getByText('Function name is not valid.').click();
|
||||
});
|
||||
|
||||
|
||||
test('should display error on adding invalid characters under function name', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-function-dropdown"] button').filter({ hasText: 'save' }).click();
|
||||
await page.locator('[data-test="saved-function-name-input"]').fill('e2e@@@');
|
||||
await page.locator('[data-test="saved-view-dialog-save-btn"]').click();
|
||||
await page.getByText('Function name is not valid.').click();
|
||||
});
|
||||
|
||||
test('should display added function on switching between tabs and again navigate to log', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=2');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="menu-link-\\/metrics-item"]').click();
|
||||
await page.locator('[data-test="menu-link-\\/logs-item"]').click();
|
||||
await page.locator('[data-test="menu-link-/logs-item"]').click({ force: true });
|
||||
// Assert that ".a=2" is visible
|
||||
const logsPage = await page.locator('.q-page-container');
|
||||
await expect(logsPage).toContainText(".a=2");
|
||||
|
||||
});
|
||||
|
||||
test('should display bar chart when histogram toggle is on', async ({ page }) => {
|
||||
await page.locator('[data-test="log-search-index-list-field-search-input"]').click();
|
||||
await page.locator('[data-test="log-search-index-list-field-search-input"]').fill('code');
|
||||
await page.waitForTimeout(4000);
|
||||
await page.getByLabel('Expand "code"').click();
|
||||
await page.waitForTimeout(4000);
|
||||
// await page.locator('[data-test="logs-search-subfield-add-code-200"] [data-test="log-search-subfield-list-equal-code-field-btn"]').click();
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="logs-search-result-bar-chart"] canvas').click({
|
||||
});
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="logs-search-result-bar-chart"] canvas').click({
|
||||
});
|
||||
await page.locator('[data-test="logs-search-bar-show-histogram-toggle-btn"] div').nth(2).click();
|
||||
});
|
||||
|
||||
test('should display search around in histogram mode', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="log-table-column-0-source"]').click();
|
||||
await page.locator('[data-test="logs-detail-table-search-around-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
const element = await page.locator('[data-test="log-table-column-0-source"]');
|
||||
const isVisible = await element.isVisible();
|
||||
expect(isVisible).toBeTruthy();
|
||||
|
||||
});
|
||||
|
||||
|
||||
test.skip('should display results for search around after adding function', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('#fnEditor').getByRole('textbox').click();
|
||||
await page.locator('#fnEditor').getByRole('textbox').fill('.a=1');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="log-table-column-3-source"]').getByText('{"_timestamp":').click();
|
||||
await page.locator('[data-test="logs-detail-table-search-around-btn"]').click();
|
||||
await page.waitForTimeout(1000);
|
||||
const element = await page.locator('[data-test="log-table-column-0-source"]');
|
||||
const isVisible = await element.isVisible();
|
||||
expect(isVisible).toBeTruthy();
|
||||
|
||||
});
|
||||
|
||||
test('should display search around in SQL mode', async ({ page }) => {
|
||||
await page.waitForTimeout(1000);
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.locator('[data-test="log-table-column-0-source"]').click();
|
||||
await page.locator('[data-test="logs-detail-table-search-around-btn"]').click();
|
||||
await page.waitForTimeout(2000)
|
||||
const element = await page.locator('[data-test="log-table-column-0-source"]');
|
||||
const isVisible = await element.isVisible();
|
||||
expect(isVisible).toBeTruthy();
|
||||
|
||||
});
|
||||
|
||||
test("should display results for search around with limit query", async ({ page }) => {
|
||||
await page.waitForTimeout(2000);
|
||||
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 });
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]')
|
||||
await page.keyboard.type("match_all('code') limit 5");
|
||||
await page.waitForTimeout(2000);
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-test="log-table-column-0-source"]').click();
|
||||
await page.locator('[data-test="logs-detail-table-search-around-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
const element = await page.locator('[data-test="log-table-column-0-source"]');
|
||||
const isVisible = await element.isVisible();
|
||||
expect(isVisible).toBeTruthy();
|
||||
await expect(page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test("should not display pagination for limit query", async ({ page }) => {
|
||||
await page.waitForTimeout(2000);
|
||||
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 });
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]')
|
||||
await page.keyboard.type("match_all('code') limit 5");
|
||||
await page.waitForTimeout(2000);
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
const fastRewindElement = page.locator('[data-test="logs-search-result-records-per-page"]').getByText('50');
|
||||
await expect(fastRewindElement).not.toBeVisible();
|
||||
|
||||
});
|
||||
|
||||
test("should not display pagination for SQL limit query", async ({ page }) => {
|
||||
await page.waitForTimeout(2000);
|
||||
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 });
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]');
|
||||
await page.keyboard.type('SELECT * FROM "e2e_automate" ORDER BY _timestamp DESC limit 5');
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
const fastRewindElement = page.locator('[data-test="logs-search-result-records-per-page"]').getByText('50');
|
||||
await expect(fastRewindElement).not.toBeVisible();
|
||||
});
|
||||
|
||||
test("should not display pagination for SQL group/order/limit query", async ({ page }) => {
|
||||
await page.waitForTimeout(2000);
|
||||
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 });
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]');
|
||||
await page.keyboard.type('SELECT * FROM "e2e_automate" WHERE code < 400 GROUP BY code ORDER BY count(*) DESC LIMIT 5');
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.waitForTimeout(2000);
|
||||
const fastRewindElement = page.locator('[data-test="logs-search-result-records-per-page"]').getByText('50');
|
||||
await expect(fastRewindElement).not.toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -1,331 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
test.describe("Logs Queries testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
// click on the run query button
|
||||
// Type the value of a variable into an input field
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000)
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000)
|
||||
logsPage = new LogsPage(page);
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
test("should display quick mode toggle button", async ({ page }) => {
|
||||
await expect(
|
||||
page.locator('[data-test="logs-search-bar-quick-mode-toggle-btn"]')
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test.skip("should add timestamp to editor save this view and switch", async ({ page }) => {
|
||||
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('[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');
|
||||
await page.getByTitle('e2etimestamp').click();
|
||||
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.getByTitle('e2etimestamp').click();
|
||||
// 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 }) => {
|
||||
// Generate a random saved view name
|
||||
const randomSavedViewName = `streamslog${Math.random().toString(36).substring(2, 10)}`;
|
||||
|
||||
// Interactions with the page
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.locator('[data-test="logs-search-saved-views-btn"]').getByLabel('Expand').click();
|
||||
await page.locator('button').filter({ hasText: 'savesaved_search' }).click();
|
||||
await page.locator('[data-test="add-alert-name-input"]').click();
|
||||
await page.locator('[data-test="add-alert-name-input"]').fill(randomSavedViewName); // Use the random name
|
||||
await page.locator('[data-test="saved-view-dialog-save-btn"]').click({ force: true });
|
||||
await page.waitForTimeout(5000);
|
||||
await page.locator('[data-test="menu-link-\\/streams-item"]').click({ force: true });
|
||||
await page.getByPlaceholder('Search Stream').click();
|
||||
await page.getByPlaceholder('Search Stream').fill('e2e');
|
||||
await page.waitForTimeout(1000);
|
||||
await page.getByRole('button', { name: 'Explore' }).first().click({ force: true });
|
||||
await page.waitForTimeout(5000);
|
||||
await page.waitForSelector('[data-test="logs-search-saved-views-btn"]');
|
||||
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({ force: true });
|
||||
await page.locator('[data-test="log-search-saved-view-field-search-input"]').fill(randomSavedViewName); // Use the random name here
|
||||
await page.waitForTimeout(3000);
|
||||
await page.waitForSelector(`:text("${randomSavedViewName}")`);
|
||||
await page.click(`:text("${randomSavedViewName}")`);
|
||||
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.getByTitle(randomSavedViewName).click(); // Use the random name here
|
||||
|
||||
// Dynamic delete button selector using the random saved view name
|
||||
const deleteButtonSelector = `[data-test="logs-search-bar-delete-${randomSavedViewName}-saved-view-btn"]`;
|
||||
await page.locator(deleteButtonSelector).click(); // Click delete
|
||||
await page.locator('[data-test="confirm-button"]').click(); // Confirm deletion
|
||||
});
|
||||
|
||||
test("should reset the editor on clicking reset filter button", async ({ page }) => {
|
||||
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 });
|
||||
await page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox').click();
|
||||
await page.keyboard.type("match_all_raw_ignore_case('provide_credentials')");
|
||||
await page.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content').waitFor({ state: "visible" });
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({ force: true });
|
||||
await page.locator('[data-test="logs-search-bar-reset-filters-btn"]').click({ force: true });
|
||||
await page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox').waitFor({ state: "visible" });
|
||||
const text = await page.evaluate(() => {
|
||||
const editor = document.querySelector('[data-test="logs-search-bar-query-editor"]').querySelector('.cm-content');
|
||||
return editor ? editor.textContent : null;
|
||||
});
|
||||
await expect(text).toEqual("");
|
||||
});
|
||||
|
||||
test("should add invalid query and display error", async ({ page }) => {
|
||||
// Type the value of a variable into an input field
|
||||
|
||||
await page.waitForTimeout(2000);
|
||||
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 });
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]')
|
||||
await page.keyboard.type("kubernetes");
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content').click({ force: true })
|
||||
await expect(page.locator('[data-test="logs-search-error-message"]')).toBeVisible();
|
||||
});
|
||||
|
||||
test("should not display error if match all case 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("match_all('code')");
|
||||
|
||||
// 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();
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("should change stream settings and click on search stream", async ({ page }) => {
|
||||
// Type the value of a variable into an input field
|
||||
await page.locator('[data-test="menu-link-/streams-item"]').click({ force: true });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.click('[data-test="streams-search-stream-input"]')
|
||||
await page.keyboard.type("e2e_automate");
|
||||
await page.waitForTimeout(2000);
|
||||
await page.locator("[title=\"Stream Detail\"]").first().click({ force: true });
|
||||
await page.locator(':nth-child(2) > [data-test="schema-stream-index-select"]').click();
|
||||
const scope = page.locator(".q-virtual-scroll__content");
|
||||
await scope.getByText(/Full text search/).first().click();
|
||||
await page.locator('[data-test="schema-update-settings-button"]').click({ force: true });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator(".col-auto > .q-btn > .q-btn__content").click({ force: true });
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[title=\"Explore\"]").first().click({ force: true });
|
||||
await expect(page.locator('[data-test="log-table-column-0-source"]')).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
test("should display error if blank spaces added under stream name and clicked create stream ", async ({ page }) => {
|
||||
await page.locator('[data-test="menu-link-/streams-item"]').click({ force: true });
|
||||
await page.locator('[data-test="log-stream-add-stream-btn"]').click({ force: true });
|
||||
await page.click('[data-test="add-stream-name-input"]')
|
||||
await page.keyboard.type(" ");
|
||||
await page.locator('[data-test="save-stream-btn"]').click({ force: true });
|
||||
await expect(page.getByText(/Field is required/).first()).toBeVisible();
|
||||
});
|
||||
|
||||
|
||||
|
||||
test("should display error if create stream is clicked without adding name", async ({ page }) => {
|
||||
await page.locator('[data-test="menu-link-/streams-item"]').click({ force: true });
|
||||
await page.locator('[data-test="log-stream-add-stream-btn"]').click({ force: true });
|
||||
await page.locator('[data-test="save-stream-btn"]').waitFor({ state: "visible" });
|
||||
await page.locator('[data-test="save-stream-btn"]').scrollIntoViewIfNeeded();
|
||||
await page.locator('[data-test="save-stream-btn"]').click({ force: true });
|
||||
await expect(page.getByText(/Field is required/).first()).toBeVisible();
|
||||
});
|
||||
|
||||
test("should display enter count query", async ({ page }) => {
|
||||
await page.locator('[data-test="logs-search-bar-query-editor"]').getByRole('textbox').click();
|
||||
// await page.click('.cm-lines')
|
||||
await page.keyboard.type('SELECT COUNT(_timestamp) AS xyz, _timestamp FROM "e2e_automate" Group by _timestamp ORDER BY _timestamp DESC');
|
||||
await page.waitForTimeout(4000);
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await expect(page.locator(
|
||||
'[data-cy="search-bar-refresh-button"] > .q-btn__content')).toBeVisible(); await page.waitForTimeout(
|
||||
3000); await page.locator(
|
||||
"[data-test='logs-search-bar-refresh-btn']").click({
|
||||
|
||||
force: true
|
||||
});
|
||||
await page.waitForTimeout(4000);
|
||||
await expect(page.getByRole('heading', { name: 'Error while fetching' })).not.toBeVisible();
|
||||
await page.locator('[data-test="logs-search-result-bar-chart"] canvas').click({
|
||||
position: {
|
||||
x: 182,
|
||||
y: 66
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
test("should display values API text successfully and error to not be displayed", async ({ page }) => {
|
||||
await page.locator('[data-test="log-search-index-list-field-search-input"]').fill('kubernetes_pod_name');
|
||||
await page.getByLabel('Expand "kubernetes_pod_name"').click();
|
||||
const errorMessage = page.getByText('Error while fetching field values');
|
||||
await expect(errorMessage).not.toBeVisible();
|
||||
await page.getByText('ziox-ingester-').click();
|
||||
await page.locator('[data-test="logs-search-bar-refresh-btn"]').click();
|
||||
await page.getByLabel('Collapse "kubernetes_pod_name"').click();
|
||||
await page.getByLabel('Expand "kubernetes_pod_name"').click();
|
||||
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,
|
||||
}) => {
|
||||
|
||||
await logsPage.setDateTimeToToday();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("should display results if stringmatch ignorecase lowercase added in log query search", async ({ page }) => {
|
||||
await logsPage.setDateTimeTo15Minutes();
|
||||
await logsPage.searchWithStringMatchIgnoreCase('ziox');
|
||||
});
|
||||
|
||||
test("should display results if stringmatch ignorecase uppercase added in log query search", async ({ page }) => {
|
||||
await logsPage.setDateTimeTo15Minutes();
|
||||
await logsPage.searchWithStringMatchIgnoreCase('Ziox');
|
||||
});
|
||||
|
||||
test("should trigger search results when pressing Cmd+Enter or Ctrl+Enter", async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutTest();
|
||||
});
|
||||
|
||||
test("should execute query with keyboard shortcut (Cmd+Enter or Ctrl+Enter) after clicking elsewhere ", async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutAfterClickingElsewhere();
|
||||
});
|
||||
|
||||
test("should execute different query with keyboard shortcut (Cmd+Enter or Ctrl+Enter)", async ({ page }) => {
|
||||
await logsPage.executeQueryWithKeyboardShortcutWithDifferentQuery();
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
})
|
||||
@@ -1,315 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
console.log("ZO_BASE_URL", process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
await page
|
||||
.locator('[data-cy="login-user-id"]')
|
||||
.fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
//Enter Password
|
||||
await page
|
||||
.locator('[data-cy="login-password"]')
|
||||
.fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
await page.waitForTimeout(4000);
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
}
|
||||
|
||||
async function ingestion(page) {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const streamName = "e2e_automate";
|
||||
const basicAuthCredentials = Buffer.from(
|
||||
`${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}`
|
||||
).toString('base64');
|
||||
|
||||
const headers = {
|
||||
"Authorization": `Basic ${basicAuthCredentials}`,
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
const response = await page.evaluate(async ({ url, headers, orgId, streamName, logsdata }) => {
|
||||
const fetchResponse = await fetch(`${url}/api/${orgId}/${streamName}/_json`, {
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
body: JSON.stringify(logsdata)
|
||||
});
|
||||
return await fetchResponse.json();
|
||||
}, {
|
||||
url: process.env.INGESTION_URL,
|
||||
headers: headers,
|
||||
orgId: orgId,
|
||||
streamName: streamName,
|
||||
logsdata: logsdata
|
||||
});
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
|
||||
|
||||
test.describe("Logs Quickmode testcases", () => {
|
||||
let logsPage;
|
||||
// let logData;
|
||||
function removeUTFCharacters(text) {
|
||||
// console.log(text, "tex");
|
||||
// Remove UTF characters using regular expression
|
||||
return text.replace(/[^\x00-\x7F]/g, " ");
|
||||
}
|
||||
async function applyQueryButton(page) {
|
||||
// click on the run query button
|
||||
// Type the value of a variable into an input field
|
||||
const search = page.waitForResponse(logData.applyQuery);
|
||||
await page.waitForTimeout(3000);
|
||||
await page.locator("[data-test='logs-search-bar-refresh-btn']").click({
|
||||
force: true,
|
||||
});
|
||||
// get the data from the search variable
|
||||
await expect.poll(async () => (await search).status()).toBe(200);
|
||||
// await search.hits.FIXME_should("be.an", "array");
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
await page.waitForTimeout(1000)
|
||||
await ingestion(page);
|
||||
await page.waitForTimeout(2000)
|
||||
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
|
||||
await applyQueryButton(page);
|
||||
|
||||
// Get the toggle button element
|
||||
const toggleButton = await page.$('[data-test="logs-search-bar-quick-mode-toggle-btn"] > .q-toggle__inner');
|
||||
// Evaluate the class attribute to determine if the toggle is in the off state
|
||||
const isSwitchedOff = await toggleButton.evaluate(node => node.classList.contains('q-toggle__inner--falsy'));
|
||||
// If the toggle is switched off, click on it to switch it on
|
||||
if (isSwitchedOff) {
|
||||
await toggleButton.click();
|
||||
}
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
test("should click on interesting fields icon and display query in editor", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_pod_id");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_pod_id-field-btn"]'
|
||||
)
|
||||
.first()
|
||||
.click();
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(
|
||||
page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]')
|
||||
.getByText(/kubernetes_pod_id/)
|
||||
.first()
|
||||
).toBeVisible();
|
||||
});
|
||||
test("should display quick mode toggle button", async ({ page }) => {
|
||||
await expect(
|
||||
page.locator('[data-test="logs-search-bar-quick-mode-toggle-btn"]')
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should click on interesting fields icon in histogram mode and run query", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_pod_id");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_pod_id-field-btn"]'
|
||||
)
|
||||
.first()
|
||||
.click();
|
||||
await page
|
||||
.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content')
|
||||
.click();
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(
|
||||
page
|
||||
.locator('[data-test="log-table-column-0-source"]')
|
||||
.getByText(/kubernetes_pod_id/)
|
||||
// .getByText(/_timestamp/)
|
||||
.first()
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should display error on entering random text in histogram mode when quick mode is on", async ({ page }) => {
|
||||
await page.waitForTimeout(2000)
|
||||
// Click on the Monaco Editor to focus it
|
||||
await page.click('[data-test="logs-search-bar-query-editor"]');
|
||||
// Type into the Monaco Editor
|
||||
await page.keyboard.type("oooo");
|
||||
await page.waitForTimeout(1000)
|
||||
await page.waitForSelector('[data-cy="search-bar-refresh-button"] > .q-btn__content', { visible: true, timeout: 5000 });
|
||||
|
||||
// Click on the refresh button
|
||||
await page.click('[data-cy="search-bar-refresh-button"] > .q-btn__content', { force: true });
|
||||
|
||||
await page.waitForTimeout(2000)
|
||||
// Wait for the error message to appear and ensure it is visible
|
||||
await expect(page.locator('[data-test="logs-search-error-message"]').first()).toBeVisible({ timeout: 10000 });
|
||||
});
|
||||
|
||||
test("should display selected interestesing field and order by - as default in editor", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_pod_id");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_pod_id-field-btn"]'
|
||||
)
|
||||
.first()
|
||||
.click();
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.waitForSelector('[data-test="logs-search-bar-query-editor"]');
|
||||
await expect(
|
||||
page.locator('[data-test="logs-search-bar-query-editor"]')
|
||||
).toBeVisible();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("should adding/removing interesting field removes it from editor and results too", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_container_name");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_container_name-field-btn"]'
|
||||
)
|
||||
.first()
|
||||
.click();
|
||||
await page.locator('[data-cy="index-field-search-input"]').clear();
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("level");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-level-field-btn"]'
|
||||
)
|
||||
.last()
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page
|
||||
.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await expect(
|
||||
page
|
||||
.locator('[data-test="log-table-column-0-source"]')
|
||||
// .locator('text=_timestamp')
|
||||
).toBeVisible();
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-level-field-btn"]'
|
||||
)
|
||||
.last()
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await expect(
|
||||
page.locator('[data-test="logs-search-bar-query-editor"]')
|
||||
).not.toHaveText(/level/);
|
||||
await page
|
||||
.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content')
|
||||
.click();
|
||||
await expect(
|
||||
page.locator('[data-test="log-table-column-1-source"]')
|
||||
).not.toHaveText(/source/);
|
||||
});
|
||||
|
||||
test("should display order by in sql mode by default even after page reload", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_pod_id");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_pod_id-field-btn"]'
|
||||
)
|
||||
.last()
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page
|
||||
.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.reload();
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(
|
||||
page
|
||||
.locator('[data-test="logs-search-bar-query-editor"]')
|
||||
.locator(
|
||||
'text=SELECT kubernetes_pod_id FROM "e2e_automate"'
|
||||
)
|
||||
).toBeVisible();
|
||||
});
|
||||
|
||||
test("should display results without adding timestamp in quick mode", async ({
|
||||
page,
|
||||
}) => {
|
||||
|
||||
await page.locator('[data-cy="index-field-search-input"]').clear();
|
||||
await page
|
||||
.locator('[data-cy="index-field-search-input"]')
|
||||
.fill("kubernetes_pod_id");
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator(
|
||||
'[data-test="log-search-index-list-interesting-kubernetes_pod_id-field-btn"]'
|
||||
)
|
||||
.last()
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.getByRole('switch', { name: 'SQL Mode' }).locator('div').nth(2).click();
|
||||
await page.waitForTimeout(2000);
|
||||
await page
|
||||
.locator('[data-cy="search-bar-refresh-button"] > .q-btn__content')
|
||||
.click({
|
||||
force: true,
|
||||
});
|
||||
await page.waitForTimeout(2000);
|
||||
await expect(
|
||||
page
|
||||
.locator('[data-test="log-search-result-table-th-source"]')
|
||||
).toHaveText(/source/);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
@@ -97,7 +97,7 @@ test.describe("Stream multiselect testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
await logsPage.clickQuickModeToggle();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./baseFixtures.js";
|
||||
import { LoginPage } from '../pages/loginPage.js';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
import { IngestionPage } from '../pages/ingestionPage.js';
|
||||
import { ManagementPage } from '../pages/managementPage.js';
|
||||
|
||||
@@ -39,13 +39,15 @@ test.describe("Pagination for logs", () => {
|
||||
await logsPage.selectIndexStream(streamName);
|
||||
console.log(streamName);
|
||||
await logsPage.typeQuery(`SELECT * FROM "${streamName}" WHERE match_all("2022-12-27T14:11:27Z INFO zinc_enl")`);
|
||||
await page.waitForTimeout(2000);
|
||||
await page.waitForTimeout(3000); // Wait for query preparation
|
||||
await logsPage.selectRunQuery();
|
||||
await page.waitForTimeout(2000);
|
||||
await page.waitForTimeout(3000); // Wait for query results
|
||||
await logsPage.clickResultsPerPage();
|
||||
await logsPage.selectResultsPerPageAndVerify('2', 'Showing 11 to 20 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('3', 'Showing 21 to 30 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('4', 'Showing 31 to 39 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('2', 'Showing 11 to 20 out of');
|
||||
await page.waitForTimeout(1000); // Wait for pagination change
|
||||
await logsPage.selectResultsPerPageAndVerify('3', 'Showing 21 to 30 out of');
|
||||
await page.waitForTimeout(1000); // Wait for pagination change
|
||||
await logsPage.selectResultsPerPageAndVerify('4', 'Showing 31 to');
|
||||
});
|
||||
|
||||
test("HTTP Pagination for running query to validate WHERE match_all('zin*')", async ({ page }) => {
|
||||
@@ -103,9 +105,9 @@ test.describe("Pagination for logs", () => {
|
||||
await logsPage.selectRunQuery();
|
||||
await page.waitForTimeout(2000);
|
||||
await logsPage.clickResultsPerPage();
|
||||
await logsPage.selectResultsPerPageAndVerify('2', 'Showing 11 to 20 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('3', 'Showing 21 to 30 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('4', 'Showing 31 to 39 out of 39');
|
||||
await logsPage.selectResultsPerPageAndVerify('2', 'Showing 11 to 20 out of');
|
||||
await logsPage.selectResultsPerPageAndVerify('3', 'Showing 21 to 30 out of');
|
||||
await logsPage.selectResultsPerPageAndVerify('4', 'Showing 31 to');
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query to validate WHERE match_all('zin*')", async ({ page }) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import PipelinePage from "../pages/pipelinePage";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
@@ -111,7 +111,7 @@ test.describe("Core Pipeline Tests", () => {
|
||||
await page.goto(
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
// import { log } from "console";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import PipelinePage from "../pages/pipelinePage";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
@@ -176,7 +176,7 @@ test.describe("Pipeline testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ async function login(page) {
|
||||
}
|
||||
|
||||
|
||||
const selectStreamAndStreamTypeForLogs = async (page,stream) => {await page.waitForTimeout(
|
||||
const selectStream = async (page,stream) => {await page.waitForTimeout(
|
||||
4000);await page.locator(
|
||||
'[data-test="log-search-index-list-select-stream"]').click({ force: true });await page.locator(
|
||||
"div.q-item").getByText(`${stream}`).first().click({ force: true });
|
||||
@@ -99,7 +99,7 @@ test.describe("Region testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await selectStreamAndStreamTypeForLogs(page,logData.Stream);
|
||||
await selectStream(page,logData.Stream);
|
||||
await applyQueryButton(page);
|
||||
const searchBarRegionBtn = await page.locator('[data-test="logs-search-bar-region-btn"]');
|
||||
if (!(await searchBarRegionBtn.isVisible())) {
|
||||
|
||||
@@ -89,7 +89,7 @@ async function ingestion(page) {
|
||||
console.log(response);
|
||||
}
|
||||
|
||||
const selectStreamAndStreamTypeForLogs = async (page, stream) => {
|
||||
const selectStream = async (page, stream) => {
|
||||
await page.waitForTimeout(4000);
|
||||
await page
|
||||
.locator('[data-test="log-search-index-list-select-stream"]')
|
||||
@@ -243,7 +243,7 @@ test.describe("Pipeline testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await selectStreamAndStreamTypeForLogs(page, logData.Stream);
|
||||
await selectStream(page, logData.Stream);
|
||||
await applyQueryButton(page);
|
||||
//this only be called when no authorization token is present so that the remote will destination will be the same as the environment
|
||||
if (AuthorizationToken.length == 0) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from './baseFixtures';
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { toZonedTime } from "date-fns-tz";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
const folderName = `Folder ${Date.now()}`;
|
||||
@@ -89,7 +89,7 @@ test.describe("Sanity testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from './baseFixtures';
|
||||
import logData from "../cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { toZonedTime } from "date-fns-tz";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
const folderName = `Folder ${Date.now()}`;
|
||||
@@ -89,7 +89,7 @@ test.describe("Sanity testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
// const streams = page.waitForResponse("**/api/default/streams**");
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
const streamName = `stream${Date.now()}`;
|
||||
@@ -82,7 +82,7 @@ test.describe("Schema testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from './baseFixtures';
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { test, expect } from './baseFixtures.js';
|
||||
import logData from "../cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
@@ -95,6 +95,7 @@ test.describe("Search Partition Tests", () => {
|
||||
expect(matchingCall.sql).toContain('SELECT histogram(_timestamp');
|
||||
}
|
||||
} else {
|
||||
await logsPage.clickRunQueryButton();
|
||||
await logsPage.verifyStreamingModeResponse();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Implementation test.spec.js
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import { LoginPage } from '../pages/loginPage.js';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
|
||||
import { startTimeValue, endTimeValue } from '../pages/CommonLocator.js';
|
||||
|
||||
@@ -1,220 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures.js";
|
||||
import { LoginPage } from '../pages/loginPage.js';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { IngestionPage } from '../pages/ingestionPage.js';
|
||||
import { ManagementPage } from '../pages/managementPage.js';
|
||||
|
||||
|
||||
|
||||
test.describe.configure({ mode: 'parallel' });
|
||||
|
||||
test.describe("Streaming for logs", () => {
|
||||
let loginPage, logsPage, ingestionPage, managementPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
loginPage = new LoginPage(page);
|
||||
ingestionPage = new IngestionPage(page);
|
||||
logsPage = new LogsPage(page);
|
||||
managementPage = new ManagementPage(page);
|
||||
await loginPage.gotoLoginPage();
|
||||
await loginPage.loginAsInternalUser();
|
||||
await loginPage.login(); // Login as root user
|
||||
await ingestionPage.ingestion();
|
||||
await ingestionPage.ingestionJoin();
|
||||
await managementPage.goToManagement();
|
||||
await page.waitForTimeout(5000);
|
||||
await managementPage.checkStreaming();
|
||||
});
|
||||
|
||||
test("Run query after selecting two streams after enabling streaming", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.displayTwoStreams();
|
||||
await logsPage.selectRunQuery();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams and SQL Mode On", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.displayTwoStreams();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, selecting field and SQL Mode On", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerName();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join queries", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameJoin();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.displayCountQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join limit", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameJoinLimit();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering join like", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameJoinLike();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Left join queries", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameLeftJoin();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Right join queries", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameRightJoin();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for running query after selecting two streams, SQL Mode On and entering Full join queries", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.kubernetesContainerNameFullJoin();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.validateResult();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("Enable Streaming for clicking on interesting field icon and display field in editor", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.clickQuickModeToggle();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.clickInterestingFields();
|
||||
await logsPage.validateInterestingFields();
|
||||
});
|
||||
|
||||
test("Enable Streaming for clicking on interesting field icon and display query in editor", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.clickQuickModeToggle();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.clickInterestingFields();
|
||||
await logsPage.validateInterestingFieldsQuery();
|
||||
});
|
||||
|
||||
test("Enable Streaming for Adding or removing interesting field removes it from editor and results too", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexAndStreamJoin();
|
||||
// await logsPage.enableSQLMode();
|
||||
await logsPage.clickQuickModeToggle();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.clickInterestingFields();
|
||||
await logsPage.addRemoveInteresting();
|
||||
});
|
||||
|
||||
test("Streaming enabled histogram is disabled and run query, results appear and then user switches on Histogram, getting error", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexStreamDefault();
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.toggleHistogram();
|
||||
await logsPage.selectRunQuery();
|
||||
|
||||
await logsPage.toggleHistogram();
|
||||
|
||||
// Check that the error message is not visible
|
||||
const errorHeading = page.getByRole('heading', { name: 'Error while fetching' });
|
||||
await expect(errorHeading).not.toBeVisible();
|
||||
|
||||
// Ensure that the error details button is also not visible or disabled
|
||||
const errorDetailsButton = page.locator('[data-test="logs-page-histogram-error-details-btn"]');
|
||||
await expect(errorDetailsButton).not.toBeVisible();
|
||||
|
||||
|
||||
});
|
||||
|
||||
test("No Histogram should be displayed if Data is not available", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexStreamDefault();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.clearAndFillQueryEditor('SELECT count(_timestamp) FROM "default" where code = 201');
|
||||
await page.waitForTimeout(1000);
|
||||
await logsPage.selectRunQuery();
|
||||
await logsPage.waitForSearchResultAndCheckText('warning No data found for histogram.');
|
||||
|
||||
});
|
||||
|
||||
test("Histogram should be displayed if it is enabled again and data is available", async ({ page }) => {
|
||||
|
||||
await logsPage.navigateToLogs();
|
||||
await logsPage.selectIndexStreamDefault();
|
||||
await logsPage.enableSQLMode();
|
||||
await logsPage.clearAndFillQueryEditor('SELECT count(_timestamp) FROM "default" where code = 200');
|
||||
await page.waitForTimeout(1000);
|
||||
await logsPage.selectRunQuery();
|
||||
await expect(page.locator('[data-test="logs-search-result-bar-chart"] canvas')).toBeVisible();
|
||||
await logsPage.toggleHistogram();
|
||||
await logsPage.selectRunQuery();
|
||||
await expect(page.locator('[data-test="logs-search-result-bar-chart"] canvas')).not.toBeVisible();
|
||||
await logsPage.toggleHistogram();
|
||||
await logsPage.selectRunQuery();
|
||||
await expect(page.locator('[data-test="logs-search-result-bar-chart"] canvas')).toBeVisible();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,64 +0,0 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { StreamPage } from '../pages/streamPage.js';
|
||||
import { getHeaders, getIngestionUrl, sendRequest } from '../utils/apiUtils.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
|
||||
async function login(page) {
|
||||
await page.goto(process.env["ZO_BASE_URL"]);
|
||||
await page.waitForTimeout(1000);
|
||||
if (await page.getByText('Login as internal user').isVisible()) {
|
||||
await page.getByText('Login as internal user').click();
|
||||
}
|
||||
|
||||
await page.locator('[data-cy="login-user-id"]').fill(process.env["ZO_ROOT_USER_EMAIL"]);
|
||||
await page.locator("label").filter({ hasText: "Password *" }).click();
|
||||
await page.locator('[data-cy="login-password"]').fill(process.env["ZO_ROOT_USER_PASSWORD"]);
|
||||
await page.locator('[data-cy="login-sign-in"]').click();
|
||||
}
|
||||
|
||||
test.describe("Stream multiselect testcases", () => {
|
||||
let logsPage;
|
||||
let streamPage;
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await login(page);
|
||||
logsPage = new LogsPage(page);
|
||||
streamPage = new StreamPage(page);
|
||||
await page.waitForTimeout(5000);
|
||||
});
|
||||
|
||||
test("should preserve stream name casing after ingestion and show in stream explorer", async ({ page }) => {
|
||||
const orgId = process.env["ORGNAME"];
|
||||
const headers = getHeaders();
|
||||
|
||||
const streams = [
|
||||
{ name: "MyUpperStream1" },
|
||||
{ name: "mylowerstream1" },
|
||||
];
|
||||
|
||||
// Ingest data into streams
|
||||
for (const stream of streams) {
|
||||
const ingestionUrl = getIngestionUrl(orgId, stream.name);
|
||||
const payload = {
|
||||
level: "info",
|
||||
job: "test",
|
||||
log: `test message for stream ${stream.name}`,
|
||||
e2e: "1",
|
||||
};
|
||||
const response = await sendRequest(page, ingestionUrl, payload, headers);
|
||||
console.log(`Ingested to ${stream.name}:`, response);
|
||||
}
|
||||
|
||||
// Validate streams in Stream Explorer
|
||||
for (const stream of streams) {
|
||||
await streamPage.navigateToStreamExplorer();
|
||||
await streamPage.searchStream(stream.name);
|
||||
await streamPage.verifyStreamNameVisibility(stream.name);
|
||||
await streamPage.exploreStream();
|
||||
await streamPage.verifyStreamExploration();
|
||||
await streamPage.goBack();
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -2,7 +2,7 @@ import { test, expect } from "./baseFixtures";
|
||||
import logData from "../../ui-testing/cypress/fixtures/log.json";
|
||||
import logsdata from "../../test-data/logs_data.json";
|
||||
import UnflattenedPage from "../pages/unflattened";
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
|
||||
test.describe.configure({ mode: "parallel" });
|
||||
const streamName = `stream${Date.now()}`;
|
||||
@@ -102,7 +102,7 @@ test.describe("Unflattened testcases", () => {
|
||||
`${logData.logsUrl}?org_identifier=${process.env["ORGNAME"]}`
|
||||
);
|
||||
const allsearch = page.waitForResponse("**/api/default/_search**");
|
||||
await logsPage.selectStreamAndStreamTypeForLogs("e2e_automate");
|
||||
await logsPage.selectStream("e2e_automate");
|
||||
await applyQueryButton(page);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { test, expect } from "./baseFixtures";
|
||||
import { LoginPage } from '../pages/loginPage';
|
||||
import { LogsPage } from '../pages/logsPage.js';
|
||||
import { LogsPage } from '../pages/logsPages/logsPage.js';
|
||||
import { IngestionPage } from '../pages/ingestionPage';
|
||||
import { ManagementPage } from '../pages/managementPage';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user