mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
	
	
		
			204 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
		
		
			
		
	
	
			204 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
| 
								 | 
							
								import { random } from 'lodash';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								import { test, expect, DataSourceConfigPage } from '@grafana/plugin-e2e';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const DATASOURCE_ID = 'sandbox-test-datasource';
							 | 
						||
| 
								 | 
							
								let DATASOURCE_CONNECTION_ID = '';
							 | 
						||
| 
								 | 
							
								const DATASOURCE_TYPED_NAME = 'SandboxDatasourceInstance';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Originally skipped due to flakiness/race conditions with same old arch test e2e/various-suite/frontend-sandbox-datasource.spec.ts
							 | 
						||
| 
								 | 
							
								// TODO: fix and remove skip
							 | 
						||
| 
								 | 
							
								test.describe.skip(
							 | 
						||
| 
								 | 
							
								  'Datasource sandbox',
							 | 
						||
| 
								 | 
							
								  {
							 | 
						||
| 
								 | 
							
								    tag: ['@various', '@wip'],
							 | 
						||
| 
								 | 
							
								  },
							 | 
						||
| 
								 | 
							
								  () => {
							 | 
						||
| 
								 | 
							
								    let configPage: DataSourceConfigPage;
							 | 
						||
| 
								 | 
							
								    test.beforeEach(async ({ createDataSourceConfigPage }) => {
							 | 
						||
| 
								 | 
							
								      // Add the datasource
							 | 
						||
| 
								 | 
							
								      configPage = await createDataSourceConfigPage({
							 | 
						||
| 
								 | 
							
								        type: 'sandbox',
							 | 
						||
| 
								 | 
							
								        name: DATASOURCE_TYPED_NAME,
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test.describe('Config Editor', () => {
							 | 
						||
| 
								 | 
							
								      test.describe('Sandbox disabled', () => {
							 | 
						||
| 
								 | 
							
								        test.beforeEach(async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.evaluate(() => {
							 | 
						||
| 
								 | 
							
								            localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=0');
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should not render a sandbox wrapper around the datasource config editor', async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto(`/connections/datasources/edit/${DATASOURCE_CONNECTION_ID}`);
							 | 
						||
| 
								 | 
							
								          await page.waitForTimeout(300); // wait to prevent false positives because playwright checks too fast
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const sandboxDiv = page.locator(`div[data-plugin-sandbox="${DATASOURCE_ID}"]`);
							 | 
						||
| 
								 | 
							
								          await expect(sandboxDiv).toBeHidden();
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      test.describe('Sandbox enabled', () => {
							 | 
						||
| 
								 | 
							
								        test.beforeEach(async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.evaluate(() => {
							 | 
						||
| 
								 | 
							
								            localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=1');
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should render a sandbox wrapper around the datasource config editor', async ({ page, selectors }) => {
							 | 
						||
| 
								 | 
							
								          const sandboxDiv = page.locator(`div[data-plugin-sandbox="${DATASOURCE_ID}"]`);
							 | 
						||
| 
								 | 
							
								          await expect(sandboxDiv).toBeVisible();
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should store values in jsonData and secureJsonData correctly', async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto(`/connections/datasources/edit/${DATASOURCE_CONNECTION_ID}`);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const valueToStore = 'test' + random(100);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const queryInput = page.locator('[data-testid="sandbox-config-editor-query-input"]');
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).not.toBeDisabled();
							 | 
						||
| 
								 | 
							
								          await queryInput.fill(valueToStore);
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).toHaveValue(valueToStore);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const saveButton = page.getByTestId('data-testid Data source settings page Save and test button');
							 | 
						||
| 
								 | 
							
								          await saveButton.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const alert = page.locator('[data-testid="data-testid Alert"]');
							 | 
						||
| 
								 | 
							
								          await expect(alert).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await expect(alert).toContainText('Sandbox Success');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // validate the value was stored
							 | 
						||
| 
								 | 
							
								          await page.goto(`/connections/datasources/edit/${DATASOURCE_CONNECTION_ID}`);
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).not.toBeDisabled();
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).toHaveValue(valueToStore);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test.describe('Explore Page', () => {
							 | 
						||
| 
								 | 
							
								      test.describe('Sandbox disabled', () => {
							 | 
						||
| 
								 | 
							
								        test.beforeEach(async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.evaluate(() => {
							 | 
						||
| 
								 | 
							
								            localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=0');
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should not wrap the query editor in a sandbox wrapper', async ({ page, dashboardPage, selectors }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto('/explore');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const dataSourcePicker = dashboardPage.getByGrafanaSelector(selectors.components.DataSourcePicker.container);
							 | 
						||
| 
								 | 
							
								          await expect(dataSourcePicker).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await dataSourcePicker.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const datasourceOption = page.locator(`text=${DATASOURCE_TYPED_NAME}`);
							 | 
						||
| 
								 | 
							
								          await expect(datasourceOption).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.scrollIntoViewIfNeeded();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // make sure the datasource was correctly selected and rendered
							 | 
						||
| 
								 | 
							
								          const breadcrumb = dashboardPage.getByGrafanaSelector(
							 | 
						||
| 
								 | 
							
								            selectors.components.Breadcrumbs.breadcrumb(DATASOURCE_TYPED_NAME)
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								          await expect(breadcrumb).toBeVisible();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          await page.waitForTimeout(300); // wait to prevent false positives because playwright checks too fast
							 | 
						||
| 
								 | 
							
								          const sandboxDiv = page.locator(`div[data-plugin-sandbox="${DATASOURCE_ID}"]`);
							 | 
						||
| 
								 | 
							
								          await expect(sandboxDiv).toBeHidden();
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should accept values when typed', async ({ page, dashboardPage, selectors }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto('/explore');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const dataSourcePicker = dashboardPage.getByGrafanaSelector(selectors.components.DataSourcePicker.container);
							 | 
						||
| 
								 | 
							
								          await expect(dataSourcePicker).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await dataSourcePicker.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const datasourceOption = page.locator(`text=${DATASOURCE_TYPED_NAME}`);
							 | 
						||
| 
								 | 
							
								          await expect(datasourceOption).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.scrollIntoViewIfNeeded();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // make sure the datasource was correctly selected and rendered
							 | 
						||
| 
								 | 
							
								          const breadcrumb = dashboardPage.getByGrafanaSelector(
							 | 
						||
| 
								 | 
							
								            selectors.components.Breadcrumbs.breadcrumb(DATASOURCE_TYPED_NAME)
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								          await expect(breadcrumb).toBeVisible();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const valueToType = 'test' + random(100);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const queryInput = page.locator('[data-testid="sandbox-query-editor-query-input"]');
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).not.toBeDisabled();
							 | 
						||
| 
								 | 
							
								          await queryInput.fill(valueToType);
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).toHaveValue(valueToType);
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								      test.describe('Sandbox enabled', () => {
							 | 
						||
| 
								 | 
							
								        test.beforeEach(async ({ page }) => {
							 | 
						||
| 
								 | 
							
								          await page.evaluate(() => {
							 | 
						||
| 
								 | 
							
								            localStorage.setItem('grafana.featureToggles', 'pluginsFrontendSandbox=1');
							 | 
						||
| 
								 | 
							
								          });
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should wrap the query editor in a sandbox wrapper', async ({ page, dashboardPage, selectors }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto('/explore');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const dataSourcePicker = dashboardPage.getByGrafanaSelector(selectors.components.DataSourcePicker.container);
							 | 
						||
| 
								 | 
							
								          await expect(dataSourcePicker).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await dataSourcePicker.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const datasourceOption = page.locator(`text=${DATASOURCE_TYPED_NAME}`);
							 | 
						||
| 
								 | 
							
								          await expect(datasourceOption).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.scrollIntoViewIfNeeded();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // make sure the datasource was correctly selected and rendered
							 | 
						||
| 
								 | 
							
								          const breadcrumb = dashboardPage.getByGrafanaSelector(
							 | 
						||
| 
								 | 
							
								            selectors.components.Breadcrumbs.breadcrumb(DATASOURCE_TYPED_NAME)
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								          await expect(breadcrumb).toBeVisible();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const sandboxDiv = page.locator(`div[data-plugin-sandbox="${DATASOURCE_ID}"]`);
							 | 
						||
| 
								 | 
							
								          await expect(sandboxDiv).toBeVisible();
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        test('Should accept values when typed', async ({ page, dashboardPage, selectors }) => {
							 | 
						||
| 
								 | 
							
								          await page.goto('/explore');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const dataSourcePicker = dashboardPage.getByGrafanaSelector(selectors.components.DataSourcePicker.container);
							 | 
						||
| 
								 | 
							
								          await expect(dataSourcePicker).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await dataSourcePicker.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const datasourceOption = page.locator(`text=${DATASOURCE_TYPED_NAME}`);
							 | 
						||
| 
								 | 
							
								          await expect(datasourceOption).toBeVisible();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.scrollIntoViewIfNeeded();
							 | 
						||
| 
								 | 
							
								          await datasourceOption.click();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // make sure the datasource was correctly selected and rendered
							 | 
						||
| 
								 | 
							
								          const breadcrumb = dashboardPage.getByGrafanaSelector(
							 | 
						||
| 
								 | 
							
								            selectors.components.Breadcrumbs.breadcrumb(DATASOURCE_TYPED_NAME)
							 | 
						||
| 
								 | 
							
								          );
							 | 
						||
| 
								 | 
							
								          await expect(breadcrumb).toBeVisible();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const valueToType = 'test' + random(100);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          const queryInput = page.locator('[data-testid="sandbox-query-editor-query-input"]');
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).not.toBeDisabled();
							 | 
						||
| 
								 | 
							
								          await queryInput.fill(valueToType);
							 | 
						||
| 
								 | 
							
								          await expect(queryInput).toHaveValue(valueToType);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								          // typing the query editor should reflect in the url
							 | 
						||
| 
								 | 
							
								          await expect(page).toHaveURL(new RegExp(valueToType));
							 | 
						||
| 
								 | 
							
								        });
							 | 
						||
| 
								 | 
							
								      });
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    test.afterEach(async ({ page }) => {
							 | 
						||
| 
								 | 
							
								      // Clear cookies after each test
							 | 
						||
| 
								 | 
							
								      await page.context().clearCookies();
							 | 
						||
| 
								 | 
							
								    });
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								);
							 |