From c65704895eeaf5fca3e53933515cbd206f775f2c Mon Sep 17 00:00:00 2001 From: Sergej-Vlasov <37613182+Sergej-Vlasov@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:11:35 +0300 Subject: [PATCH] Repeats: Add E2E tests for custom grid repeats (#110884) * add e2e test for custom grid repeats * update codeowners file * adjust embedded panel test to account for different base url * replace waitFor * run bookmark e2e consecutively --- .github/CODEOWNERS | 1 + .../dashboards-repeats-custom-grid.spec.ts | 500 ++++++++++++++++++ .../dashboards/TestV2Dashboard.json | 79 ++- .../dashboards/V2DashWithRepeats.json | 496 +++++++++++++++++ .../various-suite/bookmarks.spec.ts | 3 + 5 files changed, 1078 insertions(+), 1 deletion(-) create mode 100644 e2e-playwright/dashboard-new-layouts/dashboards-repeats-custom-grid.spec.ts create mode 100644 e2e-playwright/dashboards/V2DashWithRepeats.json diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ccc3f1d103f..7fd2901c580 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -426,6 +426,7 @@ /e2e-playwright/dashboards/PanelSandboxDashboard.json @grafana/plugins-platform-frontend /e2e-playwright/dashboards/TestDashboard.json @grafana/dashboards-squad @grafana/grafana-search-navigate-organise /e2e-playwright/dashboards/TestV2Dashboard.json @grafana/dashboards-squad +/e2e-playwright/dashboards/V2DashWithRepeats.json @grafana/dashboards-squad /e2e-playwright/dashboards-suite/adhoc-filter-from-panel.spec.ts @grafana/datapro /e2e-playwright/dashboards-suite/dashboard-browse-nested.spec.ts @grafana/grafana-search-navigate-organise /e2e-playwright/dashboards-suite/dashboard-browse.spec.ts @grafana/grafana-search-navigate-organise diff --git a/e2e-playwright/dashboard-new-layouts/dashboards-repeats-custom-grid.spec.ts b/e2e-playwright/dashboard-new-layouts/dashboards-repeats-custom-grid.spec.ts new file mode 100644 index 00000000000..4e12c03bc34 --- /dev/null +++ b/e2e-playwright/dashboard-new-layouts/dashboards-repeats-custom-grid.spec.ts @@ -0,0 +1,500 @@ +import { Page } from 'playwright-core'; + +import { test, expect, E2ESelectorGroups, DashboardPage } from '@grafana/plugin-e2e'; + +import testV2Dashboard from '../dashboards/TestV2Dashboard.json'; +import testV2DashWithRepeats from '../dashboards/V2DashWithRepeats.json'; + +const repeatTitleBase = 'repeat - '; +const newTitleBase = 'edited rep - '; +const repeatOptions = [1, 2, 3, 4]; + +test.use({ + featureToggles: { + kubernetesDashboards: true, + dashboardNewLayouts: true, + groupByVariable: true, + }, +}); + +test.use({ + viewport: { width: 1920, height: 1080 }, +}); + +test.describe( + 'Repeats - Dashboard custom grid', + { + tag: ['@dashboards'], + }, + () => { + test('can enable repeats', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard(page, selectors, 'Custom grid repeats - add repeats'); + + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + + await dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title('New panel')).first().click(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')) + .fill(`${repeatTitleBase}$c1`); + + const repeatOptionsGroup = dashboardPage.getByGrafanaSelector( + selectors.components.OptionsGroup.group('repeat-options') + ); + // expand repeat options dropdown + await repeatOptionsGroup.getByRole('button').first().click(); + // find repeat variable dropdown + await repeatOptionsGroup.getByRole('combobox').click(); + await page.getByRole('option', { name: 'c1' }).click(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, repeatTitleBase, repeatOptions); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, repeatTitleBase, repeatOptions); + }); + + test('can update repeats with variable change', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - update on variable change', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage + .getByGrafanaSelector( + selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts(repeatOptions.join(',')) + ) + .click(); + + // deselect last variable option + await dashboardPage + .getByGrafanaSelector( + selectors.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts(`${repeatOptions.at(-1)}`) + ) + .click(); + await page.locator('body').click({ position: { x: 0, y: 0 } }); // blur select + + // verify that repeats are present for first 3 values + await checkRepeatedPanelTitles(dashboardPage, selectors, repeatTitleBase, repeatOptions.slice(0, -1)); + + // verify there is no repeat with last value + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ) + ).toBeHidden(); + }); + test('can update repeats in edit pane', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - update through edit pane', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + + // select first/original repeat panel to activate edit pane + await dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`)) + .click(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')) + .fill(`${newTitleBase}$c1`); + await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')).blur(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + }); + + test('can update repeats in panel editor', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - update through panel editor', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + + // selecting last repeat + const panel = dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ); + await panel.hover(); + await page.keyboard.press('e'); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.DashboardEditPaneSplitter.primaryBody) + ).toBeHidden(); // verifying that panel editor loaded + + // verify original repeat panel is loaded + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeVisible(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')) + .fill(`${newTitleBase}$c1`); + await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')).blur(); + + // playwright too fast, verifying JSON diff that changes landed + await verifyChanges(dashboardPage, page, selectors, newTitleBase); + + // verify panel title change in panel editor UI + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${newTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeVisible(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton) + .click(); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.DashboardEditPaneSplitter.primaryBody) + ).toBeVisible(); // verifying that dashboard loaded + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + }); + + test('can update repeats in panel editor when loaded directly', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - update through directly loaded panel editor', + JSON.stringify(testV2DashWithRepeats) + ); + + // loading directly into panel editor + await page.goto(`${page.url()}&editPanel=1`); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.DashboardEditPaneSplitter.primaryBody) + ).toBeHidden(); // verifying that panel editor loaded + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeVisible(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')) + .fill(`${newTitleBase}$c1`); + + await dashboardPage.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldInput('Title')).blur(); + + // playwright too fast, verifying JSON diff that changes landed + await verifyChanges(dashboardPage, page, selectors, newTitleBase); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${newTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeVisible(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton) + .click(); + + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.DashboardEditPaneSplitter.primaryBody) + ).toBeVisible(); // verifying that dashboard loaded + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + await checkRepeatedPanelTitles(dashboardPage, selectors, newTitleBase, repeatOptions); + }); + test('can move repeated panels', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - move repeated panels', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + + await movePanel(dashboardPage, selectors, `${repeatTitleBase}${repeatOptions.at(0)}`, 'New panel'); + + // verify move by panel title order + expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).first()).toHaveText( + 'New panel' + ); + expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).last()).toHaveText( + `${repeatTitleBase}${repeatOptions.at(-1)}` + ); + + // verify move by panel position + let repeatedPanel = await getPanelPosition(dashboardPage, selectors, `${repeatTitleBase}${repeatOptions.at(0)}`); + let normalPanel = await getPanelPosition(dashboardPage, selectors, 'New panel'); + expect(normalPanel?.y).toBeLessThan(repeatedPanel?.y || 0); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + const repeatedPanel2 = await getPanelPosition( + dashboardPage, + selectors, + `${repeatTitleBase}${repeatOptions.at(0)}` + ); + + const normalPanel2 = await getPanelPosition(dashboardPage, selectors, 'New panel'); + + expect(normalPanel2?.y).toBeLessThan(repeatedPanel2?.y || 0); + expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).first()).toHaveText( + 'New panel' + ); + expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).last()).toHaveText( + `${repeatTitleBase}${repeatOptions.at(-1)}` + ); + }); + test('can view repeated panel', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - move repeated panels', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`)) + .hover(); + await page.keyboard.press('v'); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeHidden(); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ) + ).toBeVisible(); + + const repeatedPanelUrl = page.url(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton) + .click(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`)) + .hover(); + await page.keyboard.press('v'); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ) + ).toBeHidden(); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`) + ) + ).toBeVisible(); + + // load view panel directly + await page.goto(repeatedPanelUrl); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ) + ).toBeVisible(); + }); + + test('can view embedded repeated panel', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - view embedded repeated panel', + JSON.stringify(testV2DashWithRepeats) + ); + + await dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`)) + .hover(); + await page.keyboard.press('p+e'); + + // extracting embedded panel url from UI + const textAreaValue = await page.getByTestId('share-embed-html').evaluate((el) => el.textContent); + const srcRegex = /src="([^"]*)"/; + let soloPanelUrl = textAreaValue.match(srcRegex)?.[1]; + + expect(soloPanelUrl).toBeDefined(); + + // adjust base url (different each time in CI) + const currentUrl = page.url(); + const baseUrlRegex = /^http:\/\/[^/:]+:3001\//; + const baseUrl = currentUrl.match(baseUrlRegex)?.[0]; + soloPanelUrl = soloPanelUrl!.replace(baseUrlRegex, baseUrl!); + + page.goto(soloPanelUrl!); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(-1)}`) + ) + ).toBeVisible(); + }); + test('can remove repeats', async ({ dashboardPage, selectors, page }) => { + await importTestDashboard( + page, + selectors, + 'Custom grid repeats - remove repeats', + JSON.stringify(testV2DashWithRepeats) + ); + + // verify 6 panels are present (4 repeats and 2 normal) + expect( + await dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).all() + ).toHaveLength(6); + + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click(); + + await dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.at(0)}`)) + .click(); + + const repeatOptionsGroup = dashboardPage.getByGrafanaSelector( + selectors.components.OptionsGroup.group('repeat-options') + ); + // expand repeat options dropdown + await repeatOptionsGroup.getByRole('button').first().click(); + // find repeat variable dropdown + await repeatOptionsGroup.getByRole('combobox').first().click(); + await page.getByRole('option', { name: 'Disable repeating' }).click(); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.join(' + ')}`) + ) + ).toBeVisible(); + + // verify only 3 panels are present + expect( + await dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).all() + ).toHaveLength(3); + + await saveDashboard(dashboardPage, selectors); + await page.reload(); + + await expect( + dashboardPage.getByGrafanaSelector( + selectors.components.Panels.Panel.title(`${repeatTitleBase}${repeatOptions.join(' + ')}`) + ) + ).toBeVisible(); + + expect( + await dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer).all() + ).toHaveLength(3); + }); + } +); + +async function importTestDashboard(page: Page, selectors: E2ESelectorGroups, title: string, dashInput?: string) { + await page.goto(selectors.pages.ImportDashboard.url); + await page + .getByTestId(selectors.components.DashboardImportPage.textarea) + .fill(dashInput || JSON.stringify(testV2Dashboard)); + await page.getByTestId(selectors.components.DashboardImportPage.submit).click(); + await page.getByTestId(selectors.components.ImportDashboardForm.name).fill(title); + await page.getByTestId(selectors.components.DataSourcePicker.inputV2).click(); + await page.locator('div[data-testid="data-source-card"]').first().click(); + await page.getByTestId(selectors.components.ImportDashboardForm.submit).click(); + const undockMenuButton = page.locator('[aria-label="Undock menu"]'); + const undockMenuVisible = await undockMenuButton.isVisible(); + if (undockMenuVisible) { + undockMenuButton.click(); + } + + await expect(page.locator('[data-testid="uplot-main-div"]').first()).toBeVisible(); +} + +async function saveDashboard(dashboardPage: DashboardPage, selectors: E2ESelectorGroups) { + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.saveButton).click(); + await dashboardPage.getByGrafanaSelector(selectors.components.Drawer.DashboardSaveDrawer.saveButton).click(); +} + +async function checkRepeatedPanelTitles( + dashboardPage: DashboardPage, + selectors: E2ESelectorGroups, + title: string, + options: Array +) { + for (const option of options) { + await expect( + dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title(`${title}${option}`)) + ).toBeVisible(); + } +} + +async function movePanel( + dashboardPage: DashboardPage, + selectors: E2ESelectorGroups, + sourcePanel: string | RegExp, + targetPanel: string | RegExp +) { + // Get target panel position + const targetPanelElement = dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer) + .filter({ hasText: targetPanel }) + .first(); + + // Get source panel element + const sourcePanelElement = dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer) + .filter({ hasText: sourcePanel }); + + // Perform drag and drop + await sourcePanelElement.dragTo(targetPanelElement); +} + +async function getPanelPosition( + dashboardPage: DashboardPage, + selectors: E2ESelectorGroups, + panelTitle: string | RegExp +) { + const panel = dashboardPage + .getByGrafanaSelector(selectors.components.Panels.Panel.headerContainer) + .filter({ hasText: panelTitle }) + .first(); + const boundingBox = await panel.boundingBox(); + return boundingBox; +} + +async function verifyChanges( + dashboardPage: DashboardPage, + page: Page, + selectors: E2ESelectorGroups, + changeText: string +) { + await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.saveButton).click(); + await dashboardPage.getByGrafanaSelector(selectors.components.Tab.title('Changes')).click(); + await expect(page.getByText('Full JSON diff').locator('..')).toContainText(changeText); + await dashboardPage.getByGrafanaSelector(selectors.components.Drawer.General.close).click(); +} diff --git a/e2e-playwright/dashboards/TestV2Dashboard.json b/e2e-playwright/dashboards/TestV2Dashboard.json index e4b81d82bf4..39629595e93 100644 --- a/e2e-playwright/dashboards/TestV2Dashboard.json +++ b/e2e-playwright/dashboards/TestV2Dashboard.json @@ -413,7 +413,84 @@ "to": "now" }, "title": "TEST!!!!", - "variables": [] + "variables": [ + { + "kind": "CustomVariable", + "spec": { + "allowCustomValue": true, + "current": { + "text": ["1", "2", "3", "4"], + "value": ["1", "2", "3", "4"] + }, + "hide": "dontHide", + "includeAll": true, + "multi": true, + "name": "c1", + "options": [ + { + "selected": true, + "text": "1", + "value": "1" + }, + { + "selected": true, + "text": "2", + "value": "2" + }, + { + "selected": true, + "text": "3", + "value": "3" + }, + { + "selected": true, + "text": "4", + "value": "4" + } + ], + "query": "1,2,3,4", + "skipUrlSync": false + } + }, + { + "kind": "CustomVariable", + "spec": { + "allowCustomValue": true, + "current": { + "text": ["A", "B", "C", "D"], + "value": ["A", "B", "C", "D"] + }, + "hide": "dontHide", + "includeAll": true, + "multi": true, + "name": "c2", + "options": [ + { + "selected": true, + "text": "A", + "value": "A" + }, + { + "selected": true, + "text": "B", + "value": "B" + }, + { + "selected": true, + "text": "C", + "value": "C" + }, + { + "selected": true, + "text": "D", + "value": "D" + } + ], + "query": "A,B,C,D", + "skipUrlSync": false + } + } + ] }, "status": {} } diff --git a/e2e-playwright/dashboards/V2DashWithRepeats.json b/e2e-playwright/dashboards/V2DashWithRepeats.json new file mode 100644 index 00000000000..fc4a65bad7e --- /dev/null +++ b/e2e-playwright/dashboards/V2DashWithRepeats.json @@ -0,0 +1,496 @@ +{ + "apiVersion": "dashboard.grafana.app/v2beta1", + "kind": "Dashboard", + "metadata": { + "name": "adbb8vn", + "namespace": "default", + "uid": "HfsxD1uoxnIHuobmUUQE0QdGf44ZRuXYcllg0DT3AaUX", + "resourceVersion": "2", + "generation": 2, + "creationTimestamp": "2025-09-09T07:20:09Z", + "labels": {}, + "annotations": {} + }, + "spec": { + "annotations": [], + "cursorSync": "Off", + "description": "", + "editable": true, + "elements": { + "panel-1": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "PD8C576611E62080A" + }, + "group": "grafana-testdata-datasource", + "kind": "DataQuery", + "spec": {}, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "", + "id": 1, + "links": [], + "title": "repeat - $c1", + "vizConfig": { + "group": "timeseries", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + } + }, + "version": "12.2.0-pre" + } + } + }, + "panel-2": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "PD8C576611E62080A" + }, + "group": "grafana-testdata-datasource", + "kind": "DataQuery", + "spec": { + "scenarioId": "random_walk", + "seriesCount": 1 + }, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "", + "id": 2, + "links": [], + "title": "New panel", + "vizConfig": { + "group": "timeseries", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + } + }, + "version": "12.2.0-pre" + } + } + }, + "panel-3": { + "kind": "Panel", + "spec": { + "data": { + "kind": "QueryGroup", + "spec": { + "queries": [ + { + "kind": "PanelQuery", + "spec": { + "hidden": false, + "query": { + "datasource": { + "name": "PD8C576611E62080A" + }, + "group": "grafana-testdata-datasource", + "kind": "DataQuery", + "spec": {}, + "version": "v0" + }, + "refId": "A" + } + } + ], + "queryOptions": {}, + "transformations": [] + } + }, + "description": "", + "id": 3, + "links": [], + "title": "New panel", + "vizConfig": { + "group": "timeseries", + "kind": "VizConfig", + "spec": { + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "barWidthFactor": 0.6, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "showValues": false, + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": 0 + }, + { + "color": "red", + "value": 80 + } + ] + } + }, + "overrides": [] + }, + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "hideZeros": false, + "mode": "single", + "sort": "none" + } + } + }, + "version": "12.2.0-pre" + } + } + } + }, + "layout": { + "kind": "GridLayout", + "spec": { + "items": [ + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-1" + }, + "height": 8, + "repeat": { + "direction": "h", + "mode": "variable", + "value": "c1" + }, + "width": 24, + "x": 0, + "y": 0 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-2" + }, + "height": 8, + "width": 12, + "x": 0, + "y": 8 + } + }, + { + "kind": "GridLayoutItem", + "spec": { + "element": { + "kind": "ElementReference", + "name": "panel-3" + }, + "height": 8, + "width": 12, + "x": 12, + "y": 8 + } + } + ] + } + }, + "links": [], + "liveNow": false, + "preload": false, + "tags": [], + "timeSettings": { + "autoRefresh": "", + "autoRefreshIntervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], + "fiscalYearStartMonth": 0, + "from": "now-6h", + "hideTimepicker": false, + "timezone": "browser", + "to": "now" + }, + "title": "TEST!!!!2", + "variables": [ + { + "kind": "CustomVariable", + "spec": { + "allowCustomValue": true, + "current": { + "text": ["1", "2", "3", "4"], + "value": ["1", "2", "3", "4"] + }, + "hide": "dontHide", + "includeAll": true, + "multi": true, + "name": "c1", + "options": [ + { + "selected": true, + "text": "1", + "value": "1" + }, + { + "selected": true, + "text": "2", + "value": "2" + }, + { + "selected": true, + "text": "3", + "value": "3" + }, + { + "selected": true, + "text": "4", + "value": "4" + } + ], + "query": "1,2,3,4", + "skipUrlSync": false + } + }, + { + "kind": "CustomVariable", + "spec": { + "allowCustomValue": true, + "current": { + "text": ["A", "B", "C", "D"], + "value": ["A", "B", "C", "D"] + }, + "hide": "dontHide", + "includeAll": true, + "multi": true, + "name": "c2", + "options": [ + { + "selected": true, + "text": "A", + "value": "A" + }, + { + "selected": true, + "text": "B", + "value": "B" + }, + { + "selected": true, + "text": "C", + "value": "C" + }, + { + "selected": true, + "text": "D", + "value": "D" + } + ], + "query": "A,B,C,D", + "skipUrlSync": false + } + } + ] + }, + "status": {} +} diff --git a/e2e-playwright/various-suite/bookmarks.spec.ts b/e2e-playwright/various-suite/bookmarks.spec.ts index 9c67884ea7e..e1dfcd4ca73 100644 --- a/e2e-playwright/various-suite/bookmarks.spec.ts +++ b/e2e-playwright/various-suite/bookmarks.spec.ts @@ -6,6 +6,9 @@ test.describe( tag: ['@various'], }, () => { + // test were flaky when run at the same time, adding serial mode to run consecutively + test.describe.configure({ mode: 'serial' }); + test.beforeEach(async ({ page }) => { // Set localStorage to dock the navigation await page.evaluate(() => {