mirror of
https://github.com/penpot/penpot.git
synced 2026-06-09 17:02:05 +00:00
The setup-wasm-features function is the single source of truth for
resolving the renderer choice (URL param > profile preference > team
flags), storing the result in state[:features]. Several helpers were
re-deriving the same priority chain independently, duplicating logic:
- wasm-enabled?, wasm-url-override, wasm-url-override-ref
- enabled-by-flags?, enabled-without-migration?
This change removes all duplicated helpers and simplifies the
remaining functions to rely exclusively on the pre-computed
:features set:
- active-feature? — now just checks (contains? (:features state)
feature) without special-casing render-wasm/v1
- use-feature — uses the reactive features-ref for all features
- initialize/recompute-features effects — use the local features
binding directly
Since :features is rebuilt by setup-wasm-features on every
initialization and recompute, this preserves correctness while
eliminating ~50 lines of duplicated code.
113 lines
3.0 KiB
JavaScript
113 lines
3.0 KiB
JavaScript
import { expect } from "@playwright/test";
|
|
import { WorkspacePage } from "./WorkspacePage";
|
|
|
|
export const WASM_PROFILE = "logged-in-user/get-profile-wasm-renderer.json";
|
|
|
|
export const WASM_FLAGS = [
|
|
"enable-feature-render-wasm",
|
|
"enable-render-wasm-dpr",
|
|
"enable-feature-text-editor-v2",
|
|
// Default flags enable render-wasm-info; keep screenshots stable in e2e.
|
|
"disable-render-wasm-info",
|
|
];
|
|
|
|
export class WasmWorkspacePage extends WorkspacePage {
|
|
static async init(page) {
|
|
await super.init(page);
|
|
await WasmWorkspacePage.mockConfigFlags(page, WASM_FLAGS);
|
|
await WasmWorkspacePage.mockRPC(page, "get-profile", WASM_PROFILE);
|
|
|
|
await page.addInitScript(() => {
|
|
document.addEventListener("penpot:wasm:loaded", () => {
|
|
window.wasmModuleLoaded = true;
|
|
});
|
|
|
|
document.addEventListener("penpot:wasm:render", () => {
|
|
window.wasmRenderCount = (window.wasmRenderCount || 0) + 1;
|
|
});
|
|
|
|
document.addEventListener("penpot:wasm:set-objects", () => {
|
|
window.wasmSetObjectsFinished = true;
|
|
});
|
|
});
|
|
}
|
|
|
|
static async mockConfigFlags(page, flags) {
|
|
await super.mockConfigFlags(page, [...WASM_FLAGS, ...flags]);
|
|
}
|
|
|
|
async mockConfigFlags(flags) {
|
|
return WasmWorkspacePage.mockConfigFlags(this.page, flags);
|
|
}
|
|
|
|
constructor(page, options) {
|
|
super(page, options);
|
|
this.canvas = page.getByTestId("canvas-wasm-shapes");
|
|
}
|
|
|
|
async waitForIdle(options) {
|
|
return this.page.evaluate(
|
|
(options) => new Promise((resolve) => globalThis.requestIdleCallback(resolve, options)),
|
|
options
|
|
);
|
|
}
|
|
|
|
async waitForFirstRender() {
|
|
await this.pageName.waitFor();
|
|
await this.canvas.waitFor();
|
|
await this.page.waitForFunction(() => {
|
|
console.log("RAF:", window.wasmSetObjectsFinished);
|
|
return window.wasmSetObjectsFinished;
|
|
});
|
|
}
|
|
|
|
async waitForFirstRenderWithoutUI() {
|
|
await this.waitForFirstRender();
|
|
await this.hideUI();
|
|
}
|
|
|
|
async getRenderCount() {
|
|
return this.page.evaluate(() => window.wasmRenderCount || 0);
|
|
}
|
|
|
|
async waitForNextRender(previousCount = null) {
|
|
const baseCount =
|
|
previousCount === null ? await this.getRenderCount() : previousCount;
|
|
await this.page.waitForFunction(
|
|
(count) => (window.wasmRenderCount || 0) > count,
|
|
baseCount,
|
|
);
|
|
}
|
|
|
|
async hideUI() {
|
|
await this.page.keyboard.press("\\");
|
|
await expect(this.pageName).not.toBeVisible();
|
|
}
|
|
|
|
static async mockGoogleFont(page, fontSlug, assetFilename, options = {}) {
|
|
const url = new RegExp(`/internal/gfonts/font/${fontSlug}`);
|
|
return await page.route(url, (route) =>
|
|
route.fulfill({
|
|
status: 200,
|
|
path: `playwright/data/${assetFilename}`,
|
|
contentType: "application/font-ttf",
|
|
...options,
|
|
}),
|
|
);
|
|
}
|
|
|
|
async mockGoogleFont(fontSlug, assetFilename, options) {
|
|
return WasmWorkspacePage.mockGoogleFont(
|
|
this.page,
|
|
fontSlug,
|
|
assetFilename,
|
|
options,
|
|
);
|
|
}
|
|
|
|
async setupEmptyFile() {
|
|
await super.setupEmptyFile();
|
|
await this.mockRPC("get-profile", WASM_PROFILE);
|
|
}
|
|
}
|