e2e: Adds ScenarioContext and video recordings to e2e (#21110)

* Refactor: Adds ScenarioContext

* Refactor: Removes async

* Refactor: Adds video and reverts CIRCLE_SHA2 to CIRCLE_SHA1

* Refactor: Adds videos to release job as well
This commit is contained in:
Hugo Häggmark
2019-12-16 08:49:36 +01:00
committed by GitHub
parent fcc74ad2b4
commit 664cb5f8f1
10 changed files with 62 additions and 46 deletions

View File

@@ -125,7 +125,7 @@ jobs:
- node_modules
- run:
name: run end-to-end tests
command: 'env BASE_URL=http://127.0.0.1:3000 yarn e2e-tests'
command: 'env BASE_URL=http://127.0.0.1:3000 yarn e2e-tests:ci'
no_output_timeout: 5m
- store_artifacts:
path: public/e2e-tests/screenShots/theTruth
@@ -133,6 +133,9 @@ jobs:
- store_artifacts:
path: public/e2e-tests/screenShots/theOutput
destination: output-screenshots
- store_artifacts:
path: public/e2e-tests/videos
destination: output-videos
- run:
name: ci job failed
command: './scripts/ci-job-failed.sh'
@@ -164,7 +167,7 @@ jobs:
- node_modules
- run:
name: run end-to-end tests
command: 'env BASE_URL=http://127.0.0.1:3000 yarn e2e-tests'
command: 'env BASE_URL=http://127.0.0.1:3000 yarn e2e-tests:ci'
no_output_timeout: 5m
- store_artifacts:
path: public/e2e-tests/screenShots/theTruth
@@ -172,6 +175,9 @@ jobs:
- store_artifacts:
path: public/e2e-tests/screenShots/theOutput
destination: output-screenshots
- store_artifacts:
path: public/e2e-tests/videos
destination: output-videos
- run:
name: ci job failed
command: './scripts/ci-job-failed.sh'

2
.gitignore vendored
View File

@@ -101,4 +101,4 @@ compilation-stats.json
/packages/grafana-e2e/cypress/logs
/public/e2e-test/screenShots/theOutput
/public/e2e-tests/screenShots/theOutput/*.png
public/e2e-tests/videos

View File

@@ -162,8 +162,9 @@
"typecheckPackages": "yarn workspaces run typecheck",
"jest": "jest --notify --watch",
"jest-ci": "mkdir -p reports/junit && export JEST_JUNIT_OUTPUT_DIR=reports/junit && jest --ci --reporters=default --reporters=jest-junit --maxWorkers 2",
"e2e": "cd packages/grafana-e2e && yarn start --env BASE_URL=$BASE_URL,CIRCLE_SHA2=$CIRCLE_SHA2,SLOWMO=$SLOWMO --record --config integrationFolder=../../public/e2e-tests/integration,screenshotsFolder=../../public/e2e-tests/screenShots,fileServerFolder=./cypress,video=false,viewportWidth=1920,viewportHeight=1080,trashAssetsBeforeRuns=false",
"e2e": "cd packages/grafana-e2e && yarn start --env BASE_URL=$BASE_URL,CIRCLE_SHA1=$CIRCLE_SHA1,SLOWMO=$SLOWMO --config integrationFolder=../../public/e2e-tests/integration,screenshotsFolder=../../public/e2e-tests/screenShots,videosFolder=../../public/e2e-tests/videos,fileServerFolder=./cypress,viewportWidth=1920,viewportHeight=1080,trashAssetsBeforeRuns=false",
"e2e-tests": "yarn e2e",
"e2e-tests:ci": "yarn e2e --record",
"e2e-tests:debug": "SLOWMO=1 yarn e2e --headed --no-exit",
"api-tests": "jest --notify --watch --config=devenv/e2e-api-tests/jest.js",
"storybook": "cd packages/grafana-ui && yarn storybook --ci",

View File

@@ -1,21 +1,17 @@
import { e2e } from '../index';
import { Url } from '../support/url';
export const addDashboard = async (): Promise<{ dashboardTitle: string; uid: string }> => {
export const addDashboard = () => {
e2e().logToConsole('Adding dashboard');
e2e.pages.AddDashboard.visit();
const dashboardTitle = e2e.flows.saveNewDashboard();
e2e().logToConsole('Added dashboard with title:', dashboardTitle);
return new Promise(resolve => {
e2e()
.url()
.then((url: string) => {
resolve({
dashboardTitle,
uid: Url.getDashboardUid(url),
});
});
});
e2e()
.url()
.then((url: string) => {
e2e.context().set('lastAddedDashboard', dashboardTitle);
e2e.context().set('lastAddedDashboardUid', Url.getDashboardUid(url));
});
};

View File

@@ -16,6 +16,7 @@ export const addDataSource = (pluginName?: string): string => {
e2e.pages.DataSource.alert().should('exist');
e2e.pages.DataSource.alertMessage().should('contain.text', 'Data source is working');
e2e().logToConsole('Added data source with name:', dataSourceName);
e2e.context().set('lastAddedDataSource', dataSourceName);
return dataSourceName;
};

View File

@@ -6,6 +6,7 @@
import { e2eScenario, ScenarioArguments } from './support/scenario';
import { Pages } from './pages';
import { Flows } from './flows';
import { scenarioContext } from './support/scenarioContext';
export type SelectorFunction = (text?: string) => Cypress.Chainable<any>;
export type SelectorObject<S> = {
@@ -19,6 +20,7 @@ const e2eObject = {
blobToBase64String: (blob: any) => Cypress.Blob.blobToBase64String(blob),
imgSrcToBlob: (url: string) => Cypress.Blob.imgSrcToBlob(url),
scenario: (args: ScenarioArguments) => e2eScenario(args),
context: scenarioContext,
pages: Pages,
flows: Flows,
};

View File

@@ -1,5 +1,3 @@
import { ScenarioContext } from './scenario';
export { ScenarioContext };
export * from './types';
export * from './selector';
export * from './scenarioContext';

View File

@@ -1,15 +1,9 @@
import { e2e } from '../index';
export interface ScenarioContext {
dataSourceName?: string;
dashboardTitle?: string;
dashboardUid?: string;
}
export interface ScenarioArguments {
describeName: string;
itName: string;
scenario: (context: ScenarioContext) => void;
scenario: () => void;
skipScenario?: boolean;
addScenarioDataSource?: boolean;
addScenarioDashBoard?: boolean;
@@ -32,37 +26,27 @@ export const e2eScenario = ({
return;
}
let scenarioDataSource: string;
let scenarioDashBoardTitle: string;
let scenarioDashBoardUid: string;
beforeEach(async () => {
beforeEach(() => {
e2e.flows.login('admin', 'admin');
if (addScenarioDataSource) {
scenarioDataSource = e2e.flows.addDataSource('TestData DB');
e2e.flows.addDataSource('TestData DB');
}
if (addScenarioDashBoard) {
const { dashboardTitle, uid } = await e2e.flows.addDashboard();
scenarioDashBoardTitle = dashboardTitle;
scenarioDashBoardUid = uid;
e2e.flows.addDashboard();
}
});
afterEach(() => {
if (scenarioDataSource) {
e2e.flows.deleteDataSource(scenarioDataSource);
if (e2e.context().get('lastAddedDataSource')) {
e2e.flows.deleteDataSource(e2e.context().get('lastAddedDataSource'));
}
if (scenarioDashBoardUid) {
e2e.flows.deleteDashboard(scenarioDashBoardUid);
if (e2e.context().get('lastAddedDashboardUid')) {
e2e.flows.deleteDashboard(e2e.context().get('lastAddedDashboardUid'));
}
});
it(itName, () => {
scenario({
dashboardTitle: scenarioDashBoardTitle,
dashboardUid: scenarioDashBoardUid,
dataSourceName: scenarioDataSource,
});
scenario();
});
});
};

View File

@@ -0,0 +1,29 @@
export interface ScenarioContext {
lastAddedDataSource: string;
lastAddedDashboard: string;
lastAddedDashboardUid: string;
[key: string]: any;
}
const scenarioContexts: ScenarioContext = {
lastAddedDataSource: '',
lastAddedDashboard: '',
lastAddedDashboardUid: '',
};
export interface ScenarioContextApi {
get: <T>(name: string | keyof ScenarioContext) => T;
set: <T>(name: string | keyof ScenarioContext, value: T) => void;
}
export const scenarioContext = (): ScenarioContextApi => {
const get = <T>(name: string | keyof ScenarioContext): T => scenarioContexts[name] as T;
const set = <T>(name: string | keyof ScenarioContext, value: T): void => {
scenarioContexts[name] = value;
};
return {
get,
set,
};
};

View File

@@ -1,5 +1,4 @@
import { e2e } from '@grafana/e2e';
import { ScenarioContext } from '@grafana/e2e/src/support';
e2e.scenario({
describeName: 'Smoke tests',
@@ -7,8 +6,8 @@ e2e.scenario({
addScenarioDataSource: true,
addScenarioDashBoard: true,
skipScenario: false,
scenario: ({ dataSourceName, dashboardTitle, dashboardUid }: ScenarioContext) => {
e2e.flows.openDashboard(dashboardUid);
scenario: () => {
e2e.flows.openDashboard(e2e.context().get('lastAddedDashboardUid'));
e2e.pages.Dashboard.toolbarItems('Add panel')
.should('be.visible') // prevents flakiness
.click();