From e7f327f7af07e4c5fea6973e016fad06e54ef40e Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 18:51:14 +0100 Subject: [PATCH 1/8] Replace Puppeteer with Playwright --- build/generate-doc-images.ts | 15 +- jest.config.ts | 2 +- package-lock.json | 694 +------------------- package.json | 2 +- test/bench/gl-stats.ts | 12 +- test/bench/run-benchmarks.ts | 11 +- test/integration/README.md | 2 +- test/integration/browser/browser.test.ts | 63 +- test/integration/query/query.test.ts | 20 +- test/integration/render/run_render_tests.ts | 36 +- 10 files changed, 114 insertions(+), 743 deletions(-) diff --git a/build/generate-doc-images.ts b/build/generate-doc-images.ts index 5ce312095c..3ba6801d10 100644 --- a/build/generate-doc-images.ts +++ b/build/generate-doc-images.ts @@ -1,20 +1,21 @@ import path from 'path'; import fs from 'fs'; -import puppeteer from 'puppeteer'; +import playwright from 'playwright'; import packageJson from '../package.json' with { type: 'json' }; const exampleName = process.argv[2]; const useLocalhost = (process.argv.length > 3) && (process.argv[3] === 'serve'); const examplePath = path.resolve('test', 'examples'); -const browser = await puppeteer.launch({headless: true}); - -const page = await browser.newPage(); +const browser = await playwright.chromium.launch({headless: true}); +const context = await browser.newContext({ + deviceScaleFactor: 2 +}); +const page = await context.newPage(); // set viewport and double deviceScaleFactor to get a closer shot of the map -await page.setViewport({ +await page.setViewportSize({ width: 600, - height: 250, - deviceScaleFactor: 2 + height: 250 }); async function createImage(exampleName) { diff --git a/jest.config.ts b/jest.config.ts index 58baa44515..53697bcf00 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -49,7 +49,7 @@ const config: Config = { displayName: 'integration', testEnvironment: 'node', testMatch: [ - '/test/integration/**/*.test.{ts,js}', + '/test/integration/browser/*.test.{ts,js}', ], ...sharedConfig, }, diff --git a/package-lock.json b/package-lock.json index 6c5eabfc91..cec72043d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -107,12 +107,12 @@ "npm-run-all": "^4.1.5", "pdf-merger-js": "^5.1.2", "pixelmatch": "^6.0.0", + "playwright": "^1.48.2", "pngjs": "^7.0.0", "postcss": "^8.4.47", "postcss-cli": "^11.0.0", "postcss-inline-svg": "^6.0.0", "pretty-bytes": "^6.1.1", - "puppeteer": "^23.6.1", "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.24.3", @@ -2230,28 +2230,6 @@ "node": ">=14" } }, - "node_modules/@puppeteer/browsers": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.4.0.tgz", - "integrity": "sha512-x8J1csfIygOwf6D6qUAZ0ASk3z63zPb7wkNeHRerCMh82qWKUrOgkuP005AJC8lDL6/evtXETGEJVcwykKT4/g==", - "dev": true, - "dependencies": { - "debug": "^4.3.6", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.3", - "tar-fs": "^3.0.6", - "unbzip2-stream": "^1.4.3", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/@rollup/plugin-commonjs": { "version": "28.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", @@ -2817,12 +2795,6 @@ "node": ">= 10" } }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "dev": true - }, "node_modules/@trysound/sax": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", @@ -3445,16 +3417,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.12.2", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.12.2.tgz", @@ -4031,18 +3993,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "dev": true, - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", @@ -4136,12 +4086,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "dev": true - }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -4236,52 +4180,6 @@ "dev": true, "license": "MIT" }, - "node_modules/bare-events": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.0.tgz", - "integrity": "sha512-/E8dDe9dsbLyh2qrZ64PEPadOQ0F4gbl1sUJOrmph7xOiIxfY8vwab/4bFLh4Y88/Hk/ujKcrQKc+ps0mv873A==", - "dev": true, - "optional": true - }, - "node_modules/bare-fs": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-2.3.5.tgz", - "integrity": "sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==", - "dev": true, - "optional": true, - "dependencies": { - "bare-events": "^2.0.0", - "bare-path": "^2.0.0", - "bare-stream": "^2.0.0" - } - }, - "node_modules/bare-os": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", - "integrity": "sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==", - "dev": true, - "optional": true - }, - "node_modules/bare-path": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-2.1.3.tgz", - "integrity": "sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==", - "dev": true, - "optional": true, - "dependencies": { - "bare-os": "^2.1.0" - } - }, - "node_modules/bare-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.3.2.tgz", - "integrity": "sha512-EFZHSIBkDgSHIwj2l2QZfP4U5OcD4xFAOwhSb/vlr9PIqyGJGvB/nfClJbcnh3EY4jtPE4zsb5ztae96bVF79A==", - "dev": true, - "optional": true, - "dependencies": { - "streamx": "^2.20.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "dev": true, @@ -4301,15 +4199,6 @@ ], "license": "MIT" }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/benchmark": { "version": "2.1.4", "dev": true, @@ -4416,39 +4305,6 @@ "node": ">= 0.4.0" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/buffer-from": { "version": "1.1.2", "dev": true, @@ -4693,20 +4549,6 @@ "node": ">=10" } }, - "node_modules/chromium-bidi": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.8.0.tgz", - "integrity": "sha512-uJydbGdTw0DEUjhoogGveneJVWX/9YuqkWePzMmkBYwtdAqo5d3J/ovNKFr+/2hWXYmYCr6it8mSSTIj6SS6Ug==", - "dev": true, - "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0", - "zod": "3.23.8" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, "node_modules/ci-info": { "version": "3.3.2", "dev": true, @@ -5847,15 +5689,6 @@ "node": ">=12" } }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "dev": true, - "engines": { - "node": ">= 14" - } - }, "node_modules/data-urls": { "version": "3.0.2", "dev": true, @@ -6015,20 +5848,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "dev": true, - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/delaunator": { "version": "5.0.0", "dev": true, @@ -6276,15 +6095,6 @@ "dev": true, "license": "MIT" }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7149,41 +6959,6 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/extract-zip/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "dev": true, @@ -7198,12 +6973,6 @@ "node": ">=6.0.0" } }, - "node_modules/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", @@ -7261,15 +7030,6 @@ "dev": true, "license": "MIT" }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, "node_modules/fdir": { "version": "6.4.2", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.2.tgz", @@ -7696,21 +7456,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/get-uri": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", - "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", - "dev": true, - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4", - "fs-extra": "^11.2.0" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/gl-matrix": { "version": "3.4.3", "license": "MIT" @@ -8341,25 +8086,6 @@ "node": ">=12" } }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ip-address/node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true - }, "node_modules/is-array-buffer": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", @@ -9771,12 +9497,6 @@ "js-yaml": "bin/js-yaml.js" } }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true - }, "node_modules/jsdom": { "version": "25.0.1", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", @@ -10269,15 +9989,6 @@ "loose-envify": "cli.js" } }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "dev": true, - "engines": { - "node": ">=12" - } - }, "node_modules/lunr": { "version": "2.3.9", "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz", @@ -10649,12 +10360,6 @@ "node": ">= 8" } }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "dev": true - }, "node_modules/mkdirp": { "version": "1.0.4", "dev": true, @@ -10768,15 +10473,6 @@ "node": ">= 0.6" } }, - "node_modules/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/nice-try": { "version": "1.0.5", "dev": true, @@ -11247,76 +10943,6 @@ "node": ">=6" } }, - "node_modules/pac-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.2.tgz", - "integrity": "sha512-BFi3vZnO9X5Qt6NRz7ZOaPja3ic0PhlsmCRYLOpN11+mWBCR6XJDqW5RF3j8jm4WGGQZtBA+bTfxYzeKW73eHg==", - "dev": true, - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.5", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "dev": true, - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/package-json-from-dist": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", @@ -11497,12 +11123,6 @@ "node": ">=16" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, "node_modules/picocolors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", @@ -11569,6 +11189,38 @@ "dev": true, "license": "MIT" }, + "node_modules/playwright": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.48.2.tgz", + "integrity": "sha512-NjYvYgp4BPmiwfe31j4gHLa3J7bD2WiBz8Lk2RoSsmX38SVIARZ18VYjxLjAcDsAhA+F4iSEXTSGgjua0rrlgQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.48.2.tgz", + "integrity": "sha512-sjjw+qrLFlriJo64du+EK0kJgZzoQPsabGF4lBvsid+3CNIZIYLgnMj9V6JY5VhM2Peh20DJWIVpVljLLnlawA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/pngjs": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-7.0.0.tgz", @@ -12280,15 +11932,6 @@ "node": ">= 0.8" } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, "node_modules/prompts": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", @@ -12331,69 +11974,6 @@ "version": "3.6.0", "license": "MIT" }, - "node_modules/proxy-agent": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.4.0.tgz", - "integrity": "sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.3", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.0.1", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-agent/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "node_modules/pseudomap": { "version": "1.0.2", "dev": true, @@ -12404,16 +11984,6 @@ "dev": true, "license": "MIT" }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -12432,56 +12002,6 @@ "node": ">=6" } }, - "node_modules/puppeteer": { - "version": "23.6.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-23.6.1.tgz", - "integrity": "sha512-8+ALGQgwXd3P/tGcuSsxTPGDaOQIjcDIm04I5hpWZv/PiN5q8bQNHRUyfYrifT+flnM9aTWCP7tLEzuB6SlIgA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@puppeteer/browsers": "2.4.0", - "chromium-bidi": "0.8.0", - "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1354347", - "puppeteer-core": "23.6.1", - "typed-query-selector": "^2.12.0" - }, - "bin": { - "puppeteer": "lib/cjs/puppeteer/node/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer-core": { - "version": "23.6.1", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.6.1.tgz", - "integrity": "sha512-DoNLAzQfGklPauEn33N4h9cM9GubJSINEn+AUMwAXwW159Y9JLk5y34Jsbv4c7kG8P0puOYWV9leu2siMZ/QpQ==", - "dev": true, - "dependencies": { - "@puppeteer/browsers": "2.4.0", - "chromium-bidi": "0.8.0", - "debug": "^4.3.7", - "devtools-protocol": "0.0.1354347", - "typed-query-selector": "^2.12.0", - "ws": "^8.18.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer-core/node_modules/devtools-protocol": { - "version": "0.0.1354347", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1354347.tgz", - "integrity": "sha512-BlmkSqV0V84E2WnEnoPnwyix57rQxAM5SKJjf4TbYOCGLAWtz8CDH8RIaGOjPgPCXo2Mce3kxSY497OySidY3Q==", - "dev": true - }, - "node_modules/puppeteer/node_modules/devtools-protocol": { - "version": "0.0.1354347", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1354347.tgz", - "integrity": "sha512-BlmkSqV0V84E2WnEnoPnwyix57rQxAM5SKJjf4TbYOCGLAWtz8CDH8RIaGOjPgPCXo2Mce3kxSY497OySidY3Q==", - "dev": true - }, "node_modules/pure-rand": { "version": "6.0.4", "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.0.4.tgz", @@ -12522,12 +12042,6 @@ ], "license": "MIT" }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, "node_modules/quickselect": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/quickselect/-/quickselect-3.0.0.tgz", @@ -13223,62 +12737,12 @@ "node": ">=8" } }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, "node_modules/smob": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/smob/-/smob-1.1.1.tgz", "integrity": "sha512-i5aqEBPnDv9d77+NDxfjROtywxzNdAVNyaOr+RsLhM28Ts+Ar7luIp/Q+SBYa6wv/7BBcOpEkrhtDxsl2WA9Jg==", "dev": true }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/socks-proxy-agent/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, "node_modules/source-map": { "version": "0.7.4", "dev": true, @@ -13556,20 +13020,6 @@ "node": ">=8" } }, - "node_modules/streamx": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.20.1.tgz", - "integrity": "sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.3.2", - "queue-tick": "^1.0.1", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "dev": true, @@ -14254,31 +13704,6 @@ "node": ">= 10" } }, - "node_modules/tar-fs": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz", - "integrity": "sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==", - "dev": true, - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^2.1.1", - "bare-path": "^2.1.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/terser": { "version": "5.17.4", "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.4.tgz", @@ -14335,23 +13760,11 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/text-decoder": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.1.tgz", - "integrity": "sha512-x9v3H/lTKIJKQQe7RPQkLfKAnc9lUTkWDypIQgTzPJAq+5/GCDHonmshfvlsNSj58yyshbIJJDLmU15qNERrXQ==", - "dev": true - }, "node_modules/text-table": { "version": "0.2.0", "dev": true, "license": "MIT" }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/tinyglobby": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.10.tgz", @@ -14693,12 +14106,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typed-query-selector": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", - "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", - "dev": true - }, "node_modules/typedoc": { "version": "0.26.10", "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.26.10.tgz", @@ -14799,16 +14206,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/undici-types": { "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", @@ -14950,12 +14347,6 @@ "requires-port": "^1.0.0" } }, - "node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true - }, "node_modules/util-deprecate": { "version": "1.0.2", "dev": true, @@ -15515,16 +14906,6 @@ "node": ">=12" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "node_modules/yn": { "version": "3.1.1", "dev": true, @@ -15544,15 +14925,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", diff --git a/package.json b/package.json index 417d9744ad..9dcc133074 100644 --- a/package.json +++ b/package.json @@ -115,12 +115,12 @@ "npm-run-all": "^4.1.5", "pdf-merger-js": "^5.1.2", "pixelmatch": "^6.0.0", + "playwright": "^1.48.2", "pngjs": "^7.0.0", "postcss": "^8.4.47", "postcss-cli": "^11.0.0", "postcss-inline-svg": "^6.0.0", "pretty-bytes": "^6.1.1", - "puppeteer": "^23.6.1", "react": "^18.3.1", "react-dom": "^18.3.1", "rollup": "^4.24.3", diff --git a/test/bench/gl-stats.ts b/test/bench/gl-stats.ts index f705cec4f2..773437b6e0 100644 --- a/test/bench/gl-stats.ts +++ b/test/bench/gl-stats.ts @@ -1,4 +1,4 @@ -import puppeteer, {Page} from 'puppeteer'; +import { chromium, Page } from 'playwright'; import fs from 'fs'; import zlib from 'zlib'; import {execSync} from 'child_process'; @@ -20,11 +20,12 @@ function waitForConsole(page: Page): Promise { }); } -const browser = await puppeteer.launch({headless: true}); +const browser = await chromium.launch({headless: true}); try { - - const page = await browser.newPage(); - await page.setViewport({width: 600, height: 600, deviceScaleFactor: 2}); + const context = await browser.newContext({deviceScaleFactor: 2}); + const page = await context.newPage(); + await page.setViewportSize({width: 600, height: 600}); + console.log('collecting stats...'); await page.setContent(benchHTML); @@ -40,6 +41,7 @@ try { fs.writeFileSync('data.json.gz', zlib.gzipSync(JSON.stringify(stats))); await page.close(); + await context.close(); } finally { await browser.close(); } diff --git a/test/bench/run-benchmarks.ts b/test/bench/run-benchmarks.ts index 1fa8df346b..f6b0771379 100644 --- a/test/bench/run-benchmarks.ts +++ b/test/bench/run-benchmarks.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import puppeteer from 'puppeteer'; +import {chromium} from 'playwright'; import PDFMerger from 'pdf-merger-js'; import minimist from 'minimist'; @@ -39,13 +39,12 @@ if (argv.compare !== true && argv.compare !== undefined) { // handle --compare w console.log(`Starting headless chrome at: ${url.toString()}`); -const browser = await puppeteer.launch({headless: true}); +const browser = await chromium.launch({headless: true}); try { - - const webPage = await browser.newPage(); - await webPage.setDefaultTimeout(0); - await webPage.setViewport({width: 1280, height: 1024}); + const context = await browser.newContext(); + const webPage = await context.newPage(); + await webPage.setViewportSize({width: 1280, height: 1024}); url.hash = 'NONE'; // this will simply load the page without running any benchmarks await webPage.goto(url.toString()); diff --git a/test/integration/README.md b/test/integration/README.md index ee0231aaa4..67ba74e4e3 100644 --- a/test/integration/README.md +++ b/test/integration/README.md @@ -92,7 +92,7 @@ npm run test-render -- raster-masking/overlapping-zoom --debug ### Viewing render test results -During a render test run, the test harness will use puppeteer to drive real browser and create an `actual.png` image from the given `style.json`, and will then use [pixelmatch](https://github.com/mapbox/pixelmatch) to compare that image to `expected.png`, generating a `diff.png` highlighting the mismatching pixels (if any) in red. +During a render test run, the test harness will use playwright to drive real browser and create an `actual.png` image from the given `style.json`, and will then use [pixelmatch](https://github.com/mapbox/pixelmatch) to compare that image to `expected.png`, generating a `diff.png` highlighting the mismatching pixels (if any) in red. By default render tests generate reports in ./test/integration/render/ directory: ``` diff --git a/test/integration/browser/browser.test.ts b/test/integration/browser/browser.test.ts index 5efa3b2508..b68917ffd2 100644 --- a/test/integration/browser/browser.test.ts +++ b/test/integration/browser/browser.test.ts @@ -1,4 +1,4 @@ -import puppeteer, {Page, Browser} from 'puppeteer'; +import {Page, Browser, chromium, BrowserContext} from 'playwright'; import st from 'st'; import http, {type Server} from 'http'; import type {AddressInfo} from 'net'; @@ -11,6 +11,7 @@ const deviceScaleFactor = 2; let server: Server; let browser: Browser; +let context: BrowserContext; let page: Page; let map: Map; let maplibregl: typeof MapLibreGL; @@ -26,19 +27,21 @@ describe('Browser tests', () => { ); await new Promise((resolve) => server.listen(resolve)); - browser = await puppeteer.launch({ + browser = await chromium.launch({ headless: true, args: [ '--use-gl=angle', '--use-angle=gl' ], }); + context = await browser.newContext({deviceScaleFactor}) }, 40000); beforeEach(async () => { - page = await browser.newPage(); - await page.setViewport({width: testWidth, height: testHeight, deviceScaleFactor}); + page = await context.newPage(); + await page.setViewportSize({width: testWidth, height: testHeight}); + await page.evaluate(`window.devicePixelRatio = ${deviceScaleFactor}`); const port = (server.address() as AddressInfo).port; @@ -56,10 +59,11 @@ describe('Browser tests', () => { }, 40000); afterEach(async() => { - page.close(); + await page.close(); }, 40000); afterAll(async () => { + await context.close(); await browser.close(); if (server) { server.close(); @@ -104,8 +108,8 @@ describe('Browser tests', () => { }, 20000); test('Drag to the left', async () => { - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox(); + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox(); const dragToLeft = async () => { await page.mouse.move(canvasBB!.x, canvasBB!.y); @@ -121,56 +125,49 @@ describe('Browser tests', () => { }); }; - await page.emulateMediaFeatures([ - {name: 'prefers-reduced-motion', value: 'reduce'}, - ]); + await page.emulateMedia({reducedMotion: 'reduce'}); const centerWithoutInertia = await dragToLeft(); expect(centerWithoutInertia.lng).toBeCloseTo(-35.15625, 4); expect(centerWithoutInertia.lat).toBeCloseTo(0, 7); - await page.emulateMediaFeatures([ - {name: 'prefers-reduced-motion', value: 'reduce'}, - ]); + await page.emulateMedia({reducedMotion: 'reduce'}); const centerWithInertia = await dragToLeft(); expect(centerWithInertia.lng).toBeLessThan(-60); expect(centerWithInertia.lat).toBeCloseTo(0, 7); - }, 20000); + }); test('Resize viewport (page)', async () => { - - await page.setViewport({width: 400, height: 400, deviceScaleFactor: 2}); - + await page.setViewportSize({width: 400, height: 400}); + await page.evaluate(`window.devicePixelRatio = ${deviceScaleFactor}`); await sleep(200); - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox(); + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox(); expect(canvasBB?.width).toBeCloseTo(400); expect(canvasBB?.height).toBeCloseTo(400); }, 20000); test('Resize div', async () => { - await page.evaluate(() => { document.getElementById('map')!.style.width = '200px'; document.getElementById('map')!.style.height = '200px'; }); await sleep(1000); - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox(); + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox(); expect(canvasBB!.width).toBeCloseTo(200); expect(canvasBB!.height).toBeCloseTo(200); }, 20000); test('Zoom: Double click at the center', async () => { - - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox()!; - await page.mouse.click(canvasBB?.x!, canvasBB?.y!, {clickCount: 2}); + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox()!; + await page.mouse.dblclick(canvasBB?.x! + canvasBB?.width! / 2, canvasBB?.y! + canvasBB?.height! / 2); // Wait until the map has settled, then report the zoom level back. const zoom = await page.evaluate(() => { - return new Promise((resolve, _reject) => { + return new Promise((resolve, _reject) => { map.once('idle', () => resolve(map.getZoom())); }); }); @@ -187,8 +184,8 @@ describe('Browser tests', () => { .addTo(map); return map.getCenter(); }); - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox()!; + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox()!; const dragToLeft = async () => { await page.mouse.move(canvasBB!.x + canvasBB!.width / 2, canvasBB!.y + canvasBB!.height / 2); await page.mouse.down(); @@ -393,9 +390,8 @@ describe('Browser tests', () => { }, 20000); test('Load map with RTL plugin should throw exception for invalid URL', async () => { - + const rtlPromise = page.evaluate(() => { - // console.log('Testing start'); return maplibregl.setRTLTextPlugin('badURL', false); }); @@ -404,7 +400,6 @@ describe('Browser tests', () => { const regex = new RegExp('Failed to execute \'importScripts\'.*'); await expect(rtlPromise).rejects.toThrow(regex); - }, 2000); test('Movement with transformCameraUpdate and terrain', async () => { @@ -431,8 +426,8 @@ describe('Browser tests', () => { map.transformCameraUpdate = () => ({}); }); - const canvas = await page.$('.maplibregl-canvas'); - const canvasBB = await canvas?.boundingBox(); + const canvas = page.locator('.maplibregl-canvas'); + const canvasBB = await canvas.boundingBox(); await page.mouse.move(canvasBB!.x, canvasBB!.y); await page.mouse.down(); await page.mouse.move(100, 0, { diff --git a/test/integration/query/query.test.ts b/test/integration/query/query.test.ts index 57570cf73a..afbe9d0b19 100644 --- a/test/integration/query/query.test.ts +++ b/test/integration/query/query.test.ts @@ -1,5 +1,5 @@ -import puppeteer, {Page, Browser} from 'puppeteer'; +import {chromium, Page, Browser, BrowserContext} from 'playwright'; import {deepEqual} from '../lib/json-diff'; import st from 'st'; @@ -18,7 +18,7 @@ let maplibregl: typeof maplibreglModule; jest.retryTimes(3); -function performQueryOnFixture(fixture) { +function performQueryOnFixture(fixture) { return new Promise((resolve, _reject) => { @@ -83,7 +83,7 @@ function performQueryOnFixture(fixture) { const options = style.metadata.test; const skipLayerDelete = style.metadata.skipLayerDelete; - const map = new maplibregl.Map({ + const map = new maplibregl.Map({ container: 'map', style, interactive: false, @@ -124,6 +124,7 @@ function performQueryOnFixture(fixture) { describe('query tests', () => { let browser: Browser; + let context: BrowserContext; let server: Server; beforeAll(async () => { @@ -133,7 +134,8 @@ describe('query tests', () => { cors: true, }) ); - browser = await puppeteer.launch({headless: true}); + browser = await chromium.launch({headless: true}); + context = await browser.newContext({deviceScaleFactor: 2}); await new Promise((resolve) => server.listen(resolve)); }, 60000); @@ -145,10 +147,10 @@ describe('query tests', () => { let page: Page; beforeEach(async () => { - page = await browser.newPage(); - await page.setViewport({width: 512, height: 512, deviceScaleFactor: 2}); + page = await context.newPage(); + await page.setViewportSize({width: 512, height: 512}); }); - afterEach(async() => { + afterEach(async () => { await page.close(); }); @@ -212,7 +214,7 @@ async function dirToJson(dir: string, port: number) { style?: any; expected?: any; actual?: any; - [s:string]:unknown; + [s: string]: unknown; }; for (const file of files) { @@ -239,7 +241,7 @@ async function dirToJson(dir: string, port: number) { return result; } -function processStyle(testName:string, style: unknown, port:number) { +function processStyle(testName: string, style: unknown, port: number) { const clone = JSON.parse(JSON.stringify(style)); localizeURLs(clone, port, 'test/integration'); diff --git a/test/integration/render/run_render_tests.ts b/test/integration/render/run_render_tests.ts index 5c06757533..05d0d75018 100644 --- a/test/integration/render/run_render_tests.ts +++ b/test/integration/render/run_render_tests.ts @@ -6,7 +6,7 @@ import pixelmatch from 'pixelmatch'; import {fileURLToPath} from 'url'; import {globSync} from 'glob'; import http from 'http'; -import puppeteer, {Page, Browser} from 'puppeteer'; +import {chromium, Page, Browser} from 'playwright'; import {CoverageReport} from 'monocart-coverage-reports'; import {localizeURLs} from '../lib/localize-urls'; import type {Map as MaplibreMap, CanvasSource, PointLike, StyleSpecification} from '../../../dist/maplibre-gl'; @@ -256,7 +256,7 @@ async function getImageFromStyle(styleForTest: StyleWithTestData, page: Page): P const width = styleForTest.metadata.test.width; const height = styleForTest.metadata.test.height; - await page.setViewport({width, height, deviceScaleFactor: 2}); + await page.setViewportSize({width, height}); await page.setContent(` @@ -301,7 +301,7 @@ async function getImageFromStyle(styleForTest: StyleWithTestData, page: Page): P }`; const fragmentSource = `#version 300 es - + out highp vec4 fragColor; void main() { fragColor = vec4(1.0, 0.0, 0.0, 1.0); @@ -452,7 +452,7 @@ async function getImageFromStyle(styleForTest: StyleWithTestData, page: Page): P // Inject MapLibre projection code ${shaderDescription.vertexShaderPrelude} ${shaderDescription.define} - + in vec3 a_pos; void main() { @@ -915,8 +915,9 @@ async function runTests(page: Page, testStyles: StyleWithTestData[], directory: } async function createPageAndStart(browser: Browser, testStyles: StyleWithTestData[], directory: string, options: RenderOptions) { - const page = await browser.newPage(); - await page.coverage.startJSCoverage({includeRawScriptCoverage: true}); + const context = await browser.newContext({deviceScaleFactor: 2}); + const page = await context.newPage(); + await page.coverage.startJSCoverage({}); applyDebugParameter(options, page); await page.addScriptTag({path: 'dist/maplibre-gl-dev.js'}); await runTests(page, testStyles, directory); @@ -930,17 +931,16 @@ async function closePageAndFinish(page: Page, reportCoverage: boolean) { return; } - const rawV8CoverageData = coverage.map((it) => { - // Convert to raw v8 coverage format - const entry: any = { - source: it.text, - ...it.rawScriptCoverage - }; - if (entry.url.endsWith('maplibre-gl-dev.js')) { - entry.sourceMap = JSON.parse(fs.readFileSync('dist/maplibre-gl-dev.js.map').toString('utf-8')); - } - return entry; - }); + + const rawV8CoverageData = coverage.map((entry) => ({ + source: entry.source, + url: entry.url, + functions: entry.functions, + scriptId: entry.scriptId, + sourceMap: entry.url.endsWith('maplibre-gl-dev.js') + ? JSON.parse(fs.readFileSync('dist/maplibre-gl-dev.js.map', 'utf-8')) + : undefined + })); const coverageReport = new CoverageReport({ name: 'MapLibre Coverage Report', @@ -982,7 +982,7 @@ async function executeRenderTests() { options.openBrowser = checkParameter(options, '--open-browser'); } - const browser = await puppeteer.launch({headless: !options.openBrowser, args: ['--enable-webgl', '--no-sandbox', + const browser = await chromium.launch({headless: !options.openBrowser, args: ['--enable-webgl', '--no-sandbox', '--disable-web-security']}); const server = http.createServer( From 0743ba53b1ed72b9c73dc8bc4b7da04092561118 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:09:47 +0100 Subject: [PATCH 2/8] lint --- test/integration/render/run_render_tests.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/test/integration/render/run_render_tests.ts b/test/integration/render/run_render_tests.ts index 05d0d75018..705ddc13e8 100644 --- a/test/integration/render/run_render_tests.ts +++ b/test/integration/render/run_render_tests.ts @@ -931,7 +931,6 @@ async function closePageAndFinish(page: Page, reportCoverage: boolean) { return; } - const rawV8CoverageData = coverage.map((entry) => ({ source: entry.source, url: entry.url, From 1a3a89f305693953e4482fda54ecbcfdacb40b21 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:17:42 +0100 Subject: [PATCH 3/8] jest confi --- jest.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jest.config.ts b/jest.config.ts index 53697bcf00..58baa44515 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -49,7 +49,7 @@ const config: Config = { displayName: 'integration', testEnvironment: 'node', testMatch: [ - '/test/integration/browser/*.test.{ts,js}', + '/test/integration/**/*.test.{ts,js}', ], ...sharedConfig, }, From 7294880b7793c72a5f10bec192bd196a1dbec56a Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:20:20 +0100 Subject: [PATCH 4/8] send context to createPageAndStart --- test/integration/render/run_render_tests.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/integration/render/run_render_tests.ts b/test/integration/render/run_render_tests.ts index 705ddc13e8..17098cdd22 100644 --- a/test/integration/render/run_render_tests.ts +++ b/test/integration/render/run_render_tests.ts @@ -6,7 +6,7 @@ import pixelmatch from 'pixelmatch'; import {fileURLToPath} from 'url'; import {globSync} from 'glob'; import http from 'http'; -import {chromium, Page, Browser} from 'playwright'; +import {chromium, Page, Browser, BrowserContext} from 'playwright'; import {CoverageReport} from 'monocart-coverage-reports'; import {localizeURLs} from '../lib/localize-urls'; import type {Map as MaplibreMap, CanvasSource, PointLike, StyleSpecification} from '../../../dist/maplibre-gl'; @@ -914,8 +914,8 @@ async function runTests(page: Page, testStyles: StyleWithTestData[], directory: } } -async function createPageAndStart(browser: Browser, testStyles: StyleWithTestData[], directory: string, options: RenderOptions) { - const context = await browser.newContext({deviceScaleFactor: 2}); +async function createPageAndStart(context: BrowserContext, testStyles: StyleWithTestData[], directory: string, options: RenderOptions) { + const page = await context.newPage(); await page.coverage.startJSCoverage({}); applyDebugParameter(options, page); @@ -984,6 +984,8 @@ async function executeRenderTests() { const browser = await chromium.launch({headless: !options.openBrowser, args: ['--enable-webgl', '--no-sandbox', '--disable-web-security']}); + const context = await browser.newContext({deviceScaleFactor: 2}); + const server = http.createServer( st({ path: 'test/integration/assets', @@ -1009,13 +1011,13 @@ async function executeRenderTests() { testStyles = testStyles.splice(+process.env.CURRENT_SPLIT_INDEX * numberOfTestsForThisPart, numberOfTestsForThisPart); } - let page = await createPageAndStart(browser, testStyles, directory, options); + let page = await createPageAndStart(context, testStyles, directory, options); const failedTests = testStyles.filter(t => t.metadata.test.error || !t.metadata.test.ok); await closePageAndFinish(page, failedTests.length === 0); if (failedTests.length > 0 && failedTests.length < testStyles.length) { console.log(`Re-running failed tests: ${failedTests.length}`); options.debug = true; - page = await createPageAndStart(browser, failedTests, directory, options); + page = await createPageAndStart(context, failedTests, directory, options); await closePageAndFinish(page, true); } From c108f457ef9e406742e1600f58094f885fd6ab72 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:28:25 +0100 Subject: [PATCH 5/8] close context --- test/integration/query/query.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/test/integration/query/query.test.ts b/test/integration/query/query.test.ts index afbe9d0b19..a044e34b62 100644 --- a/test/integration/query/query.test.ts +++ b/test/integration/query/query.test.ts @@ -140,6 +140,7 @@ describe('query tests', () => { }, 60000); afterAll(async () => { + await context.close(); await browser.close(); await new Promise(resolve => server.close(resolve)); }); From 109a9e7b5186cf6ec5ef41fc2162fa48564cb4ca Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:44:28 +0100 Subject: [PATCH 6/8] install playwright in ci --- .github/workflows/test-all.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index d1abba961f..1d3ef535c5 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -81,6 +81,8 @@ jobs: with: node-version-file: '.nvmrc' - run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps - run: npm run build-dist - uses: actions/upload-artifact@v4 if: '!cancelled()' @@ -117,6 +119,8 @@ jobs: if: runner.os == 'Linux' run: sudo apt install fonts-noto-cjk - run: npm ci + - name: Install Playwright Browsers + run: npx playwright install --with-deps - name: Start display server if: runner.os == 'Linux' run: nohup Xvfb & From 5c82684e91ed433e801a4c7798d391cf1df59e13 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:50:32 +0100 Subject: [PATCH 7/8] depend on @playwright/test --- build/generate-doc-images.ts | 2 +- package-lock.json | 18 +++++++++++++++++- package.json | 2 +- test/bench/gl-stats.ts | 2 +- test/bench/run-benchmarks.ts | 2 +- test/integration/browser/browser.test.ts | 2 +- test/integration/query/query.test.ts | 2 +- test/integration/render/run_render_tests.ts | 2 +- 8 files changed, 24 insertions(+), 8 deletions(-) diff --git a/build/generate-doc-images.ts b/build/generate-doc-images.ts index 3ba6801d10..781ae0f2e5 100644 --- a/build/generate-doc-images.ts +++ b/build/generate-doc-images.ts @@ -1,6 +1,6 @@ import path from 'path'; import fs from 'fs'; -import playwright from 'playwright'; +import playwright from '@playwright/test'; import packageJson from '../package.json' with { type: 'json' }; const exampleName = process.argv[2]; diff --git a/package-lock.json b/package-lock.json index cec72043d2..6fefed9b6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "devDependencies": { "@mapbox/mapbox-gl-rtl-text": "^0.3.0", "@mapbox/mvt-fixtures": "^3.10.0", + "@playwright/test": "^1.48.2", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.3.0", @@ -107,7 +108,6 @@ "npm-run-all": "^4.1.5", "pdf-merger-js": "^5.1.2", "pixelmatch": "^6.0.0", - "playwright": "^1.48.2", "pngjs": "^7.0.0", "postcss": "^8.4.47", "postcss-cli": "^11.0.0", @@ -2230,6 +2230,22 @@ "node": ">=14" } }, + "node_modules/@playwright/test": { + "version": "1.48.2", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.48.2.tgz", + "integrity": "sha512-54w1xCWfXuax7dz4W2M9uw0gDyh+ti/0K/MxcCUxChFh37kkdxPdfZDw5QBbuPUJHr1CiHJ1hXgSs+GgeQc5Zw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.48.2" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/@rollup/plugin-commonjs": { "version": "28.0.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz", diff --git a/package.json b/package.json index 9dcc133074..2ce879b9f8 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "devDependencies": { "@mapbox/mapbox-gl-rtl-text": "^0.3.0", "@mapbox/mvt-fixtures": "^3.10.0", + "@playwright/test": "^1.48.2", "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.3.0", @@ -115,7 +116,6 @@ "npm-run-all": "^4.1.5", "pdf-merger-js": "^5.1.2", "pixelmatch": "^6.0.0", - "playwright": "^1.48.2", "pngjs": "^7.0.0", "postcss": "^8.4.47", "postcss-cli": "^11.0.0", diff --git a/test/bench/gl-stats.ts b/test/bench/gl-stats.ts index 773437b6e0..ae6c44c832 100644 --- a/test/bench/gl-stats.ts +++ b/test/bench/gl-stats.ts @@ -1,4 +1,4 @@ -import { chromium, Page } from 'playwright'; +import { chromium, Page } from '@playwright/test'; import fs from 'fs'; import zlib from 'zlib'; import {execSync} from 'child_process'; diff --git a/test/bench/run-benchmarks.ts b/test/bench/run-benchmarks.ts index f6b0771379..9c8b21ca54 100644 --- a/test/bench/run-benchmarks.ts +++ b/test/bench/run-benchmarks.ts @@ -1,5 +1,5 @@ import fs from 'fs'; -import {chromium} from 'playwright'; +import {chromium} from '@playwright/test'; import PDFMerger from 'pdf-merger-js'; import minimist from 'minimist'; diff --git a/test/integration/browser/browser.test.ts b/test/integration/browser/browser.test.ts index b68917ffd2..1210281e48 100644 --- a/test/integration/browser/browser.test.ts +++ b/test/integration/browser/browser.test.ts @@ -1,4 +1,4 @@ -import {Page, Browser, chromium, BrowserContext} from 'playwright'; +import {Page, Browser, chromium, BrowserContext} from '@playwright/test'; import st from 'st'; import http, {type Server} from 'http'; import type {AddressInfo} from 'net'; diff --git a/test/integration/query/query.test.ts b/test/integration/query/query.test.ts index a044e34b62..8917914fe0 100644 --- a/test/integration/query/query.test.ts +++ b/test/integration/query/query.test.ts @@ -1,5 +1,5 @@ -import {chromium, Page, Browser, BrowserContext} from 'playwright'; +import {chromium, Page, Browser, BrowserContext} from '@playwright/test'; import {deepEqual} from '../lib/json-diff'; import st from 'st'; diff --git a/test/integration/render/run_render_tests.ts b/test/integration/render/run_render_tests.ts index 17098cdd22..e80236690e 100644 --- a/test/integration/render/run_render_tests.ts +++ b/test/integration/render/run_render_tests.ts @@ -6,7 +6,7 @@ import pixelmatch from 'pixelmatch'; import {fileURLToPath} from 'url'; import {globSync} from 'glob'; import http from 'http'; -import {chromium, Page, Browser, BrowserContext} from 'playwright'; +import {chromium, Page, Browser, BrowserContext} from '@playwright/test'; import {CoverageReport} from 'monocart-coverage-reports'; import {localizeURLs} from '../lib/localize-urls'; import type {Map as MaplibreMap, CanvasSource, PointLike, StyleSpecification} from '../../../dist/maplibre-gl'; From 38cc51881f7248693f17a3658cc24ce126190eb6 Mon Sep 17 00:00:00 2001 From: Birk Skyum Date: Thu, 31 Oct 2024 19:59:47 +0100 Subject: [PATCH 8/8] add 20s timeout removed by mistake --- test/integration/browser/browser.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/browser/browser.test.ts b/test/integration/browser/browser.test.ts index 1210281e48..89b6241614 100644 --- a/test/integration/browser/browser.test.ts +++ b/test/integration/browser/browser.test.ts @@ -134,7 +134,7 @@ describe('Browser tests', () => { const centerWithInertia = await dragToLeft(); expect(centerWithInertia.lng).toBeLessThan(-60); expect(centerWithInertia.lat).toBeCloseTo(0, 7); - }); + }, 20000); test('Resize viewport (page)', async () => { await page.setViewportSize({width: 400, height: 400});