Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 25 additions & 12 deletions .github/workflows/run-nala-default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,42 +17,50 @@ permissions:

jobs:
run-nala-tests:
name: Running Nala E2E UI Tests
name: Running Nala E2E UI Tests (${{ matrix.lane_id }})
runs-on: ubuntu-latest
timeout-minutes: 30
strategy:
# Don't cancel the other shards when one fails — we want the full picture.
# Don't cancel the other lanes when one fails — we want the full picture.
fail-fast: false
matrix:
node-version: [24.x]
# Split the suite across parallel runner jobs. Playwright's --shard
# deterministically partitions tests, so 4 shards ≈ 4x throughput.
shard: [1, 2, 3, 4]
# Lanes run as parallel runner jobs. The non-color suite is split across
# 4 shards (Playwright's --shard deterministically partitions tests). The
# heavy color-shared blocks are pulled OUT of the shards (each shard lane
# excludes @color) and run in their own serial lane (workers=1) so they
# never cluster on one shard and starve each other's decoration — the
# cause of the recurring color-block waitReady timeouts.
include:
- { lane_id: shard1, node: 24.x, shard: '1/4', exclude: '@color', grep: '', workers: '' }
- { lane_id: shard2, node: 24.x, shard: '2/4', exclude: '@color', grep: '', workers: '' }
- { lane_id: shard3, node: 24.x, shard: '3/4', exclude: '@color', grep: '', workers: '' }
- { lane_id: shard4, node: 24.x, shard: '4/4', exclude: '@color', grep: '', workers: '' }
- { lane_id: color, node: 24.x, shard: '', exclude: '', grep: '@color', workers: '1' }

steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
with:
fetch-depth: 2

- name: Set up Node.js ${{ matrix.node-version }}
- name: Set up Node.js ${{ matrix.node }}
uses: actions/setup-node@cdca7365b2dadb8aad0a33bc7601856ffabcc48e
with:
node-version: ${{ matrix.node-version }}
node-version: ${{ matrix.node }}

- name: Cache node_modules
uses: actions/cache@v4
with:
path: |
~/.npm
**/node_modules
key: npm-${{ runner.os }}-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') }}
key: npm-${{ runner.os }}-${{ matrix.node }}-${{ hashFiles('**/package-lock.json') }}

- name: Cache Playwright browsers
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ms-playwright-${{ runner.os }}-${{ matrix.node-version }}-chromium
key: ms-playwright-${{ runner.os }}-${{ matrix.node }}-chromium

- name: Install dependencies
run: npm ci --no-fund --prefer-offline
Expand All @@ -75,7 +83,12 @@ jobs:
# PR gate: full cross-browser matrix, sharded across parallel jobs
# so wall-clock stays low even with all three browsers.
NALA_PROJECTS: --project=express-live-chromium --project=express-live-firefox --project=express-live-webkit
SHARD: ${{ matrix.shard }}/4
# Sharded lanes: SHARD set + exclude @color. Color lane: no shard,
# grep only @color, workers=1 (serial).
SHARD: ${{ matrix.shard }}
NALA_EXTRA_GREP_INVERT: ${{ matrix.exclude }}
NALA_GREP: ${{ matrix.grep }}
NALA_WORKERS: ${{ matrix.workers }}
labels: ${{ join(github.event.pull_request.labels.*.name, ' ') }}
branch: ${{ github.event.pull_request.head.ref }}
repoName: ${{ github.repository }}
Expand All @@ -92,7 +105,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: nala-test-results-${{ github.run_number }}-shard${{ matrix.shard }}
name: nala-test-results-${{ github.run_number }}-${{ matrix.lane_id }}
path: |
test-results/
test-html-results/
Expand Down
22 changes: 17 additions & 5 deletions nala/utils/pr.run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@ set -e

TAGS=""
REPORTER=""
EXCLUDE_TAGS="--grep-invert nopr"
EXCLUDE_MONITORING="--grep-invert @monitoring"
# Single combined --grep-invert: Playwright applies only the LAST --grep-invert
# flag, so every exclusion must live in one regex. nopr = never run in PR/CI;
# @monitoring = synthetic monitors. Sharded lanes additionally pass
# NALA_EXTRA_GREP_INVERT="@color" to hand the heavy color blocks off to their
# own serial lane (they starve each other's decoration when clustered).
GREP_INVERT="nopr|@monitoring"
[[ -n "$NALA_EXTRA_GREP_INVERT" ]] && GREP_INVERT="${GREP_INVERT}|${NALA_EXTRA_GREP_INVERT}"
EXCLUDE_TAGS="--grep-invert ${GREP_INVERT}"
EXIT_STATUS=0

echo "GITHUB_REF: $GITHUB_REF"
Expand Down Expand Up @@ -74,13 +80,18 @@ done
# Remove first pipe if TAGS not empty
[[ ! -z "$TAGS" ]] && TAGS="${TAGS:1}" && TAGS="-g $TAGS"

# Positive grep. A lane override (NALA_GREP, e.g. "@color" for the serial color
# lane) takes precedence over PR-label tags.
GREP_ARG="$TAGS"
[[ -n "$NALA_GREP" ]] && GREP_ARG="-g $NALA_GREP"

# Reporter (override if provided)
REPORTER=$reporter
[[ ! -z "$REPORTER" ]] && REPORTER="--reporter $REPORTER"

echo "Running Nala on branch: $FEATURE_BRANCH"
echo "Tags: ${TAGS:-"No @tags or annotations on this PR"}"
echo "Run Command: npx playwright test ${TAGS} ${EXCLUDE_TAGS} ${EXCLUDE_MONITORING} ${REPORTER}"
echo "Run Command: npx playwright test ${GREP_ARG} ${EXCLUDE_TAGS} ${REPORTER}"
echo -e "\n"
echo "*******************************"

Expand All @@ -102,10 +113,11 @@ SHARD_ARG=""

# Run Playwright tests
echo "*** Running tests on projects: ${PROJECTS} ${SHARD_ARG:-"(no shard)"} ***"
echo "*** Excluding monitoring tests (@monitoring) ***"
echo "*** grep-invert: ${GREP_INVERT} ***"
[[ -n "$NALA_GREP" ]] && echo "*** grep (include only): ${NALA_GREP} — workers: ${NALA_WORKERS:-config default} ***"
npx playwright test \
--config=./playwright.config.cjs \
${TAGS} ${EXCLUDE_TAGS} ${EXCLUDE_MONITORING} ${REPORTER} \
${GREP_ARG} ${EXCLUDE_TAGS} ${REPORTER} \
${PROJECTS} ${SHARD_ARG} || EXIT_STATUS=$?

# Exit status
Expand Down
Loading