test: add dashboard override config test case (#8652)

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


___

### **Description**
- Add override config E2E test

- Introduce override config locators

- Implement robust sidebar scrolling

- Save override via UI flow


___

### Diagram Walkthrough


```mermaid
flowchart LR
  Spec["Visualize spec: override test"] -- uses --> PageObj["DashboardPanelConfigs helpers"]
  PageObj -- adds --> Locators["Override locators"]
  PageObj -- adds --> Scroll["Robust sidebar scroll"]
  Spec -- verifies --> Table["Colored table cells present"]
  Spec -- persists --> Dashboard["Add panel to new dashboard"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>dashboard-panel-configs.js</strong><dd><code>Add
override helpers and scrolling in panel configs</code>&nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

tests/ui-testing/pages/dashboardPages/dashboard-panel-configs.js

<ul><li>Add override config locators.<br> <li> Add configureOverride
workflow with save.<br> <li> Implement scrolling to reveal override
control.<br> <li> Minor whitespace/cleanup.</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/8652/files#diff-f9ea2c35d253aa0c99b5c165f575a883ee898f981dc0a451502e230f03a0995c">+69/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Tests</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>visualize.spec.js</strong><dd><code>Add E2E test
validating override color application</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

tests/ui-testing/playwright-tests/dashboards/visualize.spec.js

<ul><li>Add test for override after histogram.<br> <li> Use new panel
config helpers.<br> <li> Assert colored cells and persist panel.<br>
<li> Log styles and cleanup dashboard.</ul>


</details>


  </td>
<td><a
href="https://github.com/openobserve/openobserve/pull/8652/files#diff-d144f23552ec150db375c89e52c3a53ede9ff3fa5dcd6092694fbe0a308d22ec">+82/-0</a>&nbsp;
&nbsp; </td>

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

</details>

___
This commit is contained in:
ktx-akshay
2025-09-26 13:52:02 +05:30
committed by GitHub
parent 3b6b2bce68
commit d2a65f967f
2 changed files with 151 additions and 0 deletions
@@ -82,6 +82,15 @@ export default class DashboardPanelConfigs {
//Map locators
this.mapType = page.locator('[data-test="dashboard-config-map-type"]');
// Override config locators
this.overrideColumnSelect = page.locator(
'[data-test="dashboard-addpanel-config-unit-config-select-column-0"]'
);
this.overrideTypeSelect = page.locator(
'[data-test="dashboard-addpanel-config-type-select-0"]'
);
this.sidebarScrollContainer = page.locator('.sidebar-content.scroll');
}
/// Open the config panel
async openConfigPanel() {
@@ -279,6 +288,65 @@ export default class DashboardPanelConfigs {
await this.overrideConfig.click();
}
// Add and configure override with dynamic column and type
async configureOverride({ columnName, typeName, enableTypeCheckbox = true }) {
// Ensure the override button is visible by scrolling the sidebar
await this.scrollDownSidebarUntilOverrideVisible();
await this.overrideConfig.click();
// Select column
await this.overrideColumnSelect.waitFor({ state: "visible" });
await this.overrideColumnSelect.click();
const columnOption = this.page.getByRole("option", { name: columnName }).first();
await columnOption.waitFor({ state: "visible" });
await columnOption.click();
// Select type
await this.overrideTypeSelect.waitFor({ state: "visible" });
await this.overrideTypeSelect.click();
const typeOption = this.page.getByRole("option", { name: typeName }).first();
await typeOption.waitFor({ state: "visible" });
await typeOption.click();
// Optionally enable checkbox corresponding to the selected type
if (enableTypeCheckbox) {
const typeCheckbox = this.page.getByRole("checkbox", { name: typeName });
await typeCheckbox.waitFor({ state: "visible" });
await typeCheckbox.click();
}
const saveBtn = this.page.getByRole('button', { name: 'Save' });
await saveBtn.waitFor({ state: "visible", timeout: 5000 });
await saveBtn.click();
}
// Click-hold on the sidebar and scroll down until the Override button is visible
async scrollDownSidebarUntilOverrideVisible() {
const sidebar = this.page.locator('.sidebar-content');
await sidebar.waitFor({ state: "visible" });
// Bring sidebar into view and hover so wheel events target it
await sidebar.scrollIntoViewIfNeeded();
await sidebar.hover();
// Press and hold mouse, then wheel scroll in chunks while checking visibility
await this.page.mouse.down();
for (let i = 0; i < 12; i++) {
if (await this.overrideConfig.isVisible().catch(() => false)) break;
await this.page.mouse.wheel(0, 900);
}
await this.page.mouse.up();
// If still not visible, do a final programmatic scroll as a safe fallback
if (!(await this.overrideConfig.isVisible().catch(() => false))) {
await this.page.evaluate((selector) => {
const el = document.querySelector(selector);
if (el) el.scrollTop = el.scrollHeight;
}, ".sidebar-content");
}
// Ensure the button is actually visible before proceeding
await this.overrideConfig.scrollIntoViewIfNeeded();
await this.overrideConfig.waitFor({ state: "visible" });
}
//Metric Text
//BG color
async selectBGColor(color) {
@@ -299,4 +367,5 @@ export default class DashboardPanelConfigs {
await this.gaugeMax.click();
await this.gaugeMax.fill(max);
}
}
@@ -7,8 +7,10 @@ import { ingestion } from "./utils/dashIngestion.js";
import logData from "../../fixtures/log.json";
import PageManager from "../../pages/page-manager";
import { waitForDateTimeButtonToBeEnabled } from "../../pages/dashboardPages/dashboard-time";
import DashboardPanelConfigs from "../../pages/dashboardPages/dashboard-panel-configs";
import { waitForDashboardPage, deleteDashboard } from "./utils/dashCreation.js";
const testLogger = require("../utils/test-logger.js");
//Dashboard name
const randomDashboardName =
@@ -639,4 +641,84 @@ test.describe("logs testcases", () => {
);
await expect(quickModeToggle).toHaveAttribute("aria-checked", "false");
});
test("should apply override config after running histogram query", async ({
page,
}) => {
const pm = new PageManager(page);
// Open logs and prepare histogram query
await pm.logsVisualise.openLogs();
await pm.logsVisualise.openQueryEditor();
await pm.logsVisualise.fillLogsQueryEditor(histogramQuery);
await pm.logsVisualise.setRelative("6", "w");
await pm.logsVisualise.logsApplyQueryButton();
// Go to visualize and wait for chart to render
await pm.logsVisualise.openVisualiseTab();
await pm.chartTypeSelector.selectChartType("table");
await pm.logsVisualise.verifyChartRenders(page);
// Open panel configs and configure override
const panelConfigs = new DashboardPanelConfigs(page);
await panelConfigs.openConfigPanel();
await page.waitForTimeout(2000);
await panelConfigs.scrollDownSidebarUntilOverrideVisible();
await panelConfigs.configureOverride({
columnName: "x_axis_1",
typeName: "Unique Value Color",
enableTypeCheckbox: true,
});
// Re-run the query to apply override effect and wait for rendering
await pm.logsVisualise.runQueryAndWaitForCompletion();
await pm.logsVisualise.verifyChartRenders(page);
// Assert that at least one table cell has a background color applied
const coloredCells = page.locator(
'[data-test="dashboard-panel-table"] tbody .q-td[style*="background-color"]'
);
await expect(coloredCells.first()).toBeVisible();
const coloredCount = await coloredCells.count();
testLogger.error(`[TEST] Colored cells detected: ${coloredCount}`);
expect(coloredCount).toBeGreaterThan(0);
// Capture and log the inline style(s) applied to colored cells
const coloredStyles = await coloredCells.evaluateAll((nodes) =>
nodes.map((n) => n.getAttribute("style") || "")
);
testLogger.error("[TEST] Colored cell inline styles:", coloredStyles);
await pm.logsVisualise.addPanelToNewDashboard(
randomDashboardName,
panelName
);
// Wait for and assert the success message
const successMessage = page.getByText("Panel added to dashboard");
await expect(successMessage).toBeVisible({ timeout: 10000 });
// Assert that at least one table cell has a background color applied
const coloredCellsonPanel = page.locator(
'[data-test="dashboard-panel-table"] tbody .q-td[style*="background-color"]'
);
await expect(coloredCellsonPanel.first()).toBeVisible();
const coloredCountOnPanel = await coloredCellsonPanel.count();
testLogger.error(`[TEST] Colored cells detected: ${coloredCountOnPanel}`);
expect(coloredCountOnPanel).toBeGreaterThan(0);
// Capture and log the inline style(s) applied to colored cells
const coloredStylesOnPanel = await coloredCellsonPanel.evaluateAll((nodes) =>
nodes.map((n) => n.getAttribute("style") || "")
);
testLogger.error("[TEST] Colored cell inline styles:", coloredStylesOnPanel );
// delete the dashboard
await page.locator('[data-test="dashboard-back-btn"]').click();
await deleteDashboard(page, randomDashboardName);
});
});