Skip to content

Rename CFWOS to CFOS #1

Rename CFWOS to CFOS

Rename CFWOS to CFOS #1

Workflow file for this run

# P6.7: Lighthouse CI Workflow for Accessibility Testing
#
# Runs Lighthouse audits against the cass Archive web viewer
# to ensure WCAG 2.1 AA compliance and performance targets.
#
# Triggers:
# - Push to main (pages-related files)
# - Pull requests modifying web viewer
# - Manual dispatch
name: Lighthouse CI
on:
push:
branches: [main]
paths:
- 'src/pages/**'
- 'src/pages_assets/**'
- 'tests/accessibility/**'
- 'tests/performance/lighthouse.config.js'
- '.github/workflows/lighthouse.yml'
pull_request:
paths:
- 'src/pages/**'
- 'src/pages_assets/**'
- 'tests/accessibility/**'
- 'tests/performance/lighthouse.config.js'
workflow_dispatch:
inputs:
url:
description: 'URL to test (leave empty for local build)'
required: false
default: ''
env:
CARGO_TERM_COLOR: always
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
permissions:
contents: read
jobs:
lighthouse:
name: Lighthouse Accessibility Audit
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Install Lighthouse CI
run: npm install -g @lhci/cli@0.13.x
- name: Setup Rust
uses: dtolnay/rust-toolchain@881ba7bf39a41cda34ac9e123fb41b44ed08232f # nightly
with:
components: rustfmt, clippy
- name: Cache Cargo
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: |
~/.cargo/bin/
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
- name: Build cass
run: cargo build --release
- name: Create test archive
run: |
mkdir -p test-archive
# Create a minimal test archive for Lighthouse
echo '{"version":1,"created":"2024-01-01T00:00:00Z"}' > test-archive/config.json
cp src/pages_assets/* test-archive/
# Create encrypted test data (minimal)
./target/release/cass pages --export-only --output test-archive --no-encryption || true
- name: Start local server
run: |
cd test-archive
python3 -m http.server 8080 &
sleep 2
# Verify server is running
curl -I http://localhost:8080/ || exit 1
- name: Run Lighthouse CI
run: |
lhci autorun \
--config=tests/performance/lighthouse.config.js \
--collect.url=http://localhost:8080/ \
--upload.target=temporary-public-storage
env:
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}
- name: Upload Lighthouse Report
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: lighthouse-report
path: .lighthouseci/
retention-days: 14
- name: Check Accessibility Score
run: |
# Extract accessibility score from the report
SCORE=$(cat .lighthouseci/lhr-*.json | jq -r '.categories.accessibility.score')
echo "Accessibility Score: $SCORE"
# Fail if below threshold (0.9 = 90%)
if (( $(echo "$SCORE < 0.9" | bc -l) )); then
echo "::error::Accessibility score $SCORE is below threshold 0.9"
exit 1
fi
echo "::notice::Accessibility score $SCORE meets threshold"
axe-core:
name: axe-core Accessibility Tests
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout code
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
- name: Setup Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
with:
node-version: '20'
- name: Install dependencies
run: |
npm install @axe-core/playwright playwright
npx playwright install chromium
- name: Setup Rust and build
uses: dtolnay/rust-toolchain@881ba7bf39a41cda34ac9e123fb41b44ed08232f # nightly
- name: Cache Cargo
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4
with:
path: |
~/.cargo/registry/index/
~/.cargo/registry/cache/
~/.cargo/git/db/
target/
key: ${{ runner.os }}-cargo-axe-${{ hashFiles('**/Cargo.lock') }}
- name: Build cass
run: cargo build --release
- name: Create test archive
run: |
mkdir -p test-archive
echo '{"version":1}' > test-archive/config.json
cp src/pages_assets/* test-archive/
- name: Start server
run: |
cd test-archive
python3 -m http.server 8080 &
sleep 2
- name: Run axe-core tests
run: npx playwright test tests/accessibility/axe-core.test.js --reporter=github
continue-on-error: true
- name: Upload test results
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
if: always()
with:
name: axe-core-results
path: test-results/
retention-days: 7
accessibility-report:
name: Accessibility Summary
runs-on: ubuntu-latest
needs: [lighthouse, axe-core]
if: always()
timeout-minutes: 10
steps:
- name: Download Lighthouse Report
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: lighthouse-report
path: lighthouse-report/
continue-on-error: true
- name: Generate Summary
run: |
echo "## Accessibility Audit Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ -f lighthouse-report/lhr-*.json ]; then
A11Y_SCORE=$(cat lighthouse-report/lhr-*.json | jq -r '.categories.accessibility.score * 100')
PERF_SCORE=$(cat lighthouse-report/lhr-*.json | jq -r '.categories.performance.score * 100')
echo "| Metric | Score |" >> $GITHUB_STEP_SUMMARY
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
echo "| Accessibility | ${A11Y_SCORE}% |" >> $GITHUB_STEP_SUMMARY
echo "| Performance | ${PERF_SCORE}% |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
# List any violations
VIOLATIONS=$(cat lighthouse-report/lhr-*.json | jq -r '.audits | to_entries | map(select(.value.score == 0 and .value.details.items != null)) | .[].key')
if [ -n "$VIOLATIONS" ]; then
echo "### Failed Audits" >> $GITHUB_STEP_SUMMARY
echo "$VIOLATIONS" | while read audit; do
echo "- $audit" >> $GITHUB_STEP_SUMMARY
done
fi
else
echo "Lighthouse report not available" >> $GITHUB_STEP_SUMMARY
fi
echo "" >> $GITHUB_STEP_SUMMARY
echo "### WCAG 2.1 AA Compliance Target: 90%" >> $GITHUB_STEP_SUMMARY