Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
647a6ab
Add e2e testing framework
imnasnainaec May 21, 2026
7946657
Fix test workflows
imnasnainaec May 21, 2026
61721a1
En-doc-inate
imnasnainaec May 21, 2026
205cdaa
Build core dll
imnasnainaec May 21, 2026
b6efd54
Fix test; Expand OSes
imnasnainaec May 21, 2026
075fbd1
Fix Windows CI/CD
imnasnainaec May 22, 2026
69a5529
Wait for webpack compilation before returning from global-setup
imnasnainaec May 22, 2026
46bee55
Retry on socket hang up in waitForHttpOk
imnasnainaec May 22, 2026
497a166
Fix Jest setup resolution in CI and remove setup file
imnasnainaec May 22, 2026
c9d9d35
Harden e2e readiness checks and CI artifact capture
imnasnainaec May 22, 2026
3d4dced
Fix Windows Jest setup resolution in CI
imnasnainaec May 22, 2026
ee8243b
Relax CI e2e readiness gating and capture renderer logs
imnasnainaec May 22, 2026
1e0dab9
Stabilize CI install and verify jest-dom presence
imnasnainaec May 22, 2026
115bdb3
Retry main page load when Electron opens chrome-error
imnasnainaec May 22, 2026
796360e
Try without explicit path
imnasnainaec May 22, 2026
aad2b25
Make smoke tests wait for the real renderer URL
imnasnainaec May 22, 2026
8f2eff7
Wait for renderer window by URL in smoke tests
imnasnainaec May 22, 2026
6818273
Use BrowserWindow.loadURL to escape chrome-error page in CI
imnasnainaec May 22, 2026
ce2bc7b
Fix renderer readiness probe URL and remove CI degradation
imnasnainaec May 22, 2026
6189dc4
Fix CI smoke setup and upload sanitized renderer logs
imnasnainaec May 22, 2026
0000f73
Install lightningcss binary for e2e smoke CI
imnasnainaec May 22, 2026
9ed39e2
Remove renderer dev server log workflow steps
imnasnainaec May 22, 2026
c960d3f
Nix possibly redundant stuff
imnasnainaec May 22, 2026
d054d54
Nix more possibly extraneous things
imnasnainaec May 22, 2026
d12df9f
Remove diagnostic jest-dom verification step
imnasnainaec May 22, 2026
0b61b8d
Remove fail-fast: false from unit test job
imnasnainaec May 22, 2026
d32ea60
Don't explicitly include optional
imnasnainaec May 22, 2026
059e415
Try to omit optional again
imnasnainaec May 22, 2026
a5fc375
Try to fix failing Windows test run
imnasnainaec May 22, 2026
083d205
Try to fix failing Windows test run
imnasnainaec May 22, 2026
b432abc
Document why --omit=optional is excluded from extension install
imnasnainaec May 22, 2026
95776fe
Restore jest.setup.ts (was a red herring, real fix was --omit=optional)
imnasnainaec May 22, 2026
ca10849
Try removing --include=dev
imnasnainaec May 22, 2026
8e6bfd9
Document why --omit=optional is excluded from key install steps
imnasnainaec May 22, 2026
8ca7cdf
Add README
imnasnainaec May 22, 2026
bf53dad
Discard renderer dev server logs to match paranext-core
imnasnainaec May 22, 2026
d8735ee
Add e2e-tests README
imnasnainaec May 22, 2026
c6b4dd5
Add missing content
imnasnainaec May 22, 2026
a348eb0
Fix Devin bugs
imnasnainaec May 22, 2026
d8d075f
Pin all workflow action versions to SHA and set persist-credentials: …
imnasnainaec May 22, 2026
df59cd3
Add JSDoc to all internal closures in e2e-tests
imnasnainaec May 22, 2026
b9ab327
Remove template codeowners file
imnasnainaec May 22, 2026
127fd32
Add persist-credentials: false to e2e-smoke checkout steps
imnasnainaec May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ coverage
package-lock.json

# #endregion

