chore(security and testing): patch sigstore and run Playwright CI on the nashua self-hosted runner for release/3.12 (#6123)

This commit is contained in:
Joe Boccanfuso 2026-07-07 19:53:57 +02:00 committed by GitHub
parent 8460409a62
commit 646dd583a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 382 additions and 226 deletions

View File

@ -137,6 +137,7 @@ jobs:
"GHSA-7r86-cg39-jmmj" # CVE-2026-27903 - minimatch same as above
"GHSA-23c5-xmqv-rm74" # CVE-2026-27904 - minimatch same as above
"GHSA-c2c7-rcm5-vvqj" # CVE-2026-33671 - picomatch is generally used for development and CI/CD purposes
"GHSA-mp2f-45pm-3cg9" # CVE-2026-53486 - decompress is called only ever decompresses a hash-pinned, hardcoded archive in a dev-only CLI
)
# Build ignore flags

View File

@ -9,8 +9,8 @@ concurrency:
jobs:
playwright-tests:
timeout-minutes: 60
runs-on: self-hosted
timeout-minutes: 120
runs-on: [self-hosted, nashua]
strategy:
fail-fast: false
matrix:
@ -28,11 +28,16 @@ jobs:
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Install Playwright browsers
run: npx playwright install
# Only chromium is used (firefox/webkit projects are commented out in
# playwright.config.ts). Scoping the install to chromium avoids
# downloading + dep-validating browsers we never launch (the WebKit
# validation is what surfaces "missing libwoff1/libflite1/..." on hosts
# without those libs).
run: npx playwright install chromium
- name: Run Playwright tests
run: |
export NODE_OPTIONS="--max_old_space_size=10192"
bun run test:e2e:coverage
bash .scripts/ci/with-nashua-lock.sh bun run test:e2e:coverage
- name: Create directory of test results
if: ${{ !cancelled() }}
run: |

View File

@ -0,0 +1,54 @@
#!/usr/bin/env bash
#
# Run a command while holding the nashua Playwright mutex.
#
# Only one Playwright run may execute at a time on the shared nashua self-hosted
# runner — across THIS repo (OHIF) AND the cornerstone3D repo. GitHub's
# `concurrency:` is scoped per-repository and cannot coordinate across the two
# orgs, so the mutex lives on the box's filesystem.
#
# This is OHIF's own copy (the script can't be shared across separate repos). It
# MUST use the SAME lock path as cornerstone3D's copy (NASHUA_LOCK_FILE default
# below) — if the paths differ, the mutex silently does nothing.
#
# flock holds the lock via fd 9 and it releases automatically when the wrapped
# command exits — including on job cancel / timeout / SIGKILL — so there are no
# stale locks to clean up.
#
# Usage: .scripts/ci/with-nashua-lock.sh <command> [args...]
# Strict mode: -e abort on any unhandled command failure, -u treat use of an
# unset variable as an error, -o pipefail make a pipeline fail if ANY stage
# fails (not just the last). Catches mistakes early instead of pressing on.
set -euo pipefail
LOCK="${NASHUA_LOCK_FILE:-/var/tmp/nashua-playwright.lock}" # MUST match cornerstone3D's copy
LOCK_WAIT="${NASHUA_LOCK_WAIT:-5400}" # max seconds to wait
# Guard: a command to wrap is required. With no arguments there is nothing to
# run, so print usage and exit instead of silently grabbing and releasing the
# lock for no reason (which would mask a mis-wired workflow step).
if [ "$#" -eq 0 ]; then
echo "usage: $0 <command> [args...]" >&2
exit 2
fi
# Open the lock file on fd 9 (read-write, create if missing, never truncate).
exec 9<>"$LOCK" || { echo "::error::cannot open lock file $LOCK"; exit 1; }
# Try instantly; if busy, report who holds it, then block up to LOCK_WAIT.
if ! flock -n 9; then
echo "nashua Playwright runner busy — held by: $(cat "${LOCK}.info" 2>/dev/null || echo unknown). Waiting up to ${LOCK_WAIT}s…"
if ! flock -w "$LOCK_WAIT" 9; then
echo "::error::Timed out after ${LOCK_WAIT}s waiting for the nashua Playwright lock"
exit 1
fi
fi
# Record the current holder for other jobs' "held by" message (best-effort).
echo "${GITHUB_REPOSITORY:-local}#${GITHUB_RUN_ID:-0} @ $(date -u +%FT%TZ 2>/dev/null || true)" > "${LOCK}.info" 2>/dev/null || true
echo "✅ Acquired nashua Playwright lock ($LOCK); running: $*"
# Replace the shell with the command. fd 9 is inherited (not close-on-exec), so
# the lock is held for the whole command and released when it exits.
exec "$@"

