Skip to content

Commit

Permalink
ci(e2e): support relative imports (fabricjs#9108)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaMan123 authored Jul 24, 2023
1 parent 0fbafcb commit d2c7b89
Show file tree
Hide file tree
Showing 13 changed files with 342 additions and 24 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/cached-install
with:
node-version: 18.x
- name: Build fabric.js
uses: ./.github/actions/build-fabric-cached
# Playwright suggests against caching the browser install
Expand All @@ -127,7 +129,7 @@ jobs:
with:
name: e2e-report
path: ./e2e/test-report/
- name: Upload test coverage
- name: Upload Test Coverage
uses: actions/upload-artifact@v3
with:
name: coverage-e2e
Expand Down
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]

- ci(e2e): support relative imports [#9108](https://github.com/fabricjs/fabric.js/pull/9108)
- chore(TS): complete type check [#9119](https://github.com/fabricjs/fabric.js/pull/9119)
- chore(TS): Add type-checking to files excluded with ts-nocheck [#9097](https://github.com/fabricjs/fabric.js/pull/9097)
- chore(TS): Add type-checking to files excluded with ts-nocheck ( Parser mostly ) [#9085](https://github.com/fabricjs/fabric.js/pull/9085)
Expand Down
49 changes: 49 additions & 0 deletions e2e/.babelrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// https://github.com/viruscamp/babel-plugin-transform-imports#using-a-function-as-the-transformer

const path = require('path');
const testsDir = path.resolve('./e2e/tests');
const testsBuiltDir = path.resolve('./e2e/dist');

function resolve(file) {
const found = ['', '.ts', '/index.ts']
.map((resolution) => `${file}${resolution}`)
.find((file) => {
try {
return require.resolve(file);
} catch (error) {
return false;
}
});
if (!found) {
console.error(`Failed to resolve ${file}`);
process.exit(1);
}
return require.resolve(found).replace(/\.ts$/, '.js');
}

module.exports = {
extends: '../.babelrcAlt',
plugins: [
[
'transform-imports',
{
'\\..*': {
skipDefaultConversion: true,
transform: function (importName, matches, filename) {
const file = resolve(
path.resolve(path.dirname(filename), `${matches[0]}`)
);
return `/${path
.relative(
process.cwd(),
file.startsWith(testsDir)
? path.resolve(testsBuiltDir, path.relative(testsDir, file))
: file
)
.replaceAll('\\', '/')}`;
},
},
},
],
],
};
6 changes: 3 additions & 3 deletions e2e/imports.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { readJSONSync } from 'fs-extra';

/**
* The import map used by `./utils/setupApp` to inject into the page
* so test scripts can use modules (relative imports don't seem to work out of the box)
* The import map used by `./utils/setupApp` to inject into the page so test scripts can use modules.
*
* Relative imports are supported thanks to babel, see `./.babelrc.js`.
*
* **IMPORTANT**: be sure to update the paths field in `./tsconfig.json` to reflect imports correctly
*/
export default {
fabric: readJSONSync('./package.json').module.slice(1),
test: '/e2e/dist/test.js',
};
2 changes: 1 addition & 1 deletion e2e/setup/setupApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ test.beforeEach(async ({ page }, { file }) => {
await page.addScriptTag({
type: 'module',
content: `${readFileSync(
path.relative(process.cwd(), pathToApp)
path.relative(process.cwd(), pathToBuiltApp)
).toString()}
window.dispatchEvent(new CustomEvent('fabric:setup'));
`,
Expand Down
4 changes: 2 additions & 2 deletions e2e/tests/template/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/**
* Runs in the **BROWSER**
* Use absolute imports defined in 'e2e/imports.ts'
* Imports are defined in 'e2e/imports.ts'
*/

import * as fabric from 'fabric';
import { beforeAll } from 'test';
import { beforeAll } from '../test';

beforeAll((canvas) => {
const textbox = new fabric.Textbox('fabric.js test', {
Expand Down
27 changes: 19 additions & 8 deletions e2e/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { Canvas } from 'fabric';
const canvasMap = (window.canvasMap = new Map<HTMLCanvasElement, Canvas>());
const objectMap = (window.objectMap = new Map<string, FabricObject>());

type AsyncReturnValue<T> = T | Promise<T>;

const setupTasks: Promise<void>[] = [];
const teardownTasks: Awaited<VoidFunction>[] = [];

Expand All @@ -26,14 +28,16 @@ export function before(
/**
* @returns a map of objects for playwright to access during tests
*/
cb: Awaited<(canvas: Canvas) => Record<string, FabricObject>>,
options?
cb: (canvas: HTMLCanvasElement) => AsyncReturnValue<{
canvas: Canvas;
objects?: Record<string, FabricObject>;
}>
) {
const task = Promise.resolve().then(async () => {
const el = document.querySelector<HTMLCanvasElement>(selector);
const canvas = new Canvas(el, options);
const { canvas, objects = {} } = await cb(el);
canvasMap.set(el, canvas);
Object.entries((await cb(canvas)) || {}).forEach(([key, value]) => {
Object.entries(objects).forEach(([key, value]) => {
if (objectMap.has(key)) {
throw new Error(
`Object identifiers must be unique: ${key} is already defined`
Expand All @@ -52,20 +56,27 @@ export function before(
* @param options canvas options
*/
export function beforeAll(
cb: Awaited<(canvas: Canvas) => Record<string, FabricObject>>,
cb: (canvas: Canvas) => AsyncReturnValue<Record<string, FabricObject>>,
options?
) {
before('#canvas', cb, options);
before('#canvas', async (el) => {
const canvas = new Canvas(el, options);
const objects = await cb(canvas);
return { canvas, objects };
});
}

export function after(selector: string, cb: Awaited<(canvas: Canvas) => void>) {
export function after(
selector: string,
cb: (canvas: Canvas) => AsyncReturnValue<void>
) {
teardownTasks.push(() => {
const el = document.querySelector<HTMLCanvasElement>(selector);
const canvas = canvasMap.get(el);
return cb(canvas);
});
}

export function afterAll(cb: Awaited<(canvas: Canvas) => void>) {
export function afterAll(cb: (canvas: Canvas) => AsyncReturnValue<void>) {
after('#canvas', cb);
}
7 changes: 1 addition & 6 deletions e2e/tests/text/text-editing/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
/**
* Runs in the **BROWSER**
* Use absolute imports defined in 'e2e/imports.ts'
*/

import { Textbox } from 'fabric';
import { beforeAll } from 'test';
import { beforeAll } from '../../test';

beforeAll((canvas) => {
const textbox = new Textbox('initial text', { width: 200, left: 50 });
Expand Down
2 changes: 1 addition & 1 deletion e2e/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
* A reflection of the configured imports used by test scripts
* **IMPORTANT**: be sure to keep this updated to reflect `./imports.ts` correctly
*/
"paths": { "fabric": ["../dist"], "test": ["./tests/test.ts"] }
"paths": { "fabric": ["../dist"] }
}
}
Loading

0 comments on commit d2c7b89

Please sign in to comment.