mirror of https://github.com/grafana/grafana.git
E2E: Remove cypress `dashboards-suite` (#109038)
* add equivalent dashboard-time-zone test * remove cypress dashboards-suite * modify tests to work with schema-v2 + update workflow to run playwright instead * fix package.json * update CODEOWNERS * fix start-server to include ARCH
This commit is contained in:
parent
db2ba4f7e2
commit
6408e3acaa
|
|
@ -412,6 +412,39 @@
|
|||
/e2e/cloud-plugins-suite/ @grafana/partner-datasources
|
||||
/e2e-playwright/ @grafana/grafana-frontend-platform
|
||||
/e2e-playwright/dashboard-new-layouts @grafana/dashboards-squad
|
||||
/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
|
||||
/e2e-playwright/dashboards-suite/dashboard-export-image.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-export-json.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-keybindings.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-links-without-slug.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-live-streaming.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-public-create.spec.ts @grafana/grafana-operator-experience-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-public-templating.spec.ts @grafana/grafana-operator-experience-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-share-externally-create.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-share-internally.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-share-snapshot-create.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-templating.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-time-zone.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/dashboard-timepicker.spec.ts @grafana/grafana-frontend-platform
|
||||
/e2e-playwright/dashboards-suite/embedded-dashboard.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/general-dashboards.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/import-dashboard.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/load-options-from-url.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-constant-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-custom-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-datasource-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-interval-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-query-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/new-text-box-variable.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/repeating-a-panel-horizontally.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/repeating-a-panel-vertically.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/repeating-an-empty-row.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/set-options-from-ui.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/snapshot-create.spec.ts @grafana/sharing-squad
|
||||
/e2e-playwright/dashboards-suite/templating-dashboard-links-and-variables.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/textbox-variables.spec.ts @grafana/dashboards-squad
|
||||
/e2e-playwright/dashboards-suite/utils/makeDashboard.ts @grafana/grafana-search-navigate-organise
|
||||
/e2e-playwright/panels-suite/dashlist.spec.ts @grafana/grafana-search-navigate-organise
|
||||
/e2e-playwright/panels-suite/datagrid-data-change.spec.ts @grafana/dataviz-squad
|
||||
/e2e-playwright/panels-suite/datagrid-editing-features.spec.ts @grafana/dataviz-squad
|
||||
|
|
|
|||
|
|
@ -206,8 +206,6 @@ jobs:
|
|||
include:
|
||||
- suite: various-suite
|
||||
path: e2e/various-suite
|
||||
- suite: dashboards-suite
|
||||
path: e2e/dashboards-suite
|
||||
- suite: various-suite (old arch)
|
||||
path: e2e/old-arch/various-suite
|
||||
flags: --flags="--env dashboardScene=false"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ env:
|
|||
|
||||
jobs:
|
||||
dashboard-schema-v2-e2e:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-latest-8-cores
|
||||
continue-on-error: true
|
||||
if: github.event.pull_request.draft == false
|
||||
steps:
|
||||
|
|
@ -32,12 +32,10 @@ jobs:
|
|||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: yarn install --immutable
|
||||
- name: Install Playwright browsers
|
||||
run: yarn playwright install --with-deps chromium
|
||||
- name: Build grafana
|
||||
run: make build
|
||||
- name: Install Cypress dependencies
|
||||
uses: cypress-io/github-action@b8ba51a856ba5f4c15cf39007636d4ab04f23e3c
|
||||
with:
|
||||
runTests: false
|
||||
- name: Run dashboard scenes e2e
|
||||
run: yarn e2e:schema-v2 || echo "Test failed but marking as success since schema V2 is behind a feature flag and should not block PRs"
|
||||
|
||||
|
|
|
|||
|
|
@ -9,13 +9,13 @@ const NUM_NESTED_DASHBOARDS = 60;
|
|||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
tableNextGen: true,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
// TODO change this test so it doesn't conflict with the existing dashboard browse test
|
||||
// probably needs a separate user
|
||||
test.describe.skip(
|
||||
test.describe.fixme(
|
||||
'Dashboard browse (nested)',
|
||||
{
|
||||
tag: ['@dashboards'],
|
||||
|
|
@ -107,7 +107,7 @@ test.describe.skip(
|
|||
await expect(page.getByText('Nested folder 00')).toBeVisible();
|
||||
|
||||
// Get the table body container for scrolling
|
||||
const tableBody = page.getByRole('grid');
|
||||
const tableBody = page.getByTestId(selectors.pages.BrowseDashboards.table.body).locator('> div');
|
||||
|
||||
// Scroll the page and check visibility of next set of items
|
||||
await tableBody.evaluate((el) => el.scrollTo(0, 2100));
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
import testDashboard from '../dashboards/TestDashboard.json';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Dashboard browse',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ test.use({
|
|||
scenes: true,
|
||||
newDashboardSharingComponent: true,
|
||||
sharingDashboardImage: true, // Enable the export image feature
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Export as JSON',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Dashboard keybindings',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
import testDashboard from '../dashboards/DataLinkWithoutSlugTest.json';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Dashboard with data links that have no slug',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import testDashboard from '../dashboards/DashboardLiveTest.json';
|
|||
test.use({
|
||||
featureToggles: {
|
||||
tableNextGen: true,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
test.use({
|
||||
featureToggles: {
|
||||
newDashboardSharingComponent: false,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
test.use({
|
||||
featureToggles: {
|
||||
newDashboardSharingComponent: false,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ test.use({
|
|||
featureToggles: {
|
||||
scenes: true,
|
||||
newDashboardSharingComponent: true,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ test.use({
|
|||
featureToggles: {
|
||||
scenes: true,
|
||||
newDashboardSharingComponent: true,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ test.use({
|
|||
featureToggles: {
|
||||
scenes: true,
|
||||
newDashboardSharingComponent: true,
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ const DASHBOARD_UID = 'HYaGDGIMk';
|
|||
|
||||
test.use({
|
||||
timezoneId: 'Pacific/Easter',
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,289 @@
|
|||
import { addDays, addHours, differenceInCalendarDays, differenceInMinutes, isBefore, parseISO, toDate } from 'date-fns';
|
||||
import { Page } from 'playwright-core';
|
||||
|
||||
import { test, expect, DashboardPage, E2ESelectorGroups } from '@grafana/plugin-e2e';
|
||||
|
||||
const TIMEZONE_DASHBOARD_UID = 'd41dbaa2-a39e-4536-ab2b-caca52f1a9c8';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Dashboard time zone support',
|
||||
{
|
||||
tag: ['@dashboards'],
|
||||
},
|
||||
() => {
|
||||
test('Tests dashboard time zone scenarios', async ({ page, gotoDashboardPage, selectors }) => {
|
||||
const dashboardPage = await gotoDashboardPage({ uid: TIMEZONE_DASHBOARD_UID });
|
||||
|
||||
const fromTimeZone = 'UTC';
|
||||
const toTimeZone = 'America/Chicago';
|
||||
const offset = offsetBetweenTimeZones(toTimeZone, fromTimeZone);
|
||||
|
||||
// Enter edit mode
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.editButton).click();
|
||||
|
||||
// Open dashboard settings
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.settingsButton).click();
|
||||
|
||||
// Change timezone to UTC
|
||||
await page.getByTestId(selectors.components.TimeZonePicker.containerV2).click();
|
||||
await page.getByRole('option', { name: 'Coordinated Universal Time ' }).click();
|
||||
|
||||
// Close settings and refresh
|
||||
await dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
|
||||
.click();
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.RefreshPicker.runButtonV2).click();
|
||||
|
||||
const panelsToCheck = ['Panel in timezone'];
|
||||
|
||||
const timesInUtc: Record<string, string> = {};
|
||||
|
||||
// Verify all panels are visible
|
||||
for (const title of panelsToCheck) {
|
||||
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title(title))).toBeVisible();
|
||||
const timeCell = dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title(title))
|
||||
.getByRole('row')
|
||||
.nth(1)
|
||||
.getByRole('cell')
|
||||
.first();
|
||||
const time = await timeCell.textContent();
|
||||
if (time) {
|
||||
timesInUtc[title] = time;
|
||||
}
|
||||
}
|
||||
|
||||
// Open dashboard settings
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.settingsButton).click();
|
||||
|
||||
// Change timezone to America/Chicago
|
||||
await page.getByTestId(selectors.components.TimeZonePicker.containerV2).click();
|
||||
await page.getByRole('option', { name: toTimeZone }).click();
|
||||
|
||||
// Close settings and refresh
|
||||
await dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.NavToolbar.editDashboard.backToDashboardButton)
|
||||
.click();
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.RefreshPicker.runButtonV2).click();
|
||||
|
||||
// Verify panels are still visible after timezone change
|
||||
for (const title of panelsToCheck) {
|
||||
await expect(dashboardPage.getByGrafanaSelector(selectors.components.Panels.Panel.title(title))).toBeVisible();
|
||||
const timeCell = dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title(title))
|
||||
.getByRole('row')
|
||||
.nth(1)
|
||||
.getByRole('cell')
|
||||
.first();
|
||||
await expect(async () => {
|
||||
const inUtc = timesInUtc[title];
|
||||
const inTz = await timeCell.textContent();
|
||||
expect(inTz).not.toBeNull();
|
||||
if (inTz) {
|
||||
const isCorrect = isTimeCorrect(inUtc, inTz, offset);
|
||||
expect(isCorrect).toEqual(true);
|
||||
}
|
||||
}).toPass();
|
||||
}
|
||||
});
|
||||
|
||||
test('Tests relative timezone support and overrides', async ({ page, gotoDashboardPage, selectors }) => {
|
||||
// Open dashboard
|
||||
const dashboardPage = await gotoDashboardPage({
|
||||
uid: TIMEZONE_DASHBOARD_UID,
|
||||
});
|
||||
|
||||
// Switch to Browser timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Browser',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Today so far, still in Browser timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel in timezone'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Test UTC timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Coordinated Universal Time',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Today so far, still in UTC timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel in timezone'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Test Tokyo timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Asia/Tokyo',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Today so far, still in Tokyo timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel in timezone'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Test LA timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'America/Los Angeles',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
// Today so far, still in LA timezone
|
||||
await setTimeRange(page, dashboardPage, selectors, {
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel with relative time override'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
|
||||
await expect(
|
||||
dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.Panels.Panel.title('Panel in timezone'))
|
||||
.locator('[role="row"]')
|
||||
.filter({ hasText: '00:00:00' })
|
||||
).toBeVisible();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Helper function to set time range with optional timezone
|
||||
async function setTimeRange(
|
||||
page: Page,
|
||||
dashboardPage: DashboardPage,
|
||||
selectors: E2ESelectorGroups,
|
||||
options: { from: string; to: string; zone?: string }
|
||||
) {
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.TimePicker.openButton).click();
|
||||
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.TimePicker.fromField).fill(options.from);
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.TimePicker.toField).fill(options.to);
|
||||
|
||||
if (options.zone) {
|
||||
await page.getByRole('button', { name: 'Change time settings' }).click();
|
||||
await page.getByTestId(selectors.components.TimeZonePicker.containerV2).click();
|
||||
await page.getByRole('option', { name: options.zone }).click();
|
||||
}
|
||||
|
||||
await dashboardPage.getByGrafanaSelector(selectors.components.TimePicker.applyTimeRange).click();
|
||||
}
|
||||
|
||||
const isTimeCorrect = (inUtc: string, inTz: string, offset: number): boolean => {
|
||||
if (inUtc === inTz) {
|
||||
// we need to catch issues when timezone isn't changed for some reason like https://github.com/grafana/grafana/issues/35504
|
||||
return false;
|
||||
}
|
||||
|
||||
const utcDate = toDate(parseISO(inUtc));
|
||||
const utcDateWithOffset = addHours(toDate(parseISO(inUtc)), offset);
|
||||
const dayDifference = differenceInCalendarDays(utcDate, utcDateWithOffset); // if the utcDate +/- offset is the day before/after then we need to adjust reference
|
||||
const dayOffset = isBefore(utcDateWithOffset, utcDate) ? dayDifference * -1 : dayDifference;
|
||||
const tzDate = addDays(toDate(parseISO(inTz)), dayOffset); // adjust tzDate with any dayOffset
|
||||
const diff = Math.abs(differenceInMinutes(utcDate, tzDate)); // use Math.abs if tzDate is in future
|
||||
|
||||
return diff <= Math.abs(offset * 60);
|
||||
};
|
||||
|
||||
const offsetBetweenTimeZones = (timeZone1: string, timeZone2: string, when: Date = new Date()): number => {
|
||||
const t1 = convertDateToAnotherTimeZone(when, timeZone1);
|
||||
const t2 = convertDateToAnotherTimeZone(when, timeZone2);
|
||||
return (t1.getTime() - t2.getTime()) / (1000 * 60 * 60);
|
||||
};
|
||||
|
||||
const convertDateToAnotherTimeZone = (date: Date, timeZone: string): Date => {
|
||||
const dateString = date.toLocaleString('en-US', {
|
||||
timeZone: timeZone,
|
||||
});
|
||||
return new Date(dateString);
|
||||
};
|
||||
|
|
@ -15,6 +15,9 @@ test.use({
|
|||
cookies: [],
|
||||
origins: [],
|
||||
},
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Embedded dashboard',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = 'edediimbjhdz4b/a-tall-dashboard';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Dashboards',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
import testDashboard from '../dashboards/TestDashboard.json';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Import Dashboards Test',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Load options from Url',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Constant',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -50,6 +50,12 @@ async function assertPreviewValues(
|
|||
}
|
||||
}
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Custom',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Datasource',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ async function assertPreviewValues(
|
|||
}
|
||||
}
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Interval',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
const DASHBOARD_NAME = 'Templating - Nested Template Variables';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Query - Add variable',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,6 +3,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Text box',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = 'WVpf2jp7z/repeating-a-panel-horizontally';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Repeating a panel horizontally',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = 'OY8Ghjt7k/repeating-a-panel-vertically';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Repeating a panel vertically',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = 'dtpl2Ctnk/repeating-an-empty-row';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Repeating empty rows',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Variables - Set options from ui',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ const DASHBOARD_UID = 'ZqZnVvFZz';
|
|||
test.use({
|
||||
featureToggles: {
|
||||
newDashboardSharingComponent: false, // Use legacy sharing component for this test
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,12 @@ import { test, expect } from '@grafana/plugin-e2e';
|
|||
|
||||
const DASHBOARD_UID = 'yBCC3aKGk';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'Templating dashboard links and variables',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4,6 +4,12 @@ import { test, expect, E2ESelectorGroups, DashboardPage } from '@grafana/plugin-
|
|||
|
||||
const PAGE_UNDER_TEST = 'AejrN1AMz';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
kubernetesDashboards: process.env.KUBERNETES_DASHBOARDS === 'true',
|
||||
},
|
||||
});
|
||||
|
||||
test.describe(
|
||||
'TextBox - load options scenarios',
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,99 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
const PAGE_UNDER_TEST = 'WVpf2jp7z/repeating-a-panel-horizontally';
|
||||
|
||||
describe('Repeating a panel horizontally', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('should be able to repeat a panel horizontally', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
let prevLeft = Number.NEGATIVE_INFINITY;
|
||||
let prevTop: number | null = null;
|
||||
const panelTitles = ['Panel Title 1', 'Panel Title 2', 'Panel Title 3'];
|
||||
panelTitles.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(left).to.be.greaterThan(prevLeft);
|
||||
if (prevTop !== null) {
|
||||
expect(top).to.be.equal(prevTop);
|
||||
}
|
||||
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('responds to changes to the variables', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
let prevLeft = Number.NEGATIVE_INFINITY;
|
||||
let prevTop: number | null = null;
|
||||
const panelTitles = ['Panel Title 1', 'Panel Title 2', 'Panel Title 3'];
|
||||
panelTitles.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('be.visible');
|
||||
});
|
||||
|
||||
// Change to only show panels 1 + 3
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('horizontal')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
|
||||
|
||||
// blur the dropdown
|
||||
cy.get('body').click();
|
||||
|
||||
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
|
||||
const panelsNotShown = ['Panel Title 2'];
|
||||
panelsShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(left).to.be.greaterThan(prevLeft);
|
||||
if (prevTop !== null) {
|
||||
expect(top).to.be.equal(prevTop);
|
||||
}
|
||||
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
panelsNotShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a dashboard based on the query params correctly', () => {
|
||||
// Have to manually add the queryParams to the url because they have the same name
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?var-horizontal=1&var-horizontal=3` });
|
||||
let prevLeft = Number.NEGATIVE_INFINITY;
|
||||
let prevTop: number | null = null;
|
||||
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
|
||||
const panelsNotShown = ['Panel Title 2'];
|
||||
// Check correct panels are displayed
|
||||
panelsShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(left).to.be.greaterThan(prevLeft);
|
||||
if (prevTop !== null) {
|
||||
expect(top).to.be.equal(prevTop);
|
||||
}
|
||||
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
panelsNotShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
const PAGE_UNDER_TEST = 'OY8Ghjt7k/repeating-a-panel-vertically';
|
||||
|
||||
describe('Repeating a panel vertically', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('should be able to repeat a panel vertically', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
let prevLeft: number | null = null;
|
||||
const panelTitles = ['Panel Title 1', 'Panel Title 2', 'Panel Title 3'];
|
||||
panelTitles.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
if (prevLeft !== null) {
|
||||
expect(left).to.be.equal(prevLeft);
|
||||
}
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('responds to changes to the variables', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
let prevLeft: number | null = null;
|
||||
const panelTitles = ['Panel Title 1', 'Panel Title 2', 'Panel Title 3'];
|
||||
panelTitles.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('be.visible');
|
||||
});
|
||||
|
||||
// Change to only show panels 1 + 3
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('vertical')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
|
||||
|
||||
// blur the dropdown
|
||||
cy.get('body').click();
|
||||
|
||||
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
|
||||
const panelsNotShown = ['Panel Title 2'];
|
||||
panelsShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
if (prevLeft !== null) {
|
||||
expect(left).to.be.equal(prevLeft);
|
||||
}
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
panelsNotShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a dashboard based on the query params correctly', () => {
|
||||
// Have to manually add the queryParams to the url because they have the same name
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?var-vertical=1&var-vertical=3` });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
let prevLeft: number | null = null;
|
||||
const panelsShown = ['Panel Title 1', 'Panel Title 3'];
|
||||
const panelsNotShown = ['Panel Title 2'];
|
||||
panelsShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { left, top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
if (prevLeft !== null) {
|
||||
expect(left).to.be.equal(prevLeft);
|
||||
}
|
||||
prevLeft = left;
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
panelsNotShown.forEach((title) => {
|
||||
e2e.components.Panels.Panel.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
const PAGE_UNDER_TEST = 'dtpl2Ctnk/repeating-an-empty-row';
|
||||
|
||||
describe('Repeating empty rows', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('should be able to repeat empty rows vertically', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
const rowTitles = ['Row title 1', 'Row title 2', 'Row title 3'];
|
||||
rowTitles.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('responds to changes to the variables', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
const rowTitles = ['Row title 1', 'Row title 2', 'Row title 3'];
|
||||
|
||||
rowTitles.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title).should('be.visible');
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('row')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('1').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('3').click();
|
||||
|
||||
// blur the dropdown
|
||||
cy.get('body').click();
|
||||
|
||||
const rowsShown = ['Row title 1', 'Row title 3'];
|
||||
const rowsNotShown = ['Row title 2'];
|
||||
rowsShown.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
|
||||
rowsNotShown.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
|
||||
it('loads a dashboard based on the query params correctly', () => {
|
||||
// Have to manually add the queryParams to the url because they have the same name
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?var-row=1&var-row=3` });
|
||||
|
||||
let prevTop = Number.NEGATIVE_INFINITY;
|
||||
const rowsShown = ['Row title 1', 'Row title 3'];
|
||||
const rowsNotShown = ['Row title 2'];
|
||||
rowsShown.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title)
|
||||
.should('be.visible')
|
||||
.then(($el) => {
|
||||
const { top } = $el[0].getBoundingClientRect();
|
||||
expect(top).to.be.greaterThan(prevTop);
|
||||
prevTop = top;
|
||||
});
|
||||
});
|
||||
|
||||
rowsNotShown.forEach((title) => {
|
||||
e2e.components.DashboardRow.title(title).should('not.exist');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
import { makeNewDashboardRequestBody } from './utils/makeDashboard';
|
||||
|
||||
const NUM_ROOT_FOLDERS = 60;
|
||||
const NUM_ROOT_DASHBOARDS = 60;
|
||||
const NUM_NESTED_FOLDERS = 60;
|
||||
const NUM_NESTED_DASHBOARDS = 60;
|
||||
|
||||
// TODO enable this test when nested folders goes live
|
||||
describe.skip('Dashboard browse (nested)', () => {
|
||||
const dashboardUIDsToCleanUp: string[] = [];
|
||||
const folderUIDsToCleanUp: string[] = [];
|
||||
|
||||
// Add nested folder structure
|
||||
before(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'), false);
|
||||
|
||||
// Add root folders
|
||||
for (let i = 0; i < NUM_ROOT_FOLDERS; i++) {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/folders',
|
||||
body: {
|
||||
title: `Root folder ${i.toString().padStart(2, '0')}`,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then((response) => {
|
||||
folderUIDsToCleanUp.push(response.body.uid);
|
||||
});
|
||||
}
|
||||
|
||||
// Add root dashboards
|
||||
for (let i = 0; i < NUM_ROOT_DASHBOARDS; i++) {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/dashboards/db',
|
||||
body: makeNewDashboardRequestBody(`Root dashboard ${i.toString().padStart(2, '0')}`),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then((response) => {
|
||||
dashboardUIDsToCleanUp.push(response.body.uid);
|
||||
});
|
||||
}
|
||||
|
||||
// Add folder with children
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/folders',
|
||||
body: {
|
||||
title: 'A root folder with children',
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}).then((response) => {
|
||||
const folderUid = response.body.uid;
|
||||
folderUIDsToCleanUp.push(folderUid);
|
||||
// Add nested folders
|
||||
for (let i = 0; i < NUM_NESTED_FOLDERS; i++) {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/folders',
|
||||
body: {
|
||||
title: `Nested folder ${i.toString().padStart(2, '0')}`,
|
||||
parentUid: folderUid,
|
||||
},
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
}
|
||||
// Add nested dashboards
|
||||
for (let i = 0; i < NUM_NESTED_DASHBOARDS; i++) {
|
||||
cy.request({
|
||||
method: 'POST',
|
||||
url: '/api/dashboards/db',
|
||||
body: makeNewDashboardRequestBody(`Nested dashboard ${i.toString().padStart(2, '0')}`, folderUid),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Remove nested folder structure
|
||||
after(() => {
|
||||
// Clean up root dashboards
|
||||
for (const dashboardUID of dashboardUIDsToCleanUp) {
|
||||
e2e.flows.deleteDashboard({
|
||||
uid: dashboardUID,
|
||||
quick: true,
|
||||
title: '',
|
||||
});
|
||||
}
|
||||
// Clean up root folders (cascading delete will remove any nested folders and dashboards)
|
||||
for (const folderUID of folderUIDsToCleanUp) {
|
||||
cy.request({
|
||||
method: 'DELETE',
|
||||
url: `/api/folders/${folderUID}`,
|
||||
qs: {
|
||||
forceDeleteRules: false,
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it('pagination works correctly for folders and root', () => {
|
||||
e2e.pages.Dashboards.visit();
|
||||
|
||||
cy.contains('A root folder with children').should('be.visible');
|
||||
|
||||
// Expand A root folder with children
|
||||
cy.get('[aria-label="Expand folder A root folder with children"]').click();
|
||||
cy.contains('Nested folder 00').should('be.visible');
|
||||
|
||||
// Scroll the page and check visibility of next set of items
|
||||
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 1700);
|
||||
cy.contains('Nested folder 59').should('be.visible');
|
||||
cy.contains('Nested dashboard 00').should('be.visible');
|
||||
|
||||
// Scroll the page and check visibility of next set of items
|
||||
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 3800);
|
||||
cy.contains('Nested dashboard 59').should('be.visible');
|
||||
cy.contains('Root folder 00').should('be.visible');
|
||||
|
||||
// Scroll the page and check visibility of next set of items
|
||||
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 5900);
|
||||
cy.contains('Root folder 59').should('be.visible');
|
||||
cy.contains('Root dashboard 00').should('be.visible');
|
||||
|
||||
// Scroll the page and check visibility of next set of items
|
||||
e2e.pages.BrowseDashboards.table.body().find('> div').scrollTo(0, 8000);
|
||||
cy.contains('Root dashboard 59').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
import testDashboard from '../dashboards/TestDashboard.json';
|
||||
import { e2e } from '../utils';
|
||||
// Skipping due to race conditions with same old arch test e2e/dashboards-suite/dashboard-browse.spec.ts
|
||||
describe.skip('Dashboard browse', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Manage Dashboards tests', () => {
|
||||
e2e.flows.importDashboard(testDashboard, 1000, true);
|
||||
|
||||
e2e.pages.Dashboards.visit();
|
||||
|
||||
// Folders and dashboards should be visible
|
||||
e2e.pages.BrowseDashboards.table.row('gdev dashboards').should('be.visible');
|
||||
e2e.pages.BrowseDashboards.table.row('E2E Test - Import Dashboard').should('be.visible');
|
||||
|
||||
// gdev dashboards folder is collapsed - its content should not be visible
|
||||
e2e.pages.BrowseDashboards.table.row('Bar Gauge Demo').should('not.exist');
|
||||
|
||||
// should click a folder and see it's children
|
||||
e2e.pages.BrowseDashboards.table.row('gdev dashboards').find('[aria-label^="Expand folder"]').click();
|
||||
e2e.pages.BrowseDashboards.table.row('Bar Gauge Demo').should('be.visible');
|
||||
|
||||
// Open the new folder drawer
|
||||
cy.contains('button', 'New').click();
|
||||
cy.contains('button', 'New folder').click();
|
||||
|
||||
// And create a new folder
|
||||
e2e.pages.BrowseDashboards.NewFolderForm.nameInput().type('My new folder');
|
||||
e2e.pages.BrowseDashboards.NewFolderForm.form().contains('button', 'Create').click();
|
||||
e2e.components.Alert.alertV2('success').find('button[aria-label="Close alert"]').click();
|
||||
cy.contains('h1', 'My new folder').should('be.visible');
|
||||
|
||||
// Delete the folder and expect to go back to the root
|
||||
cy.contains('button', 'Folder actions').click();
|
||||
cy.contains('button', 'Delete').click();
|
||||
e2e.flows.confirmDelete();
|
||||
cy.contains('h1', 'Dashboards').should('be.visible');
|
||||
|
||||
// Can collapse the gdev folder and delete the dashboard we imported
|
||||
e2e.pages.BrowseDashboards.table.row('gdev dashboards').find('[aria-label^="Collapse folder"]').click();
|
||||
e2e.pages.BrowseDashboards.table
|
||||
.row('E2E Test - Import Dashboard')
|
||||
.find('[type="checkbox"]')
|
||||
.click({ force: true });
|
||||
|
||||
cy.contains('button', 'Delete').click();
|
||||
e2e.flows.confirmDelete();
|
||||
e2e.pages.BrowseDashboards.table.row('E2E Test - Import Dashboard').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
import '../utils/support/clipboard';
|
||||
|
||||
describe('Export as JSON', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Export for internal and external use', () => {
|
||||
// Opening a dashboard
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({
|
||||
uid: 'ZqZnVvFZz',
|
||||
queryParams: { '__feature.scenes': true, '__feature.newDashboardSharingComponent': true },
|
||||
});
|
||||
cy.wait('@query');
|
||||
|
||||
// cy.wrap(
|
||||
// Cypress.automation('remote:debugger:protocol', {
|
||||
// command: 'Browser.grantPermissions',
|
||||
// params: {
|
||||
// permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
// origin: window.location.origin,
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
// Open the export drawer
|
||||
e2e.pages.Dashboard.DashNav.NewExportButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.NewExportButton.Menu.exportAsJson().click();
|
||||
|
||||
cy.url().should('include', 'shareView=export');
|
||||
|
||||
// Export as JSON
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.container().should('be.visible');
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.exportExternallyToggle().should('not.be.checked');
|
||||
e2e.components.CodeEditor.container().should('exist');
|
||||
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.saveToFileButton().should('exist');
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.copyToClipboardButton().should('exist');
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.cancelButton().should('exist');
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// Copy link button should be visible
|
||||
// e2e.pages.ExportDashboardDrawer.ExportAsJson.copyToClipboardButton()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.copyFromClipboard().then((url) => {
|
||||
// cy.wrap(url).should('not.include', '__inputs');
|
||||
// });
|
||||
// });
|
||||
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.exportExternallyToggle().click({ force: true });
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// e2e.pages.ExportDashboardDrawer.ExportAsJson.copyToClipboardButton()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.copyFromClipboard().then((url) => {
|
||||
// cy.wrap(url).should('include', '__inputs');
|
||||
// });
|
||||
// });
|
||||
|
||||
e2e.pages.ExportDashboardDrawer.ExportAsJson.cancelButton().click();
|
||||
|
||||
cy.url().should('not.include', 'shareView=export');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Dashboard keybindings', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('should collapse and expand all rows', () => {
|
||||
e2e.flows.openDashboard({ uid: 'Repeating-rows-uid/repeating-rows' });
|
||||
e2e.components.Panels.Panel.content().should('have.length', 5);
|
||||
e2e.components.Panels.Panel.title('server = A, pod = Bob').should('be.visible');
|
||||
e2e.components.Panels.Panel.title('server = B, pod = Bob').should('be.visible');
|
||||
|
||||
cy.get('body').type('d').type('{shift}c');
|
||||
e2e.components.Panels.Panel.content().should('have.length', 0);
|
||||
e2e.components.Panels.Panel.title('server = A, pod = Bob').should('not.exist');
|
||||
e2e.components.Panels.Panel.title('server = B, pod = Bob').should('not.exist');
|
||||
|
||||
cy.get('body').type('d').type('{shift}e');
|
||||
e2e.components.Panels.Panel.content().should('have.length', 6);
|
||||
e2e.components.Panels.Panel.title('server = A, pod = Bob').should('be.visible');
|
||||
e2e.components.Panels.Panel.title('server = B, pod = Bob').should('be.visible');
|
||||
});
|
||||
|
||||
it('should open panel inspect', () => {
|
||||
e2e.flows.openDashboard({ uid: 'edediimbjhdz4b/a-tall-dashboard' });
|
||||
e2e.components.Panels.Panel.title('Panel #1').type('i');
|
||||
e2e.components.PanelInspector.Json.content().should('be.visible');
|
||||
cy.get('body').type('{esc}');
|
||||
e2e.components.PanelInspector.Json.content().should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import testDashboard from '../dashboards/DataLinkWithoutSlugTest.json';
|
||||
import { e2e } from '../utils';
|
||||
|
||||
describe('Dashboard with data links that have no slug', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Should not reload if linking to same dashboard', () => {
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
|
||||
e2e.flows.importDashboard(testDashboard, 1000, true);
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.components.Panels.Panel.title('Data links without slug').should('exist');
|
||||
|
||||
e2e.components.DataLinksContextMenu.singleLink().contains('9yy21uzzxypg').click();
|
||||
cy.contains('Loading', { timeout: 500 })
|
||||
.should(() => {}) // prevent test from failing if it does not find loading
|
||||
.then(throwIfLoadingFound);
|
||||
cy.url().should('include', urlShouldContain);
|
||||
|
||||
e2e.components.DataLinksContextMenu.singleLink().contains('dr199bpvpcru').click();
|
||||
cy.contains('Loading', { timeout: 500 })
|
||||
.should(() => {}) // prevent test from failing if it does not find loading
|
||||
.then(throwIfLoadingFound);
|
||||
cy.url().should('include', urlShouldContain);
|
||||
|
||||
e2e.components.DataLinksContextMenu.singleLink().contains('dre33fzyxcrz').click();
|
||||
cy.contains('Loading', { timeout: 500 })
|
||||
.should(() => {}) // prevent test from failing if it does not find loading
|
||||
.then(throwIfLoadingFound);
|
||||
cy.url().should('include', urlShouldContain);
|
||||
});
|
||||
});
|
||||
|
||||
const urlShouldContain = '/d/data-link-no-slug/data-link-without-slug-test';
|
||||
|
||||
const throwIfLoadingFound = (el: JQuery) => {
|
||||
if (el.length) {
|
||||
// This means dashboard refreshes when clicking self-referencing data link
|
||||
// that has no slug in it
|
||||
throw new Error('Should not contain Loading');
|
||||
}
|
||||
};
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
import testDashboard from '../dashboards/DashboardLiveTest.json';
|
||||
import { e2e } from '../utils';
|
||||
|
||||
// Skipping due to flakiness/race conditions with same old arch test e2e/dashboards-suite/dashboard-live-streaming.spec.ts
|
||||
describe.skip('Dashboard Live streaming support', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
e2e.flows.importDashboard(testDashboard, 1000);
|
||||
});
|
||||
|
||||
it('Should receive streaming data', () => {
|
||||
e2e.flows.openDashboard({ uid: 'live-e2e-test', queryParams: { '__feature.tableNextGen': false } });
|
||||
cy.wait(1000);
|
||||
e2e.components.Panels.Panel.title('Live').should('exist');
|
||||
e2e.components.Panels.Visualization.Table.body().find('[role="row"]').should('have.length.at.least', 5);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,153 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
// Skipping due to race conditions with same old arch test e2e/dashboards-suite/dashboard-public-create.spec.ts
|
||||
describe.skip('Public dashboards', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Create a public dashboard', () => {
|
||||
// Opening a dashboard without template variables
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
|
||||
cy.wait('@query');
|
||||
|
||||
// Open sharing modal
|
||||
e2e.components.NavToolbar.shareDashboard().click();
|
||||
|
||||
// Select public dashboards tab
|
||||
e2e.components.Tab.title('Public dashboard').click();
|
||||
|
||||
// Create button should be disabled
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('be.disabled');
|
||||
|
||||
// Create flow shouldn't show these elements
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableAnnotationsSwitch().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableTimeRangeSwitch().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.DeleteButton().should('not.exist');
|
||||
|
||||
// Acknowledge checkboxes
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.WillBePublicCheckbox().should('be.enabled').click({ force: true });
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.LimitedDSCheckbox().should('be.enabled').click({ force: true });
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CostIncreaseCheckbox().should('be.enabled').click({ force: true });
|
||||
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('be.enabled');
|
||||
|
||||
// Create public dashboard
|
||||
cy.intercept('POST', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('save');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().click();
|
||||
cy.wait('@save');
|
||||
|
||||
// These elements shouldn't be rendered after creating public dashboard
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.WillBePublicCheckbox().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.LimitedDSCheckbox().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CostIncreaseCheckbox().should('not.exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('not.exist');
|
||||
|
||||
// These elements should be rendered
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.DeleteButton().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.SettingsDropdown().should('exist');
|
||||
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.SettingsDropdown().click();
|
||||
// There elements should be rendered once the Settings dropdown is opened
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableAnnotationsSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableTimeRangeSwitch().should('exist');
|
||||
});
|
||||
|
||||
it('Open a public dashboard', () => {
|
||||
// Opening a dashboard without template variables
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
|
||||
cy.wait('@query');
|
||||
|
||||
// Tag indicating a dashboard is public
|
||||
e2e.pages.Dashboard.DashNav.publicDashboardTag().should('exist');
|
||||
|
||||
// Open sharing modal
|
||||
e2e.components.NavToolbar.shareDashboard().click();
|
||||
|
||||
// Select public dashboards tab
|
||||
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
|
||||
e2e.components.Tab.title('Public dashboard').click();
|
||||
cy.wait('@query-public-dashboard');
|
||||
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.DeleteButton().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.SettingsDropdown().should('exist');
|
||||
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.SettingsDropdown().click();
|
||||
// There elements should be rendered once the Settings dropdown is opened
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableTimeRangeSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.EnableAnnotationsSwitch().should('exist');
|
||||
|
||||
// Make a request to public dashboards api endpoint without authentication
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput()
|
||||
.invoke('val')
|
||||
.then((url) => {
|
||||
cy.clearCookies()
|
||||
.request(getPublicDashboardAPIUrl(String(url)))
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('Disable a public dashboard', () => {
|
||||
// Opening a dashboard without template variables
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz' });
|
||||
cy.wait('@query');
|
||||
|
||||
// Open sharing modal
|
||||
e2e.components.NavToolbar.shareDashboard().click();
|
||||
|
||||
// Select public dashboards tab
|
||||
cy.intercept('GET', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards').as('query-public-dashboard');
|
||||
e2e.components.Tab.title('Public dashboard').click();
|
||||
cy.wait('@query-public-dashboard');
|
||||
|
||||
// save url before disabling public dashboard
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput()
|
||||
.invoke('val')
|
||||
.then((text) => cy.wrap(text).as('url'));
|
||||
|
||||
// Save public dashboard
|
||||
cy.intercept('PATCH', '/api/dashboards/uid/ZqZnVvFZz/public-dashboards/*').as('update');
|
||||
// Switch off enabling toggle
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('be.enabled').click({ force: true });
|
||||
cy.wait('@update');
|
||||
|
||||
// Url should be hidden
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlInput().should('be.disabled');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CopyUrlButton().should('be.disabled');
|
||||
|
||||
// Make a request to public dashboards api endpoint without authentication
|
||||
cy.get('@url').then((url) => {
|
||||
cy.clearCookies()
|
||||
.request({ url: getPublicDashboardAPIUrl(String(url)), failOnStatusCode: false })
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(403);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const getPublicDashboardAPIUrl = (url: string): string => {
|
||||
let accessToken = url.split('/').pop();
|
||||
return `/api/public/dashboards/${accessToken}`;
|
||||
};
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Create a public dashboard with template variables shows a template variable warning', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Create a public dashboard with template variables shows a template variable warning', () => {
|
||||
// Opening a dashboard with template variables
|
||||
e2e.flows.openDashboard({ uid: 'HYaGDGIMk', queryParams: { '__feature.newDashboardSharingComponent': false } });
|
||||
|
||||
// Open sharing modal
|
||||
e2e.components.NavToolbar.shareDashboard().click();
|
||||
|
||||
// Select public dashboards tab
|
||||
e2e.components.Tab.title('Public Dashboard').click();
|
||||
|
||||
// Warning Alert dashboard cannot be made public because it has template variables
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.TemplateVariablesWarningAlert().should('be.visible');
|
||||
|
||||
// Configuration elements for public dashboards should not exist
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.WillBePublicCheckbox().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.LimitedDSCheckbox().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CostIncreaseCheckbox().should('exist');
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.CreateButton().should('exist');
|
||||
|
||||
e2e.pages.ShareDashboardModal.PublicDashboard.PauseSwitch().should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,182 +0,0 @@
|
|||
import { PublicDashboard } from '../../public/app/features/dashboard/components/ShareModal/SharePublicDashboard/SharePublicDashboardUtils';
|
||||
import { e2e } from '../utils';
|
||||
import '../utils/support/clipboard';
|
||||
|
||||
describe('Shared dashboards', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Close share externally drawer', () => {
|
||||
openDashboard();
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareExternally().click();
|
||||
|
||||
cy.url().should('include', 'shareView=public_dashboard');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.container().should('be.visible');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.PublicShare.cancelButton().click();
|
||||
|
||||
cy.url().should('not.include', 'shareView=public_dashboard');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.container().should('not.exist');
|
||||
});
|
||||
|
||||
// Skipping due to being a flaky test
|
||||
// https://drone.grafana.net/grafana/grafana/201217/6/14
|
||||
it.skip('Create a shared dashboard and check API', () => {
|
||||
openDashboard();
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareExternally().click();
|
||||
|
||||
// Create button should be disabled
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.PublicShare.createButton().should('be.disabled');
|
||||
|
||||
// Create flow shouldn't show these elements
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableTimeRangeSwitch().should('not.exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableAnnotationsSwitch().should('not.exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton().should('not.exist');
|
||||
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.revokeAccessButton().should('not.exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.toggleAccessButton().should('not.exist');
|
||||
|
||||
// Acknowledge checkbox
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.willBePublicCheckbox()
|
||||
.should('be.enabled')
|
||||
.click({ force: true });
|
||||
|
||||
// Create shared dashboard
|
||||
cy.intercept('POST', '/api/dashboards/uid/edediimbjhdz4b/public-dashboards').as('create');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.PublicShare.createButton().should('be.enabled').click();
|
||||
cy.wait('@create')
|
||||
.its('response.body')
|
||||
.then((body: PublicDashboard) => {
|
||||
cy.log(JSON.stringify(body));
|
||||
cy.clearCookies()
|
||||
.request(getPublicDashboardAPIUrl(body.accessToken))
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
|
||||
// These elements shouldn't be rendered after creating public dashboard
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.willBePublicCheckbox().should('not.exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Creation.PublicShare.createButton().should('not.exist');
|
||||
|
||||
// These elements should be rendered
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableTimeRangeSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableAnnotationsSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.revokeAccessButton().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.toggleAccessButton().should('exist');
|
||||
});
|
||||
|
||||
// Skipping as clipboard permissions are failing in CI. Public dashboard creation is checked in previous test on purpose
|
||||
it.skip('Open a shared dashboard', () => {
|
||||
openDashboard();
|
||||
|
||||
cy.wrap(
|
||||
Cypress.automation('remote:debugger:protocol', {
|
||||
command: 'Browser.grantPermissions',
|
||||
params: {
|
||||
permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
origin: window.location.origin,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
// Tag indicating a dashboard is public
|
||||
e2e.pages.Dashboard.DashNav.publicDashboardTag().should('exist');
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareExternally().click();
|
||||
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableTimeRangeSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.enableAnnotationsSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.revokeAccessButton().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.toggleAccessButton().should('exist');
|
||||
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton()
|
||||
.click()
|
||||
.then(() => {
|
||||
cy.copyFromClipboard().then((url) => {
|
||||
cy.clearCookies()
|
||||
.request(getPublicDashboardAPIUrl(String(url)))
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(200);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it.skip('Disable a shared dashboard', () => {
|
||||
openDashboard();
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// cy.wrap(
|
||||
// Cypress.automation('remote:debugger:protocol', {
|
||||
// command: 'Browser.grantPermissions',
|
||||
// params: {
|
||||
// permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
// origin: window.location.origin,
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareExternally().click();
|
||||
|
||||
// Save public dashboard
|
||||
cy.intercept('PATCH', '/api/dashboards/uid/edediimbjhdz4b/public-dashboards/*').as('update');
|
||||
|
||||
// Switch off enabling toggle
|
||||
e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.toggleAccessButton()
|
||||
.should('be.enabled')
|
||||
.click({ force: true });
|
||||
|
||||
cy.wait('@update')
|
||||
.its('response')
|
||||
.then((rs) => {
|
||||
expect(rs.statusCode).eq(200);
|
||||
const publicDashboard: PublicDashboard = rs.body;
|
||||
cy.clearCookies()
|
||||
.request({ url: getPublicDashboardAPIUrl(publicDashboard.accessToken), failOnStatusCode: false })
|
||||
.then((resp) => {
|
||||
expect(resp.status).to.eq(403);
|
||||
});
|
||||
});
|
||||
// .then(() => {
|
||||
// e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.toggleAccessButton().contains('Resume access');
|
||||
// e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton().should('be.enabled');
|
||||
// });
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// e2e.pages.ShareDashboardDrawer.ShareExternally.Configuration.copyUrlButton()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.copyFromClipboard().then((url) => {
|
||||
// cy.clearCookies()
|
||||
// .request({ url: getPublicDashboardAPIUrl(String(url)), failOnStatusCode: false })
|
||||
// .then((resp) => {
|
||||
// expect(resp.status).to.eq(403);
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
const openDashboard = () => {
|
||||
e2e.flows.openDashboard({
|
||||
uid: 'edediimbjhdz4b',
|
||||
queryParams: { '__feature.scenes': true, '__feature.newDashboardSharingComponent': true },
|
||||
});
|
||||
};
|
||||
|
||||
const getPublicDashboardAPIUrl = (accessToken: string): string => {
|
||||
return `/api/public/dashboards/${accessToken}`;
|
||||
};
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
import { ShareLinkConfiguration } from '../../public/app/features/dashboard-scene/sharing/ShareButton/utils';
|
||||
import { e2e } from '../utils';
|
||||
import '../utils/support/clipboard';
|
||||
|
||||
describe('Share internally', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
cy.window().then((win) => {
|
||||
win.localStorage.removeItem('grafana.dashboard.link.shareConfiguration');
|
||||
});
|
||||
});
|
||||
|
||||
it('Create a locked time range short link', () => {
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
openDashboard();
|
||||
cy.wait('@query');
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// cy.wrap(
|
||||
// Cypress.automation('remote:debugger:protocol', {
|
||||
// command: 'Browser.grantPermissions',
|
||||
// params: {
|
||||
// permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
// origin: window.location.origin,
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
|
||||
cy.intercept('POST', '/api/short-urls').as('create');
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareInternally().click();
|
||||
|
||||
cy.url().should('include', 'shareView=link');
|
||||
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.lockTimeRangeSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.shortenUrlSwitch().should('exist');
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.copyUrlButton().should('exist');
|
||||
e2e.components.RadioButton.container().should('have.length', 3);
|
||||
|
||||
cy.window().then((win) => {
|
||||
const shareConfiguration = win.localStorage.getItem('grafana.dashboard.link.shareConfiguration');
|
||||
expect(shareConfiguration).equal(null);
|
||||
});
|
||||
cy.wait('@create')
|
||||
.its('response')
|
||||
.then((rs) => {
|
||||
expect(rs.statusCode).eq(200);
|
||||
const body: { url: string; uid: string } = rs.body;
|
||||
expect(body.url).contain('goto');
|
||||
|
||||
// const url = fromBaseUrl(getShortLinkUrl(body.uid));
|
||||
// cy.intercept('GET', url).as('get');
|
||||
// cy.visit(url, { retryOnNetworkFailure: true });
|
||||
// cy.wait('@get');
|
||||
//
|
||||
// cy.url().should('not.include', 'from=now-6h&to=now');
|
||||
});
|
||||
});
|
||||
|
||||
it('Create a relative time range short link', () => {
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
openDashboard();
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareInternally().click();
|
||||
|
||||
cy.intercept('POST', '/api/short-urls').as('update');
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.lockTimeRangeSwitch().click({ force: true });
|
||||
|
||||
cy.window().then((win) => {
|
||||
const shareConfiguration = win.localStorage.getItem('grafana.dashboard.link.shareConfiguration');
|
||||
const { useAbsoluteTimeRange, useShortUrl, theme }: ShareLinkConfiguration = JSON.parse(shareConfiguration);
|
||||
expect(useAbsoluteTimeRange).eq(false);
|
||||
expect(useShortUrl).eq(true);
|
||||
expect(theme).eq('current');
|
||||
});
|
||||
|
||||
cy.wait('@update')
|
||||
.its('response')
|
||||
.then((rs) => {
|
||||
expect(rs.statusCode).eq(200);
|
||||
const body: { url: string; uid: string } = rs.body;
|
||||
expect(body.url).contain('goto');
|
||||
|
||||
// const url = fromBaseUrl(getShortLinkUrl(body.uid));
|
||||
// cy.intercept('GET', url).as('get');
|
||||
// cy.visit(url, { retryOnNetworkFailure: true });
|
||||
// cy.wait('@get');
|
||||
//
|
||||
// cy.url().should('include', 'from=now-6h&to=now');
|
||||
});
|
||||
|
||||
//
|
||||
// e2e.pages.ShareDashboardDrawer.ShareInternally.shortenUrlSwitch().click({ force: true });
|
||||
//
|
||||
// cy.window().then((win) => {
|
||||
// const shareConfiguration = win.localStorage.getItem('grafana.dashboard.link.shareConfiguration');
|
||||
// const { useAbsoluteTimeRange, useShortUrl, theme }: ShareLinkConfiguration = JSON.parse(shareConfiguration);
|
||||
// expect(useAbsoluteTimeRange).eq(true);
|
||||
// expect(useShortUrl).eq(false);
|
||||
// expect(theme).eq('current');
|
||||
// });
|
||||
|
||||
// e2e.pages.ShareDashboardDrawer.ShareInternally.copyUrlButton().should('exist');
|
||||
|
||||
// e2e.pages.ShareDashboardDrawer.ShareInternally.copyUrlButton()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.copyFromClipboard().then((url) => {
|
||||
// cy.wrap(url).should('include', 'from=now-6h&to=now');
|
||||
// cy.wrap(url).should('not.include', 'goto');
|
||||
// });
|
||||
// });
|
||||
});
|
||||
|
||||
it('Create a relative time range short link', () => {
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
openDashboard();
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareInternally().click();
|
||||
|
||||
cy.intercept('POST', '/api/short-urls').as('update');
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.lockTimeRangeSwitch().click({ force: true });
|
||||
|
||||
cy.window().then((win) => {
|
||||
const shareConfiguration = win.localStorage.getItem('grafana.dashboard.link.shareConfiguration');
|
||||
const { useAbsoluteTimeRange, useShortUrl, theme }: ShareLinkConfiguration = JSON.parse(shareConfiguration);
|
||||
expect(useAbsoluteTimeRange).eq(false);
|
||||
expect(useShortUrl).eq(true);
|
||||
expect(theme).eq('current');
|
||||
});
|
||||
|
||||
cy.wait('@update')
|
||||
.its('response')
|
||||
.then((rs) => {
|
||||
expect(rs.statusCode).eq(200);
|
||||
const body: { url: string; uid: string } = rs.body;
|
||||
expect(body.url).contain('goto');
|
||||
|
||||
// const url = fromBaseUrl(getShortLinkUrl(body.uid));
|
||||
// cy.intercept('GET', url).as('get');
|
||||
// cy.visit(url, { retryOnNetworkFailure: true });
|
||||
// cy.wait('@get');
|
||||
//
|
||||
// cy.url().should('include', 'from=now-6h&to=now');
|
||||
});
|
||||
});
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
it.skip('Share button gets configured link', () => {
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
openDashboard();
|
||||
cy.wait('@query');
|
||||
|
||||
// cy.wrap(
|
||||
// Cypress.automation('remote:debugger:protocol', {
|
||||
// command: 'Browser.grantPermissions',
|
||||
// params: {
|
||||
// permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
// origin: window.location.origin,
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// e2e.pages.Dashboard.DashNav.newShareButton
|
||||
// .shareLink()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.window()
|
||||
// .then((win) => {
|
||||
// return win.navigator.clipboard.readText().then((url) => {
|
||||
// cy.wrap(url).as('url');
|
||||
// });
|
||||
// })
|
||||
// .then(() => {
|
||||
// cy.get('@url').then((url) => {
|
||||
// cy.wrap(url).should('not.include', 'from=now-6h&to=now');
|
||||
// cy.wrap(url).should('include', 'goto');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
|
||||
// Open share externally drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareInternally().click();
|
||||
|
||||
cy.window().then((win) => {
|
||||
const shareConfiguration = win.localStorage.getItem('grafana.dashboard.link.shareConfiguration');
|
||||
expect(shareConfiguration).equal(null);
|
||||
});
|
||||
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.shortenUrlSwitch().click({ force: true });
|
||||
e2e.pages.ShareDashboardDrawer.ShareInternally.lockTimeRangeSwitch().click({ force: true });
|
||||
|
||||
e2e.components.Drawer.General.close().click();
|
||||
|
||||
cy.url().should('not.include', 'shareView=link');
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// e2e.pages.Dashboard.DashNav.newShareButton
|
||||
// .shareLink()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.window()
|
||||
// .then((win) => {
|
||||
// return win.navigator.clipboard.readText().then((url) => {
|
||||
// cy.wrap(url).as('url');
|
||||
// });
|
||||
// })
|
||||
// .then(() => {
|
||||
// cy.get('@url').then((url) => {
|
||||
// cy.wrap(url).should('include', 'from=now-6h&to=now');
|
||||
// cy.wrap(url).should('not.include', 'goto');
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
const openDashboard = () => {
|
||||
e2e.flows.openDashboard({
|
||||
uid: 'ZqZnVvFZz',
|
||||
queryParams: { '__feature.scenes': true, '__feature.newDashboardSharingComponent': true },
|
||||
timeRange: { from: 'now-6h', to: 'now' },
|
||||
});
|
||||
};
|
||||
|
||||
// const getShortLinkUrl = (uid: string): string => {
|
||||
// return `/goto/${uid}`;
|
||||
// };
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import { SnapshotCreateResponse } from '../../public/app/features/dashboard/services/SnapshotSrv';
|
||||
import { e2e } from '../utils';
|
||||
import { fromBaseUrl } from '../utils/support/url';
|
||||
import '../utils/support/clipboard';
|
||||
|
||||
describe('Snapshots', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Create a snapshot dashboard', () => {
|
||||
// Opening a dashboard
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({
|
||||
uid: 'ZqZnVvFZz',
|
||||
queryParams: { '__feature.scenes': true, '__feature.newDashboardSharingComponent': true },
|
||||
});
|
||||
cy.wait('@query');
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// cy.wrap(
|
||||
// Cypress.automation('remote:debugger:protocol', {
|
||||
// command: 'Browser.grantPermissions',
|
||||
// params: {
|
||||
// permissions: ['clipboardReadWrite', 'clipboardSanitizedWrite'],
|
||||
// origin: window.location.origin,
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
|
||||
const panelsToCheck = [
|
||||
'Raw Data Graph',
|
||||
'Last non-null',
|
||||
'min',
|
||||
'Max',
|
||||
'The data from graph above with seriesToColumns transform',
|
||||
];
|
||||
|
||||
// Open the sharing drawer
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.arrowMenu().click();
|
||||
e2e.pages.Dashboard.DashNav.newShareButton.menu.shareSnapshot().click();
|
||||
|
||||
// Publish snapshot
|
||||
cy.intercept('POST', '/api/snapshots').as('create');
|
||||
e2e.pages.ShareDashboardDrawer.ShareSnapshot.publishSnapshot().click();
|
||||
cy.wait('@create')
|
||||
.its('response')
|
||||
.then((rs) => {
|
||||
expect(rs.statusCode).eq(200);
|
||||
const body: SnapshotCreateResponse = rs.body;
|
||||
cy.visit(fromBaseUrl(getSnapshotUrl(body.key)));
|
||||
|
||||
// Validate the dashboard controls are rendered
|
||||
e2e.pages.Dashboard.Controls().should('exist');
|
||||
|
||||
// Validate the panels are rendered
|
||||
for (const title of panelsToCheck) {
|
||||
e2e.components.Panels.Panel.title(title).should('be.visible');
|
||||
}
|
||||
});
|
||||
|
||||
// Copy link button should be visible
|
||||
// e2e.pages.ShareDashboardDrawer.ShareSnapshot.copyUrlButton().should('exist');
|
||||
|
||||
//TODO Failing in CI/CD. Fix it
|
||||
// Copy the snapshot URL form the clipboard and open the snapshot
|
||||
// e2e.pages.ShareDashboardDrawer.ShareSnapshot.copyUrlButton()
|
||||
// .click()
|
||||
// .then(() => {
|
||||
// cy.copyFromClipboard().then((url) => {
|
||||
// cy.wrap(url).as('url');
|
||||
// });
|
||||
// })
|
||||
// .then(() => {
|
||||
// cy.get('@url').then((url) => {
|
||||
// e2e.pages.ShareDashboardDrawer.ShareSnapshot.visit(getSnapshotKey(String(url)));
|
||||
// });
|
||||
//
|
||||
// // Validate the dashboard controls are rendered
|
||||
// e2e.pages.Dashboard.Controls().should('exist');
|
||||
//
|
||||
// // Validate the panels are rendered
|
||||
// for (const title of panelsToCheck) {
|
||||
// e2e.components.Panels.Panel.title(title).should('be.visible');
|
||||
// }
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
const getSnapshotUrl = (uid: string): string => {
|
||||
return `/dashboard/snapshot/${uid}`;
|
||||
};
|
||||
|
||||
// const getSnapshotKey = (url: string): string => {
|
||||
// return url.split('/').pop();
|
||||
// };
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Dashboard templating', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
// Note: Only works in Chrome/Chromium-based browsers
|
||||
Cypress.automation('remote:debugger:protocol', {
|
||||
command: 'Emulation.setTimezoneOverride',
|
||||
params: {
|
||||
timezoneId: 'Pacific/Easter', // OR 'UTC'
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('Verify variable interpolation works', () => {
|
||||
// Open dashboard global variables and interpolation
|
||||
e2e.flows.openDashboard({ uid: 'HYaGDGIMk' });
|
||||
|
||||
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||
const example = `Example: from=now-6h&to=now&timezone=${encodeURIComponent(timeZone)}`;
|
||||
|
||||
const items: string[] = [];
|
||||
const expectedItems: string[] = [
|
||||
'__dashboard = Templating - Global variables and interpolation',
|
||||
'__dashboard.name = Templating - Global variables and interpolation',
|
||||
'__dashboard.uid = HYaGDGIMk',
|
||||
'__org.name = Main Org.',
|
||||
'__org.id = 1',
|
||||
'__user.id = 1',
|
||||
'__user.login = admin',
|
||||
'__user.email = admin@localhost',
|
||||
`Server:raw = A'A"A,BB\\B,CCC`,
|
||||
`Server:regex = (A'A"A|BB\\\\B|CCC)`,
|
||||
`Server:lucene = ("A'A\\"A" OR "BB\\\\B" OR "CCC")`,
|
||||
`Server:glob = {A'A"A,BB\\B,CCC}`,
|
||||
`Server:pipe = A'A"A|BB\\B|CCC`,
|
||||
`Server:distributed = A'A"A,Server=BB\\B,Server=CCC`,
|
||||
`Server:csv = A'A"A,BB\\B,CCC`,
|
||||
`Server:html = A'A"A, BB\\B, CCC`,
|
||||
`Server:json = ["A'A\\"A","BB\\\\B","CCC"]`,
|
||||
`Server:percentencode = %7BA%27A%22A%2CBB%5CB%2CCCC%7D`,
|
||||
`Server:singlequote = 'A\\'A"A','BB\\B','CCC'`,
|
||||
`Server:doublequote = "A'A\\"A","BB\\B","CCC"`,
|
||||
`Server:sqlstring = 'A''A\\"A','BB\\\B','CCC'`,
|
||||
`Server:date = NaN`,
|
||||
`Server:text = All`,
|
||||
`Server:queryparam = var-Server=$__all`,
|
||||
`1 < 2`,
|
||||
example,
|
||||
];
|
||||
|
||||
cy.get('.markdown-html li')
|
||||
.should('have.length', 26)
|
||||
.each((element) => {
|
||||
items.push(element.text());
|
||||
})
|
||||
.then(() => {
|
||||
expectedItems.forEach((expected, index) => {
|
||||
expect(items[index]).to.equal(expected);
|
||||
});
|
||||
});
|
||||
|
||||
// Check link interpolation is working correctly
|
||||
cy.contains('a', example).should(
|
||||
'have.attr',
|
||||
'href',
|
||||
`https://example.com/?from=now-6h&to=now&timezone=${encodeURIComponent(timeZone)}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,263 +0,0 @@
|
|||
import {
|
||||
addDays,
|
||||
addHours,
|
||||
differenceInCalendarDays,
|
||||
differenceInMinutes,
|
||||
format,
|
||||
isBefore,
|
||||
parseISO,
|
||||
toDate,
|
||||
} from 'date-fns';
|
||||
|
||||
import { e2e } from '../utils';
|
||||
|
||||
describe('Dashboard time zone support', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it.skip('Tests dashboard time zone scenarios', () => {
|
||||
e2e.flows.openDashboard({ uid: '5SdHCasdf' });
|
||||
|
||||
const fromTimeZone = 'UTC';
|
||||
const toTimeZone = 'America/Chicago';
|
||||
const offset = offsetBetweenTimeZones(toTimeZone, fromTimeZone);
|
||||
|
||||
const panelsToCheck = [
|
||||
'Random walk series',
|
||||
'Millisecond res x-axis and tooltip',
|
||||
'2 yaxis and axis labels',
|
||||
'Stacking value ontop of nulls',
|
||||
'Null between points',
|
||||
'Legend Table No Scroll Visible',
|
||||
];
|
||||
|
||||
const timesInUtc: Record<string, string> = {};
|
||||
|
||||
for (const title of panelsToCheck) {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
e2e.components.Panels.Visualization.Graph.xAxis.labels().should('be.visible');
|
||||
e2e.components.Panels.Visualization.Graph.xAxis
|
||||
.labels()
|
||||
.last()
|
||||
.should((element) => {
|
||||
timesInUtc[title] = element.text();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
e2e.components.PageToolbar.item('Dashboard settings').click();
|
||||
|
||||
e2e.components.TimeZonePicker.containerV2()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
e2e.components.Select.singleValue().should('have.text', 'Coordinated Universal Time');
|
||||
e2e.components.Select.input().should('be.visible').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('be.visible').contains(toTimeZone).click();
|
||||
|
||||
// click to go back to the dashboard.
|
||||
e2e.pages.Dashboard.Settings.Actions.close().click();
|
||||
e2e.components.RefreshPicker.runButtonV2().should('be.visible').click();
|
||||
|
||||
for (const title of panelsToCheck) {
|
||||
e2e.components.Panels.Panel.title(title)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
e2e.components.Panels.Visualization.Graph.xAxis.labels().should('be.visible');
|
||||
e2e.components.Panels.Visualization.Graph.xAxis
|
||||
.labels()
|
||||
.last()
|
||||
.should((element) => {
|
||||
const inUtc = timesInUtc[title];
|
||||
const inTz = element.text();
|
||||
const isCorrect = isTimeCorrect(inUtc, inTz, offset);
|
||||
expect(isCorrect).to.be.equal(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: remove skip once https://github.com/grafana/grafana/issues/86420 is done
|
||||
it.skip('Tests relative timezone support and overrides', () => {
|
||||
// Open dashboard
|
||||
e2e.flows.openDashboard({
|
||||
uid: 'd41dbaa2-a39e-4536-ab2b-caca52f1a9c8',
|
||||
});
|
||||
|
||||
cy.intercept('/api/ds/query*').as('dataQuery');
|
||||
|
||||
// Switch to Browser timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Browser',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Today so far, still in Browser timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel in timezone')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
// Test UTC timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Coordinated Universal Time',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Today so far, still in UTC timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel in timezone')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Test Tokyo timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'Asia/Tokyo',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Today so far, still in Tokyo timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel in timezone')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Test LA timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now-6h',
|
||||
to: 'now',
|
||||
zone: 'America/Los_Angeles',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
// Today so far, still in LA timezone
|
||||
e2e.flows.setTimeRange({
|
||||
from: 'now/d',
|
||||
to: 'now',
|
||||
});
|
||||
// Need to wait for 2 calls as there's 2 panels
|
||||
cy.wait(['@dataQuery', '@dataQuery']);
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel with relative time override')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
|
||||
e2e.components.Panels.Panel.title('Panel in timezone')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.contains('[role="row"]', '00:00:00').should('be.visible');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const isTimeCorrect = (inUtc: string, inTz: string, offset: number): boolean => {
|
||||
if (inUtc === inTz) {
|
||||
// we need to catch issues when timezone isn't changed for some reason like https://github.com/grafana/grafana/issues/35504
|
||||
return false;
|
||||
}
|
||||
|
||||
const reference = format(new Date(), 'yyyy-LL-dd');
|
||||
|
||||
const utcDate = toDate(parseISO(`${reference} ${inUtc}`));
|
||||
const utcDateWithOffset = addHours(toDate(parseISO(`${reference} ${inUtc}`)), offset);
|
||||
const dayDifference = differenceInCalendarDays(utcDate, utcDateWithOffset); // if the utcDate +/- offset is the day before/after then we need to adjust reference
|
||||
const dayOffset = isBefore(utcDateWithOffset, utcDate) ? dayDifference * -1 : dayDifference;
|
||||
const tzDate = addDays(toDate(parseISO(`${reference} ${inTz}`)), dayOffset); // adjust tzDate with any dayOffset
|
||||
const diff = Math.abs(differenceInMinutes(utcDate, tzDate)); // use Math.abs if tzDate is in future
|
||||
|
||||
return diff <= Math.abs(offset * 60);
|
||||
};
|
||||
|
||||
const offsetBetweenTimeZones = (timeZone1: string, timeZone2: string, when: Date = new Date()): number => {
|
||||
const t1 = convertDateToAnotherTimeZone(when, timeZone1);
|
||||
const t2 = convertDateToAnotherTimeZone(when, timeZone2);
|
||||
return (t1.getTime() - t2.getTime()) / (1000 * 60 * 60);
|
||||
};
|
||||
|
||||
const convertDateToAnotherTimeZone = (date: Date, timeZone: string): Date => {
|
||||
const dateString = date.toLocaleString('en-US', {
|
||||
timeZone: timeZone,
|
||||
});
|
||||
return new Date(dateString);
|
||||
};
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Dashboard timepicker', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Shows the correct calendar days with custom timezone set via preferences', () => {
|
||||
e2e.flows.setUserPreferences({
|
||||
timezone: 'Asia/Tokyo',
|
||||
});
|
||||
|
||||
// Open dashboard with time range from 8th to end of 10th.
|
||||
// Will be Tokyo time because of above preference
|
||||
e2e.flows.openDashboard({
|
||||
uid: '5SdHCasdf',
|
||||
timeRange: {
|
||||
zone: 'Default',
|
||||
from: '2022-06-08 00:00:00',
|
||||
to: '2022-06-10 23:59:59',
|
||||
},
|
||||
});
|
||||
|
||||
// Assert that the calendar shows 08 and 09 and 10 as selected days
|
||||
e2e.components.TimePicker.openButton().click();
|
||||
e2e.components.TimePicker.calendar.openButton().first().click();
|
||||
cy.get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
|
||||
});
|
||||
|
||||
it('Shows the correct calendar days with custom timezone set via time picker', () => {
|
||||
// Open dashboard with time range from 2022-06-08 00:00:00 to 2022-06-10 23:59:59 in Tokyo time
|
||||
e2e.flows.openDashboard({
|
||||
uid: '5SdHCasdf',
|
||||
timeRange: {
|
||||
zone: 'Asia/Tokyo',
|
||||
from: '2022-06-08 00:00:00',
|
||||
to: '2022-06-10 23:59:59',
|
||||
},
|
||||
});
|
||||
|
||||
// Assert that the calendar shows 08 and 09 and 10 as selected days
|
||||
e2e.components.TimePicker.openButton().click();
|
||||
e2e.components.TimePicker.calendar.openButton().first().click();
|
||||
cy.get('.react-calendar__tile--active, .react-calendar__tile--hasActive').should('have.length', 3);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { e2e } from '../utils';
|
||||
import { fromBaseUrl } from '../utils/support/url';
|
||||
|
||||
describe('Embedded dashboard', function () {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('open test page', function () {
|
||||
cy.visit(fromBaseUrl('/dashboards/embedding-test'));
|
||||
|
||||
// Verify pie charts are rendered
|
||||
cy.get(
|
||||
`[data-viz-panel-key="panel-11"] [data-testid^="${selectors.components.Panels.Visualization.PieChart.svgSlice}"]`
|
||||
).should('have.length', 5);
|
||||
|
||||
// Verify no url sync
|
||||
e2e.components.TimePicker.openButton().click();
|
||||
cy.get('label:contains("Last 1 hour")').click();
|
||||
cy.url().should('eq', fromBaseUrl('/dashboards/embedding-test'));
|
||||
});
|
||||
});
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'edediimbjhdz4b/a-tall-dashboard';
|
||||
|
||||
describe('Dashboards', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('should restore scroll position', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
e2e.components.Panels.Panel.title('Panel #1').should('be.visible');
|
||||
|
||||
// scroll to the bottom
|
||||
cy.scrollTo('bottom', {
|
||||
timeout: 5 * 1000,
|
||||
});
|
||||
|
||||
// The last panel should be visible...
|
||||
e2e.components.Panels.Panel.title('Panel #50').should('be.visible');
|
||||
|
||||
// Then we open and close the panel editor
|
||||
e2e.components.Panels.Panel.menu('Panel #50').click({ force: true }); // it only shows on hover
|
||||
e2e.components.Panels.Panel.menuItems('Edit').click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
|
||||
// The last panel should still be visible!
|
||||
e2e.components.Panels.Panel.title('Panel #50').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
import testDashboard from '../dashboards/TestDashboard.json';
|
||||
import { e2e } from '../utils';
|
||||
|
||||
describe('Import Dashboards Test', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Ensure you can import a number of json test dashboards from a specific test directory', () => {
|
||||
e2e.flows.importDashboard(testDashboard, 1000);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
|
||||
describe('Variables - Load options from Url', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('default options should be correct', () => {
|
||||
e2e.flows.openDashboard({ uid: PAGE_UNDER_TEST });
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
pathname: '/api/ds/query*',
|
||||
}).as('query');
|
||||
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('C').should('be.visible');
|
||||
|
||||
cy.get('body').click(0, 0);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('AA')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AC').should('be.visible');
|
||||
|
||||
cy.get('body').click(0, 0);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('$__all')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAC').should('be.visible');
|
||||
});
|
||||
|
||||
it('options set in url should load correct options', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=B&var-server=BB&var-pod=BBB` });
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('B')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('C').should('be.visible');
|
||||
|
||||
cy.get('body').click(0, 0);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('BB')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BC').should('be.visible');
|
||||
|
||||
cy.get('body').click(0, 0);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('BBB')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBC').should('be.visible');
|
||||
});
|
||||
|
||||
it('options set in url that do not exist should load correct options', () => {
|
||||
// @ts-ignore some typing issue
|
||||
cy.on('uncaught:exception', (err) => {
|
||||
if (err.stack?.indexOf("Couldn't find any field of type string in the results.") !== -1) {
|
||||
// return false to prevent the error from
|
||||
// failing this test
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=X` });
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('X')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('C').should('be.visible');
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('$__all')
|
||||
.should('be.visible')
|
||||
.should('have.length', 2);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
describe('Variables - Constant', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('can add a new constant variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "Constant" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Constant{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.ConstantVariable.constantOptionsQueryInputV2().type('pesto').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
|
||||
|
||||
// e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(0).should('have.text', 'pesto');
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
e2e.components.RefreshPicker.runButtonV2().click();
|
||||
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: pesto');
|
||||
|
||||
// Assert the variable is not visible in the dashboard nav
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('Variable under test').should('not.exist');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,68 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
function fillInCustomVariable(name: string, label: string, value: string) {
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Custom{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type(name).blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type(label).blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.CustomVariable.customValueInput().type(value).blur();
|
||||
}
|
||||
|
||||
function assertPreviewValues(expectedValues: string[]) {
|
||||
for (const expected of expectedValues) {
|
||||
const index = expectedValues.indexOf(expected);
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(index).should('have.text', expected);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Variables - Custom', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('can add a custom template variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "Custom" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
fillInCustomVariable('VariableUnderTest', 'Variable under test', 'one,two,three');
|
||||
assertPreviewValues(['one', 'two', 'three']);
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('one').click();
|
||||
e2e.components.Select.option().contains('two').click();
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: two');
|
||||
});
|
||||
|
||||
it('can add a custom template variable with labels', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "Custom" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Custom{enter}');
|
||||
});
|
||||
|
||||
// Set its name, label, and content
|
||||
fillInCustomVariable('VariableUnderTest', 'Variable under test', 'One : 1,Two : 2, Three : 3');
|
||||
assertPreviewValues(['One', 'Two', 'Three']);
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('1').click();
|
||||
e2e.components.Select.option().contains('Two').click();
|
||||
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: 2');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
// Skipping due to flakiness/race conditions with same old arch test e2e/dashboards-suite/new-datasource-variable.spec.ts
|
||||
describe.skip('Variables - Datasource', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('can add a new datasource variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "Datasource" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Data source{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
|
||||
|
||||
// If this is failing, but sure to check there are Prometheus datasources named "gdev-prometheus" and "gdev-slow-prometheus"
|
||||
// Or, just update is to match some gdev datasources to test with :)
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.DatasourceVariable.datasourceSelect().within(() => {
|
||||
cy.get('input').type('Prometheus{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should(
|
||||
'contain.text',
|
||||
'gdev-prometheus'
|
||||
);
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should(
|
||||
'contain.text',
|
||||
'gdev-slow-prometheus'
|
||||
);
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
e2e.components.RefreshPicker.runButtonV2().click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('gdev-prometheus').click();
|
||||
e2e.components.Select.option().contains('gdev-slow-prometheus').click();
|
||||
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: gdev-slow-prometheus-uid');
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTestText: gdev-slow-prometheus');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
function assertPreviewValues(expectedValues: string[]) {
|
||||
for (const expected of expectedValues) {
|
||||
const index = expectedValues.indexOf(expected);
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().eq(index).should('have.text', expected);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Variables - Interval', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('can add a new interval variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "Interval" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Interval{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.IntervalVariable.intervalsValueInput()
|
||||
.clear()
|
||||
.type('10s,10m,60m,90m,1h30m')
|
||||
.blur();
|
||||
|
||||
assertPreviewValues(['10s', '10m', '60m', '90m', '1h30m']);
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
|
||||
e2e.components.RefreshPicker.runButtonV2().click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('Variable under test').next().should('have.text', `10s`).click();
|
||||
e2e.components.Select.option().contains('1h30m').click();
|
||||
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: 1h30m');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,184 +0,0 @@
|
|||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
const DASHBOARD_NAME = 'Templating - Nested Template Variables';
|
||||
|
||||
describe('Variables - Query - Add variable', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('query variable should be default and default fields should be correct', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
cy.get(`[data-testid="${selectors.pages.Dashboard.Settings.Variables.List.newButton}"]`)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2()
|
||||
.should('be.visible')
|
||||
.within((input) => {
|
||||
expect(input.attr('placeholder')).equals('Variable name');
|
||||
expect(input.val()).equals('query0');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2()
|
||||
.should('be.visible')
|
||||
.within((select) => {
|
||||
e2e.components.Select.singleValue().should('have.text', 'Query');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2()
|
||||
.should('be.visible')
|
||||
.within((input) => {
|
||||
expect(input.attr('placeholder')).equals('Label name');
|
||||
expect(input.val()).equals('');
|
||||
});
|
||||
cy.get('[placeholder="Descriptive text"]')
|
||||
.should('be.visible')
|
||||
.within((input) => {
|
||||
expect(input.attr('placeholder')).equals('Descriptive text');
|
||||
expect(input.val()).equals('');
|
||||
});
|
||||
cy.get('label').contains('Hide').should('be.visible');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsDataSourceSelect()
|
||||
.get('input[placeholder="gdev-testdata"]')
|
||||
.scrollIntoView()
|
||||
.should('be.visible');
|
||||
|
||||
cy.get('label').contains('Refresh').scrollIntoView().should('be.visible');
|
||||
cy.get('label').contains('On dashboard load').scrollIntoView().should('be.visible');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2()
|
||||
.should('be.visible')
|
||||
.within((input) => {
|
||||
const placeholder = '/.*-(?<text>.*)-(?<value>.*)-.*/';
|
||||
expect(input.attr('placeholder')).equals(placeholder);
|
||||
expect(input.val()).equals('');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsSortSelectV2()
|
||||
.should('be.visible')
|
||||
.within((select) => {
|
||||
e2e.components.Select.singleValue().should('have.text', 'Disabled');
|
||||
});
|
||||
|
||||
cy.contains('label', 'Multi-value').within(() => {
|
||||
cy.get('input[type="checkbox"]').should('not.be.checked');
|
||||
});
|
||||
|
||||
cy.contains('label', 'Include All option').within(() => {
|
||||
cy.get('input[type="checkbox"]').should('not.be.checked');
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should('not.exist');
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput().should('not.exist');
|
||||
});
|
||||
|
||||
it('adding a single value query variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
cy.get(`[data-testid="${selectors.pages.Dashboard.Settings.Variables.List.newButton}"]`)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2()
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('a label');
|
||||
|
||||
cy.get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
|
||||
|
||||
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-testdata{enter}');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
|
||||
.should('be.visible')
|
||||
.type('*')
|
||||
.blur();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2()
|
||||
.should('be.visible')
|
||||
.type('/.*C.*/')
|
||||
.blur();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should('exist');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().scrollIntoView().should('be.visible').click();
|
||||
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('a label').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem()
|
||||
.should('have.length', 4)
|
||||
.eq(3)
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('have.length', 1);
|
||||
e2e.components.Select.option().contains('C');
|
||||
});
|
||||
|
||||
it('adding a multi value query variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
cy.get(`[data-testid="${selectors.pages.Dashboard.Settings.Variables.List.newButton}"]`)
|
||||
.should('be.visible')
|
||||
.click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2()
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('a label');
|
||||
|
||||
cy.get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');
|
||||
|
||||
e2e.components.DataSourcePicker.container().type('gdev-testdata{enter}');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
|
||||
.should('be.visible')
|
||||
.type('*')
|
||||
.blur();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsRegExInputV2()
|
||||
.should('be.visible')
|
||||
.type('/.*C.*/')
|
||||
.blur();
|
||||
|
||||
cy.contains('label', 'Multi-value').within(() => {
|
||||
cy.get('input[type="checkbox"]').click({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
cy.contains('label', 'Include All option').within(() => {
|
||||
cy.get('input[type="checkbox"]').click({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.selectionOptionsCustomAllInput().within((input) => {
|
||||
expect(input.val()).equals('');
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption().should('exist');
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.submitButton().scrollIntoView().should('be.visible').click();
|
||||
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('a label').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem()
|
||||
.should('have.length', 4)
|
||||
.eq(3)
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('have.length', 3);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.components.Select.option().contains('All');
|
||||
e2e.components.Select.option().contains('C');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'kVi2Gex7z/test-variable-output';
|
||||
const DASHBOARD_NAME = 'Test variable output';
|
||||
|
||||
describe('Variables - Text box', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('can add a new text box variable', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&editview=variables` });
|
||||
cy.contains(DASHBOARD_NAME).should('be.visible');
|
||||
|
||||
// Create a new "text box" variable
|
||||
e2e.components.CallToActionCard.buttonV2('Add variable').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalTypeSelectV2().within(() => {
|
||||
cy.get('input').type('Textbox{enter}');
|
||||
});
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalNameInputV2().clear().type('VariableUnderTest').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.generalLabelInputV2().type('Variable under test').blur();
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.TextBoxVariable.textBoxOptionsQueryInputV2().type('cat-dog').blur();
|
||||
|
||||
// Navigate back to the homepage and change the selected variable value
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.applyButton().click();
|
||||
e2e.components.NavToolbar.editDashboard.backToDashboardButton().click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem().within(() => {
|
||||
cy.get('input').clear().type('dog-cat').blur();
|
||||
});
|
||||
// Assert it was rendered
|
||||
cy.get('.markdown-html').should('include.text', 'VariableUnderTest: dog-cat');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,171 +0,0 @@
|
|||
import { selectors } from '@grafana/e2e-selectors';
|
||||
|
||||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = '-Y-tnEDWk/templating-nested-template-variables';
|
||||
|
||||
describe('Variables - Set options from ui', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('clicking a value that is not part of dependents options should change these to All', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=A&var-server=AA&var-pod=AAA` });
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible').click();
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible').click();
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('B').scrollIntoView().should('be.visible');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('$__all')
|
||||
.should('have.length', 2)
|
||||
.eq(0)
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().parent().should('have.length', 10);
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (1)');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BC').should('be.visible');
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('pod')
|
||||
.parent()
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
// length is 11 because of virtualized select options
|
||||
e2e.components.Select.option().parent().should('have.length', 11);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAC').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAD').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAE').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BAF').should('be.visible');
|
||||
});
|
||||
|
||||
it('adding a value that is not part of dependents options should add the new values dependant options', () => {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=A&var-server=AA&var-pod=AAA` });
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('B').should('be.visible').click();
|
||||
|
||||
e2e.components.Select.toggleAllOptions().should('have.text', 'Selected (2)');
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
cy.wait('@query');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A,B').scrollIntoView().should('be.visible');
|
||||
|
||||
cy.get(`[aria-label="${selectors.components.LoadingIndicator.icon}"]`).should('not.exist');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('AA')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('have.length', 11);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AC').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AD').should('be.visible');
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('AAA')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('have.length', 10);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('AAC').should('be.visible');
|
||||
});
|
||||
|
||||
it('removing a value that is part of dependents options should remove the new values dependant options', () => {
|
||||
e2e.flows.openDashboard({
|
||||
uid: `${PAGE_UNDER_TEST}?orgId=1&var-datacenter=A&var-datacenter=B&var-server=AA&var-server=BB&var-pod=AAA&var-pod=BBB`,
|
||||
});
|
||||
cy.intercept({ pathname: '/api/ds/query' }).as('query');
|
||||
|
||||
cy.wait('@query');
|
||||
cy.get(`[aria-label="${selectors.components.LoadingIndicator.icon}"]`).should('not.exist');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('A,B')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('A').should('be.visible').click();
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
cy.wait('@query');
|
||||
cy.get(`[aria-label="${selectors.components.LoadingIndicator.icon}"]`).should('not.exist');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('B').should('be.visible');
|
||||
|
||||
cy.get(`[aria-label="${selectors.components.LoadingIndicator.icon}"]`).should('not.exist');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('BB')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.components.Select.option().should('have.length', 10);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('All').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BC').should('be.visible');
|
||||
|
||||
cy.get('body').click(0, 0);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('BBB')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
e2e.components.Select.option().should('have.length', 10);
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBA').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBB').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('BBC').should('be.visible');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Snapshots', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Create a snapshot dashboard', () => {
|
||||
// Opening a dashboard
|
||||
cy.intercept({
|
||||
pathname: '/api/ds/query',
|
||||
}).as('query');
|
||||
e2e.flows.openDashboard({ uid: 'ZqZnVvFZz', queryParams: { '__feature.newDashboardSharingComponent': false } });
|
||||
cy.wait('@query');
|
||||
|
||||
const panelsToCheck = [
|
||||
'Raw Data Graph',
|
||||
'Last non-null',
|
||||
'min',
|
||||
'Max',
|
||||
'The data from graph above with seriesToColumns transform',
|
||||
];
|
||||
|
||||
// Open the sharing modal
|
||||
e2e.components.NavToolbar.shareDashboard().click();
|
||||
|
||||
// Select the snapshot tab
|
||||
e2e.components.Tab.title('Snapshot').click();
|
||||
|
||||
// Publish snapshot
|
||||
cy.intercept('POST', '/api/snapshots').as('save');
|
||||
e2e.pages.ShareDashboardModal.SnapshotScene.PublishSnapshot().click();
|
||||
cy.wait('@save');
|
||||
|
||||
// Copy link button should be visible
|
||||
e2e.pages.ShareDashboardModal.SnapshotScene.CopyUrlButton().should('exist');
|
||||
|
||||
// Copy the snapshot URL form the input and open the snapshot
|
||||
e2e.pages.ShareDashboardModal.SnapshotScene.CopyUrlInput()
|
||||
.invoke('val')
|
||||
.then((text) => cy.wrap(text).as('url'));
|
||||
|
||||
// Open the snapshot using the new URL
|
||||
cy.get('@url').then((url) => {
|
||||
e2e.pages.ShareDashboardModal.SnapshotScene.visit(getSnapshotKey(String(url)));
|
||||
});
|
||||
|
||||
// Validate the dashboard controls are rendered
|
||||
e2e.pages.Dashboard.Controls().should('exist');
|
||||
|
||||
// Validate the panels are rendered
|
||||
for (const title of panelsToCheck) {
|
||||
e2e.components.Panels.Panel.title(title).should('be.visible');
|
||||
}
|
||||
});
|
||||
});
|
||||
//
|
||||
const getSnapshotKey = (url: string): string => {
|
||||
return url.split('/').pop();
|
||||
};
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
describe('Templating', () => {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('Tests dashboard links and variables in links', () => {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/api/search?tag=templating&limit=100',
|
||||
}).as('tagsTemplatingSearch');
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/api/search?tag=demo&limit=100',
|
||||
}).as('tagsDemoSearch');
|
||||
|
||||
e2e.flows.openDashboard({ uid: 'yBCC3aKGk' });
|
||||
|
||||
// waiting for network requests first
|
||||
cy.wait(['@tagsTemplatingSearch', '@tagsDemoSearch']);
|
||||
|
||||
const verifyLinks = (variableValue: string) => {
|
||||
e2e.components.DashboardLinks.link()
|
||||
.should('be.visible')
|
||||
.should((links) => {
|
||||
expect(links).to.have.length.greaterThan(13);
|
||||
|
||||
for (let index = 0; index < links.length; index++) {
|
||||
expect(Cypress.$(links[index]).attr('href')).contains(variableValue);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
e2e.components.DashboardLinks.dropDown().should('be.visible').click().wait('@tagsTemplatingSearch');
|
||||
|
||||
verifyLinks('var-custom=$__all');
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownValueLinkTexts('$__all')
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input').click();
|
||||
});
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemValueDropDownOptionTexts('p2').should('be.visible').click();
|
||||
|
||||
cy.get('body').click();
|
||||
|
||||
e2e.components.DashboardLinks.dropDown()
|
||||
.scrollIntoView()
|
||||
.should('be.visible')
|
||||
.click()
|
||||
.wait('@tagsTemplatingSearch');
|
||||
|
||||
// verify all links, should have p2 value
|
||||
verifyLinks('p2');
|
||||
});
|
||||
});
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
import { e2e } from '../utils';
|
||||
|
||||
const PAGE_UNDER_TEST = 'AejrN1AMz';
|
||||
|
||||
describe('TextBox - load options scenarios', function () {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('default options should be correct', function () {
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}/templating-textbox-e2e-scenarios?orgId=1` });
|
||||
|
||||
validateTextboxAndMarkup('default value');
|
||||
});
|
||||
|
||||
it('loading variable from url should be correct', function () {
|
||||
e2e.flows.openDashboard({
|
||||
uid: `${PAGE_UNDER_TEST}/templating-textbox-e2e-scenarios?orgId=1&var-text=not default value`,
|
||||
});
|
||||
|
||||
validateTextboxAndMarkup('not default value');
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('TextBox - change query scenarios', function () {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('when changing the query value and not saving current as default should revert query value', function () {
|
||||
copyExistingDashboard();
|
||||
|
||||
changeQueryInput();
|
||||
|
||||
e2e.components.BackButton.backArrow().should('be.visible').click({ force: true });
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
|
||||
saveDashboard(false);
|
||||
|
||||
cy.get<string>('@dashuid').then((dashuid) => {
|
||||
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
|
||||
|
||||
e2e.flows.openDashboard({ uid: dashuid });
|
||||
|
||||
cy.wait('@load-dash');
|
||||
|
||||
validateTextboxAndMarkup('default value');
|
||||
|
||||
validateVariable('changed value');
|
||||
});
|
||||
});
|
||||
|
||||
it('when changing the query value and saving current as default should change query value', function () {
|
||||
copyExistingDashboard();
|
||||
|
||||
changeQueryInput();
|
||||
|
||||
e2e.components.BackButton.backArrow().should('be.visible').click({ force: true });
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
|
||||
saveDashboard(true);
|
||||
|
||||
cy.get<string>('@dashuid').then((dashuid) => {
|
||||
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
|
||||
|
||||
e2e.flows.openDashboard({ uid: dashuid });
|
||||
|
||||
cy.wait('@load-dash');
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
|
||||
validateVariable('changed value');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe.skip('TextBox - change picker value scenarios', function () {
|
||||
beforeEach(() => {
|
||||
e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'));
|
||||
});
|
||||
|
||||
it('when changing the input value and not saving current as default should revert query value', function () {
|
||||
copyExistingDashboard();
|
||||
|
||||
changeTextBoxInput();
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
|
||||
saveDashboard(false);
|
||||
|
||||
cy.get<string>('@dashuid').then((dashuid) => {
|
||||
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
|
||||
|
||||
e2e.flows.openDashboard({ uid: dashuid });
|
||||
|
||||
cy.wait('@load-dash');
|
||||
|
||||
validateTextboxAndMarkup('default value');
|
||||
validateVariable('default value');
|
||||
});
|
||||
});
|
||||
|
||||
it('when changing the input value and saving current as default should change query value', function () {
|
||||
copyExistingDashboard();
|
||||
|
||||
changeTextBoxInput();
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
|
||||
saveDashboard(true);
|
||||
|
||||
cy.get<string>('@dashuid').then((dashuid) => {
|
||||
expect(dashuid).not.to.eq(PAGE_UNDER_TEST);
|
||||
|
||||
e2e.flows.openDashboard({ uid: dashuid });
|
||||
|
||||
cy.wait('@load-dash');
|
||||
|
||||
validateTextboxAndMarkup('changed value');
|
||||
validateVariable('changed value');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function copyExistingDashboard() {
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: '/api/search?query=&type=dash-folder&permission=Edit',
|
||||
}).as('dash-settings');
|
||||
cy.intercept({
|
||||
method: 'POST',
|
||||
url: '/api/dashboards/db/',
|
||||
}).as('save-dash');
|
||||
cy.intercept({
|
||||
method: 'GET',
|
||||
url: /\/api\/dashboards\/uid\/(?!AejrN1AMz)\w+/,
|
||||
}).as('load-dash');
|
||||
e2e.flows.openDashboard({ uid: `${PAGE_UNDER_TEST}/templating-textbox-e2e-scenarios?orgId=1&editview=settings` });
|
||||
|
||||
cy.wait('@dash-settings');
|
||||
|
||||
e2e.pages.Dashboard.Settings.General.saveAsDashBoard().should('be.visible').click();
|
||||
|
||||
e2e.pages.SaveDashboardAsModal.newName().should('be.visible').type(`${Date.now()}`);
|
||||
|
||||
e2e.pages.SaveDashboardAsModal.save().should('be.visible').click();
|
||||
|
||||
cy.wait('@save-dash');
|
||||
cy.wait('@load-dash');
|
||||
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem().should('be.visible');
|
||||
|
||||
cy.location().then((loc) => {
|
||||
const dashuid = /\/d\/(\w+)\//.exec(loc.href)![1];
|
||||
cy.wrap(dashuid).as('dashuid');
|
||||
});
|
||||
|
||||
cy.wait(500);
|
||||
}
|
||||
|
||||
function saveDashboard(saveVariables: boolean) {
|
||||
e2e.components.PageToolbar.item('Save dashboard').should('be.visible').click();
|
||||
|
||||
if (saveVariables) {
|
||||
e2e.pages.SaveDashboardModal.saveVariables().should('exist').click({ force: true });
|
||||
}
|
||||
|
||||
e2e.pages.SaveDashboardModal.save().should('be.visible').click();
|
||||
|
||||
cy.wait('@save-dash');
|
||||
}
|
||||
|
||||
function validateTextboxAndMarkup(value: string) {
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('text').should('be.visible');
|
||||
cy.get('input').should('be.visible').should('have.value', value);
|
||||
});
|
||||
|
||||
e2e.components.Panels.Visualization.Text.container()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('h1').should('be.visible').should('have.text', `variable: ${value}`);
|
||||
});
|
||||
}
|
||||
|
||||
function validateVariable(value: string) {
|
||||
e2e.components.PageToolbar.item('Dashboard settings').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.General.sectionItems('Variables').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.List.tableRowNameFields('text').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.TextBoxVariable.textBoxOptionsQueryInputV2()
|
||||
.should('be.visible')
|
||||
.should('have.value', value);
|
||||
}
|
||||
|
||||
function changeTextBoxInput() {
|
||||
e2e.pages.Dashboard.SubMenu.submenuItemLabels('text').should('be.visible');
|
||||
e2e.pages.Dashboard.SubMenu.submenuItem()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input')
|
||||
.should('be.visible')
|
||||
.should('have.value', 'default value')
|
||||
.clear()
|
||||
.type('changed value')
|
||||
.type('{enter}');
|
||||
});
|
||||
|
||||
cy.location().should((loc) => {
|
||||
expect(loc.search).to.contain('var-text=changed%20value');
|
||||
});
|
||||
}
|
||||
|
||||
function changeQueryInput() {
|
||||
e2e.components.PageToolbar.item('Dashboard settings').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.General.sectionItems('Variables').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.List.tableRowNameFields('text').should('be.visible').click();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.TextBoxVariable.textBoxOptionsQueryInputV2()
|
||||
.should('be.visible')
|
||||
.clear()
|
||||
.type('changed value')
|
||||
.blur();
|
||||
|
||||
e2e.pages.Dashboard.Settings.Variables.Edit.General.previewOfValuesOption()
|
||||
.should('have.length', 1)
|
||||
.should('have.text', 'changed value');
|
||||
}
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
export function makeNewDashboardRequestBody(dashboardName: string, folderUid?: string) {
|
||||
return {
|
||||
dashboard: {
|
||||
annotations: {
|
||||
list: [
|
||||
{
|
||||
builtIn: 1,
|
||||
datasource: { type: 'grafana', uid: '-- Grafana --' },
|
||||
enable: true,
|
||||
hide: true,
|
||||
iconColor: 'rgba(0, 211, 255, 1)',
|
||||
name: 'Annotations & Alerts',
|
||||
type: 'dashboard',
|
||||
},
|
||||
],
|
||||
},
|
||||
editable: true,
|
||||
fiscalYearStartMonth: 0,
|
||||
graphTooltip: 0,
|
||||
links: [],
|
||||
liveNow: false,
|
||||
panels: [
|
||||
{
|
||||
datasource: { type: 'testdata', uid: '89_jzlT4k' },
|
||||
gridPos: { h: 9, w: 12, x: 0, y: 0 },
|
||||
id: 2,
|
||||
options: {
|
||||
code: {
|
||||
language: 'plaintext',
|
||||
showLineNumbers: false,
|
||||
showMiniMap: false,
|
||||
},
|
||||
content: '***A nice little happy empty dashboard***',
|
||||
mode: 'markdown',
|
||||
},
|
||||
pluginVersion: '9.4.0-pre',
|
||||
title: 'Nothing to see here',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
refresh: '',
|
||||
revision: 1,
|
||||
schemaVersion: 38,
|
||||
tags: [],
|
||||
templating: { list: [] },
|
||||
time: { from: 'now-6h', to: 'now' },
|
||||
timepicker: {},
|
||||
timezone: '',
|
||||
title: dashboardName,
|
||||
version: 0,
|
||||
uid: '',
|
||||
weekStart: '',
|
||||
},
|
||||
message: '',
|
||||
overwrite: false,
|
||||
folderUid,
|
||||
} as const;
|
||||
}
|
||||
|
|
@ -28,7 +28,6 @@ declare -A env=(
|
|||
testFilesForSingleSuite="*.spec.ts"
|
||||
rootForEnterpriseSuite="./e2e/extensions"
|
||||
rootForOldArch="./e2e/old-arch"
|
||||
rootForKubernetesDashboards="./e2e/dashboards-suite"
|
||||
rootForSearchDashboards="./e2e/dashboards-search-suite"
|
||||
|
||||
declare -A cypressConfig=(
|
||||
|
|
@ -111,24 +110,6 @@ case "$1" in
|
|||
cypressConfig[video]=${args[1]}
|
||||
env[dashboardScene]=false
|
||||
;;
|
||||
"dashboards-schema-v2")
|
||||
env[kubernetesDashboards]=true
|
||||
cypressConfig[specPattern]=$rootForKubernetesDashboards/$testFilesForSingleSuite
|
||||
cypressConfig[video]=false
|
||||
case "$2" in
|
||||
"debug")
|
||||
echo -e "Debug mode"
|
||||
env[SLOWMO]=1
|
||||
PARAMS="--no-exit"
|
||||
enterpriseSuite=$(basename "${args[2]}")
|
||||
;;
|
||||
"dev")
|
||||
echo "Dev mode"
|
||||
CMD="cypress open"
|
||||
enterpriseSuite=$(basename "${args[2]}")
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"dashboards-search")
|
||||
env[kubernetesDashboards]=true
|
||||
cypressConfig[specPattern]=$rootForSearchDashboards/$testFilesForSingleSuite
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"dev": "NODE_ENV=dev nx exec -- webpack --config scripts/webpack/webpack.dev.js",
|
||||
"e2e": "./e2e/start-and-run-suite",
|
||||
"e2e:old-arch": "./e2e/start-and-run-suite old-arch",
|
||||
"e2e:schema-v2": "./e2e/start-and-run-suite dashboards-schema-v2",
|
||||
"e2e:schema-v2": "KUBERNETES_DASHBOARDS=true yarn playwright test --project dashboards",
|
||||
"e2e:dashboards-search": "./e2e/start-and-run-suite dashboards-search",
|
||||
"e2e:debug": "./e2e/start-and-run-suite debug",
|
||||
"e2e:dev": "./e2e/start-and-run-suite dev",
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ echo starting server
|
|||
# air now deletes the binary, so we check if we need to build it before trying to start the server
|
||||
# see https://github.com/air-verse/air/issues/525
|
||||
# if this gets resolved, we could remove the go build and rely on the binary being present as before
|
||||
if [[ ! -f ./bin/grafana ]]; then
|
||||
if [[ ! -f ./bin/"$ARCH"grafana ]]; then
|
||||
make GO_BUILD_DEV=1 build-go-fast
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue