From 4b17062fbae103856a8eb2b8ad5ec36c9dc882a9 Mon Sep 17 00:00:00 2001 From: WombatFromHell Date: Mon, 5 Feb 2024 21:34:04 -0700 Subject: [PATCH 01/31] Revamp of E2E testing workflows --- .dockerignore | 2 + .github/workflows/tests.yaml | 36 +++++++++ .gitignore | 11 +-- CONTRIBUTING.md | 11 +-- Dockerfile.e2etest | 19 +++++ package.json | 7 +- playwright.config.ts | 9 ++- pnpm-lock.yaml | 141 +++++++++++++++++++---------------- seccomp_profile.json | 12 +++ test.sh | 76 +++++++++++++++++++ tests/fixtures/index.ts | 30 ++++---- utils/testlogin.js | 7 +- 12 files changed, 257 insertions(+), 104 deletions(-) create mode 100644 .github/workflows/tests.yaml create mode 100644 Dockerfile.e2etest create mode 100644 seccomp_profile.json create mode 100755 test.sh diff --git a/.dockerignore b/.dockerignore index 4eb56ae6..bc448422 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,3 +4,5 @@ node_modules dist dist-firefox artifacts +results +seccomp_profile.json diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 00000000..35d5ab33 --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,36 @@ +name: Playwright Tests +on: + push: + branches: [master, testing] + pull_request: + branches: [master, testing] + +jobs: + playwright: + name: "Playwright Tests" + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/playwright:v1.41.1-jammy + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: 21 + E2E_SHACKLI: ${{ secrets.E2E_SHACKLI }} + - name: Install PNPM + run: corepack enable + - name: Install project dependencies + run: pnpm install + - name: Install test dependencies + run: pnpm test:deps + - name: Build in prod mode + run: pnpm build + - name: Run the test suite against Chromium + run: pnpm test + env: + HOME: /root + - name: Upload test report + uses: actions/upload-artifact@v2 + with: + name: test-report + path: results/* diff --git a/.gitignore b/.gitignore index 0e4d7204..a0df8efe 100644 --- a/.gitignore +++ b/.gitignore @@ -1,25 +1,16 @@ .idea* node_modules -coverage-ts dist -dist-chrome dist-firefox artifacts # make sure to use --id option when signing! .web-extension-id -Session.vim dist.crx dist.pem tsconfig.tsbuildinfo -mochawesome-report -/cypress/screenshots/ -/cypress/fixtures/_shack_li_.txt -debug.log .DS_Store .envrc .env .direnv -/test-results/ -/playwright-report/ -/playwright/.cache/ +results _shack_li_.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de020764..455f208d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,13 +39,14 @@ If you're interested in contributing a new content script or feature suggestion: - The WinChatty notifications' `processNotifyEvent` exposes the latest event message retrieved from the server (see: [WinChatty API](http://winchatty.com/v2/readme)). - Content scripts have to be registered in `content.ts`. Make sure to put event-dependent handlers **_before_** the `ChromeShack.install()` line. -## Running integration tests +## Running integration tests locally -The E2E integration test suite requires a login cookie fixture in order to run all tests successfully. To setup the local testing environment do the following: +The E2E integration test suite requires a valid Shacknews login cookie fixture loaded into the environment var `E2E_SHACKLI` in order to run all tests successfully. This variable can be loaded from a `.env` file placed in the project root or exported from your shell. To setup the local testing environment and generate the fixture from scratch do the following: - If you haven't already, make sure to do: `pnpm install` +- **STRONGLY RECOMMENDED**: Use the included `test.sh` in the project root to leverage Docker/Podman for containerized testing! - Make sure you're running on a supported OS version, see [this doc](https://playwright.dev/docs/intro#system-requirements) for details. Typically Windows, MacOS, or an LTS version of Ubuntu are supported. -- Verify that Cypress and Chrome are installed and can run: `pnpm exec playwright install --with-deps chromium` +- Verify that Playwright and Chromium are installed with: `pnpm test:deps` - Put your test credentials in an `.env` file in the project root in the following format: ```text @@ -53,8 +54,8 @@ The E2E integration test suite requires a login cookie fixture in order to run a TESTPW=password ``` -- Create the login cookie fixture: `pnpm generate-cookie` -- Run the test suite (NOTE: this can take significant machine resources): `pnpm test` +- Authenticate your credentials and create the login cookie fixture in `.env`: `pnpm testlogin` +- Run the test suite (NOTE: this can take significant machine resources): `pnpm build && pnpm test` or `./test.sh` in the project root. ## Release procedure diff --git a/Dockerfile.e2etest b/Dockerfile.e2etest new file mode 100644 index 00000000..7563dcf0 --- /dev/null +++ b/Dockerfile.e2etest @@ -0,0 +1,19 @@ +# Pull the base image +FROM mcr.microsoft.com/playwright:v1.41.1-jammy + +ARG SCOOKIE +ARG CI + +ENV CI=$CI +ENV E2E_SHACKLI=$SCOOKIE +ENV PNPM_HOME="/pnpm" +ENV PATH="$PNPM_HOME:$PATH" +RUN corepack enable + +WORKDIR /code/ +COPY . /code/ +RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile +RUN pnpm test:deps && \ + pnpm build + +CMD ["/bin/bash"] diff --git a/package.json b/package.json index afcc9e79..e80c9954 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "build:popup": "vite build --config vite.popup.config.ts", "build:permissions": "vite build --config vite.permissions.config.ts", "build:js": "run-p build:serviceWorker build:content build:popup build:permissions", - "clean": "rm -rf dist-firefox/* dist/* artifacts/dist/* artifacts/dist-firefox/* playwright-report/ test-results/", + "clean": "rm -rf dist-firefox/* dist/* artifacts/dist/* artifacts/dist-firefox/*", "dev:crxjs": "vite dev", "dev:firefoxjs": "NODE_ENV=development run-p build:js", "dev": "run-s clean lint && tsc && run-p dev:crxjs dev:firefoxjs", @@ -21,6 +21,7 @@ "build:ffxcrxjs": "run-s build:js", "build": "run-s clean lint && tsc && run-p build:crxjs build:ffxcrxjs", "build:pkg": "run-s build pkgsrc", + "test:deps": "playwright install chromium --with-deps", "test": "playwright test", "pretty": "prettier -w ./src/*.html ./src/styles/*.css ./public/*.html", "lint": "biome lint .", @@ -55,7 +56,7 @@ "@types/jquery": "^3.5.29", "@types/lodash.isequal": "^4.5.8", "@types/node": "^20.11.16", - "@types/react": "^18.2.51", + "@types/react": "^18.2.54", "@types/react-dom": "^18.2.18", "adm-zip": "^0.5.10", "dotenv": "^16.4.1", @@ -64,7 +65,7 @@ "jest": "^29.7.0", "license-checker": "^25.0.1", "npm-run-all": "^4.1.5", - "prettier": "^3.2.4", + "prettier": "^3.2.5", "typescript": "^5.3.3", "vite": "^5.0.12" } diff --git a/playwright.config.ts b/playwright.config.ts index 3608f05b..744a4a64 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -17,9 +17,13 @@ export default defineConfig({ forbidOnly: !!process.env.CI, retries: process.env.CI ? 0 : 1, /* Opt out of parallel tests on CI */ - workers: process.env.CI ? 1 : 2, + workers: process.env.CI ? 1 : 3, /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: [["html"], ["list"]], + reporter: [ + ["list", { printSteps: true, outputFolder: "results/reports" }], + ["html", { open: "never", outputFolder: "results/reports" }], + ], + outputDir: "results/tests", /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ use: { @@ -28,6 +32,7 @@ export default defineConfig({ screenshot: "only-on-failure", trace: "retain-on-failure", video: "retain-on-failure", + headless: true, }, /* Configure projects for major browsers */ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5196bcd3..f4359985 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -52,7 +52,7 @@ dependencies: version: 1.0.14 zustand: specifier: ^4.5.0 - version: 4.5.0(@types/react@18.2.51)(react@18.2.0) + version: 4.5.0(@types/react@18.2.54)(react@18.2.0) devDependencies: '@biomejs/biome': @@ -83,8 +83,8 @@ devDependencies: specifier: ^20.11.16 version: 20.11.16 '@types/react': - specifier: ^18.2.51 - version: 18.2.51 + specifier: ^18.2.54 + version: 18.2.54 '@types/react-dom': specifier: ^18.2.18 version: 18.2.18 @@ -110,8 +110,8 @@ devDependencies: specifier: ^4.1.5 version: 4.1.5 prettier: - specifier: ^3.2.4 - version: 3.2.4 + specifier: ^3.2.5 + version: 3.2.5 typescript: specifier: ^5.3.3 version: 5.3.3 @@ -1139,7 +1139,7 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.17.0 + fastq: 1.17.1 dev: true /@pkgjs/parseargs@0.11.0: @@ -1451,11 +1451,11 @@ packages: /@types/react-dom@18.2.18: resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: - '@types/react': 18.2.51 + '@types/react': 18.2.54 dev: true - /@types/react@18.2.51: - resolution: {integrity: sha512-XeoMaU4CzyjdRr3c4IQQtiH7Rpo18V07rYZUucEZQwOUEtGgTXv7e6igQiQ+xnV6MbMe1qjEmKdgMNnfppnXfg==} + /@types/react@18.2.54: + resolution: {integrity: sha512-039k+vrVJymDoe2y+HLk3O3oI3sa+C8KNjuDKofqrIJK26ramnqLNj9VJTaxAzFGMvpW/79HrrAJapHzpQ9fGQ==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.8 @@ -1559,11 +1559,12 @@ packages: sprintf-js: 1.0.3 dev: true - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 dev: true /array-find-index@1.0.2: @@ -1571,16 +1572,17 @@ packages: engines: {node: '>=0.10.0'} dev: true - /arraybuffer.prototype.slice@1.0.2: - resolution: {integrity: sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==} + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 + array-buffer-byte-length: 1.0.1 call-bind: 1.0.5 define-properties: 1.2.1 es-abstract: 1.22.3 - get-intrinsic: 1.2.2 - is-array-buffer: 3.0.2 + es-errors: 1.3.0 + get-intrinsic: 1.2.3 + is-array-buffer: 3.0.4 is-shared-array-buffer: 1.0.2 dev: true @@ -1706,8 +1708,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001582 - electron-to-chromium: 1.4.654 + caniuse-lite: 1.0.30001584 + electron-to-chromium: 1.4.657 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.22.3) dev: true @@ -1726,7 +1728,7 @@ packages: resolution: {integrity: sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==} dependencies: function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 set-function-length: 1.2.0 dev: true @@ -1745,8 +1747,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite@1.0.30001582: - resolution: {integrity: sha512-vsJG3V5vgfduaQGVxL53uSX/HUzxyr2eA8xCo36OLal7sRcSZbibJtLeh0qja4sFOr/QQGt4opB4tOy+eOgAxg==} + /caniuse-lite@1.0.30001584: + resolution: {integrity: sha512-LOz7CCQ9M1G7OjJOF9/mzmqmj3jE/7VOmrfw6Mgs0E8cjOsbRXQJHsPBfmBOXDskXKrHLyyW3n7kpDW/4BsfpQ==} dev: true /chalk@2.4.2: @@ -1989,7 +1991,7 @@ packages: resolution: {integrity: sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 gopd: 1.0.1 has-property-descriptors: 1.0.1 dev: true @@ -2056,8 +2058,8 @@ packages: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} dev: true - /electron-to-chromium@1.4.654: - resolution: {integrity: sha512-hjfFa+Vj4WGLRVTlCQa+IivBkpcp+boGxMQfusOC/me5Y5NfU4wX7wyw+K9p8Cw4tl0BVIZGH2n7y/jMc3w4pg==} + /electron-to-chromium@1.4.657: + resolution: {integrity: sha512-On2ymeleg6QbRuDk7wNgDdXtNqlJLM2w4Agx1D/RiTmItiL+a9oq5p7HUa2ZtkAtGBe/kil2dq/7rPfkbe0r5w==} dev: true /embla-carousel-react@8.0.0-rc19(react@18.2.0): @@ -2108,15 +2110,15 @@ packages: resolution: {integrity: sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - arraybuffer.prototype.slice: 1.0.2 + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 available-typed-arrays: 1.0.6 call-bind: 1.0.5 es-set-tostringtag: 2.0.2 es-to-primitive: 1.2.1 function.prototype.name: 1.1.6 - get-intrinsic: 1.2.2 - get-symbol-description: 1.0.0 + get-intrinsic: 1.2.3 + get-symbol-description: 1.0.1 globalthis: 1.0.3 gopd: 1.0.1 has-property-descriptors: 1.0.1 @@ -2124,7 +2126,7 @@ packages: has-symbols: 1.0.3 hasown: 2.0.0 internal-slot: 1.0.6 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-callable: 1.2.7 is-negative-zero: 2.0.2 is-regex: 1.1.4 @@ -2149,6 +2151,11 @@ packages: which-typed-array: 1.1.14 dev: true + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: true + /es-module-lexer@0.10.5: resolution: {integrity: sha512-+7IwY/kiGAacQfY+YBhKMvEmyAJnw5grTUgjG85Pe7vcUI/6b7pZjZG8nQ7+48YhzEAEqrEgD2dCz/JIK+AYvw==} dev: true @@ -2157,7 +2164,7 @@ packages: resolution: {integrity: sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 has-tostringtag: 1.0.2 hasown: 2.0.0 dev: true @@ -2202,8 +2209,8 @@ packages: '@esbuild/win32-x64': 0.19.12 dev: true - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: true @@ -2273,8 +2280,8 @@ packages: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} dev: true - /fastq@1.17.0: - resolution: {integrity: sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w==} + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 dev: true @@ -2371,9 +2378,11 @@ packages: engines: {node: 6.* || 8.* || >= 10.*} dev: true - /get-intrinsic@1.2.2: - resolution: {integrity: sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==} + /get-intrinsic@1.2.3: + resolution: {integrity: sha512-JIcZczvcMVE7AUOP+X72bh8HqHBRxFdz5PDHYtNG/lE3yk9b3KZBJlwFcTyPYjg3L4RLLmZJzvjxhaZVapxFrQ==} + engines: {node: '>= 0.4'} dependencies: + es-errors: 1.3.0 function-bind: 1.1.2 has-proto: 1.0.1 has-symbols: 1.0.3 @@ -2390,12 +2399,12 @@ packages: engines: {node: '>=10'} dev: true - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + /get-symbol-description@1.0.1: + resolution: {integrity: sha512-KmuibvwbWaM4BHcBRYwJfZ1JxyJeBwB8ct9YYu67SvYdbEIlcQ2e56dHxfbobqW38GXo8/zDFqJeGtHiVbWyQw==} engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 + es-errors: 1.3.0 dev: true /glob-parent@5.1.2: @@ -2443,7 +2452,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 dev: true /graceful-fs@4.2.11: @@ -2467,7 +2476,7 @@ packages: /has-property-descriptors@1.0.1: resolution: {integrity: sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 dev: true /has-proto@1.0.1: @@ -2582,17 +2591,17 @@ packages: resolution: {integrity: sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 hasown: 2.0.0 side-channel: 1.0.4 dev: true - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 - is-typed-array: 1.1.13 + get-intrinsic: 1.2.3 dev: true /is-arrayish@0.2.1: @@ -2750,7 +2759,7 @@ packages: '@babel/parser': 7.23.9 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true @@ -3128,7 +3137,7 @@ packages: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: true @@ -3356,7 +3365,7 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} dependencies: - semver: 7.5.4 + semver: 7.6.0 dev: true /makeerror@1.0.12: @@ -3715,8 +3724,8 @@ packages: fsevents: 2.3.2 dev: true - /postcss@8.4.33: - resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==} + /postcss@8.4.34: + resolution: {integrity: sha512-4eLTO36woPSocqZ1zIrFD2K1v6wH7pY1uBh0JIM2KKfrVtGvPFiAku6aNOP0W1Wr9qwnaCsF0Z+CrVnryB2A8Q==} engines: {node: ^10 || ^12 || >=14} dependencies: nanoid: 3.3.7 @@ -3727,8 +3736,8 @@ packages: /preact@10.19.3: resolution: {integrity: sha512-nHHTeFVBTHRGxJXKkKu5hT8C/YWBkPso4/Gad6xuj5dbptt9iF9NZr9pHbPhBrnT2klheu7mHTxTZ/LjwJiEiQ==} - /prettier@3.2.4: - resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} + /prettier@3.2.5: + resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==} engines: {node: '>=14'} hasBin: true dev: true @@ -3929,7 +3938,7 @@ packages: engines: {node: '>=0.4'} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 has-symbols: 1.0.3 isarray: 2.0.5 dev: true @@ -3939,7 +3948,7 @@ packages: engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 is-regex: 1.1.4 dev: true @@ -3953,8 +3962,8 @@ packages: hasBin: true dev: true - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -3967,7 +3976,7 @@ packages: dependencies: define-data-property: 1.1.1 function-bind: 1.1.2 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 gopd: 1.0.1 has-property-descriptors: 1.0.1 dev: true @@ -4013,7 +4022,7 @@ packages: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 object-inspect: 1.13.1 dev: true @@ -4309,7 +4318,7 @@ packages: engines: {node: '>= 0.4'} dependencies: call-bind: 1.0.5 - get-intrinsic: 1.2.2 + get-intrinsic: 1.2.3 is-typed-array: 1.1.13 dev: true @@ -4377,7 +4386,7 @@ packages: browserslist: '>= 4.21.0' dependencies: browserslist: 4.22.3 - escalade: 3.1.1 + escalade: 3.1.2 picocolors: 1.0.0 dev: true @@ -4439,7 +4448,7 @@ packages: dependencies: '@types/node': 20.11.16 esbuild: 0.19.12 - postcss: 8.4.33 + postcss: 8.4.34 rollup: 4.9.6 optionalDependencies: fsevents: 2.3.3 @@ -4549,7 +4558,7 @@ packages: engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 @@ -4562,7 +4571,7 @@ packages: engines: {node: '>=10'} dev: true - /zustand@4.5.0(@types/react@18.2.51)(react@18.2.0): + /zustand@4.5.0(@types/react@18.2.54)(react@18.2.0): resolution: {integrity: sha512-zlVFqS5TQ21nwijjhJlx4f9iGrXSL0o/+Dpy4txAP22miJ8Ti6c1Ol1RLNN98BMib83lmDH/2KmLwaNXpjrO1A==} engines: {node: '>=12.7.0'} peerDependencies: @@ -4577,7 +4586,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.51 + '@types/react': 18.2.54 react: 18.2.0 use-sync-external-store: 1.2.0(react@18.2.0) dev: false diff --git a/seccomp_profile.json b/seccomp_profile.json new file mode 100644 index 00000000..bfeea36c --- /dev/null +++ b/seccomp_profile.json @@ -0,0 +1,12 @@ +{ + "comment": "Allow create user namespaces", + "names": [ + "clone", + "setns", + "unshare" + ], + "action": "SCMP_ACT_ALLOW", + "args": [], + "includes": {}, + "excludes": {} +} diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..bf907533 --- /dev/null +++ b/test.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +# import env vars from the .env in this project root +while IFS= read -r line; do + if [[ "$line" =~ ^\s*#.*$ || -z "$line" ]]; then + continue + fi + key=$(echo "$line" | cut -d '=' -f 1) + value=$(echo "$line" | cut -d '=' -f 2-) + # skip comments + value=$(echo "$value" | sed -e "s/^'//" -e "s/'$//" -e 's/^"//' -e 's/"$//' -e 's/^[ \t]*//;s/[ \t]*$//') + export "$key=$value" +done <".env" + +IMAGE_NAME="chromeshack-e2e" + +if [ -z "${E2E_SHACKLI+x}" ]; then + echo + echo "ERROR: a cookie fixture in the env variable \"E2E_SHACKLI\" is required for the E2E suite!" + echo "Install a valid \".env\" in the project root and generate one with: pnpm testlogin" + echo "For more information, see CONTRIBUTING.md..." + echo + exit 1 +fi + +build() { + docker build -f ./Dockerfile.e2etest -t "$IMAGE_NAME" --build-arg SCOOKIE="$E2E_SHACKLI" +} + +run() { + mkdir -p "results/" && rm -rf "results/*" + docker run --rm --replace -it \ + --ipc=host --security-opt seccomp=seccomp_profile.json \ + -v "./results:/code/results" \ + --name "$IMAGE_NAME" "$IMAGE_NAME" \ + "${@}" +} + +help() { + echo + echo "Usage: $0 [--build | -b] [--run | -r] [--shell | -s] [--test] [--help | -h]" + echo + echo " --build, -b rebuild the image" + echo " --run, -r run the tests" + echo " --shell, -s open a shell inside the image" + echo " --test rerun the tests" + echo " --help, -h this message" + echo + exit 1 +} + +CMD=${@:-""} +case "$CMD" in + "--help" | "-h") + help + ;; + "--build" | "-b") + build + ;; + "--run" | "-r") + run pnpm test + ;; + "--shell" | "-s") + run /bin/bash + ;; + "--test") + build + run pnpm test + ;; + *) + echo "Error: Invalid argument" + help + ;; +esac + +exit 0 diff --git a/tests/fixtures/index.ts b/tests/fixtures/index.ts index 14f48012..ed617932 100644 --- a/tests/fixtures/index.ts +++ b/tests/fixtures/index.ts @@ -5,9 +5,6 @@ import path from "path"; import { test as base, chromium, type BrowserContext, type Page } from "@playwright/test"; -// @ts-ignore -import cookieFixture from "./_shack_li_.json" assert { type: "json" }; - export const loadExtensionDefaults = async (page: Page, opts?: any, data?: any) => { const _data = { enabled_suboptions: ["testing_mode"], ...data }; const _opts = { defaults: true, ...opts }; @@ -20,17 +17,20 @@ export const loadExtensionDefaults = async (page: Page, opts?: any, data?: any) ); }; export const setTestCookie = async (context: BrowserContext) => { - if (cookieFixture == null) return; - const shackli: any = Object.values(cookieFixture); - - await context.addCookies([ - { - name: "_shack_li_", - value: shackli[2]?._shack_li_ as string, - domain: ".shacknews.com", - path: "/", - }, - ]); + // only load secure cookie from a trusted source + try { + const shackli = JSON.parse(process.env.E2E_SHACKLI) as any; + await context.addCookies([ + { + name: "_shack_li_", + value: shackli[2]?._shack_li_ as string, + domain: ".shacknews.com", + path: "/", + }, + ]); + } catch (e) { + console.error("Failed to parse the secure cookie from E2E_SHACKLI: ", e); + } return context; }; export const navigate = async (page: Page, url: string, opts?: { o?: any; d?: any }, context?: BrowserContext) => { @@ -54,7 +54,7 @@ export const test = base.extend<{ const pathToExtension = fs.existsSync(prodPath) ? prodPath : devPath; const context = await chromium.launchPersistentContext("", { headless: false, - args: [`--disable-extensions-except=${pathToExtension}`, `--load-extension=${pathToExtension}`], + args: [`--disable-extensions-except=${pathToExtension}`, `--load-extension=${pathToExtension}`, "--headless=new"], }); await use(context); await context.close(); diff --git a/utils/testlogin.js b/utils/testlogin.js index 11cbc50c..bdb7a61a 100644 --- a/utils/testlogin.js +++ b/utils/testlogin.js @@ -6,7 +6,7 @@ import process from "process"; dotenv.config(); const _login = process.env.TESTUSR; const _pass = process.env.TESTPW; -const outputPath = path.resolve("./tests/fixtures/_shack_li_.json"); +const outputPath = path.resolve("./.env"); const body = `get_fields%5B%5D=result&user-identifier=${_login}&supplied-pass=${_pass}&remember-login=0`; const serializeCookie = (vals) => { @@ -31,8 +31,9 @@ fetch("https://www.shacknews.com/account/signin", { const setCookies = res.headers.getSetCookie(); const outCookies = serializeCookie(setCookies); if (outCookies) { - fs.writeFileSync(outputPath, JSON.stringify(outCookies)); - console.log("cookie written:", outputPath); + // overwrite the contents of the file "./.env" under the key "E2E_SHACKLI" with cookie data + fs.writeFileSync(outputPath, `E2E_SHACKLI=${JSON.stringify(outCookies)}`); + console.log("cookie written in .env format to:", outputPath); } else throw Error("No cookie data received from server!"); }) .catch((e) => { From bd0b8478a5138e3ed717ce7f0bfd68983d168fc3 Mon Sep 17 00:00:00 2001 From: WombatFromHell Date: Thu, 29 Feb 2024 10:42:22 -0700 Subject: [PATCH 02/31] Fixed another edge case in NCH script preventing highlighting --- package.json | 2 +- public/release_notes.html | 21 +++++++++++++++++---- src/manifestv3.ffx.json | 2 +- src/optional/new_comment_highlighter.ts | 6 ++++-- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 71e03cf1..6c13c559 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chromeshack", - "version": "1.76.0", + "version": "1.77.0", "description": "Collection of scripts for Shacknews.", "repository": "https://github.com/latestchatty/chromeshack", "type": "module", diff --git a/public/release_notes.html b/public/release_notes.html index 04c3d11b..0340209c 100644 --- a/public/release_notes.html +++ b/public/release_notes.html @@ -17,12 +17,23 @@

Chrome Shack Release Notes

+

Version 1.77

+

Version 1.76

Version 1.75