From b38ab7f35163d8091ba63bbb533301662eae88ba Mon Sep 17 00:00:00 2001 From: zoobestik Date: Sun, 20 Aug 2023 14:51:51 +0200 Subject: [PATCH] test(KTL-1189); fix "Page closed" for github_mac --- .github/workflows/e2e.yml | 3 +- playwright.config.ts | 26 ++++++++-------- .../basics.e2e.ts-basics-simple-usage-1.png | Bin 23479 -> 0 bytes tests/basics.e2e.ts | 8 ++++- tests/utlis/index.ts | 28 +++++++++++------- tests/utlis/mocks/compiler.ts | 17 ++++++----- 6 files changed, 49 insertions(+), 33 deletions(-) delete mode 100644 tests/__screenshots__/github_mac/Desktop-Safari/basics.e2e.ts-basics-simple-usage-1.png diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 86f5ee7f..de961aee 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -81,6 +81,5 @@ jobs: path: | test-results/ playwright-report/ - tests/**/__screenshots__ - !tests/**/__screenshots__/dev + tests/**/__screenshots__/github_* retention-days: 5 diff --git a/playwright.config.ts b/playwright.config.ts index 61256256..2409e4a5 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -5,17 +5,17 @@ import { defineConfig, devices } from '@playwright/test'; dotenv({ path: `.env.local`, override: true }); const PROJECTS_LIST = { - DEV: [ 'Desktop Chrome' ], - GITHUB_MAC: [ 'Desktop Safari' ], - GITHUB_LINUX: [ 'Desktop Chrome', 'Desktop Firefox' ], + DEV: ['Desktop Chrome'], + GITHUB_MAC: ['Desktop Safari'], + GITHUB_LINUX: ['Desktop Chrome', 'Desktop Firefox'], }; const envMode = (env.TEST_PROJECT_LIST || 'DEV').toUpperCase(); if (!(envMode && isKeyOfObject(envMode, PROJECTS_LIST))) { const list = Object.keys(PROJECTS_LIST) - .map((s) => `'${s.toLowerCase()}'`) - .join(' or '); + .map((s) => `'${s.toLowerCase()}'`) + .join(' or '); throw Error(`TEST_PROJECT_LIST should be ${list}`); } @@ -28,7 +28,7 @@ export default defineConfig({ testMatch: /.*\.e2e\.tsx?$/, snapshotPathTemplate: `{testDir}/__screenshots__/${mode.toLowerCase()}/{projectName}/{testFilePath}-{arg}{ext}`, - timeout: 60000, + timeout: 30000, forbidOnly: !isDevMode, reporter: 'list', retries: isDevMode ? 0 : 2, @@ -42,7 +42,9 @@ export default defineConfig({ use: { testIdAttribute: 'data-test', - headless: (value => value ? value === 'true' : !isDevMode)(env.TEST_HEADLESS_MODE), + headless: ((value) => (value ? value === 'true' : !isDevMode))( + env.TEST_HEADLESS_MODE, + ), ignoreHTTPSErrors: true, screenshot: { fullPage: true, @@ -52,15 +54,15 @@ export default defineConfig({ video: isDevMode ? 'on-first-retry' : 'on', }, - projects: PROJECTS_LIST[mode].map(project => ({ + projects: PROJECTS_LIST[mode].map((project) => ({ name: project, - use: {...devices[project]}, - })) + use: { ...devices[project] }, + })), }); export function isKeyOfObject( - key: string | number | symbol, - obj: T, + key: string | number | symbol, + obj: T, ): key is keyof T { return key in obj; } diff --git a/tests/__screenshots__/github_mac/Desktop-Safari/basics.e2e.ts-basics-simple-usage-1.png b/tests/__screenshots__/github_mac/Desktop-Safari/basics.e2e.ts-basics-simple-usage-1.png deleted file mode 100644 index bc2ecde8445e99e340ec496fd13d11d8d2ffac37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23479 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 H^S}5%5akby diff --git a/tests/basics.e2e.ts b/tests/basics.e2e.ts index 01099235..dfc18ace 100644 --- a/tests/basics.e2e.ts +++ b/tests/basics.e2e.ts @@ -19,8 +19,14 @@ import { prepareNetwork, RouteFulfill, toPostData } from './utlis'; import { mockRunRequest, waitRunRequest } from './utlis/mocks/compiler'; test.describe('basics', () => { + let unroute: CallableFunction; + test.beforeEach(async ({ context, baseURL }) => { - await prepareNetwork(context, baseURL); // offline mode + unroute = await prepareNetwork(context, baseURL); // offline mode + }); + + test.afterEach(async () => { + if (unroute) unroute(); }); test('simple usage', async ({ page }) => { diff --git a/tests/utlis/index.ts b/tests/utlis/index.ts index b89a3264..ea3cfbc5 100644 --- a/tests/utlis/index.ts +++ b/tests/utlis/index.ts @@ -3,19 +3,27 @@ import { mockVersions } from './mocks/compiler'; export type RouteFulfill = Parameters[0]; -export function refuseExternalUrls(context: BrowserContext, baseURL: string) { +export async function refuseExternalUrls( + context: BrowserContext, + baseURL: string, +) { const host = new URL(baseURL).host; - return context.route( - (url) => url.host !== host, - (route) => route.abort('connectionrefused'), - ); + + const checkUrl = (url: URL) => url.host && url.host !== host; + const onMatch = (route: Route) => route.abort('connectionrefused'); + + await context.route(checkUrl, onMatch); + return () => context.unroute(checkUrl, onMatch); } -export function prepareNetwork(context: BrowserContext, baseURL: string) { - return Promise.all([ - refuseExternalUrls(context, baseURL), - mockVersions(context), - ]); +export async function prepareNetwork(context: BrowserContext, baseURL: string) { + const unRefuse = await refuseExternalUrls(context, baseURL); + const unVersions = await mockVersions(context); + + return async () => { + await unVersions(); + await unRefuse(); + }; } export function toPostData(code: string) { diff --git a/tests/utlis/mocks/compiler.ts b/tests/utlis/mocks/compiler.ts index 8d1c3fa0..e244734d 100644 --- a/tests/utlis/mocks/compiler.ts +++ b/tests/utlis/mocks/compiler.ts @@ -6,22 +6,23 @@ export const API_HOST = 'api.kotlinlang.org'; function defaultVersions(route: Route, req: Request) { if (req.method() !== 'GET') { - route.fallback(); - return; + return route.continue(); } return route.fulfill({ path: join(__dirname, 'versions.json') }); } -export function mockVersions( +export async function mockVersions( context: BrowserContext, resp?: Parameters[1], ) { - return context.route( - (url) => - url.host === API_HOST && url.pathname.match(/^\/?\/versions$/) !== null, - resp || defaultVersions, - ); + const checkUrl = (url: URL) => + url.host === API_HOST && url.pathname.match(/^\/?\/versions$/) !== null; + const onMatch = resp || defaultVersions; + + await context.route(checkUrl, onMatch); + + return () => context.unroute(checkUrl, onMatch); } function isRunRequest(url: URL | string) {