From 3ff97016cf5df90ea64052d461822dc44c9ec730 Mon Sep 17 00:00:00 2001 From: Neha P <144308844+neha00290@users.noreply.github.com> Date: Thu, 8 May 2025 20:16:03 +0530 Subject: [PATCH] test: e2e-stream-name (#6764) Added a test to add stream name and assert if stream with uppercase exists add a stream with lowercase and assert if stream name with lowercase exists --- .github/workflows/playwright.yml | 2 + tests/ui-testing/pages/streamPage.js | 41 ++++++++++++ .../playwright-tests/streamname.spec.js | 64 +++++++++++++++++++ tests/ui-testing/utils/apiUtils.js | 28 ++++++++ 4 files changed, 135 insertions(+) create mode 100644 tests/ui-testing/pages/streamPage.js create mode 100644 tests/ui-testing/playwright-tests/streamname.spec.js create mode 100644 tests/ui-testing/utils/apiUtils.js diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml index c7056e4142..ad8e7b7f53 100644 --- a/.github/workflows/playwright.yml +++ b/.github/workflows/playwright.yml @@ -34,6 +34,7 @@ env: ZO_WEBSOCKET_ENABLED: true ZO_COLS_PER_RECORD_LIMIT: "80000" ZO_SMTP_ENABLED: true + ZO_FORMAT_STREAM_NAME_TO_LOWERCASE: false jobs: build_binary: @@ -134,6 +135,7 @@ jobs: "schemaload.spec.js", "websocket.spec.js", "alertImportTDA.spec.js", + "streamname.spec.js" # "remotepipeline.spec.js", ] diff --git a/tests/ui-testing/pages/streamPage.js b/tests/ui-testing/pages/streamPage.js new file mode 100644 index 0000000000..0ae9c0d617 --- /dev/null +++ b/tests/ui-testing/pages/streamPage.js @@ -0,0 +1,41 @@ +import { expect } from '@playwright/test'; + +export class StreamPage { + constructor(page) { + this.page = page; + this.streamExplorerLink = '[data-test="menu-link-/streams-item"]'; + this.searchStreamInput = '[placeholder="Search Stream"]'; + this.exploreButton = 'button:has-text("Explore")'; + } + + async navigateToStreamExplorer() { + await this.page.locator(this.streamExplorerLink).click({ force: true }); + await this.page.waitForTimeout(1000); + } + + async searchStream(streamName) { + await this.page.getByPlaceholder("Search Stream").click(); + await this.page.getByPlaceholder("Search Stream").fill(streamName); + await this.page.waitForTimeout(3000); + } + + async verifyStreamNameVisibility(streamName) { + await expect(this.page.getByText(streamName)).toBeVisible(); + } + + async exploreStream() { + const streamButton = this.page.getByRole("button", { name: 'Explore' }); + await expect(streamButton).toBeVisible(); + await streamButton.click({ force: true }); + await this.page.waitForTimeout(1000); + } + + async verifyStreamExploration() { + await expect(this.page.url()).toContain("logs"); + } + + async goBack() { + await this.page.goBack(); + await this.page.waitForTimeout(1000); + } +} \ No newline at end of file diff --git a/tests/ui-testing/playwright-tests/streamname.spec.js b/tests/ui-testing/playwright-tests/streamname.spec.js new file mode 100644 index 0000000000..96149ab0c8 --- /dev/null +++ b/tests/ui-testing/playwright-tests/streamname.spec.js @@ -0,0 +1,64 @@ +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(); + } + }); +}); diff --git a/tests/ui-testing/utils/apiUtils.js b/tests/ui-testing/utils/apiUtils.js new file mode 100644 index 0000000000..b8255f9304 --- /dev/null +++ b/tests/ui-testing/utils/apiUtils.js @@ -0,0 +1,28 @@ +export const getHeaders = () => { + const basicAuthCredentials = Buffer.from( + `${process.env["ZO_ROOT_USER_EMAIL"]}:${process.env["ZO_ROOT_USER_PASSWORD"]}` + ).toString("base64"); + + return { + Authorization: `Basic ${basicAuthCredentials}`, + "Content-Type": "application/json", + }; +}; + +export const getIngestionUrl = (orgId, streamName) => { + return `${process.env.INGESTION_URL}/api/${orgId}/${streamName}/_json`; +}; + +export const sendRequest = async (page, url, payload, headers) => { + return await page.evaluate( + async ({ url, headers, payload }) => { + const response = await fetch(url, { + method: "POST", + headers: headers, + body: JSON.stringify(payload), + }); + return await response.json(); + }, + { url, headers, payload } + ); +}; \ No newline at end of file