From 2577ce466381c821564f254f2b5c5f3b5acfd2db Mon Sep 17 00:00:00 2001 From: Jamal Carvalho Date: Wed, 24 Mar 2021 17:32:39 -0400 Subject: [PATCH] devtools,e2e: use a single browser instance for e2e tests Each e2e test file was starting and closing its own instance of Chrome. To speed up the tests we are now sharing a single instance of across test files and properly exiting after the tests have completed. Change-Id: Ia7ad4acaf961cf89a177e293e971c94b43b76d05 Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/304589 Trust: Jamal Carvalho Run-TryBot: Jamal Carvalho TryBot-Result: kokoro Reviewed-by: Julie Qiu --- devtools/config/e2e-config.yaml | 10 ++-------- devtools/config/jest.config.js | 2 ++ e2e/global-setup.ts | 19 +++++++++++++++++++ e2e/global-teardown.ts | 13 +++++++++++++ e2e/{globals.ts => global-types.ts} | 0 e2e/homepage.test.ts | 2 +- e2e/pkgsite.test.ts | 6 ++---- e2e/setup.ts | 17 ++++++++++++++--- package-lock.json | 26 +++++++++++++------------- package.json | 2 +- 10 files changed, 67 insertions(+), 30 deletions(-) create mode 100644 e2e/global-setup.ts create mode 100644 e2e/global-teardown.ts rename e2e/{globals.ts => global-types.ts} (100%) diff --git a/devtools/config/e2e-config.yaml b/devtools/config/e2e-config.yaml index ff658d41..28e2b4a8 100644 --- a/devtools/config/e2e-config.yaml +++ b/devtools/config/e2e-config.yaml @@ -1,9 +1,3 @@ experiments: - - name: command-toc - rollout: 100 - - name: directory-tree - rollout: 100 - - name: interactive-playground - rollout: 100 - - name: not-at-latest - rollout: 100 + - Name: sticky-header + Rollout: 100 \ No newline at end of file diff --git a/devtools/config/jest.config.js b/devtools/config/jest.config.js index a741772d..0678f98a 100644 --- a/devtools/config/jest.config.js +++ b/devtools/config/jest.config.js @@ -16,6 +16,8 @@ if (e2e) { config = { ...config, setupFilesAfterEnv: ['/e2e/setup.ts'], + globalSetup: '/e2e/global-setup.ts', + globalTeardown: '/e2e/global-teardown.ts', testEnvironment: 'node', }; } diff --git a/e2e/global-setup.ts b/e2e/global-setup.ts new file mode 100644 index 00000000..189b6bb4 --- /dev/null +++ b/e2e/global-setup.ts @@ -0,0 +1,19 @@ +import fs from 'fs'; +import os from 'os'; +import path from 'path'; +import mkdirp from 'mkdirp'; +import puppeteer, { Browser } from 'puppeteer'; + +declare const global: NodeJS.Global & typeof globalThis & { browser: Browser }; + +const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); +export default async function setup(): Promise { + global.browser = await puppeteer.launch({ + args: ['--no-sandbox', '--disable-dev-shm-usage'], + }); + + // Writing the websocket endpoint to a file so that tests + // can use it to connect to a global browser instance. + mkdirp.sync(DIR); + fs.writeFileSync(path.join(DIR, 'wsEndpoint'), global.browser.wsEndpoint()); +} diff --git a/e2e/global-teardown.ts b/e2e/global-teardown.ts new file mode 100644 index 00000000..313470b3 --- /dev/null +++ b/e2e/global-teardown.ts @@ -0,0 +1,13 @@ +import os from 'os'; +import path from 'path'; +import rimraf from 'rimraf'; +import { Browser } from 'puppeteer'; + +declare const global: NodeJS.Global & typeof globalThis & { browser: Browser }; + +const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); +export default async function teardown(): Promise { + await global.browser.close(); + // Clean-up the websocket endpoint file. + rimraf.sync(DIR); +} diff --git a/e2e/globals.ts b/e2e/global-types.ts similarity index 100% rename from e2e/globals.ts rename to e2e/global-types.ts diff --git a/e2e/homepage.test.ts b/e2e/homepage.test.ts index 370f9f0f..1fad9121 100644 --- a/e2e/homepage.test.ts +++ b/e2e/homepage.test.ts @@ -5,7 +5,7 @@ * license that can be found in the LICENSE file. */ -import './globals'; +import './global-types'; import puppeteer, { Page } from 'puppeteer'; const baseUrl = process.env.FRONTEND_URL ?? ''; diff --git a/e2e/pkgsite.test.ts b/e2e/pkgsite.test.ts index c6ce42cf..76503c60 100644 --- a/e2e/pkgsite.test.ts +++ b/e2e/pkgsite.test.ts @@ -5,7 +5,7 @@ * license that can be found in the LICENSE file. */ -import './globals'; +import './global-types'; import puppeteer, { Page } from 'puppeteer'; const baseUrl = process.env.FRONTEND_URL ?? ''; @@ -16,9 +16,7 @@ describe('golang.org/x/pkgsite', () => { beforeAll(async () => { page = await browser.newPage(); await page.goto(baseUrl); - await page.evaluate(() => - fetch(`/fetch/golang.org/x/pkgsite@v0.0.0-20210216165259-5867665b19ca`, { method: 'POST' }) - ); + await page.evaluate(() => fetch(`/fetch/golang.org/x/pkgsite`, { method: 'POST' })); }, 30000); beforeEach(async () => { diff --git a/e2e/setup.ts b/e2e/setup.ts index 55e84775..67b1e32b 100644 --- a/e2e/setup.ts +++ b/e2e/setup.ts @@ -1,3 +1,6 @@ +import fs from 'fs'; +import os from 'os'; +import path from 'path'; import { toMatchImageSnapshot } from 'jest-image-snapshot'; import puppeteer, { Browser } from 'puppeteer'; @@ -6,10 +9,18 @@ declare const global: NodeJS.Global & typeof globalThis & { browser: Browser }; expect.extend({ toMatchImageSnapshot }); beforeAll(async () => { - global.browser = await puppeteer.launch({ - args: ['--no-sandbox', '--disable-dev-shm-usage'], + const DIR = path.join(os.tmpdir(), 'jest_puppeteer_global_setup'); + const wsEndpoint = fs.readFileSync(path.join(DIR, 'wsEndpoint'), 'utf8'); + if (!wsEndpoint) { + throw new Error('wsEndpoint not found'); + } + + global.browser = await puppeteer.connect({ + browserWSEndpoint: wsEndpoint, defaultViewport: { height: 800, width: 1280 }, }); }); -afterAll(async () => await global.browser.close()); +afterAll(async () => { + global.browser.disconnect(); +}); diff --git a/package-lock.json b/package-lock.json index 16885099..bd102594 100644 --- a/package-lock.json +++ b/package-lock.json @@ -973,17 +973,17 @@ "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "requires": { - "type-fest": "^0.11.0" + "type-fest": "^0.21.3" }, "dependencies": { "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" } } }, @@ -4497,9 +4497,9 @@ "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" }, "node-notifier": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", - "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.2.tgz", + "integrity": "sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==", "optional": true, "requires": { "growly": "^1.3.0", @@ -6279,9 +6279,9 @@ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" }, "string-length": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.1.tgz", - "integrity": "sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "requires": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" diff --git a/package.json b/package.json index 38262ed7..97bde733 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "eslint-plugin-jest": "24.1.3", "eslint-plugin-prettier": "3.3.0", "jest": "26.6.3", - "jest-circus": "^26.6.3", + "jest-circus": "26.6.3", "jest-image-snapshot": "4.2.0", "js-green-licenses": "2.0.1", "npm-run-all": "4.1.5",