From 2cb6da8f78fb38b1b0d9f5ac4660ad58c70c17ae Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 23 Feb 2026 00:26:14 +0000 Subject: [PATCH] feat: add jabtrunner package and GitHub release workflow Co-authored-by: Alexander Nazarov --- .github/workflows/release-jabtrunner.yml | 44 +++++++++++++++++++ package.json | 16 +++---- packages/jabtrunner/LICENSE | 22 ++++++++++ .../{test-runner => jabtrunner}/README.md | 26 ++++++++--- .../bin/jabtrunner.mjs} | 2 +- packages/jabtrunner/package.json | 23 ++++++++++ .../{test-runner => jabtrunner}/src/human.mjs | 0 packages/test-runner/package.json | 21 --------- pnpm-lock.yaml | 22 +++++----- tests/react-demo.scenario.e2e.ts | 2 +- 10 files changed, 131 insertions(+), 47 deletions(-) create mode 100644 .github/workflows/release-jabtrunner.yml create mode 100644 packages/jabtrunner/LICENSE rename packages/{test-runner => jabtrunner}/README.md (70%) rename packages/{test-runner/bin/test-runner.mjs => jabtrunner/bin/jabtrunner.mjs} (99%) create mode 100644 packages/jabtrunner/package.json rename packages/{test-runner => jabtrunner}/src/human.mjs (100%) delete mode 100644 packages/test-runner/package.json diff --git a/.github/workflows/release-jabtrunner.yml b/.github/workflows/release-jabtrunner.yml new file mode 100644 index 0000000..8dd5f75 --- /dev/null +++ b/.github/workflows/release-jabtrunner.yml @@ -0,0 +1,44 @@ +name: Release jabtrunner + +on: + workflow_dispatch: {} + push: + tags: + - "jabtrunner-v*" + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 22 + + - name: Validate tag matches package version + if: startsWith(github.ref_name, 'jabtrunner-v') + run: | + TAG_VERSION="${GITHUB_REF_NAME#jabtrunner-v}" + PKG_VERSION="$(node -p "require('./packages/jabtrunner/package.json').version")" + if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then + echo "Tag version ($TAG_VERSION) does not match packages/jabtrunner version ($PKG_VERSION)" + exit 1 + fi + + - name: Build tarball (npm pack) + run: | + cd packages/jabtrunner + TARBALL="$(npm pack --silent)" + echo "TARBALL=$TARBALL" >> "$GITHUB_ENV" + + - name: Create GitHub Release and upload tarball + uses: softprops/action-gh-release@v2 + with: + generate_release_notes: true + files: packages/jabtrunner/${{ env.TARBALL }} + diff --git a/package.json b/package.json index 859a7b1..a1ce126 100644 --- a/package.json +++ b/package.json @@ -25,15 +25,15 @@ "scripts": { "build": "tsc -p tsconfig.server.json && tsc -p tsconfig.react.json", "prepack": "pnpm build", - "test": "pnpm run build && test-runner all", - "test:unit": "test-runner unit", - "test:e2e": "pnpm run build && test-runner e2e", - "test:scenario": "pnpm run build && test-runner scenario", - "test:smoke": "pnpm run build && test-runner scenario --smoke", + "test": "pnpm run build && jabtrunner all", + "test:unit": "jabtrunner unit", + "test:e2e": "pnpm run build && jabtrunner e2e", + "test:scenario": "pnpm run build && jabtrunner scenario", + "test:smoke": "pnpm run build && jabtrunner scenario --smoke", "test:integration": "node -e \"console.log('No integration tests in this repo. (intentional)')\"", - "test:docs": "pnpm run build && test-runner e2e --project docs", + "test:docs": "pnpm run build && jabtrunner e2e --project docs", "test:client": "pnpm run test:unit", - "test:server:coverage": "rm -rf .cache/v8-coverage && pnpm run build && NODE_V8_COVERAGE=.cache/v8-coverage test-runner scenario && NODE_V8_COVERAGE=.cache/v8-coverage test-runner e2e", + "test:server:coverage": "rm -rf .cache/v8-coverage && pnpm run build && NODE_V8_COVERAGE=.cache/v8-coverage jabtrunner scenario && NODE_V8_COVERAGE=.cache/v8-coverage jabtrunner e2e", "test:client:coverage": "rm -rf .cache/coverage/client && pnpm exec vitest run --coverage", "coverage:server:report": "rm -rf .cache/coverage/server && pnpm exec c8 report --temp-directory .cache/v8-coverage --reporter=text-summary --reporter=json-summary --report-dir .cache/coverage/server --all --src src/server --exclude \"**/playwright.config.ts\" --exclude \"tests/**\" --exclude \"src/react/**\" && node scripts/normalize-coverage-summary.mjs .cache/coverage/server/coverage-summary.json", "coverage:merge": "node scripts/merge-coverage-summaries.mjs .cache/coverage/server/coverage-summary.json .cache/coverage/client/coverage-summary.json coverage/coverage-summary.json", @@ -67,7 +67,7 @@ "@testing-library/jest-dom": "^6.9.0", "@testing-library/react": "^16.3.0", "@vitest/coverage-v8": "^3.2.4", - "test-runner": "file:packages/test-runner", + "jabtrunner": "file:packages/jabtrunner", "c8": "^10.1.3", "jsdom": "^26.1.0", "react": "^19.2.0", diff --git a/packages/jabtrunner/LICENSE b/packages/jabtrunner/LICENSE new file mode 100644 index 0000000..fb6c508 --- /dev/null +++ b/packages/jabtrunner/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2026 holiber + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/packages/test-runner/README.md b/packages/jabtrunner/README.md similarity index 70% rename from packages/test-runner/README.md rename to packages/jabtrunner/README.md index 5fd0ced..f3d5fec 100644 --- a/packages/test-runner/README.md +++ b/packages/jabtrunner/README.md @@ -1,11 +1,27 @@ -# test-runner +# jabtrunner -Small, policy-light test runner intended to be copied between repos (or published). +Just Another Browser Test Runner. + +Small, policy-light test runner intended to be copied between repos (or released as a GitHub tarball) without requiring an npm publish. + +## Install (from GitHub Releases) + +Add the `.tgz` asset URL from a release tag: + +```bash +pnpm add -D https://github.com/holiber/jabterm/releases/download/jabtrunner-v0.1.0/jabtrunner-0.1.0.tgz +``` + +Or with npm: + +```bash +npm i -D https://github.com/holiber/jabterm/releases/download/jabtrunner-v0.1.0/jabtrunner-0.1.0.tgz +``` ## CLI ```bash -test-runner [--smoke] [--human] [--pkg ...] [--project ] [--allow-missing-project] +jabtrunner [--smoke] [--human] [--pkg ...] [--project ] [--allow-missing-project] ``` Suites: @@ -27,7 +43,7 @@ Smoke rules (`--smoke`) apply to Playwright suites only: Human execution (`--human`) is orthogonal: - Playwright: `--headed`, `--workers=1`, `--trace=on` -- Exposes `TEST_RUNNER_HUMAN=1` for test utilities (see `test-runner/human`) +- Exposes `TEST_RUNNER_HUMAN=1` for test utilities (see `jabtrunner/human`) ## Artifacts @@ -62,7 +78,7 @@ export default defineConfig({ ## Test helper: `breath()` ```js -import { breath } from "test-runner/human"; +import { breath } from "jabtrunner/human"; await breath(300); ``` diff --git a/packages/test-runner/bin/test-runner.mjs b/packages/jabtrunner/bin/jabtrunner.mjs similarity index 99% rename from packages/test-runner/bin/test-runner.mjs rename to packages/jabtrunner/bin/jabtrunner.mjs index f198abe..57e223b 100755 --- a/packages/test-runner/bin/test-runner.mjs +++ b/packages/jabtrunner/bin/jabtrunner.mjs @@ -249,7 +249,7 @@ async function runPlaywright({ } const argv = await yargs(hideBin(process.argv)) - .scriptName("test-runner") + .scriptName("jabtrunner") .command( "$0 ", "Run tests", diff --git a/packages/jabtrunner/package.json b/packages/jabtrunner/package.json new file mode 100644 index 0000000..1ee0f4b --- /dev/null +++ b/packages/jabtrunner/package.json @@ -0,0 +1,23 @@ +{ + "name": "jabtrunner", + "version": "0.1.0", + "description": "Just Another Browser Test Runner (unit/e2e/scenario/smoke/human) with stable artifacts.", + "type": "module", + "license": "MIT", + "bin": { + "jabtrunner": "./bin/jabtrunner.mjs" + }, + "exports": { + "./human": "./src/human.mjs" + }, + "files": [ + "bin", + "src", + "README.md", + "LICENSE" + ], + "dependencies": { + "yargs": "^18.0.0" + } +} + diff --git a/packages/test-runner/src/human.mjs b/packages/jabtrunner/src/human.mjs similarity index 100% rename from packages/test-runner/src/human.mjs rename to packages/jabtrunner/src/human.mjs diff --git a/packages/test-runner/package.json b/packages/test-runner/package.json deleted file mode 100644 index e47b290..0000000 --- a/packages/test-runner/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "test-runner", - "version": "0.0.0", - "description": "Universal test runner (unit/e2e/scenario/smoke/human) with stable artifacts.", - "type": "module", - "license": "MIT", - "bin": { - "test-runner": "./bin/test-runner.mjs" - }, - "exports": { - "./human": "./src/human.mjs" - }, - "files": [ - "bin", - "src" - ], - "dependencies": { - "yargs": "^18.0.0" - } -} - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85742d4..a711f02 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: c8: specifier: ^10.1.3 version: 10.1.3 + jabtrunner: + specifier: file:packages/jabtrunner + version: file:packages/jabtrunner jsdom: specifier: ^26.1.0 version: 26.1.0 @@ -57,9 +60,6 @@ importers: react-dom: specifier: ^19.2.0 version: 19.2.4(react@19.2.4) - test-runner: - specifier: file:packages/test-runner - version: file:packages/test-runner typescript: specifier: ^5 version: 5.9.3 @@ -799,6 +799,10 @@ packages: resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} engines: {node: '>=8'} + jabtrunner@file:packages/jabtrunner: + resolution: {directory: packages/jabtrunner, type: directory} + hasBin: true + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -1041,10 +1045,6 @@ packages: resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} engines: {node: '>=18'} - test-runner@file:packages/test-runner: - resolution: {directory: packages/test-runner, type: directory} - hasBin: true - tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} @@ -1873,6 +1873,10 @@ snapshots: html-escaper: 2.0.2 istanbul-lib-report: 3.0.1 + jabtrunner@file:packages/jabtrunner: + dependencies: + yargs: 18.0.0 + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -2130,10 +2134,6 @@ snapshots: glob: 10.5.0 minimatch: 9.0.5 - test-runner@file:packages/test-runner: - dependencies: - yargs: 18.0.0 - tinybench@2.9.0: {} tinyexec@0.3.2: {} diff --git a/tests/react-demo.scenario.e2e.ts b/tests/react-demo.scenario.e2e.ts index 1e48258..70ad417 100644 --- a/tests/react-demo.scenario.e2e.ts +++ b/tests/react-demo.scenario.e2e.ts @@ -6,7 +6,7 @@ */ import { test, expect } from "@playwright/test"; -import { breath } from "test-runner/human"; +import { breath } from "jabtrunner/human"; test.describe("React demo page", () => { test("mount/unmount and layout resize work", async ({ page }) => {