From 0ce9d7bcfbee9bdc5b9a446c3c663fc20d153bd5 Mon Sep 17 00:00:00 2001 From: Martin Vere Cihlar Date: Tue, 4 Feb 2025 13:58:03 +0100 Subject: [PATCH] feat(e2e): Introduce JS exception catcher to whole test suite (#16788) * feat(e2e): Introduce JS exception catcher to whole test suite * fix(e2e): Disable JS catcher for bridge and safari tests --- .../suite-desktop-core/e2e/support/common.ts | 7 +++++++ .../e2e/support/fixtures.ts | 19 +++++++++++++++++++ .../bridge-tor/spawn-bridge-daemon.test.ts | 3 ++- .../e2e/tests/bridge-tor/spawn-bridge.test.ts | 3 ++- .../e2e/tests/bridge-tor/spawn-tor.test.ts | 4 +++- .../e2e/tests/browser/safari.test.ts | 8 +++++++- 6 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/suite-desktop-core/e2e/support/common.ts b/packages/suite-desktop-core/e2e/support/common.ts index efb416bb2cf..ce54bf41418 100644 --- a/packages/suite-desktop-core/e2e/support/common.ts +++ b/packages/suite-desktop-core/e2e/support/common.ts @@ -171,3 +171,10 @@ export const isEqualWithOmit = (param: { object1: any; object2: any; mask: strin isEqual(omit(param.object1, param.mask), omit(param.object2, param.mask)); export const formatAddress = (address: string) => splitStringEveryNCharacters(address, 4).join(' '); + +// This function is used to override automatic fixtures that we want to skip in specific tests. +/* eslint-disable no-empty-pattern, react-hooks/rules-of-hooks */ +export async function skipFixture({}, use: (r: void) => Promise) { + await use(); +} +/* eslint-enable no-empty-pattern, react-hooks/rules-of-hooks */ diff --git a/packages/suite-desktop-core/e2e/support/fixtures.ts b/packages/suite-desktop-core/e2e/support/fixtures.ts index e96d9e39190..a36c92bff65 100644 --- a/packages/suite-desktop-core/e2e/support/fixtures.ts +++ b/packages/suite-desktop-core/e2e/support/fixtures.ts @@ -60,6 +60,7 @@ type Fixtures = { indexedDb: IndexedDbFixture; metadataProviderMock: MetadataProviderMock; blockbookMock: BlockbookMock; + exceptionLogger: void; }; const test = base.extend({ @@ -217,6 +218,24 @@ const test = base.extend({ const blockbookMock = new BlockbookMock(); await use(blockbookMock); }, + exceptionLogger: [ + async ({ page }, use) => { + const errors: Error[] = []; + page.on('pageerror', error => { + errors.push(error); + }); + + await use(); + + if (errors.length > 0) { + throw new Error( + `There was a JS exception during test run. + \n${errors.map(error => `${error.message}\n${error.stack}`).join('\n-----\n')}`, + ); + } + }, + { auto: true }, + ], }); export { test }; diff --git a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge-daemon.test.ts b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge-daemon.test.ts index 43121d4cb6f..1d5b7d3b8cf 100644 --- a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge-daemon.test.ts +++ b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge-daemon.test.ts @@ -3,9 +3,10 @@ import { expectBridgeToBeStopped, waitForAppToBeInitialized, } from '../../support/bridge'; -import { launchSuite, launchSuiteElectronApp } from '../../support/common'; +import { launchSuite, launchSuiteElectronApp, skipFixture } from '../../support/common'; import { expect, test } from '../../support/fixtures'; +test.use({ exceptionLogger: skipFixture }); test.describe.serial('Bridge', { tag: ['@group=suite', '@desktopOnly'] }, () => { test.beforeAll(async ({ trezorUserEnvLink }) => { // Ensure bridge is stopped so we properly test the electron app starting node-bridge module. diff --git a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge.test.ts b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge.test.ts index ddc0cfe355e..839e307a27f 100644 --- a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge.test.ts +++ b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-bridge.test.ts @@ -4,12 +4,13 @@ import { expectBridgeToBeStopped, waitForAppToBeInitialized, } from '../../support/bridge'; -import { LEGACY_BRIDGE_VERSION, launchSuite } from '../../support/common'; +import { LEGACY_BRIDGE_VERSION, launchSuite, skipFixture } from '../../support/common'; import { expect, test } from '../../support/fixtures'; import { AnalyticsActions } from '../../support/pageActions/analyticsActions'; import { DevicePromptActions } from '../../support/pageActions/devicePromptActions'; import { OnboardingActions } from '../../support/pageActions/onboarding/onboardingActions'; +test.use({ exceptionLogger: skipFixture }); test.describe.serial('Bridge', { tag: ['@group=suite', '@desktopOnly'] }, () => { test.beforeEach(async ({ trezorUserEnvLink }) => { //Ensure bridge is stopped so we properly test the electron app starting node-bridge module. diff --git a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-tor.test.ts b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-tor.test.ts index 6db07fedc58..478451e62c6 100644 --- a/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-tor.test.ts +++ b/packages/suite-desktop-core/e2e/tests/bridge-tor/spawn-tor.test.ts @@ -1,9 +1,11 @@ import { Page } from '@playwright/test'; -import { launchSuite } from '../../support/common'; +import { launchSuite, skipFixture } from '../../support/common'; import { expect, test } from '../../support/fixtures'; import { NetworkAnalyzer } from '../../support/networkAnalyzer'; +test.use({ exceptionLogger: skipFixture }); + const timeout = 1000 * 60 * 5; // 5 minutes because it takes a while to start tor. const turnOnTorInSettings = async (window: Page, shouldEnableTor = true) => { diff --git a/packages/suite-desktop-core/e2e/tests/browser/safari.test.ts b/packages/suite-desktop-core/e2e/tests/browser/safari.test.ts index 00331912cf8..741f85934b1 100644 --- a/packages/suite-desktop-core/e2e/tests/browser/safari.test.ts +++ b/packages/suite-desktop-core/e2e/tests/browser/safari.test.ts @@ -1,5 +1,6 @@ import { devices } from '@playwright/test'; +import { skipFixture } from '../../support/common'; import { expect, test } from '../../support/fixtures'; const safariAria = ` @@ -15,7 +16,12 @@ const safariAria = ` - paragraph: Continue at my own risk `; -test.use({ startEmulator: false, ...devices['Desktop Safari'], channel: 'webkit' }); +test.use({ + startEmulator: false, + ...devices['Desktop Safari'], + channel: 'webkit', + exceptionLogger: skipFixture, +}); test.describe('Safari', { tag: ['@group=other', '@webOnly', '@snapshot'] }, () => { test('Suite does not support Safari', async ({ page, onboardingPage }) => { await expect(page.locator('body')).toMatchAriaSnapshot(safariAria);