# Playwright test output
e2e-tests/playwright-report
e2e-tests/test-results
8 changes: 8 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ module.exports = {
'jest/globals': true,
},
},
{
// Playwright e2e test fixtures use a `use()` callback that is Playwright's fixture API,
// not a React hook. react-hooks/rules-of-hooks v5 incorrectly flags these calls.
files: ['e2e-tests/**/*.ts', 'e2e-tests/**/*.tsx'],
rules: {
'react-hooks/rules-of-hooks': 'off',
},
},
],
parser: '@typescript-eslint/parser',
parserOptions: {
Expand Down
1 change: 0 additions & 1 deletion .github/CODEOWNERS

This file was deleted.

6 changes: 3 additions & 3 deletions .github/workflows/bump-versions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ jobs:
run: echo "${{ toJSON(github.event.inputs) }}"

- name: Checkout git repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- name: Read package.json
id: package_json
uses: zoexx/github-action-json-file-properties@1.0.6
uses: zoexx/github-action-json-file-properties@d02f28167f05bf70cd75352b11c25a4e8c39bf38 # 1.0.6
with:
file_path: 'package.json'

- name: Install Node and NPM
uses: actions/setup-node@v4
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: npm
node-version: ${{ fromJson(steps.package_json.outputs.volta).node }}
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ jobs:
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
Expand All @@ -55,7 +57,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
uses: github/codeql-action/init@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v3.36.0
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
Expand Down Expand Up @@ -83,6 +85,6 @@ jobs:
exit 1

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
uses: github/codeql-action/analyze@03e4368ac7daa2bd82b3e85262f3bf87ee112f57 # v3.36.0
with:
category: '/language:${{matrix.language}}'
8 changes: 5 additions & 3 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ jobs:
os: [ubuntu-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: extension-repo
persist-credentials: false

- name: Checkout paranext-core repo to use its sub-packages
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: paranext-core
repository: paranext/paranext-core
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: 'npm'
cache-dependency-path: |
Expand Down
20 changes: 12 additions & 8 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,20 @@ jobs:
run: echo "${{ toJSON(github.event.inputs) }}"

- name: Checkout git repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: extension-repo

- name: Checkout paranext-core repo to use its sub-packages
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: paranext-core
repository: paranext/paranext-core
persist-credentials: false

- name: Read package.json
id: package_json
uses: zoexx/github-action-json-file-properties@1.0.6
uses: zoexx/github-action-json-file-properties@d02f28167f05bf70cd75352b11c25a4e8c39bf38 # 1.0.6
with:
file_path: 'extension-repo/package.json'

Expand All @@ -65,7 +66,7 @@ jobs:
exit 1

- name: Install Node and NPM
uses: actions/setup-node@v4
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: npm
cache-dependency-path: |
Expand All @@ -75,19 +76,22 @@ jobs:

- name: Install packages
run: |
# Cannot --omit=optional: lightningcss-linux-x64-gnu is an optional dep; Tailwind needs it
# for the CSS build.
npm ci --ignore-scripts

- name: Install core packages
working-directory: paranext-core
run: |
npm ci --ignore-scripts
# Core is only checked out for its local npm packages; no core webpack build runs here.
npm ci --ignore-scripts --omit=optional

- name: Package for distribution
run: |
npm run package

- name: Publish draft release
uses: ncipollo/release-action@v1
uses: ncipollo/release-action@339a81892b84b4eeb0f6e744e4574d79d0d9b8dd # v1.21.0
with:
artifactErrorsFailBuild: true
artifacts: |
Expand All @@ -111,7 +115,7 @@ jobs:

- name: Checkout bump ref
if: ${{ inputs.newVersionAfterPublishing != '' && inputs.bumpRef != '' && inputs.bumpRef != (github.head_ref || github.ref_name) }}
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
clean: false
path: extension-repo
Expand All @@ -126,6 +130,6 @@ jobs:
# Enable tmate debugging of manually-triggered workflows if the input option was provided
- name: Setup tmate session
if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
uses: mxschmitt/action-tmate@v3
uses: mxschmitt/action-tmate@c0afd6f790e3a5564914980036ebf83216678101 # v3.23
with:
limit-access-to-actor: true
95 changes: 90 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: extension-repo
persist-credentials: false

- name: Checkout paranext-core repo to use its sub-packages
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: paranext-core
repository: paranext/paranext-core
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@v4
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: 'npm'
cache-dependency-path: |
Expand All @@ -38,7 +40,9 @@ jobs:

- name: Install extension dependencies
working-directory: extension-repo
run: npm ci --ignore-scripts --omit=optional
# Cannot --omit=optional: @swc/core-win32-x64-msvc is an optional dep and SWC needs it to
# transpile TypeScript in Jest on Windows.
run: npm ci --ignore-scripts

- name: Install core dependencies
working-directory: paranext-core
Expand All @@ -47,3 +51,84 @@ jobs:
- name: Run tests
working-directory: extension-repo
run: npm run test:coverage

e2e-smoke:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: extension-repo
persist-credentials: false

- name: Checkout paranext-core repo
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: paranext-core
repository: paranext/paranext-core
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
cache: 'npm'
cache-dependency-path: |
extension-repo/package-lock.json
paranext-core/package-lock.json
node-version-file: extension-repo/package.json

- name: Install extension dependencies
working-directory: extension-repo
# Cannot --omit=optional: @swc/core-win32-x64-msvc is an optional dep; webpack needs it to
# transpile TypeScript on Windows.
run: npm ci --ignore-scripts

- name: Install core dependencies
working-directory: paranext-core
# Cannot --omit=optional: lightningcss native binaries are optional deps required by the
# webpack build.
run: npm ci --ignore-scripts

- name: Install Electron binary
working-directory: paranext-core
run: node node_modules/electron/install.js

- name: Install system dependencies for Electron
if: matrix.os == 'ubuntu-latest'
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends xvfb libgbm-dev libnss3 libxss1 libasound2t64

- name: Build extension
working-directory: extension-repo
run: npm run build

- name: Build paranext-core dev bundle
working-directory: paranext-core
run: npm run prestart

- name: Build paranext-core renderer DLL
working-directory: paranext-core
run: npm run build:dll

- name: Run e2e smoke tests (Linux)
if: matrix.os == 'ubuntu-latest'
working-directory: extension-repo
run: xvfb-run --auto-servernum --server-args="-screen 0 1280x960x24" npm run test:e2e:smoke

- name: Run e2e smoke tests (Windows)
if: matrix.os == 'windows-latest'
working-directory: extension-repo
run: npm run test:e2e:smoke

- name: Upload Playwright test results
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always()
with:
name: playwright-results-${{ matrix.os }}
retention-days: 7
path: |
extension-repo/e2e-tests/playwright-report/
extension-repo/e2e-tests/test-results/
if-no-files-found: warn
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,7 @@ coverage
temp-build

# #endregion

# Playwright test output
e2e-tests/playwright-report
e2e-tests/test-results
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ coverage
package-lock.json

# #endregion

# Playwright test output
e2e-tests/playwright-report
e2e-tests/test-results
4 changes: 4 additions & 0 deletions .stylelintignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,7 @@ coverage
package-lock.json

# #endregion

# Playwright test output
e2e-tests/playwright-report
e2e-tests/test-results
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,48 @@ To package this extension into a zip file for distribution:

`npm run package`

## Testing

### Unit tests

Unit tests use [Jest](https://jestjs.io/) and live in `src/__tests__/`. To run:

```bash
npm test # run all tests
npm run test:coverage # run with coverage report (output to coverage/)
```

### End-to-end tests

E2E tests use [Playwright](https://playwright.dev/) and live in `e2e-tests/`. They launch Platform.Bible with this extension loaded and verify behavior through the real UI.

**Prerequisites:**

- `npm run build` must have been run (`dist/src/main.js` must exist)
- `paranext-core` must have deps installed (e.g., with `npm run core:install`)

**Smoke tests** (self-contained, good for CI — launches and tears down Platform.Bible automatically):

```bash
npm run test:e2e:smoke
```

**CDP tests** (connect to an already-running app — faster for local development):

1. Start Platform.Bible with remote debugging enabled:

```bash
npm run start:cdp
```

2. In a second terminal, run the tests:

```bash
npm run test:e2e:cdp
```

New feature tests should use `cdp.fixture` and navigate entirely through visible UI. See `e2e-tests/tests/_example/` for a reference template.

## Publishing

These steps will walk you through releasing a version on GitHub and bumping the version to a new version so future changes apply to the new in-progress version.
Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"interlinearize",
"interlinearizer",
"interlinearizing",
"lightningcss",
"localstorage",
"maximizable",
"morphosyntactic",
Expand Down
12 changes: 12 additions & 0 deletions e2e-tests/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"rules": {
// E2E tests legitimately use console for test diagnostics
"no-console": "off",
// E2E tests often need sequential async operations in loops
"no-await-in-loop": "off",
// `export default defineConfig(...)` is the standard Playwright config pattern
"import/no-anonymous-default-export": "off",
// TypeScript handles undefined references; ESLint no-undef doesn't know Node.js globals
"no-undef": "off"
}
}
Loading
Loading