From d43458ee891b50678133f1d1b1d45053e6877f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Tue, 14 May 2024 15:13:11 +0200 Subject: [PATCH] :bug: Fix mocking websockets when running multiple tests --- frontend/playwright.config.js | 2 +- .../playwright/helpers/MockWebSocketHelper.js | 63 ++++++++++++------- frontend/playwright/scripts/MockWebSocket.js | 12 ++-- .../playwright/ui/pages/BaseWebSocketPage.js | 4 +- .../playwright/ui/specs/workspace.spec.js | 6 +- 5 files changed, 51 insertions(+), 36 deletions(-) diff --git a/frontend/playwright.config.js b/frontend/playwright.config.js index f062238f2..b1b6ffd5f 100644 --- a/frontend/playwright.config.js +++ b/frontend/playwright.config.js @@ -18,7 +18,7 @@ export default defineConfig({ /* Retry on CI only */ retries: process.env.CI ? 2 : 0, /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : 1, + workers: process.env.CI ? 1 : undefined, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ reporter: "html", /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ diff --git a/frontend/playwright/helpers/MockWebSocketHelper.js b/frontend/playwright/helpers/MockWebSocketHelper.js index 3f0f845d2..42d06d5eb 100644 --- a/frontend/playwright/helpers/MockWebSocketHelper.js +++ b/frontend/playwright/helpers/MockWebSocketHelper.js @@ -2,17 +2,19 @@ export class MockWebSocketHelper extends EventTarget { static #mocks = new Map(); static async init(page) { - await page.exposeFunction("MockWebSocket$$constructor", (url, protocols) => { - const webSocket = new MockWebSocketHelper(page, url, protocols); + this.#mocks = new Map(); + + await page.exposeFunction("onMockWebSocketConstructor", (url) => { + const webSocket = new MockWebSocketHelper(page, url); this.#mocks.set(url, webSocket); }); - await page.exposeFunction("MockWebSocket$$spyMessage", (url, data) => { + await page.exposeFunction("onMockWebSocketSpyMessage", (url, data) => { if (!this.#mocks.has(url)) { throw new Error(`WebSocket with URL ${url} not found`); } this.#mocks.get(url).dispatchEvent(new MessageEvent("message", { data })); }); - await page.exposeFunction("MockWebSocket$$spyClose", (url, code, reason) => { + await page.exposeFunction("onMockWebSocketSpyClose", (url, code, reason) => { if (!this.#mocks.has(url)) { throw new Error(`WebSocket with URL ${url} not found`); } @@ -36,39 +38,52 @@ export class MockWebSocketHelper extends EventTarget { #page = null; #url; - #protocols; constructor(page, url, protocols) { super(); this.#page = page; this.#url = url; - this.#protocols = protocols; } mockOpen(options) { - return this.#page.evaluate(({ url, options }) => { - if (typeof WebSocket.getByURL !== 'function') { - throw new Error('WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?') - } - WebSocket.getByURL(url).mockOpen(options); - }, { url: this.#url, options }); + return this.#page.evaluate( + ({ url, options }) => { + if (typeof WebSocket.getByURL !== "function") { + throw new Error( + "WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?", + ); + } + WebSocket.getByURL(url).mockOpen(options); + }, + { url: this.#url, options }, + ); } mockMessage(data) { - return this.#page.evaluate(({ url, data }) => { - if (typeof WebSocket.getByURL !== 'function') { - throw new Error('WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?') - } - WebSocket.getByURL(url).mockMessage(data); - }, { url: this.#url, data }); + return this.#page.evaluate( + ({ url, data }) => { + if (typeof WebSocket.getByURL !== "function") { + throw new Error( + "WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?", + ); + } + WebSocket.getByURL(url).mockMessage(data); + }, + { url: this.#url, data }, + ); } mockClose() { - return this.#page.evaluate(({ url }) => { - if (typeof WebSocket.getByURL !== 'function') { - throw new Error('WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?') - } - WebSocket.getByURL(url).mockClose(); - }, { url: this.#url }); + return this.#page.evaluate( + ({ url }) => { + if (typeof WebSocket.getByURL !== "function") { + throw new Error( + "WebSocket.getByURL is not a function. Did you forget to call MockWebSocket.init(page)?", + ); + } + WebSocket.getByURL(url).mockClose(); + }, + { url: this.#url }, + ); } } diff --git a/frontend/playwright/scripts/MockWebSocket.js b/frontend/playwright/scripts/MockWebSocket.js index b7f5e4e30..aa54067da 100644 --- a/frontend/playwright/scripts/MockWebSocket.js +++ b/frontend/playwright/scripts/MockWebSocket.js @@ -46,14 +46,14 @@ window.WebSocket = class MockWebSocket extends EventTarget { MockWebSocket.#mocks.set(this.#url, this); - if (typeof window["MockWebSocket$$constructor"] === "function") { - MockWebSocket$$constructor(this.#url, this.#protocols); + if (typeof window["onMockWebSocketConstructor"] === "function") { + onMockWebSocketConstructor(this.#url, this.#protocols); } - if (typeof window["MockWebSocket$$spyMessage"] === "function") { - this.#spyMessage = MockWebSocket$$spyMessage; + if (typeof window["onMockWebSocketSpyMessage"] === "function") { + this.#spyMessage = onMockWebSocketSpyMessage; } - if (typeof window["MockWebSocket$$spyClose"] === "function") { - this.#spyClose = MockWebSocket$$spyClose; + if (typeof window["onMockWebSocketSpyClose"] === "function") { + this.#spyClose = onMockWebSocketSpyClose; } } diff --git a/frontend/playwright/ui/pages/BaseWebSocketPage.js b/frontend/playwright/ui/pages/BaseWebSocketPage.js index e382cd7b0..21855312e 100644 --- a/frontend/playwright/ui/pages/BaseWebSocketPage.js +++ b/frontend/playwright/ui/pages/BaseWebSocketPage.js @@ -8,8 +8,8 @@ export class BaseWebSocketPage extends BasePage { * @param {Page} page * @returns */ - static initWebSockets(page) { - return MockWebSocketHelper.init(page); + static async initWebSockets(page) { + await MockWebSocketHelper.init(page); } /** diff --git a/frontend/playwright/ui/specs/workspace.spec.js b/frontend/playwright/ui/specs/workspace.spec.js index b3b9981e5..58e9e5697 100644 --- a/frontend/playwright/ui/specs/workspace.spec.js +++ b/frontend/playwright/ui/specs/workspace.spec.js @@ -6,7 +6,7 @@ test.beforeEach(async ({ page }) => { await WorkspacePage.init(page); }); -test.skip("User loads worskpace with empty file", async ({ page }) => { +test("User loads worskpace with empty file", async ({ page }) => { const workspacePage = new WorkspacePage(page); await workspacePage.setupEmptyFile(page); @@ -15,7 +15,7 @@ test.skip("User loads worskpace with empty file", async ({ page }) => { await expect(workspacePage.pageName).toHaveText("Page 1"); }); -test.skip("User receives presence notifications updates in the workspace", async ({ page }) => { +test("User receives presence notifications updates in the workspace", async ({ page }) => { const workspacePage = new WorkspacePage(page); await workspacePage.setupEmptyFile(); @@ -25,7 +25,7 @@ test.skip("User receives presence notifications updates in the workspace", async await expect(page.getByTestId("active-users-list").getByAltText("Princesa Leia")).toHaveCount(2); }); -test.skip("User draws a rect", async ({ page }) => { +test("User draws a rect", async ({ page }) => { const workspacePage = new WorkspacePage(page); await workspacePage.setupEmptyFile(); await workspacePage.mockRPC("update-file?id=*", "workspace/update-file-create-rect.json");