From 665dc1fa449c6d541e4f61dfa768607cf180622f Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Thu, 12 Oct 2023 09:43:59 +0200 Subject: [PATCH] Sandbox: e2e tests for apps running inside the frontend sandbox (#76357) * Sandbox: Add tests for apps inside the sandbox * Force type to prevent flawky test --- .../frontend-sandbox-app-test/img/logo.svg | 1 + .../frontend-sandbox-app-test/module.js | 41 +++++++++ .../frontend-sandbox-app-test/plugin.json | 35 ++++++++ .../frontend-sandbox-panel-test/img/logo.svg | 1 + .../frontend-sandbox-panel.spec.ts | 4 +- .../frontend-sandbox-app.spec.ts | 85 +++++++++++++++++++ 6 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 e2e/custom-plugins/frontend-sandbox-app-test/img/logo.svg create mode 100644 e2e/custom-plugins/frontend-sandbox-app-test/module.js create mode 100644 e2e/custom-plugins/frontend-sandbox-app-test/plugin.json create mode 100644 e2e/custom-plugins/frontend-sandbox-panel-test/img/logo.svg create mode 100644 e2e/various-suite/frontend-sandbox-app.spec.ts diff --git a/e2e/custom-plugins/frontend-sandbox-app-test/img/logo.svg b/e2e/custom-plugins/frontend-sandbox-app-test/img/logo.svg new file mode 100644 index 00000000000..08ec9068d45 --- /dev/null +++ b/e2e/custom-plugins/frontend-sandbox-app-test/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/e2e/custom-plugins/frontend-sandbox-app-test/module.js b/e2e/custom-plugins/frontend-sandbox-app-test/module.js new file mode 100644 index 00000000000..478549ee25a --- /dev/null +++ b/e2e/custom-plugins/frontend-sandbox-app-test/module.js @@ -0,0 +1,41 @@ +/* + * This is a dummy plugin to test the frontend sandbox + * It is not meant to be used in any other way + * This file doesn't require any compilation + */ +define(['react', '@grafana/data', 'react-router-dom'], function (React, grafanaData, ReactRouterDom) { + const { AppPlugin } = grafanaData; + const { Switch, Route } = ReactRouterDom; + + function PageOne() { + return React.createElement( + 'div', + { + 'data-testid': 'sandbox-app-test-page-one', + }, + 'This is a page one' + ); + } + + function App() { + return React.createElement(Switch, null, React.createElement(Route, { component: PageOne })); + } + function AppConfig() { + return React.createElement( + 'div', + { + 'data-testid': 'sandbox-app-test-config-page', + }, + + 'This is a config page' + ); + } + + const plugin = new AppPlugin().setRootPage(App).addConfigPage({ + title: 'Configuration', + icon: 'cog', + body: AppConfig, + id: 'configuration', + }); + return { plugin }; +}); diff --git a/e2e/custom-plugins/frontend-sandbox-app-test/plugin.json b/e2e/custom-plugins/frontend-sandbox-app-test/plugin.json new file mode 100644 index 00000000000..4997ee82633 --- /dev/null +++ b/e2e/custom-plugins/frontend-sandbox-app-test/plugin.json @@ -0,0 +1,35 @@ +{ + "$schema": "https://raw.githubusercontent.com/grafana/grafana/master/docs/sources/developers/plugins/plugin.schema.json", + "type": "app", + "name": "Sandbox app test plugin", + "id": "sandbox-app-test", + "info": { + "keywords": ["app", "sandbox"], + "description": "", + "author": { + "name": "Grafana" + }, + "logos": { + "small": "img/logo.svg", + "large": "img/logo.svg" + }, + "links": [], + "screenshots": [], + "version": "1.0.0", + "updated": "2023-06-27" + }, + "includes": [ + { + "type": "page", + "icon": "cog", + "name": "Sandbox App Page", + "path": "/plugins/sandbox-app-test", + "role": "Admin", + "addToNav": true + } + ], + "dependencies": { + "grafanaDependency": ">=10.0", + "plugins": [] + } +} diff --git a/e2e/custom-plugins/frontend-sandbox-panel-test/img/logo.svg b/e2e/custom-plugins/frontend-sandbox-panel-test/img/logo.svg new file mode 100644 index 00000000000..08ec9068d45 --- /dev/null +++ b/e2e/custom-plugins/frontend-sandbox-panel-test/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/e2e/panels-suite/frontend-sandbox-panel.spec.ts b/e2e/panels-suite/frontend-sandbox-panel.spec.ts index 69205f06e09..fb237f6f54e 100644 --- a/e2e/panels-suite/frontend-sandbox-panel.spec.ts +++ b/e2e/panels-suite/frontend-sandbox-panel.spec.ts @@ -57,7 +57,7 @@ describe('Panel sandbox', () => { }); cy.get('[data-testid="panel-editor-custom-editor-input"]').should('not.be.disabled'); - cy.get('[data-testid="panel-editor-custom-editor-input"]').type('x'); + cy.get('[data-testid="panel-editor-custom-editor-input"]').type('x', { force: true }); cy.get('[data-sandbox-test="panel-editor"]').should('exist'); }); }); @@ -114,7 +114,7 @@ describe('Panel sandbox', () => { }); cy.get('[data-testid="panel-editor-custom-editor-input"]').should('not.be.disabled'); - cy.get('[data-testid="panel-editor-custom-editor-input"]').type('x'); + cy.get('[data-testid="panel-editor-custom-editor-input"]').type('x', { force: true }); cy.wait(100); // small delay to prevent false positives from too fast tests cy.get('[data-sandbox-test="panel-editor"]').should('not.exist'); }); diff --git a/e2e/various-suite/frontend-sandbox-app.spec.ts b/e2e/various-suite/frontend-sandbox-app.spec.ts new file mode 100644 index 00000000000..9bcf4d49832 --- /dev/null +++ b/e2e/various-suite/frontend-sandbox-app.spec.ts @@ -0,0 +1,85 @@ +import { e2e } from '../utils'; + +const APP_ID = 'sandbox-app-test'; + +describe('Datasource sandbox', () => { + before(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'), true); + cy.request({ + url: `${Cypress.env('BASE_URL')}/api/plugins/${APP_ID}/settings`, + method: 'POST', + body: { + enabled: true, + }, + }); + }); + beforeEach(() => { + e2e.flows.login(Cypress.env('USERNAME'), Cypress.env('PASSWORD'), true); + }); + + describe('App Page', () => { + describe('Sandbox disabled', () => { + beforeEach(() => { + cy.window().then((win) => { + win.localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=0'); + }); + }); + + it('Loads the app page without the sandbox div wrapper', () => { + e2e.pages.Home.visit(); + e2e.components.NavBar.Toggle.button().click(); + e2e.components.NavToolbar.container().get('[aria-label="Expand section Apps"]').click(); + e2e.components.NavMenu.item().contains('Sandbox app test plugin').click(); + cy.wait(200); // wait to prevent false positives because cypress checks too fast + cy.get('div[data-plugin-sandbox="sandbox-app-test"]').should('not.exist'); + cy.get('div[data-testid="sandbox-app-test-page-one"]').should('exist'); + }); + + it('Loads the app configuration without the sandbox div wrapper', () => { + e2e.pages.Home.visit(); + e2e.components.NavBar.Toggle.button().click(); + e2e.components.NavToolbar.container().get('[aria-label="Expand section Apps"]').click(); + e2e.components.NavMenu.item().contains('Apps').click(); + cy.get('a[aria-label="Tab Sandbox App Page"]').click(); + cy.wait(200); // wait to prevent false positives because cypress checks too fast + cy.get('div[data-plugin-sandbox="sandbox-app-test"]').should('not.exist'); + cy.get('div[data-testid="sandbox-app-test-config-page"]').should('exist'); + }); + }); + + describe('Sandbox enabled', () => { + beforeEach(() => { + cy.window().then((win) => { + win.localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=1'); + }); + }); + + it('Loads the app page with the sandbox div wrapper', () => { + e2e.pages.Home.visit(); + e2e.components.NavBar.Toggle.button().click(); + e2e.components.NavToolbar.container().get('[aria-label="Expand section Apps"]').click(); + e2e.components.NavMenu.item().contains('Sandbox app test plugin').click(); + cy.get('div[data-plugin-sandbox="sandbox-app-test"]').should('exist'); + cy.get('div[data-testid="sandbox-app-test-page-one"]').should('exist'); + }); + + it('Loads the app configuration with the sandbox div wrapper', () => { + e2e.pages.Home.visit(); + e2e.components.NavBar.Toggle.button().click(); + e2e.components.NavToolbar.container().get('[aria-label="Expand section Apps"]').click(); + e2e.components.NavMenu.item().contains('Apps').click(); + cy.get('a[aria-label="Tab Sandbox App Page"]').click(); + cy.get('div[data-plugin-sandbox="sandbox-app-test"]').should('exist'); + cy.get('div[data-testid="sandbox-app-test-config-page"]').should('exist'); + }); + }); + }); + + afterEach(() => { + e2e.flows.revertAllChanges(); + }); + + after(() => { + cy.clearCookies(); + }); +});