mirror of
https://github.com/openobserve/openobserve.git
synced 2026-11-04 16:09:05 +00:00
feat: default fields for add Panel and metrics page (#12509)
Design at: dashboards/default-panel-fields
This commit is contained in:
@@ -336,6 +336,9 @@ test.describe("Cross-Linking Multi-Stream testcases", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStream(STREAM_A);
|
||||
// Add Panel auto-seeds y_axis_1 = count(_timestamp); remove it to keep
|
||||
// the original single-column table shape (x-axis only).
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.dashboardPanelActions.addPanelName("CrossLink Single Stream Panel");
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
|
||||
@@ -569,6 +569,9 @@ test.describe("Cross-Linking testcases", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
// Remove the auto-seeded histogram(_timestamp) x so kubernetes_container_name
|
||||
// is the first column — the cross-link drilldown clicks the first cell.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.dashboardPanelActions.addPanelName("CrossLink Table Panel");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -1414,6 +1417,9 @@ test.describe("Cross-Linking testcases", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
// Remove the auto-seeded histogram(_timestamp) x so kubernetes_container_name
|
||||
// is the first column — the cross-link drilldown clicks the first cell.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.dashboardPanelActions.addPanelName("Org CrossLink Table Panel");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
|
||||
@@ -69,8 +69,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await waitForDateTimeButtonToBeEnabled(page);
|
||||
|
||||
await pm.dashboardTimeRefresh.setRelative("30", "m");
|
||||
@@ -198,8 +196,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"filter"
|
||||
@@ -286,8 +282,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await waitForDateTimeButtonToBeEnabled(page);
|
||||
|
||||
await pm.dashboardTimeRefresh.setRelative("30", "m");
|
||||
@@ -392,6 +386,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_image",
|
||||
"y"
|
||||
@@ -470,7 +465,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
|
||||
@@ -535,7 +529,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
// Select stream and add Y field
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
await pm.dashboardPanelActions.waitForChartToRender();
|
||||
@@ -624,7 +617,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
// Select stream and add fields
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"b"
|
||||
@@ -731,6 +723,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
// Select stream and add fields
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"y"
|
||||
@@ -831,8 +824,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await waitForDateTimeButtonToBeEnabled(page);
|
||||
|
||||
await pm.dashboardTimeRefresh.setRelative("30", "m");
|
||||
@@ -950,9 +941,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
await pm.dashboardPanelActions.waitForChartToRender();
|
||||
|
||||
@@ -1051,6 +1039,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1147,9 +1136,6 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
await pm.dashboardPanelActions.waitForChartToRender();
|
||||
|
||||
@@ -1245,6 +1231,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1342,6 +1329,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1437,6 +1425,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1532,6 +1521,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1629,6 +1619,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1726,6 +1717,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1823,6 +1815,7 @@ test.describe("dashboard filter testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y-axis field
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
|
||||
@@ -235,6 +235,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.APP_USERS);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
|
||||
@@ -262,6 +263,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.APP_USERS);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
|
||||
@@ -289,6 +291,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.APP_USERS);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("email", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "y");
|
||||
|
||||
@@ -346,6 +349,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.SESSIONS);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("device", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("browser", "y");
|
||||
|
||||
@@ -380,6 +384,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.SESSIONS, 1);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("status", "y");
|
||||
|
||||
@@ -407,6 +412,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
await verifyJoinChipIsVisible(page, STREAMS.SESSIONS);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("device", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("browser", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("os", "y");
|
||||
@@ -464,6 +470,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "y");
|
||||
@@ -491,6 +498,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("bytes", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -516,6 +524,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("response_time_ms", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -541,6 +550,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("response_time_ms", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("bytes", "y");
|
||||
|
||||
@@ -597,6 +607,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("response_time_ms", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
|
||||
@@ -620,6 +631,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("country", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
|
||||
@@ -643,6 +655,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("bytes", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "y");
|
||||
|
||||
@@ -666,6 +679,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("email", "y");
|
||||
|
||||
@@ -722,6 +736,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("plan", "y");
|
||||
@@ -750,6 +765,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("email", "y");
|
||||
@@ -778,6 +794,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("duration_mins", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("device", "y");
|
||||
|
||||
@@ -804,6 +821,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -829,6 +847,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("status", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -854,6 +873,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1002,6 +1022,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
]);
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -1103,6 +1124,7 @@ test.describe("Dashboard Joins Feature Tests (Consolidated)", () => {
|
||||
|
||||
// Add fields and apply - should work without any joins
|
||||
await pm.chartTypeSelector.searchAndAddField("request_id", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("path", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
|
||||
@@ -84,6 +84,7 @@ test.describe("Dashboard Metric Chart CamelCase Alias", () => {
|
||||
|
||||
// Builder mode: select stream and add Y-axis field (auto-generated alias y_axis_1)
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Apply with time range and verify
|
||||
@@ -118,6 +119,8 @@ test.describe("Dashboard Metric Chart CamelCase Alias", () => {
|
||||
`SELECT count(*) AS totalcount FROM "${STREAM_NAME}"`
|
||||
);
|
||||
|
||||
// Remove the default seeded Y (count) before adding ours — metric allows one Y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
// Add the lowercase alias as Y-axis field (metric chart requires Y-axis to render)
|
||||
await pm.chartTypeSelector.searchAndAddField("totalcount", "y");
|
||||
testLogger.info("Custom SQL with lowercase alias entered");
|
||||
@@ -154,6 +157,8 @@ test.describe("Dashboard Metric Chart CamelCase Alias", () => {
|
||||
`SELECT count(*) AS metricValue FROM "${STREAM_NAME}" WHERE kubernetes_container_name = 'nonexistent_container_xyz_99999'`
|
||||
);
|
||||
|
||||
// Remove the default seeded Y (count) before adding ours — metric allows one Y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
// Add Y-axis field (metric chart requires Y-axis to render)
|
||||
await pm.chartTypeSelector.searchAndAddField("metricValue", "y");
|
||||
testLogger.info("Custom SQL with non-existent filter entered");
|
||||
@@ -214,6 +219,8 @@ test.describe("Dashboard Metric Chart CamelCase Alias", () => {
|
||||
`SELECT count(*) AS countRecords FROM "${STREAM_NAME}"`
|
||||
);
|
||||
|
||||
// Remove the default seeded Y (count) before adding ours — metric allows one Y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
// Add the camelCase alias as Y-axis field (metric chart requires Y-axis to render)
|
||||
await pm.chartTypeSelector.searchAndAddField("countRecords", "y");
|
||||
testLogger.info("Custom SQL with camelCase alias entered");
|
||||
|
||||
@@ -47,6 +47,9 @@ async function buildPanel(
|
||||
if (xField) {
|
||||
await pm.chartTypeSelector.searchAndAddField(xField, "x");
|
||||
}
|
||||
// Add Panel now auto-seeds y_axis_1 = count(_timestamp). Remove it before
|
||||
// adding this tab's own y-field.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(yField, "y");
|
||||
if (breakdownField) {
|
||||
const breakdownTarget = chartType === "table" ? "p" : "b";
|
||||
@@ -66,9 +69,13 @@ async function addAndConfigureSecondQuery(pm, { yField = "kubernetes_namespace_n
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// A new tab auto-seeds x_axis_1 = histogram(_timestamp) and y_axis_1 = count(_timestamp).
|
||||
// Always remove the seeded field, then add this tab's own x/y.
|
||||
if (xField) {
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField(xField, "x");
|
||||
}
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(yField, "y");
|
||||
}
|
||||
|
||||
@@ -221,13 +228,13 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
|
||||
await msql.addQueryTab(2);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
|
||||
// Switching tabs must surface that query's own Y-axis field.
|
||||
@@ -459,9 +466,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
|
||||
await msql.switchToQueryTab(0);
|
||||
await msql.configLegend(0).waitFor({ state: "visible", timeout: 10000 });
|
||||
await msql.configLegend(0).clear();
|
||||
@@ -743,8 +749,12 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
// Q1: valid bar chart with y-field configured
|
||||
await buildPanel(page, pm, dashboardName, { chartType: "bar" });
|
||||
|
||||
// Add Q2 and intentionally leave it empty (no stream, no fields)
|
||||
// Add Q2 and intentionally make it invalid. New tabs now auto-seed
|
||||
// histogram x + count y, so strip both fields to leave Q2 unconfigured —
|
||||
// an empty query is what surfaces the execution error under test.
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
|
||||
// Switch back to Q1 — error from Q2 should surface regardless of active tab
|
||||
await msql.switchToQueryTab(0);
|
||||
@@ -998,8 +1008,9 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
|
||||
// NOTE: When addPanel() is called, the panel editor auto-populates
|
||||
// histogram(_timestamp) into Q1's x-axis. So buildPanel() must NOT pass
|
||||
// xField — Q1 already has the histogram x-field. New query tabs (Q2+)
|
||||
// always start empty, so addField calls on those work normally.
|
||||
// xField — Q1 already has the histogram x-field. New query tabs (Q2+) now
|
||||
// also auto-seed x_axis_1 = histogram(_timestamp) + y_axis_1 = count(_timestamp),
|
||||
// so tests remove the seeded field before adding a different x/y of their own.
|
||||
|
||||
test(
|
||||
"no warning with a single query using histogram x-alias",
|
||||
@@ -1037,11 +1048,11 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
yField: "kubernetes_container_hash",
|
||||
});
|
||||
|
||||
// Add Q2 also with _timestamp (histogram) — Q2 starts empty so +X works
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1071,11 +1082,15 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await removeFirstXField(page); // removes auto _timestamp
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
|
||||
// Add Q2 also with non-histogram x — Q2 starts empty so +X works
|
||||
// Add Q2 with non-histogram x (replaces the seeded histogram x)
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// New tab seeds histogram(_timestamp) x; replace it with this tab's
|
||||
// non-histogram x-field.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1104,11 +1119,15 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
yField: "kubernetes_container_hash",
|
||||
});
|
||||
|
||||
// Q2: non-histogram x (kubernetes_host) — Q2 starts empty so +X works
|
||||
// Q2: non-histogram x (kubernetes_host), replacing the seeded histogram x
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// New tab seeds histogram(_timestamp) x; replace it with this tab's
|
||||
// non-histogram x-field.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1139,11 +1158,11 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await removeFirstXField(page); // removes auto _timestamp
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
|
||||
// Q2: histogram(_timestamp) — Q2 starts empty so +X works
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1174,7 +1193,11 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// New tab seeds histogram(_timestamp) x; replace it with this tab's
|
||||
// non-histogram x-field.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1211,10 +1234,12 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
yField: "kubernetes_container_hash",
|
||||
});
|
||||
|
||||
// Q2 with ONLY a y-field — no x-field added
|
||||
// Q2 with ONLY a y-field — remove both auto-seeded fields, add only y
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1247,7 +1272,11 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// New tab seeds histogram(_timestamp) x; replace it with this tab's
|
||||
// non-histogram x-field.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1284,7 +1313,11 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// New tab seeds histogram(_timestamp) x; replace it with this tab's
|
||||
// non-histogram x-field.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1363,8 +1396,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// Q2 starts with empty x-axis; add _timestamp so the bar chart renders
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1402,7 +1435,7 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1483,7 +1516,7 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1525,8 +1558,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// Q2 starts with empty x-axis; add _timestamp so save validates cleanly
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1592,7 +1625,7 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1681,8 +1714,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(streamB);
|
||||
// Q2 needs x-field so the bar chart renders and the panel saves cleanly
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1746,8 +1779,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(streamB);
|
||||
// Q2 needs x-field so the bar chart renders and the panel saves cleanly
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1806,8 +1839,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(streamB);
|
||||
// Q2 needs x-field so the bar chart renders and the panel saves cleanly
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -1858,8 +1891,8 @@ test.describe("Multi-SQL Query Support", () => {
|
||||
await msql.addQueryTab(1);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(streamB);
|
||||
// Q2 needs x-field so the bar chart renders and the panel saves cleanly
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Q2 keeps its auto-seeded histogram(_timestamp) x; swap the seeded y.
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
|
||||
@@ -48,6 +48,7 @@ test.describe("dashboard multi y axis testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("stacked");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
@@ -111,6 +112,7 @@ test.describe("dashboard multi y axis testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("stacked");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_namespace_name",
|
||||
"y"
|
||||
|
||||
@@ -515,6 +515,7 @@ test.describe(
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
|
||||
@@ -199,6 +199,7 @@ test.describe("Dashboard Functions", () => {
|
||||
|
||||
await selectStreamAndChartType(page, pm, STREAM_NAME, "table");
|
||||
await pm.chartTypeSelector.searchAndAddField("user_name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("score", "y");
|
||||
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
@@ -221,6 +222,7 @@ test.describe("Dashboard Functions", () => {
|
||||
|
||||
await selectStreamAndChartType(page, pm, STREAM_NAME, "table");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("user_name", "y");
|
||||
|
||||
// UI shows "Distinct" for COUNT-DISTINCT function; label displays as "count"
|
||||
@@ -242,6 +244,7 @@ test.describe("Dashboard Functions", () => {
|
||||
|
||||
await selectStreamAndChartType(page, pm, STREAM_NAME, "table");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("score", "y");
|
||||
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "avg");
|
||||
@@ -262,6 +265,7 @@ test.describe("Dashboard Functions", () => {
|
||||
|
||||
await selectStreamAndChartType(page, pm, STREAM_NAME, "table");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("score", "y");
|
||||
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "sum");
|
||||
@@ -314,6 +318,7 @@ test.describe("Dashboard Functions", () => {
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
|
||||
// Add first Y-axis with COUNT
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("user_name", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -345,6 +350,7 @@ test.describe("Dashboard Functions", () => {
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
|
||||
// Add Y-axis with MIN
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("score", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "min");
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ test.describe("Pie & Donut Chart — E2E Tests (SQL Builder / Logs Stream)", ()
|
||||
await pm.chartTypeSelector.selectChartType("pie");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Pie Aggregations");
|
||||
|
||||
@@ -214,6 +215,7 @@ test.describe("Pie & Donut Chart — E2E Tests (SQL Builder / Logs Stream)", ()
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Line To Pie");
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -318,6 +320,7 @@ test.describe("Pie & Donut Chart — E2E Tests (SQL Builder / Logs Stream)", ()
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add Y field, then switch to raw and enter custom SQL
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
|
||||
// Open Y-axis function popup and switch to raw tab
|
||||
@@ -375,6 +378,7 @@ test.describe("Pie & Donut Chart — E2E Tests (SQL Builder / Logs Stream)", ()
|
||||
await pm.chartTypeSelector.selectChartType("pie");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
|
||||
// Configure Y-axis with raw count query
|
||||
@@ -408,6 +412,7 @@ test.describe("Pie & Donut Chart — E2E Tests (SQL Builder / Logs Stream)", ()
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Y-axis: kubernetes_container_name with count aggregation (cross-field)
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
await pm.chartTypeSelector.configureYAxisRawQuery(
|
||||
"y_axis_1",
|
||||
|
||||
@@ -140,7 +140,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
|
||||
// Add Y field (Value field) with count aggregation
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
// Apply and wait for render
|
||||
@@ -203,7 +202,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -273,7 +271,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -357,7 +354,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
// Check for "First Column" label (non-pivot mode)
|
||||
@@ -419,7 +415,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
@@ -533,7 +528,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -679,7 +673,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -767,7 +760,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -841,7 +833,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -928,7 +919,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
|
||||
// Add only Pivot (breakdown) + Y fields (no X)
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -987,6 +977,9 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
);
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
|
||||
// Remove the default seeded Y field (count) so this truly tests the no-Y case
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
await pm.dashboardPanelActions.waitForChartToRender();
|
||||
|
||||
@@ -1040,7 +1033,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
|
||||
// Multiple Y fields to create hierarchy
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("log", "y");
|
||||
@@ -1098,7 +1090,6 @@ test.describe("Dashboard Table Chart - Pivot Table Feature", () => {
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
|
||||
// Y field
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
|
||||
@@ -46,6 +46,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Open Y-axis popup and verify tabs
|
||||
@@ -79,6 +80,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Open popup, switch to Raw tab, enter query
|
||||
@@ -117,6 +119,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Configure raw query on Y-axis
|
||||
@@ -181,6 +184,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
await pm.chartTypeSelector.configureYAxisRawQuery(Y_AXIS_ALIAS, RAW_QUERY);
|
||||
|
||||
@@ -241,6 +245,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Open popup
|
||||
@@ -297,6 +302,7 @@ test.describe("Dashboard Raw Query testcases", () => {
|
||||
panelName = pm.dashboardPanelActions.generateUniquePanelName("raw-query-test");
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream(STREAM_NAME);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Configure raw query
|
||||
|
||||
+2
@@ -86,6 +86,7 @@ test.describe("Dashboard series color with multi-window (time shift)", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("area");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Step 3: Apply the query to render the chart initially
|
||||
@@ -223,6 +224,7 @@ test.describe("Dashboard series color with multi-window (time shift)", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
// Step 2: Apply initial query
|
||||
|
||||
@@ -167,6 +167,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
|
||||
@@ -201,7 +202,6 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
@@ -293,6 +293,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
|
||||
// Enable VRL function toggle and add a VRL function that creates a new field
|
||||
@@ -368,6 +369,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -410,6 +412,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -448,6 +451,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -492,6 +496,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -530,6 +535,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
|
||||
@@ -573,6 +579,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "filter");
|
||||
|
||||
@@ -646,6 +653,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_hash", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -741,6 +749,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -797,6 +806,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
// Add X field — shows in "First Column" area
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
// Add Y field — shows in "Other Columns" area
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
|
||||
// Verify layout labels
|
||||
@@ -837,6 +847,7 @@ test.describe("Dashboard Table Chart - Core Features", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
|
||||
// Test with "sum" aggregation
|
||||
|
||||
@@ -65,6 +65,7 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -103,6 +104,7 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -153,6 +155,7 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -201,6 +204,7 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("code", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
@@ -256,7 +260,6 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
// X: row field, P: pivot/breakdown field, Y: value field
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
@@ -293,7 +296,6 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
@@ -339,7 +341,6 @@ test.describe("Dashboard Table Chart - Copy Cell Timestamp Formatting", () => {
|
||||
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "x");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "p");
|
||||
await pm.chartTypeSelector.searchAndAddField("_timestamp", "y");
|
||||
await pm.chartTypeSelector.configureYAxisFunction("y_axis_1", "count");
|
||||
|
||||
const streamPromise = waitForStreamComplete(page);
|
||||
|
||||
@@ -43,6 +43,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"y"
|
||||
@@ -84,6 +85,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"y"
|
||||
@@ -237,6 +239,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
|
||||
// Open the configuration panel and enable dynamic columns
|
||||
@@ -288,6 +291,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
"kubernetes_container_name",
|
||||
"x"
|
||||
);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
|
||||
// Open the configuration panel and enable both the Transpose and Dynamic Column toggle buttons
|
||||
|
||||
+8
@@ -95,6 +95,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// Add X and Y axis fields (required for saving panel)
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -347,6 +348,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// Add X and Y axis fields (required for saving panel)
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -457,6 +459,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -465,6 +468,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -637,6 +641,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -644,6 +649,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -802,6 +808,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
// Save panel
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -882,6 +889,7 @@ test.describe("Dashboard Variables - Creation & Scope Restrictions", { tag: ['@d
|
||||
// Save the panel to avoid the discard confirmation dialog
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
|
||||
@@ -991,6 +991,7 @@ test.describe("Dashboard Variables - Dependency Loading", { tag: ['@dashboards',
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "filter");
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -85,6 +86,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -127,6 +129,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
}
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName(`DummyPanel${i + 1}`);
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -138,6 +141,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -283,6 +287,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -344,6 +349,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -356,6 +362,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -468,6 +475,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -546,6 +554,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -651,6 +660,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -663,6 +673,7 @@ test.describe("Dashboard Variables - Panel Level", { tag: ['@dashboards', '@dash
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
|
||||
@@ -140,6 +140,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "filter");
|
||||
// Add filter using varB
|
||||
@@ -219,6 +220,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -230,6 +232,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -294,6 +297,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "filter");
|
||||
// Add filter using the variable
|
||||
@@ -320,6 +324,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel2");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
@@ -399,6 +404,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "filter");
|
||||
// Add filter using the variable
|
||||
@@ -597,6 +603,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "filter");
|
||||
// Add filter using the variable
|
||||
@@ -674,6 +681,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "filter");
|
||||
// Add filter using the variable
|
||||
@@ -699,6 +707,7 @@ test.describe("Dashboard Variables - Refresh Indicators & Panel Reload", { tag:
|
||||
await pm.dashboardCreate.addPanelToExistingDashboard();
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "filter");
|
||||
// Add filter using the variable
|
||||
|
||||
@@ -158,6 +158,7 @@ test.describe("Dashboard Variables - URL Sync & Drilldown", { tag: ['@dashboards
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType("line");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
|
||||
@@ -527,6 +528,7 @@ test.describe("Dashboard Variables - URL Sync & Drilldown", { tag: ['@dashboards
|
||||
// This would typically be in panel settings
|
||||
// For now, verify the concept
|
||||
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_pod_name", "y");
|
||||
await pm.dashboardPanelActions.addPanelName("Panel1");
|
||||
await pm.dashboardPanelActions.savePanel();
|
||||
|
||||
@@ -106,6 +106,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Select stream and breakdown fields
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
@@ -149,6 +150,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Configure the chart
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
@@ -231,6 +233,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Select stream and add fields to chart
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
@@ -273,6 +276,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Select chart type and stream
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_labels_app_kubernetes_io_component",
|
||||
"b"
|
||||
@@ -332,6 +336,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("bar");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -398,6 +403,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
// Select a stream
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -450,6 +456,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -518,6 +525,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Add a panel name and save again
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -550,6 +558,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectChartType("area");
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
|
||||
// Add fields to chart
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
@@ -621,6 +630,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectChartType("area");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
|
||||
// Add a non-required field (B-axis), but skip Y-axis
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_host", "b");
|
||||
@@ -661,6 +671,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -699,8 +710,11 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.dashboardPanelActions.addPanelName(panelName);
|
||||
|
||||
// Configure table chart with custom SQL using camelCase aliases
|
||||
// Configure table chart with custom SQL using camelCase aliases.
|
||||
// Remove both auto-seeded builder fields — this test supplies its own
|
||||
// xAxis1/yAxis1 columns, and a stale y_axis_1 would add an empty column.
|
||||
await pm.chartTypeSelector.removeField("x_axis_1", "x");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.selectChartType("table");
|
||||
|
||||
await pm.chartTypeSelector.setCustomSQL(
|
||||
|
||||
@@ -41,6 +41,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Select stream and fields
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -89,6 +90,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
|
||||
// Select stream and fields
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_image",
|
||||
"y"
|
||||
@@ -141,6 +143,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -207,6 +210,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubernetes_io_psp",
|
||||
"y"
|
||||
@@ -252,6 +256,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_name",
|
||||
"y"
|
||||
@@ -294,6 +299,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
@@ -346,6 +352,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_image",
|
||||
"b"
|
||||
@@ -380,6 +387,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_container_hash",
|
||||
"y"
|
||||
@@ -423,6 +431,7 @@ test.describe("dashboard UI testcases", () => {
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
|
||||
// Add fields to the chart
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(
|
||||
"kubernetes_annotations_kubectl_kubernetes_io_default_container",
|
||||
"y"
|
||||
|
||||
@@ -41,6 +41,7 @@ async function buildPanelWithWideRange(page, pm, panelName, chartType = "area")
|
||||
await pm.chartTypeSelector.selectChartType(chartType);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(MAX_QUERY_STREAM);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_labels_name", "b");
|
||||
|
||||
@@ -203,6 +204,7 @@ test.describe("Dashboard Max Query Range", () => {
|
||||
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(MAX_QUERY_STREAM);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
|
||||
await pm.dashboardPanelActions.applyDashboardBtn();
|
||||
@@ -252,6 +254,7 @@ test.describe("Dashboard Max Query Range", () => {
|
||||
await pm.chartTypeSelector.selectChartType(chartType);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(MAX_QUERY_STREAM);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
|
||||
await waitForDateTimeButtonToBeEnabled(page);
|
||||
@@ -392,6 +395,7 @@ test.describe("Dashboard Max Query Range", () => {
|
||||
// First query tab
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream(MAX_QUERY_STREAM);
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "y");
|
||||
|
||||
// Second query tab
|
||||
|
||||
@@ -69,6 +69,8 @@ async function buildPanel(page, pm, dashboardName, {
|
||||
await pm.chartTypeSelector.selectChartType(chartType);
|
||||
await pm.chartTypeSelector.selectStreamType("logs");
|
||||
await pm.chartTypeSelector.selectStream("e2e_automate");
|
||||
// remove the auto-seeded default y-axis before adding this panel's measure
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(yField, "y");
|
||||
if (breakdownField) {
|
||||
await pm.chartTypeSelector.searchAndAddField(breakdownField, "b");
|
||||
|
||||
@@ -299,6 +299,8 @@ export async function addSimplePanel(pm, panelName, options = {}) {
|
||||
await pm.dashboardCreate.addPanel();
|
||||
await pm.chartTypeSelector.selectChartType(chartType);
|
||||
await pm.chartTypeSelector.selectStream(streamName);
|
||||
// remove the auto-seeded default y-axis before adding this panel's measure
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField(yAxisField, "y");
|
||||
|
||||
// Add filter fields if specified
|
||||
|
||||
@@ -59,6 +59,8 @@ export async function startPanelCreation(page, pm, config) {
|
||||
await pm.chartTypeSelector.selectStream(stream);
|
||||
|
||||
// Add fields for proper chart configuration
|
||||
// remove the auto-seeded default y-axis before adding this panel's measure
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "b");
|
||||
|
||||
@@ -179,6 +181,8 @@ export async function addPanelWithPanelTime(page, pm, config) {
|
||||
await pm.chartTypeSelector.selectStream(stream);
|
||||
|
||||
// Add fields to Y and breakdown axes for proper chart configuration
|
||||
// remove the auto-seeded default y-axis before adding this panel's measure
|
||||
await pm.chartTypeSelector.removeField("y_axis_1", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_container_name", "y");
|
||||
await pm.chartTypeSelector.searchAndAddField("kubernetes_namespace_name", "b");
|
||||
|
||||
|
||||
@@ -1140,6 +1140,9 @@ watch(
|
||||
() => [
|
||||
dashboardPanelData.data.queries[dashboardPanelData.layout.currentQueryIndex]
|
||||
?.fields?.stream,
|
||||
// Rebuild the auto query once the stream schema loads (makeAutoSQLQuery bails
|
||||
// out while groupedFields is empty).
|
||||
dashboardPanelData.meta?.streamFields?.groupedFields?.length,
|
||||
dashboardPanelData.data.queries[dashboardPanelData.layout.currentQueryIndex]
|
||||
?.fields?.x,
|
||||
dashboardPanelData.data.queries[dashboardPanelData.layout.currentQueryIndex]
|
||||
|
||||
@@ -520,24 +520,11 @@ export default defineComponent({
|
||||
});
|
||||
|
||||
const addTab = () => {
|
||||
// addQuery() seeds the new query's default builder fields (and PromQL
|
||||
// sample query) synchronously, so the tab is ready the moment it activates.
|
||||
addQuery();
|
||||
dashboardPanelData.layout.currentQueryIndex =
|
||||
dashboardPanelData.data.queries.length - 1;
|
||||
// For metrics page: when switching from custom to builder in PromQL, set sample query
|
||||
if (
|
||||
dashboardPanelData.data.queryType === "promql" &&
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.stream
|
||||
) {
|
||||
const streamName =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.stream;
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].query = `${streamName}{}`;
|
||||
}
|
||||
};
|
||||
|
||||
const updatePromQLQuery = async (value, event) => {
|
||||
|
||||
@@ -680,7 +680,19 @@ watch(
|
||||
.fields.stream_type === dashboardPanelData.meta.stream.streamResultsType
|
||||
) {
|
||||
try {
|
||||
if (promqlMode.value && dashboardPanelDataPageKey === "metrics") {
|
||||
// On stream change in PromQL mode, reset the query to `${stream}{}`.
|
||||
// Metrics: custom + builder. Add Panel: PromQL custom only (builder
|
||||
// regenerates via DashboardQueryBuilder; SQL is excluded — promql-only block).
|
||||
const promqlQuery =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
];
|
||||
const shouldResetPromqlQuery =
|
||||
promqlMode.value &&
|
||||
(dashboardPanelDataPageKey === "metrics" ||
|
||||
(dashboardPanelDataPageKey === "dashboard" &&
|
||||
promqlQuery?.customQuery));
|
||||
if (shouldResetPromqlQuery) {
|
||||
let parsedQuery = null;
|
||||
try {
|
||||
parsedQuery = parsePromQlQuery(
|
||||
|
||||
@@ -86,6 +86,15 @@ vi.mock("../../../composables/dashboard/useDashboardPanel", () => ({
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock useDefaultPanelFields — the selector only needs applyDefaultPanelFields to
|
||||
// be callable on the Builder toggle; its seeding internals are covered by its own spec.
|
||||
const mockApplyDefaultPanelFields = vi.fn();
|
||||
vi.mock("@/composables/dashboard/useDefaultPanelFields", () => ({
|
||||
default: () => ({
|
||||
applyDefaultPanelFields: mockApplyDefaultPanelFields,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock ConfirmDialog component
|
||||
const ConfirmDialogStub = {
|
||||
template: `
|
||||
|
||||
@@ -92,6 +92,7 @@ import {
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useRouter } from "vue-router";
|
||||
import useDashboardPanelData from "../../../composables/dashboard/useDashboardPanel";
|
||||
import useDefaultPanelFields from "@/composables/dashboard/useDefaultPanelFields";
|
||||
import ConfirmDialog from "../../ConfirmDialog.vue";
|
||||
import { useStore } from "vuex";
|
||||
import OToggleGroup from "@/lib/core/ToggleGroup/OToggleGroup.vue";
|
||||
@@ -121,6 +122,12 @@ export default defineComponent({
|
||||
removeXYFilters,
|
||||
updateXYFieldsForCustomQueryMode,
|
||||
} = useDashboardPanelData(dashboardPanelDataPageKey);
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields(
|
||||
dashboardPanelDataPageKey,
|
||||
);
|
||||
// Pages that re-seed default builder fields on the in-page Builder toggle.
|
||||
// (Entering a builder surface parses on mount, not via this handler.)
|
||||
const SEED_ON_TOGGLE_PAGES = ["dashboard", "metrics", "build", "logs"];
|
||||
const confirmQueryModeChangeDialog = ref(false);
|
||||
const confirmDialogMessage = ref(
|
||||
"Are you sure you want to change the query mode? The data saved for X-Axis, Y-Axis and Filters will be wiped off.",
|
||||
@@ -267,7 +274,9 @@ export default defineComponent({
|
||||
"Are you sure you want to change the query mode? The data saved for X-Axis, Y-Axis and Filters will be wiped off.";
|
||||
}
|
||||
|
||||
dashboardPanelData.data.queries[0].query != ""
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].query != ""
|
||||
? (confirmQueryModeChangeDialog.value = true)
|
||||
: changeToggle();
|
||||
}
|
||||
@@ -279,9 +288,6 @@ export default defineComponent({
|
||||
popupSelectedButtonType.value === "promql" ||
|
||||
popupSelectedButtonType.value === "sql";
|
||||
|
||||
const isSwitchingToBuilder =
|
||||
!isQueryTypeChange && popupSelectedButtonType.value === "builder";
|
||||
|
||||
if (isQueryTypeChange) {
|
||||
selectedButtonQueryType.value = popupSelectedButtonType.value;
|
||||
} else {
|
||||
@@ -304,22 +310,16 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
|
||||
// For metrics page: when switching from custom to builder in PromQL, set sample query
|
||||
if (
|
||||
dashboardPanelDataPageKey === "metrics" &&
|
||||
isSwitchingToBuilder &&
|
||||
dashboardPanelData.data.queryType === "promql" &&
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
]?.fields?.stream
|
||||
) {
|
||||
const streamName =
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].fields.stream;
|
||||
dashboardPanelData.data.queries[
|
||||
dashboardPanelData.layout.currentQueryIndex
|
||||
].query = `${streamName}{}`;
|
||||
// removeXYFilters() above wiped the builder fields; re-seed defaults when
|
||||
// the resulting mode is a builder.
|
||||
const seedQueryIdx = dashboardPanelData.layout.currentQueryIndex;
|
||||
const seedQuery = dashboardPanelData.data.queries[seedQueryIdx];
|
||||
const resultingBuilderMode = !seedQuery?.customQuery;
|
||||
const shouldSeedDefaults =
|
||||
resultingBuilderMode &&
|
||||
SEED_ON_TOGGLE_PAGES.includes(dashboardPanelDataPageKey);
|
||||
if (shouldSeedDefaults) {
|
||||
await applyDefaultPanelFields();
|
||||
}
|
||||
|
||||
// empty the errors
|
||||
|
||||
@@ -140,16 +140,26 @@ describe("useDashboardPanel", () => {
|
||||
panel.addQuery();
|
||||
expect(panel.dashboardPanelData.data.queries).toHaveLength(2);
|
||||
expect(panel.dashboardPanelData.data.queries[1].fields.stream).toBe("stream-a");
|
||||
// New query is seeded synchronously with default builder fields so the tab
|
||||
// is ready the moment it activates (no async race with stream selection).
|
||||
expect(panel.dashboardPanelData.data.queries[1].fields.y).toHaveLength(1);
|
||||
expect(panel.dashboardPanelData.data.queries[1].fields.y[0].functionName).toBe(
|
||||
"count",
|
||||
);
|
||||
|
||||
panel.removeQuery(1);
|
||||
expect(panel.dashboardPanelData.data.queries).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("resets panel data and adds default timestamp field", () => {
|
||||
it("resets panel data and seeds default histogram x + count y fields", () => {
|
||||
const panel = useDashboardPanelData("dashboard-panel-test-2");
|
||||
panel.resetDashboardPanelDataAndAddTimeField();
|
||||
|
||||
expect(addXAxisItemMock).toHaveBeenCalledWith({ name: "_ts" });
|
||||
const fields = panel.dashboardPanelData.data.queries[0].fields;
|
||||
expect(fields.x).toHaveLength(1);
|
||||
expect(fields.x[0].functionName).toBe("histogram");
|
||||
expect(fields.y).toHaveLength(1);
|
||||
expect(fields.y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("turns off VRL toggle when query type changes to promql", async () => {
|
||||
|
||||
@@ -33,6 +33,11 @@ import {
|
||||
} from "@/utils/dashboard/dashboardAutoQueryBuilder";
|
||||
import { usePanelFields } from "@/composables/dashboard/usePanelFields";
|
||||
import { usePanelAggregation } from "@/composables/dashboard/usePanelAggregation";
|
||||
import {
|
||||
DEFAULT_SQL_X_FIELD,
|
||||
DEFAULT_SQL_Y_FIELD_COUNT,
|
||||
buildDefaultBuilderFields,
|
||||
} from "@/utils/dashboard/defaultFields";
|
||||
import {
|
||||
getDefaultDashboardPanelData,
|
||||
getDefaultCustomChartText,
|
||||
@@ -161,6 +166,25 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
weight_fixed: 1,
|
||||
},
|
||||
};
|
||||
// Seed the new query's default builder fields synchronously (mirrors the
|
||||
// first query) so the tab is fully configured the moment it becomes active —
|
||||
// an async seed would race with the user/test selecting a stream next.
|
||||
// PromQL gets the `${stream}{}` sample query; SQL gets chart-type-aware x/y.
|
||||
if (dashboardPanelData.data.queryType === "promql") {
|
||||
if (newQuery.fields.stream) {
|
||||
newQuery.query = `${newQuery.fields.stream}{}`;
|
||||
}
|
||||
} else {
|
||||
const { x, y } = buildDefaultBuilderFields(
|
||||
dashboardPanelData.data.type,
|
||||
newQuery.fields.stream_type,
|
||||
dashboardPanelData.meta?.streamFields?.groupedFields ?? [],
|
||||
newQuery.fields.stream,
|
||||
);
|
||||
newQuery.fields.x = x;
|
||||
newQuery.fields.y = y;
|
||||
}
|
||||
|
||||
dashboardPanelData.data.queries.push(newQuery);
|
||||
// Initialize per-query field cache in meta
|
||||
getQueryFields(dashboardPanelData.data.queries.length - 1);
|
||||
@@ -195,10 +219,16 @@ const useDashboardPanelData = (pageKey: string = "dashboard") => {
|
||||
const resetDashboardPanelDataAndAddTimeField = () => {
|
||||
resetDashboardPanelData();
|
||||
|
||||
// add _timestamp field in x axis as default
|
||||
addXAxisItem({
|
||||
name: store.state.zoConfig.timestamp_column ?? "_timestamp",
|
||||
});
|
||||
// Seed default x (histogram(_timestamp)) and y (count(_timestamp)) from the
|
||||
// shared default-fields builder so a bar chart renders on open — the same
|
||||
// fields applyDefaultPanelFields seeds on stream/builder changes.
|
||||
const currentQueryIndex = dashboardPanelData.layout.currentQueryIndex;
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.x = [
|
||||
DEFAULT_SQL_X_FIELD(),
|
||||
];
|
||||
dashboardPanelData.data.queries[currentQueryIndex].fields.y = [
|
||||
DEFAULT_SQL_Y_FIELD_COUNT(),
|
||||
];
|
||||
};
|
||||
|
||||
// Watch queryType and toggle off VRL functions when switching to PromQL
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
// Copyright 2026 OpenObserve Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { describe, it, expect, beforeEach, vi } from "vitest";
|
||||
|
||||
const { mockUpdateGroupedFields, mockMakeAutoSQLQuery, state } = vi.hoisted(
|
||||
() => ({
|
||||
mockUpdateGroupedFields: vi.fn(),
|
||||
mockMakeAutoSQLQuery: vi.fn(),
|
||||
state: { panel: null as any },
|
||||
}),
|
||||
);
|
||||
|
||||
vi.mock("@/composables/dashboard/useDashboardPanel", () => ({
|
||||
default: () => ({
|
||||
dashboardPanelData: state.panel,
|
||||
updateGroupedFields: mockUpdateGroupedFields,
|
||||
makeAutoSQLQuery: mockMakeAutoSQLQuery,
|
||||
// Mirror the real chart-type axis rules: metric/gauge disallow an x-axis.
|
||||
isAddXAxisNotAllowed: {
|
||||
get value() {
|
||||
const t = state.panel?.data?.type;
|
||||
const xlen =
|
||||
state.panel?.data?.queries?.[0]?.fields?.x?.length ?? 0;
|
||||
if (t === "metric") return xlen >= 0; // metric: x never allowed
|
||||
if (t === "gauge" || t === "pie" || t === "donut") return xlen >= 1;
|
||||
if (t === "table") return false;
|
||||
return xlen >= 1; // bar/line/area/etc.
|
||||
},
|
||||
},
|
||||
isAddYAxisNotAllowed: {
|
||||
get value() {
|
||||
const ylen =
|
||||
state.panel?.data?.queries?.[0]?.fields?.y?.length ?? 0;
|
||||
const t = state.panel?.data?.type;
|
||||
if (["pie", "donut", "gauge", "metric"].includes(t)) return ylen >= 1;
|
||||
return false;
|
||||
},
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
import useDefaultPanelFields from "./useDefaultPanelFields";
|
||||
|
||||
function setPanel({
|
||||
type = "bar",
|
||||
queryType = "sql",
|
||||
stream = "s1",
|
||||
streamType = "logs",
|
||||
query = "",
|
||||
customQuery = true,
|
||||
groupedFields = [] as any[],
|
||||
} = {}) {
|
||||
state.panel = {
|
||||
data: {
|
||||
type,
|
||||
queryType,
|
||||
queries: [
|
||||
{
|
||||
customQuery,
|
||||
query,
|
||||
fields: {
|
||||
stream,
|
||||
stream_type: streamType,
|
||||
x: [],
|
||||
y: [],
|
||||
breakdown: [],
|
||||
filter: {},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
layout: { currentQueryIndex: 0 },
|
||||
meta: { streamFields: { groupedFields } },
|
||||
};
|
||||
}
|
||||
|
||||
const currentQuery = () => state.panel.data.queries[0];
|
||||
|
||||
describe("useDefaultPanelFields", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("PromQL", () => {
|
||||
it("seeds `${stream}{}` and sets builder mode, without touching x/y", async () => {
|
||||
setPanel({ queryType: "promql", stream: "mystream", customQuery: true });
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("metrics");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().query).toBe("mystream{}");
|
||||
expect(currentQuery().customQuery).toBe(false);
|
||||
expect(currentQuery().fields.x).toEqual([]);
|
||||
expect(mockUpdateGroupedFields).not.toHaveBeenCalled();
|
||||
expect(mockMakeAutoSQLQuery).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("leaves the query empty when no stream is selected", async () => {
|
||||
setPanel({ queryType: "promql", stream: "" });
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("metrics");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().query).toBe("");
|
||||
expect(currentQuery().customQuery).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("SQL", () => {
|
||||
it("logs stream: seeds histogram + count, resets breakdown/filter, regenerates", async () => {
|
||||
setPanel({
|
||||
queryType: "sql",
|
||||
stream: "logs1",
|
||||
streamType: "logs",
|
||||
groupedFields: [{ name: "logs1", schema: [{ name: "_timestamp" }] }],
|
||||
});
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(mockUpdateGroupedFields).toHaveBeenCalledTimes(1);
|
||||
expect(currentQuery().fields.x[0].functionName).toBe("histogram");
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("count");
|
||||
expect(currentQuery().fields.breakdown).toEqual([]);
|
||||
expect(currentQuery().fields.filter).toMatchObject({
|
||||
filterType: "group",
|
||||
logicalOperator: "AND",
|
||||
conditions: [],
|
||||
});
|
||||
expect(currentQuery().customQuery).toBe(false);
|
||||
expect(mockMakeAutoSQLQuery).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("metrics stream with a value column: seeds avg(value)", async () => {
|
||||
setPanel({
|
||||
queryType: "sql",
|
||||
stream: "m1",
|
||||
streamType: "metrics",
|
||||
groupedFields: [{ name: "m1", schema: [{ name: "value" }] }],
|
||||
});
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("metrics");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("avg");
|
||||
});
|
||||
|
||||
it("metric chart: seeds y but NOT x (x-axis not allowed for metric)", async () => {
|
||||
setPanel({
|
||||
type: "metric",
|
||||
queryType: "sql",
|
||||
stream: "logs1",
|
||||
streamType: "logs",
|
||||
groupedFields: [{ name: "logs1", schema: [{ name: "_timestamp" }] }],
|
||||
});
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().fields.x).toEqual([]);
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("gauge chart: seeds x and y (gauge allows one x when empty)", async () => {
|
||||
setPanel({
|
||||
type: "gauge",
|
||||
queryType: "sql",
|
||||
stream: "logs1",
|
||||
streamType: "logs",
|
||||
groupedFields: [{ name: "logs1", schema: [{ name: "_timestamp" }] }],
|
||||
});
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().fields.x[0].functionName).toBe("histogram");
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("no stream: seeds x/y but skips schema load and query regeneration", async () => {
|
||||
setPanel({ queryType: "sql", stream: "", streamType: "logs" });
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(mockUpdateGroupedFields).not.toHaveBeenCalled();
|
||||
expect(mockMakeAutoSQLQuery).not.toHaveBeenCalled();
|
||||
expect(currentQuery().fields.x[0].functionName).toBe("histogram");
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("does not reject when updateGroupedFields throws, and falls back to count", async () => {
|
||||
const errSpy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
// empty groupedFields = no schema for the current stream (failed/stale load)
|
||||
setPanel({
|
||||
queryType: "sql",
|
||||
stream: "m1",
|
||||
streamType: "metrics",
|
||||
groupedFields: [],
|
||||
});
|
||||
mockUpdateGroupedFields.mockRejectedValueOnce(new Error("network"));
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
|
||||
await expect(applyDefaultPanelFields()).resolves.toBeUndefined();
|
||||
expect(currentQuery().fields.y[0].functionName).toBe("count");
|
||||
expect(mockMakeAutoSQLQuery).toHaveBeenCalledTimes(1);
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("guards", () => {
|
||||
it("is a no-op for non-cartesian / custom chart types", async () => {
|
||||
setPanel({ type: "custom_chart", customQuery: true });
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().customQuery).toBe(true); // returned before any mutation
|
||||
expect(mockMakeAutoSQLQuery).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("is a no-op for heatmap (measure lives on Z; Y disallows aggregation)", async () => {
|
||||
setPanel({ type: "heatmap", customQuery: true });
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
await applyDefaultPanelFields();
|
||||
|
||||
expect(currentQuery().customQuery).toBe(true); // returned before any mutation
|
||||
expect(currentQuery().fields.x).toEqual([]);
|
||||
expect(currentQuery().fields.y).toEqual([]);
|
||||
expect(mockMakeAutoSQLQuery).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns early (no throw) when the current query is missing", async () => {
|
||||
setPanel();
|
||||
state.panel.data.queries = [];
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("dashboard");
|
||||
|
||||
await expect(applyDefaultPanelFields()).resolves.toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright 2026 OpenObserve Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import useDashboardPanelData from "@/composables/dashboard/useDashboardPanel";
|
||||
import {
|
||||
buildDefaultSqlFields,
|
||||
SKIP_SEED_TYPES,
|
||||
} from "@/utils/dashboard/defaultFields";
|
||||
|
||||
/**
|
||||
* Shared default-field seeding for the Add Panel and Metrics pages (both render
|
||||
* the same PanelEditor). Seeds the current query based on queryType + stream_type:
|
||||
* PromQL -> `${stream}{}`; SQL logs/traces -> count(_timestamp); SQL metrics ->
|
||||
* avg(value) if the stream has a "value" column, else count(_timestamp).
|
||||
*/
|
||||
const useDefaultPanelFields = (pageKey: string = "dashboard") => {
|
||||
const {
|
||||
dashboardPanelData,
|
||||
updateGroupedFields,
|
||||
makeAutoSQLQuery,
|
||||
isAddXAxisNotAllowed,
|
||||
isAddYAxisNotAllowed,
|
||||
} = useDashboardPanelData(pageKey);
|
||||
|
||||
const applyDefaultPanelFields = async () => {
|
||||
const idx = dashboardPanelData.layout.currentQueryIndex;
|
||||
const query = dashboardPanelData.data.queries[idx];
|
||||
if (!query) return;
|
||||
if (SKIP_SEED_TYPES.includes(dashboardPanelData.data.type)) return;
|
||||
|
||||
const queryType = dashboardPanelData.data.queryType;
|
||||
const stream = query.fields?.stream;
|
||||
const streamType = query.fields?.stream_type;
|
||||
|
||||
query.customQuery = false;
|
||||
|
||||
if (queryType === "promql") {
|
||||
if (stream) query.query = `${stream}{}`;
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream) {
|
||||
// updateGroupedFields has no catch of its own; swallow so a failed schema
|
||||
// load can't reject the toggle/watcher.
|
||||
try {
|
||||
await updateGroupedFields();
|
||||
} catch (e) {
|
||||
console.error("useDefaultPanelFields: updateGroupedFields failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
// hasValueColumn is scoped to `stream`, so a missing/stale schema (incl. join
|
||||
// streams) falls back to count(_timestamp).
|
||||
const { x, y } = buildDefaultSqlFields(
|
||||
streamType,
|
||||
dashboardPanelData.meta?.streamFields?.groupedFields ?? [],
|
||||
stream,
|
||||
);
|
||||
|
||||
// Respect chart-type axis rules: metric/gauge etc. don't allow an x-axis, so
|
||||
// only seed x/y where the current chart type permits it (computed from the
|
||||
// now-empty field state after removeXYFilters).
|
||||
query.fields.x = isAddXAxisNotAllowed.value ? [] : x;
|
||||
query.fields.y = isAddYAxisNotAllowed.value ? [] : y;
|
||||
query.fields.breakdown = [];
|
||||
query.fields.filter = {
|
||||
filterType: "group",
|
||||
logicalOperator: "AND",
|
||||
conditions: [],
|
||||
};
|
||||
|
||||
if (stream) await makeAutoSQLQuery();
|
||||
};
|
||||
|
||||
return { applyDefaultPanelFields };
|
||||
};
|
||||
|
||||
export default useDefaultPanelFields;
|
||||
@@ -148,11 +148,7 @@ import AutoRefreshInterval from "@/components/AutoRefreshInterval.vue";
|
||||
import { checkIfConfigChangeRequiredApiCallOrNot } from "@/utils/dashboard/checkConfigChangeApiCall";
|
||||
import { PanelEditor } from "@/components/dashboards/PanelEditor";
|
||||
import { saveMetricsStream, restoreMetricsStream } from "@/utils/streamPersist";
|
||||
import {
|
||||
DEFAULT_METRICS_X_FIELD,
|
||||
DEFAULT_METRICS_Y_FIELD,
|
||||
DEFAULT_METRICS_Y_FIELD_COUNT,
|
||||
} from "@/utils/metrics/constants";
|
||||
import useDefaultPanelFields from "@/composables/dashboard/useDefaultPanelFields";
|
||||
|
||||
const AddToDashboard = defineAsyncComponent(() => {
|
||||
return import("./../metrics/AddToDashboard.vue");
|
||||
@@ -189,9 +185,8 @@ export default defineComponent({
|
||||
resetDashboardPanelData,
|
||||
resetAggregationFunction,
|
||||
validatePanel,
|
||||
updateGroupedFields,
|
||||
makeAutoSQLQuery,
|
||||
} = useDashboardPanelData("metrics");
|
||||
const { applyDefaultPanelFields } = useDefaultPanelFields("metrics");
|
||||
const editMode = ref(false);
|
||||
const selectedDate: any = ref({
|
||||
valueType: "relative",
|
||||
@@ -227,33 +222,6 @@ export default defineComponent({
|
||||
// already resets and re-initialises the state correctly.
|
||||
});
|
||||
|
||||
/** Apply default SQL builder fields for metrics.
|
||||
* Uses avg(value) if the stream has a "value" field, otherwise count(_timestamp). */
|
||||
const applyMetricsDefaults = () => {
|
||||
const query = dashboardPanelData.data.queries[0];
|
||||
query.customQuery = false;
|
||||
query.fields.x = [DEFAULT_METRICS_X_FIELD()];
|
||||
|
||||
// Check if the current stream has a "value" field
|
||||
const streamFields =
|
||||
dashboardPanelData.meta?.streamFields?.groupedFields ?? [];
|
||||
const hasValueField = streamFields.some((stream: any) =>
|
||||
stream?.schema?.some((field: any) => field?.name === "value"),
|
||||
);
|
||||
|
||||
query.fields.y = [
|
||||
hasValueField
|
||||
? DEFAULT_METRICS_Y_FIELD()
|
||||
: DEFAULT_METRICS_Y_FIELD_COUNT(),
|
||||
];
|
||||
query.fields.breakdown = [];
|
||||
query.fields.filter = {
|
||||
filterType: "group",
|
||||
logicalOperator: "AND",
|
||||
conditions: [],
|
||||
};
|
||||
};
|
||||
|
||||
// Initialize state before any child components mount so FieldList.vue sees
|
||||
// stream_type = "metrics" from the start, preventing a spurious
|
||||
// streams?type=logs request and the double stream-list fetch that results
|
||||
@@ -294,6 +262,17 @@ export default defineComponent({
|
||||
// let it call the watchers and then mark the panel config watcher as activated
|
||||
await nextTick();
|
||||
isPanelConfigWatcherActivated = true;
|
||||
|
||||
// Seed the default builder query on initial load (the PromQL builder only
|
||||
// rebuilds on label/operation change, so the bar would otherwise be empty).
|
||||
const initialQuery = dashboardPanelData.data.queries[0];
|
||||
if (
|
||||
initialQuery?.fields?.stream &&
|
||||
!initialQuery.customQuery &&
|
||||
!initialQuery.query
|
||||
) {
|
||||
await applyDefaultPanelFields();
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
@@ -326,84 +305,17 @@ export default defineComponent({
|
||||
);
|
||||
}
|
||||
|
||||
// When stream changes while in SQL builder mode and query is empty,
|
||||
// apply defaults and regenerate query. Skip for custom mode.
|
||||
// Seed the default query when a stream becomes available in builder mode
|
||||
// with an empty query (the !query guard avoids overwriting an existing one).
|
||||
const query = dashboardPanelData.data.queries[0];
|
||||
if (
|
||||
isPanelConfigWatcherActivated &&
|
||||
stream &&
|
||||
oldStream &&
|
||||
stream !== oldStream &&
|
||||
dashboardPanelData.data.queryType === "sql" &&
|
||||
!query?.customQuery &&
|
||||
!query?.query
|
||||
) {
|
||||
await updateGroupedFields();
|
||||
applyMetricsDefaults();
|
||||
await makeAutoSQLQuery();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Handle query type switches on metrics page.
|
||||
// We use nextTick() to ensure this runs AFTER changeToggle's removeXYFilters()
|
||||
// has completed, so the defaults we apply here don't get immediately cleared.
|
||||
// Only applies for builder mode (not custom mode).
|
||||
watch(
|
||||
() => dashboardPanelData.data.queryType,
|
||||
async (newType: string, oldType: string) => {
|
||||
if (!isPanelConfigWatcherActivated) return;
|
||||
|
||||
const query = dashboardPanelData.data.queries[0];
|
||||
const stream = query?.fields?.stream;
|
||||
const isCustomMode = query?.customQuery;
|
||||
|
||||
if (newType === "sql" && oldType === "promql" && !isCustomMode) {
|
||||
// Switching to SQL builder: load stream fields first so applyMetricsDefaults
|
||||
// can check whether the current stream has a "value" field
|
||||
await nextTick();
|
||||
if (stream) {
|
||||
await updateGroupedFields();
|
||||
}
|
||||
applyMetricsDefaults();
|
||||
|
||||
if (stream) {
|
||||
await makeAutoSQLQuery();
|
||||
}
|
||||
} else if (newType === "promql" && oldType === "sql" && !isCustomMode) {
|
||||
// Switching to PromQL builder: set default builder query (streamName{})
|
||||
await nextTick();
|
||||
if (stream) {
|
||||
query.query = `${stream}{}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// When switching from custom to builder mode, apply defaults.
|
||||
// changeToggle's removeXYFilters() wipes the builder fields, so we
|
||||
// always need to re-apply defaults regardless of whether query text is empty.
|
||||
watch(
|
||||
() => dashboardPanelData.data.queries[0]?.customQuery,
|
||||
async (isCustom: boolean, wasCustom: boolean) => {
|
||||
if (!isPanelConfigWatcherActivated) return;
|
||||
// Only act when switching from custom (true) to builder (false)
|
||||
if (wasCustom && !isCustom) {
|
||||
await nextTick();
|
||||
const query = dashboardPanelData.data.queries[0];
|
||||
const stream = query?.fields?.stream;
|
||||
|
||||
if (dashboardPanelData.data.queryType === "sql") {
|
||||
if (stream) {
|
||||
await updateGroupedFields();
|
||||
}
|
||||
applyMetricsDefaults();
|
||||
if (stream) {
|
||||
await makeAutoSQLQuery();
|
||||
}
|
||||
} else if (dashboardPanelData.data.queryType === "promql" && stream) {
|
||||
query.query = `${stream}{}`;
|
||||
}
|
||||
await applyDefaultPanelFields();
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
// Copyright 2026 OpenObserve Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { describe, it, expect } from "vitest";
|
||||
import {
|
||||
DEFAULT_SQL_X_FIELD,
|
||||
DEFAULT_SQL_Y_FIELD_COUNT,
|
||||
DEFAULT_SQL_Y_FIELD_VALUE,
|
||||
hasValueColumn,
|
||||
buildDefaultSqlFields,
|
||||
buildDefaultBuilderFields,
|
||||
SKIP_SEED_TYPES,
|
||||
} from "./defaultFields";
|
||||
|
||||
describe("defaultFields", () => {
|
||||
describe("field factories", () => {
|
||||
it("DEFAULT_SQL_X_FIELD is histogram(_timestamp) on x_axis_1", () => {
|
||||
const x = DEFAULT_SQL_X_FIELD();
|
||||
expect(x).toMatchObject({
|
||||
alias: "x_axis_1",
|
||||
column: "_timestamp",
|
||||
functionName: "histogram",
|
||||
type: "build",
|
||||
sortBy: "ASC",
|
||||
});
|
||||
expect(x.args[0]).toEqual({
|
||||
type: "field",
|
||||
value: { field: "_timestamp" },
|
||||
});
|
||||
});
|
||||
|
||||
it("DEFAULT_SQL_Y_FIELD_COUNT is count(_timestamp) on y_axis_1", () => {
|
||||
const y = DEFAULT_SQL_Y_FIELD_COUNT();
|
||||
expect(y).toMatchObject({
|
||||
alias: "y_axis_1",
|
||||
column: "_timestamp",
|
||||
functionName: "count",
|
||||
});
|
||||
});
|
||||
|
||||
it("DEFAULT_SQL_Y_FIELD_VALUE is avg(value) on y_axis_1", () => {
|
||||
const y = DEFAULT_SQL_Y_FIELD_VALUE();
|
||||
expect(y).toMatchObject({
|
||||
alias: "y_axis_1",
|
||||
column: "value",
|
||||
functionName: "avg",
|
||||
});
|
||||
});
|
||||
|
||||
it("returns a fresh object each call (factory, not shared ref)", () => {
|
||||
const a = DEFAULT_SQL_X_FIELD();
|
||||
const b = DEFAULT_SQL_X_FIELD();
|
||||
expect(a).not.toBe(b);
|
||||
expect(a.args).not.toBe(b.args);
|
||||
});
|
||||
});
|
||||
|
||||
describe("hasValueColumn", () => {
|
||||
const withValue = { name: "m1", schema: [{ name: "value" }, { name: "le" }] };
|
||||
const noValue = { name: "logs", schema: [{ name: "_timestamp" }] };
|
||||
|
||||
it("returns false for empty / nullish input", () => {
|
||||
expect(hasValueColumn([])).toBe(false);
|
||||
expect(hasValueColumn(undefined as any)).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when any stream has a value column (no streamName)", () => {
|
||||
expect(hasValueColumn([noValue, withValue])).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when no stream has a value column", () => {
|
||||
expect(hasValueColumn([noValue])).toBe(false);
|
||||
});
|
||||
|
||||
it("scopes the check to the named stream only", () => {
|
||||
// join: main stream has no value, joined stream does
|
||||
const grouped = [noValue, withValue];
|
||||
expect(hasValueColumn(grouped, "logs")).toBe(false);
|
||||
expect(hasValueColumn(grouped, "m1")).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when the named stream is absent", () => {
|
||||
expect(hasValueColumn([withValue], "missing")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildDefaultSqlFields", () => {
|
||||
const metricWithValue = [{ name: "m1", schema: [{ name: "value" }] }];
|
||||
const logsSchema = [{ name: "logs", schema: [{ name: "_timestamp" }] }];
|
||||
|
||||
it("logs -> histogram(_timestamp) + count(_timestamp)", () => {
|
||||
const { x, y } = buildDefaultSqlFields("logs", logsSchema, "logs");
|
||||
expect(x[0].functionName).toBe("histogram");
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("traces -> count(_timestamp) even if a value column exists", () => {
|
||||
const traces = [{ name: "t1", schema: [{ name: "value" }] }];
|
||||
const { y } = buildDefaultSqlFields("traces", traces, "t1");
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("metrics with value column -> avg(value)", () => {
|
||||
const { y } = buildDefaultSqlFields("metrics", metricWithValue, "m1");
|
||||
expect(y[0].functionName).toBe("avg");
|
||||
expect(y[0].column).toBe("value");
|
||||
});
|
||||
|
||||
it("metrics without value column -> count(_timestamp)", () => {
|
||||
const { y } = buildDefaultSqlFields("metrics", logsSchema, "logs");
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("metrics: value column on a different (join) stream -> count for the main stream", () => {
|
||||
const grouped = [
|
||||
{ name: "main", schema: [{ name: "_timestamp" }] },
|
||||
{ name: "joined", schema: [{ name: "value" }] },
|
||||
];
|
||||
const { y } = buildDefaultSqlFields("metrics", grouped, "main");
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("always seeds exactly one x and one y field", () => {
|
||||
const { x, y } = buildDefaultSqlFields("logs", logsSchema, "logs");
|
||||
expect(x).toHaveLength(1);
|
||||
expect(y).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildDefaultBuilderFields", () => {
|
||||
const logsSchema = [{ name: "logs", schema: [{ name: "_timestamp" }] }];
|
||||
|
||||
it("cartesian chart (bar): seeds histogram x + count y", () => {
|
||||
const { x, y } = buildDefaultBuilderFields("bar", "logs", logsSchema, "logs");
|
||||
expect(x).toHaveLength(1);
|
||||
expect(x[0].functionName).toBe("histogram");
|
||||
expect(y).toHaveLength(1);
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it("metric: seeds y only (no x-axis)", () => {
|
||||
const { x, y } = buildDefaultBuilderFields("metric", "logs", logsSchema, "logs");
|
||||
expect(x).toHaveLength(0);
|
||||
expect(y).toHaveLength(1);
|
||||
expect(y[0].functionName).toBe("count");
|
||||
});
|
||||
|
||||
it.each(SKIP_SEED_TYPES)("%s: seeds nothing (self-driven builder)", (type) => {
|
||||
const { x, y } = buildDefaultBuilderFields(type, "logs", logsSchema, "logs");
|
||||
expect(x).toHaveLength(0);
|
||||
expect(y).toHaveLength(0);
|
||||
});
|
||||
|
||||
it("metrics stream with value column: seeds avg(value) y", () => {
|
||||
const grouped = [{ name: "m1", schema: [{ name: "value" }] }];
|
||||
const { y } = buildDefaultBuilderFields("bar", "metrics", grouped, "m1");
|
||||
expect(y[0].functionName).toBe("avg");
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,124 @@
|
||||
// Copyright 2026 OpenObserve Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// Default builder fields shared by the Add Panel and Metrics pages.
|
||||
|
||||
/** Default x-axis: histogram(_timestamp). */
|
||||
export const DEFAULT_SQL_X_FIELD = () => ({
|
||||
label: "_timestamp",
|
||||
alias: "x_axis_1",
|
||||
column: "_timestamp",
|
||||
color: null,
|
||||
type: "build",
|
||||
functionName: "histogram",
|
||||
args: [
|
||||
{ type: "field", value: { field: "_timestamp" } },
|
||||
{ type: "histogramInterval", value: null },
|
||||
],
|
||||
sortBy: "ASC",
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
|
||||
/** Default y-axis for logs/traces (and metrics without a "value" column): count(_timestamp). */
|
||||
export const DEFAULT_SQL_Y_FIELD_COUNT = () => ({
|
||||
label: "_timestamp",
|
||||
alias: "y_axis_1",
|
||||
column: "_timestamp",
|
||||
color: "#5960b2",
|
||||
type: "build",
|
||||
functionName: "count",
|
||||
args: [{ type: "field", value: { field: "_timestamp" } }],
|
||||
sortBy: null,
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
|
||||
/** Metrics-only y-axis when the stream has a "value" column: avg(value). */
|
||||
export const DEFAULT_SQL_Y_FIELD_VALUE = () => ({
|
||||
label: "value",
|
||||
alias: "y_axis_1",
|
||||
column: "value",
|
||||
color: "#5960b2",
|
||||
type: "build",
|
||||
functionName: "avg",
|
||||
args: [{ type: "field", value: { field: "value" } }],
|
||||
sortBy: null,
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
|
||||
/**
|
||||
* True if a stream exposes a "value" column. When `streamName` is given, only
|
||||
* that stream is checked (groupedFields also holds joined streams for SQL joins).
|
||||
*/
|
||||
export const hasValueColumn = (
|
||||
groupedFields: any[],
|
||||
streamName?: string,
|
||||
): boolean => {
|
||||
const streams = streamName
|
||||
? (groupedFields ?? []).filter((stream: any) => stream?.name === streamName)
|
||||
: (groupedFields ?? []);
|
||||
return streams.some((stream: any) =>
|
||||
stream?.schema?.some((field: any) => field?.name === "value"),
|
||||
);
|
||||
};
|
||||
|
||||
/** Default x/y for SQL builder mode; `streamName` scopes the value-column check. */
|
||||
export const buildDefaultSqlFields = (
|
||||
streamType: string,
|
||||
groupedFields: any[],
|
||||
streamName?: string,
|
||||
): { x: any[]; y: any[] } => {
|
||||
const useValueMeasure =
|
||||
streamType === "metrics" && hasValueColumn(groupedFields, streamName);
|
||||
|
||||
return {
|
||||
x: [DEFAULT_SQL_X_FIELD()],
|
||||
y: [useValueMeasure ? DEFAULT_SQL_Y_FIELD_VALUE() : DEFAULT_SQL_Y_FIELD_COUNT()],
|
||||
};
|
||||
};
|
||||
|
||||
// Chart types that drive their own builder and must not get the cartesian x/y seed.
|
||||
// heatmap is included because its measure lives on the Z/value axis — its Y axis is
|
||||
// a dimension that disallows aggregation, so a count(_timestamp) Y seed is invalid.
|
||||
export const SKIP_SEED_TYPES = [
|
||||
"geomap",
|
||||
"sankey",
|
||||
"maps",
|
||||
"custom_chart",
|
||||
"html",
|
||||
"markdown",
|
||||
"heatmap",
|
||||
];
|
||||
|
||||
/**
|
||||
* Chart-type-aware default builder fields, computed synchronously from the
|
||||
* already-loaded stream schema (no network). Mirrors applyDefaultPanelFields'
|
||||
* axis rules: self-driven builders get nothing, metric gets a measure (y) but no
|
||||
* x-axis, everything else gets the cartesian histogram-x + count/avg-y seed.
|
||||
*/
|
||||
export const buildDefaultBuilderFields = (
|
||||
chartType: string,
|
||||
streamType: string,
|
||||
groupedFields: any[],
|
||||
streamName?: string,
|
||||
): { x: any[]; y: any[] } => {
|
||||
if (SKIP_SEED_TYPES.includes(chartType)) return { x: [], y: [] };
|
||||
const { x, y } = buildDefaultSqlFields(streamType, groupedFields, streamName);
|
||||
// metric has no x-axis — it renders a single measure.
|
||||
if (chartType === "metric") return { x: [], y };
|
||||
return { x, y };
|
||||
};
|
||||
@@ -1,59 +0,0 @@
|
||||
// Copyright 2026 OpenObserve Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/** Default x-axis field for metrics builder: histogram(_timestamp) */
|
||||
export const DEFAULT_METRICS_X_FIELD = () => ({
|
||||
label: "_timestamp",
|
||||
alias: "x_axis_1",
|
||||
column: "_timestamp",
|
||||
color: null,
|
||||
type: "build",
|
||||
functionName: "histogram",
|
||||
args: [
|
||||
{ type: "field", value: { field: "_timestamp" } },
|
||||
{ type: "histogramInterval", value: null },
|
||||
],
|
||||
sortBy: "ASC",
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
|
||||
/** Default y-axis field for metrics builder: avg(value) */
|
||||
export const DEFAULT_METRICS_Y_FIELD = () => ({
|
||||
label: "value",
|
||||
alias: "y_axis_1",
|
||||
column: "value",
|
||||
color: "#5960b2",
|
||||
type: "build",
|
||||
functionName: "avg",
|
||||
args: [{ type: "field", value: { field: "value" } }],
|
||||
sortBy: null,
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
|
||||
/** Fallback y-axis field for streams without a "value" column: count(_timestamp) */
|
||||
export const DEFAULT_METRICS_Y_FIELD_COUNT = () => ({
|
||||
label: "_timestamp",
|
||||
alias: "y_axis_1",
|
||||
column: "_timestamp",
|
||||
color: "#5960b2",
|
||||
type: "build",
|
||||
functionName: "count",
|
||||
args: [{ type: "field", value: { field: "_timestamp" } }],
|
||||
sortBy: null,
|
||||
isDerived: false,
|
||||
havingConditions: [],
|
||||
});
|
||||
Reference in New Issue
Block a user