331
bun.lock
View File

@ -50,7 +50,7 @@
},
"addOns/externals/devDependencies": {
"name": "@externals/devDependencies",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@kitware/vtk.js": "34.15.1",
@ -131,14 +131,14 @@
},
"addOns/externals/dicom-microscopy-viewer": {
"name": "@externals/dicom-microscopy-viewer",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"dicom-microscopy-viewer": "0.48.17",
},
},
"extensions/cornerstone": {
"name": "@ohif/extension-cornerstone",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.15.29",
@ -165,8 +165,8 @@
"@cornerstonejs/codec-openjpeg": "1.3.0",
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.15.29",
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -178,7 +178,7 @@
},
"extensions/cornerstone-dicom-pmap": {
"name": "@ohif/extension-cornerstone-dicom-pmap",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.15.29",
@ -186,10 +186,10 @@
"@kitware/vtk.js": "34.15.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -200,15 +200,15 @@
},
"extensions/cornerstone-dicom-rt": {
"name": "@ohif/extension-cornerstone-dicom-rt",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -219,7 +219,7 @@
},
"extensions/cornerstone-dicom-seg": {
"name": "@ohif/extension-cornerstone-dicom-seg",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.15.29",
@ -227,10 +227,10 @@
"@kitware/vtk.js": "34.15.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -241,7 +241,7 @@
},
"extensions/cornerstone-dicom-sr": {
"name": "@ohif/extension-cornerstone-dicom-sr",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/adapters": "4.15.29",
@ -250,10 +250,10 @@
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-measurement-tracking": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-measurement-tracking": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -263,7 +263,7 @@
},
"extensions/cornerstone-dynamic-volume": {
"name": "@ohif/extension-cornerstone-dynamic-volume",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.15.29",
@ -271,11 +271,11 @@
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -285,7 +285,7 @@
},
"extensions/default": {
"name": "@ohif/extension-default",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/calculate-suv": "1.1.0",
@ -294,8 +294,8 @@
"react-color": "2.19.3",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/i18n": "3.12.5",
"dcmjs": "0.49.4",
"dicomweb-client": "0.10.4",
"prop-types": "15.8.1",
@ -309,7 +309,7 @@
},
"extensions/dicom-microscopy": {
"name": "@ohif/extension-dicom-microscopy",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/codec-charls": "1.2.3",
@ -320,10 +320,10 @@
"mathjs": "12.4.3",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"@ohif/ui": "3.12.5",
"prop-types": "15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
@ -334,14 +334,14 @@
},
"extensions/dicom-pdf": {
"name": "@ohif/extension-dicom-pdf",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -351,14 +351,14 @@
},
"extensions/dicom-video": {
"name": "@ohif/extension-dicom-video",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -368,20 +368,20 @@
},
"extensions/measurement-tracking": {
"name": "@ohif/extension-measurement-tracking",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@ohif/ui": "3.12.4",
"@ohif/ui": "3.12.5",
"@xstate/react": "3.2.2",
"xstate": "4.38.3",
},
"peerDependencies": {
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/ui": "3.12.5",
"classnames": "2.5.1",
"dcmjs": "0.49.4",
"lodash.debounce": "4.0.8",
@ -394,14 +394,14 @@
},
"extensions/test-extension": {
"name": "@ohif/extension-test",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -411,14 +411,14 @@
},
"extensions/tmtv": {
"name": "@ohif/extension-tmtv",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"classnames": "2.5.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/ui": "3.12.5",
"dcmjs": "0.49.4",
"dicom-parser": "1.8.21",
"hammerjs": "2.0.8",
@ -428,16 +428,16 @@
},
"extensions/usAnnotation": {
"name": "@ohif/extension-ultrasound-pleura-bline",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/ui-next": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/i18n": "3.12.5",
"@ohif/ui-next": "3.12.5",
},
"devDependencies": {
"@babel/core": "7.28.0",
@ -476,7 +476,7 @@
},
"modes/basic": {
"name": "@ohif/mode-basic",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
},
@ -485,19 +485,19 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-rt": "3.12.4",
"@ohif/extension-cornerstone-dicom-seg": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-rt": "3.12.5",
"@ohif/extension-cornerstone-dicom-seg": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
},
},
"modes/basic-dev-mode": {
"name": "@ohif/mode-basic-dev-mode",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -507,17 +507,17 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
},
},
"modes/basic-test-mode": {
"name": "@ohif/mode-test",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -527,19 +527,19 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/extension-measurement-tracking": "3.12.4",
"@ohif/extension-test": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
"@ohif/extension-measurement-tracking": "3.12.5",
"@ohif/extension-test": "3.12.5",
},
},
"modes/longitudinal": {
"name": "@ohif/mode-longitudinal",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -549,33 +549,33 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-rt": "3.12.4",
"@ohif/extension-cornerstone-dicom-seg": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/extension-measurement-tracking": "3.12.4",
"@ohif/mode-basic": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-rt": "3.12.5",
"@ohif/extension-cornerstone-dicom-seg": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
"@ohif/extension-measurement-tracking": "3.12.5",
"@ohif/mode-basic": "3.12.5",
},
},
"modes/microscopy": {
"name": "@ohif/mode-microscopy",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-dicom-microscopy": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-dicom-microscopy": "3.12.5",
},
},
"modes/preclinical-4d": {
"name": "@ohif/mode-preclinical-4d",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
},
@ -584,17 +584,17 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-seg": "3.12.4",
"@ohif/extension-cornerstone-dynamic-volume": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-tmtv": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-seg": "3.12.5",
"@ohif/extension-cornerstone-dynamic-volume": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-tmtv": "3.12.5",
},
},
"modes/segmentation": {
"name": "@ohif/mode-segmentation",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -623,20 +623,20 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-rt": "3.12.4",
"@ohif/extension-cornerstone-dicom-seg": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/mode-basic": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-rt": "3.12.5",
"@ohif/extension-cornerstone-dicom-seg": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
"@ohif/mode-basic": "3.12.5",
},
},
"modes/tmtv": {
"name": "@ohif/mode-tmtv",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next": "17.3.1",
@ -646,25 +646,25 @@
"webpack-merge": "5.10.0",
},
"peerDependencies": {
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/extension-measurement-tracking": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
"@ohif/extension-measurement-tracking": "3.12.5",
},
},
"modes/usAnnotation": {
"name": "@ohif/mode-ultrasound-pleura-bline",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/tools": "4.15.29",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-ultrasound-pleura-bline": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-ultrasound-pleura-bline": "3.12.5",
"i18next": "17.3.1",
},
"devDependencies": {
@ -693,7 +693,7 @@
},
"platform/app": {
"name": "@ohif/app",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"@cornerstonejs/codec-charls": "1.2.3",
@ -702,25 +702,25 @@
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/dicom-image-loader": "4.15.29",
"@emotion/serialize": "1.3.3",
"@ohif/core": "3.12.4",
"@ohif/extension-cornerstone": "3.12.4",
"@ohif/extension-cornerstone-dicom-rt": "3.12.4",
"@ohif/extension-cornerstone-dicom-seg": "3.12.4",
"@ohif/extension-cornerstone-dicom-sr": "3.12.4",
"@ohif/extension-default": "3.12.4",
"@ohif/extension-dicom-microscopy": "3.12.4",
"@ohif/extension-dicom-pdf": "3.12.4",
"@ohif/extension-dicom-video": "3.12.4",
"@ohif/extension-test": "3.12.4",
"@ohif/extension-ultrasound-pleura-bline": "3.12.4",
"@ohif/i18n": "3.12.4",
"@ohif/mode-basic-dev-mode": "3.12.4",
"@ohif/mode-longitudinal": "3.12.4",
"@ohif/mode-microscopy": "3.12.4",
"@ohif/mode-test": "3.12.4",
"@ohif/mode-ultrasound-pleura-bline": "3.12.4",
"@ohif/ui": "3.12.4",
"@ohif/ui-next": "3.12.4",
"@ohif/core": "3.12.5",
"@ohif/extension-cornerstone": "3.12.5",
"@ohif/extension-cornerstone-dicom-rt": "3.12.5",
"@ohif/extension-cornerstone-dicom-seg": "3.12.5",
"@ohif/extension-cornerstone-dicom-sr": "3.12.5",
"@ohif/extension-default": "3.12.5",
"@ohif/extension-dicom-microscopy": "3.12.5",
"@ohif/extension-dicom-pdf": "3.12.5",
"@ohif/extension-dicom-video": "3.12.5",
"@ohif/extension-test": "3.12.5",
"@ohif/extension-ultrasound-pleura-bline": "3.12.5",
"@ohif/i18n": "3.12.5",
"@ohif/mode-basic-dev-mode": "3.12.5",
"@ohif/mode-longitudinal": "3.12.5",
"@ohif/mode-microscopy": "3.12.5",
"@ohif/mode-test": "3.12.5",
"@ohif/mode-ultrasound-pleura-bline": "3.12.5",
"@ohif/ui": "3.12.5",
"@ohif/ui-next": "3.12.5",
"@svgr/webpack": "8.1.0",
"@types/react": "18.3.23",
"classnames": "2.5.1",
@ -772,7 +772,7 @@
},
"platform/cli": {
"name": "@ohif/cli",
"version": "3.12.4",
"version": "3.12.5",
"bin": {
"ohif-cli": "src/index.js",
},
@ -796,7 +796,7 @@
},
"platform/core": {
"name": "@ohif/core",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"dcmjs": "0.49.4",
@ -823,14 +823,14 @@
"@cornerstonejs/codec-openjph": "2.4.7",
"@cornerstonejs/core": "4.15.29",
"@cornerstonejs/dicom-image-loader": "4.15.29",
"@ohif/ui": "3.12.4",
"@ohif/ui": "3.12.5",
"cornerstone-math": "0.1.10",
"dicom-parser": "1.8.21",
},
},
"platform/i18n": {
"name": "@ohif/i18n",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@babel/runtime": "7.28.2",
"i18next-locize-backend": "2.2.2",
@ -855,7 +855,7 @@
},
"platform/ui": {
"name": "@ohif/ui",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@testing-library/react": "13.4.0",
"browser-detect": "0.2.28",
@ -905,7 +905,7 @@
},
"platform/ui-next": {
"name": "@ohif/ui-next",
"version": "3.12.4",
"version": "3.12.5",
"dependencies": {
"@radix-ui/react-accordion": "1.2.11",
"@radix-ui/react-checkbox": "1.3.2",
@ -975,6 +975,7 @@
"rollup": "2.80.0",
"serialize-javascript": "7.0.4",
"shell-quote": "1.8.4",
"sigstore": "4.1.1",
"svgo": "3.3.3",
"tapable": "2.2.2",
"tar": "7.5.11",
@ -1371,6 +1372,8 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.10", "", {}, "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ=="],
"@gar/promise-retry": ["@gar/promise-retry@1.0.3", "", {}, "sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
@ -1873,15 +1876,15 @@
"@sigstore/bundle": ["@sigstore/bundle@4.0.0", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A=="],
"@sigstore/core": ["@sigstore/core@3.1.0", "", {}, "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A=="],
"@sigstore/core": ["@sigstore/core@3.2.1", "", {}, "sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g=="],
"@sigstore/protobuf-specs": ["@sigstore/protobuf-specs@0.5.0", "", {}, "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA=="],
"@sigstore/sign": ["@sigstore/sign@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "make-fetch-happen": "^15.0.3", "proc-log": "^6.1.0", "promise-retry": "^2.0.1" } }, "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg=="],
"@sigstore/sign": ["@sigstore/sign@4.1.1", "", { "dependencies": { "@gar/promise-retry": "^1.0.2", "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.0", "@sigstore/protobuf-specs": "^0.5.0", "make-fetch-happen": "^15.0.4", "proc-log": "^6.1.0" } }, "sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ=="],
"@sigstore/tuf": ["@sigstore/tuf@4.0.1", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" } }, "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw=="],
"@sigstore/tuf": ["@sigstore/tuf@4.0.2", "", { "dependencies": { "@sigstore/protobuf-specs": "^0.5.0", "tuf-js": "^4.1.0" } }, "sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ=="],
"@sigstore/verify": ["@sigstore/verify@3.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag=="],
"@sigstore/verify": ["@sigstore/verify@3.1.1", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0" } }, "sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA=="],
"@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
@ -4725,7 +4728,7 @@
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"sigstore": ["sigstore@4.1.0", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.1.0", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.0", "@sigstore/tuf": "^4.0.1", "@sigstore/verify": "^3.1.0" } }, "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA=="],
"sigstore": ["sigstore@4.1.1", "", { "dependencies": { "@sigstore/bundle": "^4.0.0", "@sigstore/core": "^3.2.1", "@sigstore/protobuf-specs": "^0.5.0", "@sigstore/sign": "^4.1.1", "@sigstore/tuf": "^4.0.2", "@sigstore/verify": "^3.1.1" } }, "sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w=="],
"sirv": ["sirv@3.0.2", "", { "dependencies": { "@polka/url": "^1.0.0-next.24", "mrmime": "^2.0.0", "totalist": "^3.0.0" } }, "sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g=="],
@ -5589,7 +5592,7 @@
"@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.0.1", "", { "dependencies": { "@emnapi/core": "^1.4.5", "@emnapi/runtime": "^1.4.5", "@tybys/wasm-util": "^0.10.0" } }, "sha512-KVlQ/jgywZpixGCKMNwxStmmbYEMyokZpCf2YuIChhfJA2uqfAKNEM8INz7zzTo55iEXfBhIIs3VqYyqzDLj8g=="],
"@sigstore/sign/make-fetch-happen": ["make-fetch-happen@15.0.3", "", { "dependencies": { "@npmcli/agent": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "promise-retry": "^2.0.1", "ssri": "^13.0.0" } }, "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw=="],
"@sigstore/sign/make-fetch-happen": ["make-fetch-happen@15.0.6", "", { "dependencies": { "@gar/promise-retry": "^1.0.0", "@npmcli/agent": "^4.0.0", "@npmcli/redact": "^4.0.0", "cacache": "^20.0.1", "http-cache-semantics": "^4.1.1", "minipass": "^7.0.2", "minipass-fetch": "^5.0.0", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^1.0.0", "proc-log": "^6.0.0", "ssri": "^13.0.0" } }, "sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw=="],
"@sigstore/sign/proc-log": ["proc-log@6.1.0", "", {}, "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ=="],
@ -6665,6 +6668,8 @@
"@rspack/binding-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ=="],
"@sigstore/sign/make-fetch-happen/@npmcli/redact": ["@npmcli/redact@4.0.0", "", {}, "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q=="],
"@sigstore/sign/make-fetch-happen/minipass-fetch": ["minipass-fetch@5.0.1", "", { "dependencies": { "minipass": "^7.0.3", "minipass-sized": "^2.0.0", "minizlib": "^3.0.1" }, "optionalDependencies": { "encoding": "^0.1.13" } }, "sha512-yHK8pb0iCGat0lDrs/D6RZmCdaBT64tULXjdxjSMAqoDi18Q3qKEUTHypHQZQd9+FYpIS+lkvpq6C/R6SbUeRw=="],
"@sigstore/sign/make-fetch-happen/ssri": ["ssri@13.0.1", "", { "dependencies": { "minipass": "^7.0.3" } }, "sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ=="],

View File

@ -49,7 +49,7 @@
"install:update-lockfile": "yarn install && bun install --config=./bunfig.update-lockfile.toml",
"install:yarn:frozen-lockfile": "echo Deprecated - use install:frozen && yarn install --frozen-lockfile",
"install:frozen": "yarn install --frozen-lockfile",
"audit": "bun audit --ignore=GHSA-3ppc-4f35-3m26 --ignore=GHSA-7r86-cg39-jmmj --ignore=GHSA-23c5-xmqv-rm74 --ignore=GHSA-c2c7-rcm5-vvqj",
"audit": "bun audit --ignore=GHSA-3ppc-4f35-3m26 --ignore=GHSA-7r86-cg39-jmmj --ignore=GHSA-23c5-xmqv-rm74 --ignore=GHSA-c2c7-rcm5-vvqj --ignore=GHSA-mp2f-45pm-3cg9",
"preinstall": "node preinstall.js",
"start": "yarn run dev",
"test": "yarn run test:unit",
@ -167,7 +167,8 @@
"tmp": "0.2.7",
"form-data": "4.0.6",
"ws": "8.21.0",
"shell-quote": "1.8.4"
"shell-quote": "1.8.4",
"sigstore": "4.1.1"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}

View File

@ -2,9 +2,11 @@ import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
globalSetup: './tests/globalSetup.ts',
fullyParallel: !!process.env.CI,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 3 : 0,
retries: process.env.CI ? 1 : 0,
maxFailures: process.env.CI ? 10 : undefined,
workers: process.env.CI ? 6 : undefined,
snapshotPathTemplate: './tests/screenshots{/projectName}/{testFilePath}/{arg}{ext}',
outputDir: './tests/test-results',
@ -20,6 +22,10 @@ export default defineConfig({
launchOptions: {
// do not hide the scrollbars so that we can assert their look-and-feel
ignoreDefaultArgs: ['--hide-scrollbars'],
// Use the runner's EGL GPU stack for WebGL. Without this, Chromium falls
// back to software GL on the self-hosted (nashua) runner and cornerstone
// rendering produces wrong/blank frames, failing every screenshot test.
args: ['--use-gl=egl'],
},
},
@ -42,7 +48,8 @@ export default defineConfig({
//},
],
webServer: {
command: 'cross-env APP_CONFIG=config/e2e.js COVERAGE=true OHIF_PORT=3335 nyc yarn start',
command:
'cross-env APP_CONFIG=config/e2e.js COVERAGE=true OHIF_PORT=3335 OHIF_OPEN=false nyc yarn start',
url: 'http://localhost:3335',
reuseExistingServer: !process.env.CI,
timeout: 360_000,

View File

@ -32,7 +32,7 @@ test('should display the arrow tool and allow free-form text to be entered', asy
await checkForScreenshot({
page,
maxDiffPixelRatio: 0.0075,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.arrowAnnotate.arrowAnnotateDisplayedCorrectly0,
});
@ -46,7 +46,7 @@ test('should display the arrow tool and allow free-form text to be entered', asy
await checkForScreenshot({
page,
maxDiffPixelRatio: 0.0075,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.arrowAnnotate.arrowAnnotateDisplayedCorrectly1,
});
@ -60,7 +60,7 @@ test('should display the arrow tool and allow free-form text to be entered', asy
await checkForScreenshot({
page,
maxDiffPixelRatio: 0.0075,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.arrowAnnotate.arrowAnnotateDisplayedCorrectly2,
});
});

View File

@ -19,11 +19,11 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.waitForTimeout(5000);
await checkForScreenshot(
await checkForScreenshot({
page,
page,
screenShotPaths.mprThenSEGOverlayNoHydration.mprPreSEGOverlayNoHydration
);
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.mprThenSEGOverlayNoHydration.mprPreSEGOverlayNoHydration,
});
// Hover over the middle/sagittal viewport so that the data overlay menu is available.
await viewportPageObject.getById('mpr-axial').pane.hover();
@ -39,9 +39,9 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.waitForTimeout(5000);
await checkForScreenshot(
await checkForScreenshot({
page,
page,
screenShotPaths.mprThenSEGOverlayNoHydration.mprPostSEGOverlayNoHydration
);
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.mprThenSEGOverlayNoHydration.mprPostSEGOverlayNoHydration,
});
});

View File

@ -15,13 +15,25 @@ test('should hydrate RT reports correctly', async ({
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPreHydration);
await checkForScreenshot({
page,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.rtHydration.rtPreHydration,
});
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPostHydration);
await checkForScreenshot({
page,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.rtHydration.rtPostHydration,
});
await rightPanelPageObject.labelMapSegmentationPanel.panel.segmentByText('Small Sphere').click();
await page.waitForTimeout(5000);
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtJumpToStructure);
await checkForScreenshot({
page,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.rtHydration.rtJumpToStructure,
});
});

View File

@ -15,7 +15,11 @@ test('should hydrate RT reports correctly', async ({
await rightPanelPageObject.toggle();
await leftPanelPageObject.loadSeriesByModality('RTSTRUCT');
await checkForScreenshot(page, page, screenShotPaths.rtHydration2.rtPreHydration);
await checkForScreenshot({
page,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.rtHydration2.rtPreHydration,
});
// wait for 3 seconds
await page.evaluate(() => {
// Access cornerstone directly from the window object
@ -40,5 +44,9 @@ test('should hydrate RT reports correctly', async ({
// should preserve zoom and pan and scroll position after hydration
await DOMOverlayPageObject.viewport.segmentationHydration.yes.click();
await checkForScreenshot(page, page, screenShotPaths.rtHydration.rtPostHydration);
await checkForScreenshot({
page,
locator: page.getByTestId('viewport-grid'),
screenshotPath: screenShotPaths.rtHydration2.rtPostHydration,
});
});

View File

@ -27,21 +27,23 @@ test('should launch MPR with unhydrated SEG chosen from the data overlay menu',
await page.waitForTimeout(5000);
await checkForScreenshot(
await checkForScreenshot({
page,
page,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPreMPR
);
locator: page.getByTestId('viewport-grid'),
screenshotPath:
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPreMPR,
});
await mainToolbarPageObject.layoutSelection.MPR.click();
await page.waitForTimeout(5000);
await checkForScreenshot(
await checkForScreenshot({
page,
page,
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR
);
locator: page.getByTestId('viewport-grid'),
screenshotPath:
screenShotPaths.segDataOverlayNoHydrationThenMPR.segDataOverlayNoHydrationPostMPR,
});
// Adding an overlay should not show the LOAD button.
assertNumberOfModalityLoadBadges({ page, expectedCount: 0 });

View File

@ -35,10 +35,12 @@ test('should render scroll bars with the correct look-and-feel', async ({ page }
// Additional wait to ensure scrollbar rendering is stable
await page.waitForTimeout(1000);
expandedStudyRow.scrollIntoViewIfNeeded();
await checkForScreenshot({
page,
locator: expandedStudyRow,
normalizedClip: { x: 0.97, y: 0.35, width: 0.03, height: 0.65 },
normalizedClip: { x: 0.97, y: 0.35, width: 0.028, height: 0.65 },
screenshotPath: screenShotPaths.workList.scrollBarRenderedProperly,
});
});

36
tests/globalSetup.ts Normal file
View File

@ -0,0 +1,36 @@
/**
* Playwright global setup (wired via `globalSetup` in playwright.config.ts).
*
* Before the test suite runs, open the viewer once against a known study to
* "warm up" the dev server: trigger the first (slow) lazy webpack compilation,
* prime the browser/codec caches, and fetch the study metadata. Without this,
* the first real spec frequently times out waiting on a cold server compile.
* This run only loads the page and waits for a viewport pane to render; it makes
* no assertions.
*/
import { chromium, type FullConfig } from '@playwright/test';
const warmupStudyInstanceUID = '1.3.6.1.4.1.14519.5.2.1.1706.8374.643249677828306008300337414785';
const warmupTimeout = 180_000;
export default async function globalSetup(config: FullConfig) {
const baseURL = String(config.projects[0]?.use?.baseURL || 'http://localhost:3335');
const warmupURL = new URL(
`/viewer/ohif?StudyInstanceUIDs=${warmupStudyInstanceUID}`,
baseURL
).toString();
const browser = await chromium.launch();
const page = await browser.newPage();
try {
page.setDefaultTimeout(warmupTimeout);
await page.goto(warmupURL, { waitUntil: 'domcontentloaded', timeout: warmupTimeout });
await page.waitForLoadState('networkidle', { timeout: warmupTimeout }).catch(() => {});
await page
.locator('[data-cy="viewport-pane"]')
.first()
.waitFor({ state: 'visible', timeout: warmupTimeout });
} finally {
await browser.close();
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 270 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 459 KiB

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 687 B

After

Width:  |  Height:  |  Size: 646 B

View File

@ -1 +1 @@
3.12.5
3.12.6

View File

@ -2407,6 +2407,11 @@
resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.9.tgz#50dea3616bc8191fb8e112283b49eaff03e78429"
integrity sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==
"@gar/promise-retry@^1.0.0", "@gar/promise-retry@^1.0.2":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@gar/promise-retry/-/promise-retry-1.0.3.tgz#65e726428e794bc4453948e0a41e6de4215ce8b0"
integrity sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==
"@humanfs/core@^0.19.1":
version "0.19.1"
resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
@ -4504,43 +4509,43 @@
dependencies:
"@sigstore/protobuf-specs" "^0.5.0"
"@sigstore/core@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-3.1.0.tgz#b418de73f56333ad9e369b915173d8c98e9b96d5"
integrity sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==
"@sigstore/core@^3.2.0", "@sigstore/core@^3.2.1":
version "3.2.1"
resolved "https://registry.yarnpkg.com/@sigstore/core/-/core-3.2.1.tgz#4efd4ab0f59e768b6daf65612024ba925787de72"
integrity sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==
"@sigstore/protobuf-specs@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz#e5f029edcb3a4329853a09b603011e61043eb005"
integrity sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==
"@sigstore/sign@^4.1.0":
version "4.1.0"
resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-4.1.0.tgz#63df15a137337b29f463a1d1c51e1f7d4c1db2f1"
integrity sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==
"@sigstore/sign@^4.1.1":
version "4.1.1"
resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-4.1.1.tgz#34765fe4a190d693340c0771a3d150a397bcfc55"
integrity sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==
dependencies:
"@gar/promise-retry" "^1.0.2"
"@sigstore/bundle" "^4.0.0"
"@sigstore/core" "^3.1.0"
"@sigstore/core" "^3.2.0"
"@sigstore/protobuf-specs" "^0.5.0"
make-fetch-happen "^15.0.3"
make-fetch-happen "^15.0.4"
proc-log "^6.1.0"
promise-retry "^2.0.1"
"@sigstore/tuf@^4.0.1":
version "4.0.1"
resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-4.0.1.tgz#9b080390936d79ea3b6a893b64baf3123e92d6d3"
integrity sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==
"@sigstore/tuf@^4.0.2":
version "4.0.2"
resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-4.0.2.tgz#7d2fa2abcd5afa5baf752671d14a1c6ed0ed3196"
integrity sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==
dependencies:
"@sigstore/protobuf-specs" "^0.5.0"
tuf-js "^4.1.0"
"@sigstore/verify@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-3.1.0.tgz#4046d4186421db779501fe87fa5acaa5d4d21b08"
integrity sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==
"@sigstore/verify@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@sigstore/verify/-/verify-3.1.1.tgz#13c1c1cff28fe81f662de29d85ba5ae048fcbd8d"
integrity sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==
dependencies:
"@sigstore/bundle" "^4.0.0"
"@sigstore/core" "^3.1.0"
"@sigstore/core" "^3.2.1"
"@sigstore/protobuf-specs" "^0.5.0"
"@sinclair/typebox@^0.27.8":
@ -13526,7 +13531,7 @@ make-fetch-happen@15.0.2:
promise-retry "^2.0.1"
ssri "^12.0.0"
make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.1, make-fetch-happen@^15.0.3:
make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.1:
version "15.0.3"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz#1578d72885f2b3f9e5daa120b36a14fc31a84610"
integrity sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==
@ -13543,6 +13548,24 @@ make-fetch-happen@^15.0.0, make-fetch-happen@^15.0.1, make-fetch-happen@^15.0.3:
promise-retry "^2.0.1"
ssri "^13.0.0"
make-fetch-happen@^15.0.4:
version "15.0.6"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-15.0.6.tgz#079dee708c88a04a1f79735bb02789a63597840e"
integrity sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==
dependencies:
"@gar/promise-retry" "^1.0.0"
"@npmcli/agent" "^4.0.0"
"@npmcli/redact" "^4.0.0"
cacache "^20.0.1"
http-cache-semantics "^4.1.1"
minipass "^7.0.2"
minipass-fetch "^5.0.0"
minipass-flush "^1.0.5"
minipass-pipeline "^1.2.4"
negotiator "^1.0.0"
proc-log "^6.0.0"
ssri "^13.0.0"
makeerror@1.0.12:
version "1.0.12"
resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a"
@ -17869,17 +17892,17 @@ signal-exit@^4.0.1, signal-exit@^4.1.0:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
sigstore@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-4.1.0.tgz#d34b92a544a05e003a2430209d26d8dfafd805a0"
integrity sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==
sigstore@4.1.1, sigstore@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-4.1.1.tgz#2959993dbf978c759a5d23d854cbd3729b6dcd97"
integrity sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==
dependencies:
"@sigstore/bundle" "^4.0.0"
"@sigstore/core" "^3.1.0"
"@sigstore/core" "^3.2.1"
"@sigstore/protobuf-specs" "^0.5.0"
"@sigstore/sign" "^4.1.0"
"@sigstore/tuf" "^4.0.1"
"@sigstore/verify" "^3.1.0"
"@sigstore/sign" "^4.1.1"
"@sigstore/tuf" "^4.0.2"
"@sigstore/verify" "^3.1.1"
sirv@^3.0.2:
version "3.0.2"