Skip to content

Commit

Permalink
tests(): Start moving visual tests to playwright (#9481)
Browse files Browse the repository at this point in the history
  • Loading branch information
asturur authored Jul 2, 2024
1 parent efa2619 commit 4a67106
Show file tree
Hide file tree
Showing 12 changed files with 890 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [next]

- tests(): Start moving visual tests to playwrigth [#9481](https://github.com/fabricjs/fabric.js/pull/9481)
- fix(filters): Fix bugs in Pixelate and Blur filter [#9962](https://github.com/fabricjs/fabric.js/pull/9962)
- docs(): update README.md [#9957](https://github.com/fabricjs/fabric.js/pull/9957)

Expand Down
25 changes: 24 additions & 1 deletion e2e/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import * as fabric from 'fabric';

const canvasMap = (window.canvasMap = new Map<HTMLCanvasElement, Canvas>());
const objectMap = (window.objectMap = new Map<string, FabricObject>());

const renderingTestMap = (window.renderingTestMap = new Map<
string,
() => void
>());
type AsyncReturnValue<T> = T | Promise<T>;

const setupTasks: Promise<void>[] = [];
Expand Down Expand Up @@ -53,6 +56,26 @@ export function before(
setupTasks.push(task);
}

export async function beforeRenderTest(
cb: (
canvas: Canvas
) => AsyncReturnValue<{ title: string; boundFunction: () => void }[]>,
options
) {
const el = document.querySelector<HTMLCanvasElement>('#canvas');
const canvas = new Canvas(el, options);
// cb has to bind the rendering test to the specific canvas and add a clear before the test
const renderingTests = await cb(canvas);
renderingTests.forEach((renderTest) => {
if (renderingTestMap.has(renderTest.title)) {
throw new Error(
`test identifiers must be unique: ${renderTest.title} is already defined`
);
}
renderingTestMap.set(renderTest.title, renderTest.boundFunction);
});
}

/**
* Call this method **once** to initialize the default canvas
*
Expand Down
52 changes: 52 additions & 0 deletions e2e/tests/visual-output/rendering/index.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { expect, test } from '@playwright/test';
import setup from '../../../setup';
import { CanvasUtil } from '../../../utils/CanvasUtil';
import { TestingCanvas } from '../../../utils/createNodeSnapshot';
import { renderTests } from './renderingCases';
import * as fabric from 'fabric/node';

setup();

test('VISUAL RENDERING TESTS', async ({ page }, config) => {
for (const testCase of renderTests) {
if (testCase.disabled !== 'browser') {
await test.step(`browser - ${testCase.title}`, async () => {
// enable and disable this inside the loop
config.config.updateSnapshots = 'missing';
await page.evaluate(
(testTitle) => renderingTestMap.get(testTitle)(),
testCase.title
);
expect(
await new CanvasUtil(page).screenshot(),
`browser snapshot`
).toMatchSnapshot({
name: testCase.golden || `${testCase.title}.png`,
maxDiffPixelRatio: testCase.percentage,
});
});
}
if (testCase.disabled !== 'node') {
await test.step(`node - ${testCase.title}`, async () => {
// we want the browser snapshot of a test to be committed and not the node snapshot
config.config.updateSnapshots = 'none';
const canvas = new TestingCanvas(null, {
enableRetinaScaling: false,
renderOnAddRemove: false,
width: testCase.size[0],
height: testCase.size[1],
});
await testCase.renderFunction(canvas, fabric);
canvas.renderAll();
const buffer = await canvas.getNodeCanvas().toBuffer();
expect(
buffer,
`node snapshot should match browser snapshot`
).toMatchSnapshot({
name: testCase.golden || `${testCase.title}.png`,
maxDiffPixelRatio: testCase.percentage,
});
});
}
}
});
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions e2e/tests/visual-output/rendering/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* Runs in the **BROWSER**
*/

import * as fabric from 'fabric';
import { renderTests } from './renderingCases';
import { beforeRenderTest } from '../../test';

beforeRenderTest(
(canvas) => {
const boundTests = renderTests.map((renderTest) => {
return {
boundFunction: async () => {
canvas.clear();
canvas.setDimensions({
width: renderTest.size[0],
height: renderTest.size[1],
});
await renderTest.renderFunction(canvas, fabric);
},
title: renderTest.title,
};
});
return boundTests;
},
{
enableRetinaScaling: false,
}
);
Loading

0 comments on commit 4a67106

Please sign in to comment.