Skip to content

Commit

Permalink
Plugin E2E: Add isFeatureToggleEnabled fixture (#612)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunker authored Dec 19, 2023
1 parent b86314a commit 0d38477
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 1 deletion.
5 changes: 5 additions & 0 deletions packages/plugin-e2e/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ export type PluginFixture = {
* or data source and returns it as json.
*/
readProvision<T = any>(args: ReadProvisionArgs): Promise<T>;

/**
* Function that checks if a feature toggle is enabled. Only works for frontend feature toggles.
*/
isFeatureToggleEnabled<T = object>(featureToggle: keyof T): Promise<boolean>;
};

// extend Playwright with Grafana plugin specific fixtures
Expand Down
2 changes: 2 additions & 0 deletions packages/plugin-e2e/src/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import readProvision from './commands/readProvision';
import newDashboardPage from './newDashboardPage';
import variableEditPage from './variableEditPage';
import explorePage from './explorePage';
import isFeatureToggleEnabled from './isFeatureToggleEnabled';

export default {
selectors,
Expand All @@ -22,4 +23,5 @@ export default {
explorePage,
createDataSource,
readProvision,
isFeatureToggleEnabled,
};
17 changes: 17 additions & 0 deletions packages/plugin-e2e/src/fixtures/isFeatureToggleEnabled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { TestFixture } from '@playwright/test';
import { PluginFixture, PluginOptions } from '../api';
import { PlaywrightCombinedArgs } from './types';

type FeatureToggleFixture = TestFixture<
<T = object>(featureToggle: keyof T) => Promise<boolean>,
PluginFixture & PluginOptions & PlaywrightCombinedArgs
>;

const isFeatureToggleEnabled: FeatureToggleFixture = async ({ page }, use) => {
await use(async <T = object>(featureToggle: keyof T) => {
const featureToggles: T = await page.evaluate('window.grafanaBootData.settings.featureToggles');
return Boolean(featureToggles[featureToggle]);
});
};

export default isFeatureToggleEnabled;
16 changes: 15 additions & 1 deletion packages/plugin-e2e/src/models/GrafanaPage.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Locator, Request } from '@playwright/test';
import { Locator, Request, Response } from '@playwright/test';
import { NavigateOptions, PluginTestCtx } from '../types';

/**
Expand Down Expand Up @@ -72,4 +72,18 @@ export abstract class GrafanaPage {
return false;
});
}

/**
* Waits for a data source query data request to be made.
*
* @param cb optional callback to filter the request. Use this to filter by request body or other request properties
*/
async waitForQueryDataResponse(cb?: (request: Response) => boolean | Promise<boolean>) {
return this.ctx.page.waitForResponse((response) => {
if (response.url().includes(this.ctx.selectors.apis.DataSource.query) && response.request().method() === 'POST') {
return cb ? cb(response) : true;
}
return false;
});
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { expect, test } from '../../../src';
import { ProvisionFile } from '../../../src/types';

test('query data handler', async ({ selectors, panelEditPage, page, readProvision, isFeatureToggleEnabled }) => {
const provisionFile = await readProvision<ProvisionFile>({ filePath: 'datasources/redshift.yaml' });
await panelEditPage.datasource.set(provisionFile.datasources[0].name!);
await panelEditPage.timeRange.set({ from: '2020-01-31', to: '2020-02-20' });

await page.waitForFunction(() => (window as any).monaco);
await panelEditPage.getByTestIdOrAriaLabel(selectors.components.CodeEditor.container).click();
await page.keyboard.insertText('select * from long_format_example limit 100');

const asyncQueryDataHandlerEnabled = await isFeatureToggleEnabled('redshiftAsyncQueryDataSupport');
if (asyncQueryDataHandlerEnabled) {
// the async query data handler polls the backend until it receives a status of "finished"
const queryStatedResponse = panelEditPage.waitForQueryDataResponse(
(response) => response.ok() && response.body().then((body) => body.includes(`"status":"started"`))
);
const queryFinishedResponse = panelEditPage.waitForQueryDataResponse(
(response) => response.ok() && response.body().then((body) => body.includes(`"status":"finished"`))
);
await panelEditPage.refreshPanel();
await expect(await queryStatedResponse).toBeTruthy();
await expect(await queryFinishedResponse).toBeTruthy();
} else {
await expect(panelEditPage.refreshPanel()).toBeOK();
}
});

0 comments on commit 0d38477

Please sign in to comment.