Canvas: E2E test coverage (#107474)
* betterer * feat(canvas): sceneAbleManagement tests * feat(canvas): playwright tests * chore(canvas): add draft e2e tests * chore(canvas): clean draft e2e tests * chore(canvas): fix draft e2e tests * chore(canvas): todo comments * chore(canvas): update e2e tests * chore(canvas): delete scene unit tests * chore(canvas): delete sceneAbleManagement unit tests * chore(canvas): delete sceneAbleManagement unit tests * chore(canvas): linter * chore(canvas): locales * chore(canvas): remove flag checking
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { Locator } from '@playwright/test';
|
||||
|
||||
import { test, expect } from '@grafana/plugin-e2e';
|
||||
|
||||
test.use({
|
||||
featureToggles: {
|
||||
canvasPanelPanZoom: true,
|
||||
},
|
||||
});
|
||||
|
||||
test.describe('Canvas Panel - Scene Tests', () => {
|
||||
test.beforeEach(async ({ page, gotoDashboardPage }) => {
|
||||
const dashboardPage = await gotoDashboardPage({});
|
||||
const panelEditPage = await dashboardPage.addPanel();
|
||||
await panelEditPage.setVisualization('Canvas');
|
||||
|
||||
// Wait for canvas panel to load
|
||||
await page.waitForSelector('[data-testid="canvas-scene-pan-zoom"]', { timeout: 10000 });
|
||||
});
|
||||
|
||||
test('should create and render canvas panel with scene elements', async ({ page }) => {
|
||||
const canvasElement = await page.getByRole('button', { name: 'Double click to set field' });
|
||||
await expect(canvasElement).toBeVisible();
|
||||
});
|
||||
|
||||
test('should handle scene pan and zoom when enabled', async ({ page }) => {
|
||||
// Feature toggle is enabled, pan/zoom functionality should be available
|
||||
const panZoomCheckbox = await page.getByLabel('Canvas Pan and zoom field').locator('label').nth(1);
|
||||
await panZoomCheckbox.setChecked(true);
|
||||
await expect(panZoomCheckbox).toBeChecked({ checked: true });
|
||||
|
||||
const canvasElement = await page.getByRole('button', { name: 'Double click to set field' });
|
||||
const canvasSceneWrapper = await page.getByTestId('canvas-scene-wrapper');
|
||||
|
||||
// Check if infinite viewer is present (pan/zoom feature)
|
||||
await page.waitForSelector('[data-testid="canvas-scene-pan-zoom"]', { timeout: 10000 });
|
||||
const infiniteViewer = page.locator('[data-testid="canvas-scene-pan-zoom"]');
|
||||
await infiniteViewer.waitFor({ state: 'visible', timeout: 5000 });
|
||||
await expect(await infiniteViewer.isVisible()).toBe(true);
|
||||
await infiniteViewer.hover();
|
||||
|
||||
const viewerBounds = await infiniteViewer.boundingBox();
|
||||
await expect(viewerBounds).toBeDefined();
|
||||
|
||||
// Test pan functionality
|
||||
const startX = viewerBounds.x + 50;
|
||||
const startY = viewerBounds.y + 50;
|
||||
const endX = viewerBounds.x + 250;
|
||||
const endY = viewerBounds.y + 250;
|
||||
await page.getByTestId('canvas-scene-pan-zoom');
|
||||
await page.mouse.move(startX, startY);
|
||||
await page.mouse.down({ button: 'middle' });
|
||||
await page.mouse.move(endX, endY);
|
||||
await page.mouse.up({ button: 'middle' });
|
||||
await expect(await isOutsideViewport(canvasElement, canvasSceneWrapper)).toBe(true);
|
||||
|
||||
// Test zoom reset with double-click
|
||||
await page.mouse.dblclick(startX, startY);
|
||||
// Verify canvas element is visible after pan/zoom operations
|
||||
await expect(await isOutsideViewport(canvasElement, canvasSceneWrapper)).toBe(false);
|
||||
|
||||
// Test zoom functionality
|
||||
await page.mouse.move(startX, startY);
|
||||
await page.keyboard.down('Control');
|
||||
await page.mouse.wheel(0, -400); // Zoom in
|
||||
await page.keyboard.up('Control');
|
||||
// Check if canvas element is not visible after zoom operations
|
||||
await expect(await isOutsideViewport(canvasElement, canvasSceneWrapper)).toBe(true);
|
||||
|
||||
// Test zoom reset with double-click
|
||||
await page.mouse.dblclick(startX, startY);
|
||||
// Verify canvas element is visible after pan/zoom operations
|
||||
await expect(await isOutsideViewport(canvasElement, canvasSceneWrapper)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
// TODO: this function is workaround for .toBeVisible()
|
||||
async function isOutsideViewport(element: Locator, viewPort: Locator): Promise<boolean> {
|
||||
const elementBounds = await element.boundingBox();
|
||||
const viewportBounds = await viewPort.boundingBox();
|
||||
return (
|
||||
elementBounds.x + elementBounds.width < viewportBounds.x ||
|
||||
elementBounds.x > viewportBounds.x + viewportBounds.width ||
|
||||
elementBounds.y + elementBounds.height < viewportBounds.y ||
|
||||
elementBounds.y > viewportBounds.y + viewportBounds.height
|
||||
);
|
||||
}
|
||||
@@ -178,6 +178,15 @@ export default defineConfig<PluginOptions>({
|
||||
},
|
||||
dependencies: ['authenticate'],
|
||||
},
|
||||
{
|
||||
name: 'canvas',
|
||||
testDir: path.join(testDirRoot, '/canvas'),
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
storageState: 'playwright/.auth/admin.json',
|
||||
},
|
||||
dependencies: ['authenticate'],
|
||||
},
|
||||
{
|
||||
name: 'zipkin',
|
||||
testDir: path.join(testDirRoot, '/zipkin'),
|
||||
|
||||
@@ -386,13 +386,24 @@ export class Scene {
|
||||
);
|
||||
|
||||
return config.featureToggles.canvasPanelPanZoom ? (
|
||||
<div className={this.styles.viewer} ref={this.setViewerRef} key={this.revId}>
|
||||
<div className={this.styles.viewport} ref={this.setViewportRef} key={this.revId}>
|
||||
<div className={this.styles.viewer} ref={this.setViewerRef} key={this.revId} data-testid="canvas-scene-wrapper">
|
||||
<div
|
||||
className={this.styles.viewport}
|
||||
ref={this.setViewportRef}
|
||||
key={this.revId}
|
||||
data-testid="canvas-scene-pan-zoom"
|
||||
>
|
||||
{sceneDiv}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div key={this.revId} className={this.styles.wrap} style={this.style} ref={this.setRef}>
|
||||
<div
|
||||
key={this.revId}
|
||||
className={this.styles.wrap}
|
||||
style={this.style}
|
||||
ref={this.setRef}
|
||||
data-testid="canvas-scene"
|
||||
>
|
||||
{sceneDiv}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3693,7 +3693,6 @@
|
||||
}
|
||||
},
|
||||
"description-experimental-types": "Enable selection of experimental element types",
|
||||
"description-infinite-panning": "Enable infinite panning - useful for expansive canvases. Warning: this is an experimental feature and currently only works well with elements that are top / left constrained",
|
||||
"description-inline-editing": "Enable editing the panel directly",
|
||||
"description-pan-zoom": "Enable pan and zoom",
|
||||
"direction-options": {
|
||||
@@ -3794,7 +3793,6 @@
|
||||
"name-align-text": "Align text",
|
||||
"name-color": "Text color",
|
||||
"name-experimental-types": "Experimental element types",
|
||||
"name-infinite-panning": "Infinite panning",
|
||||
"name-inline-editing": "Inline editing",
|
||||
"name-pan-zoom": "Pan and zoom",
|
||||
"name-text": "Text",
|
||||
|
||||
Reference in New Issue
Block a user