-
Notifications
You must be signed in to change notification settings - Fork 4
265 lines (237 loc) · 10.9 KB
/
Copy pathe2e.yml
File metadata and controls
265 lines (237 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
name: E2E Tests
on:
pull_request:
branches: [main]
paths-ignore:
- '**.md'
- 'docs/**'
- '.github/ISSUE_TEMPLATE/**'
- 'TODO.md'
- 'todo/**'
- 'LICENSE'
- '.editorconfig'
- '.agents/**'
workflow_dispatch:
concurrency:
group: e2e-${{ github.ref }}
cancel-in-progress: true
jobs:
e2e:
name: Playwright E2E (WP ${{ matrix.wp }} shard ${{ matrix.shard }})
runs-on: ubuntu-latest
# Each shard runs ~1/3 of the 13 spec files. 90 min accounts for setup
# overhead (~20 min: pnpm install, composer, wp-env start) + worst-case test
# runtime (2 retries at 90 s/test × 3 attempts / 2 workers). The 60-min
# limit was exceeded after the per-test timeout increased from 60 s to
# 90 s in playwright.config.js — setup + test time could exceed 60 min.
timeout-minutes: 90
# This required WordPress 7.0 environment provides the browser Abilities
# API that client-abilities.spec.js must exercise. Do not allow failures to
# pass as advisory coverage.
continue-on-error: false
strategy:
fail-fast: false
matrix:
# Pin the required browser-ability coverage to WordPress 7.0-RC2. The
# final 7.0 and moving trunk builds do not reliably load
# @wordpress/core-abilities on admin pages.
wp: ['7.0-RC2']
# 3 shards split 13 spec files into ~4-5 files each. With the 90-min
# job timeout, each shard has ample headroom even with 2 retries.
shard: [1, 2, 3]
include:
- wp: '7.0-RC2'
wp_env_port: '8890'
wp_env_override: '{"core":"WordPress/WordPress#7.0"}'
# 1 worker: shard 1 still showed login and SPA-render timeouts
# with 2 workers on GitHub-hosted runners under WordPress 7.0 load.
playwright_workers: '1'
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Setup pnpm and Node.js
uses: pnpm/setup@c9883cc79df532ad1a7b81bf9ab944ceb090d65c # v2.0.0
with:
runtime: node@24
cache: true
install: false
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, intl, zip
tools: composer:v2
coverage: none
- name: Get Composer cache directory
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- name: Cache Composer dependencies
uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-composer-
- name: Install Composer dependencies
run: composer install --prefer-dist --no-progress
- name: Install Node dependencies
run: pnpm install --frozen-lockfile
- name: Patch @wordpress/env phpunit constraint
# @wordpress/env's CLI.Dockerfile installs phpunit globally. Composer
# 2.6+ defaults audit.block-insecure to true, which blocks ALL phpunit
# versions (v5–v11) due to security advisories PKSA-5jz8-6tcw-pbk4 and
# PKSA-z3gr-8qht-p93v. COMPOSER_NO_AUDIT=1 only skips post-install
# audit reporting — it does NOT disable block-insecure resolution blocking.
# Fix: prepend 'composer config --global audit.block-insecure false &&'
# to disable the resolver-level block before running the install.
# v10.x uses init-config.js; v11.x renamed it to docker-config.js.
# Remove once @wordpress/env ships a fix upstream.
run: |
node -e "
const fs = require('fs');
const path = require('path');
const base = 'node_modules/@wordpress/env/lib/runtime/docker/';
const candidates = ['init-config.js', 'docker-config.js'];
const before = 'RUN composer global require --dev phpunit/phpunit:\"^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0\"';
const after = 'RUN composer config --global audit.block-insecure false && composer global require --dev phpunit/phpunit:\"^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0 || ^10.0\"';
let patched = false;
for (const name of candidates) {
const f = path.resolve(base + name);
if (!fs.existsSync(f)) continue;
let c = fs.readFileSync(f, 'utf8');
if (!c.includes(before)) { console.log(name + ': already patched or pattern changed, skipping'); continue; }
fs.writeFileSync(f, c.replace(before, after));
console.log('Patched ' + f);
patched = true;
}
if (!patched) console.log('No files needed patching');
"
# Playwright launches the preinstalled Chrome channel below. Avoid
# `playwright install-deps`, which runs apt and can stall on a runner
# mirror before the E2E suite starts.
- name: Verify system Chrome availability
run: google-chrome --version
- name: Build plugin assets
run: pnpm run build
- name: Override wp-env core version
if: matrix.wp_env_override != ''
env:
WP_ENV_OVERRIDE: ${{ matrix.wp_env_override }}
run: |
node -e "
const fs = require('fs');
const base = JSON.parse(fs.readFileSync('.wp-env.json', 'utf8'));
const override = JSON.parse(process.env.WP_ENV_OVERRIDE);
Object.assign(base, override);
fs.writeFileSync('.wp-env.override.json', JSON.stringify(base, null, 2));
"
- name: Start wp-env
run: pnpm run wp-env:start
timeout-minutes: 10
env:
WP_ENV_HOME: /tmp/wp-env
- name: Wait for wp-env to be ready
run: |
ready=0
for i in $(seq 1 30); do
if curl -s -o /dev/null -w "%{http_code}" http://localhost:${{ matrix.wp_env_port }}/wp-login.php | grep -q "200"; then
echo "wp-env is ready on port ${{ matrix.wp_env_port }}"
ready=1
break
fi
echo "Waiting for wp-env... attempt $i"
sleep 5
done
if [ "$ready" -ne 1 ]; then
echo "wp-env did not become ready in time on port ${{ matrix.wp_env_port }}" >&2
exit 1
fi
- name: Install required WordPress 7.0-RC2 browser Abilities API build
# wp-env bootstraps from the stable source tree, then WP-CLI installs
# the RC2 build where @wordpress/core-abilities is loaded in wp-admin.
# `--` keeps wp-env from consuming WP-CLI's `--version` option.
run: |
pnpm exec wp-env run cli -- wp core update --version=7.0-RC2 --force
pnpm exec wp-env run cli -- wp core update-db
pnpm exec wp-env run cli -- wp core version | grep -x '7.0-RC2'
env:
WP_ENV_HOME: /tmp/wp-env
- name: Verify plugin health
run: |
echo "=== Plugin status ==="
pnpm exec wp-env run cli wp plugin list --format=table
echo ""
echo "=== Verify plugin is active ==="
pnpm exec wp-env run cli wp plugin is-active superdav-ai-agent && echo "Plugin is active" || echo "ERROR: Plugin is NOT active"
echo ""
echo "=== Check admin page loads (HTTP status) ==="
# Log in and fetch the admin page to verify the SPA renders.
# First get a login cookie, then check the plugin page.
LOGIN_COOKIE=$(curl -s -c - -d "log=admin&pwd=password&wp-submit=Log+In" \
"http://localhost:${{ matrix.wp_env_port }}/wp-login.php" | grep wordpress_logged_in | awk '{print $NF}')
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -b "wordpress_logged_in_=$(echo $LOGIN_COOKIE)" \
"http://localhost:${{ matrix.wp_env_port }}/wp-admin/admin.php?page=sd-ai-agent")
echo "Admin page HTTP status: $STATUS"
echo ""
echo "=== PHP error log (last 30 lines) ==="
pnpm exec wp-env run cli cat /var/www/html/wp-content/debug.log 2>/dev/null | tail -30 || echo "(no error log)"
env:
WP_ENV_HOME: /tmp/wp-env
- name: Configure plugin for E2E tests
run: |
# Mark onboarding complete so the main chat UI renders instead of
# the bootstrap discovery session (Setup Assistant agent).
pnpm exec wp-env run cli wp option update sd_ai_agent_settings \
'{"onboarding_complete":true}' --format=json
# Register the deterministic SDK provider from tests/mu-plugins so
# /providers returns one authenticated provider without installing a
# real ai-provider-for-* plugin. E2E specs mock /stream, so no real
# provider API calls are made.
pnpm exec wp-env run cli wp option update sd_ai_agent_e2e_register_provider 1
# Create a real post so the site is no longer detected as a fresh install
# even after the transient expires (belt-and-suspenders).
pnpm exec wp-env run cli wp post create --post_title='E2E Test Post' \
--post_status=publish --post_type=post
# Create the second admin user required by shared-conversations.spec.js.
# Done here (not in test.beforeAll) so WP_ENV_HOME is available and
# wp-env can locate its docker-compose.yml.
pnpm exec wp-env run cli wp user create admin2 admin2@example.com \
--role=administrator --user_pass=password2 --send-email=false || true
env:
WP_ENV_HOME: /tmp/wp-env
- name: Run Playwright E2E tests (shard ${{ matrix.shard }}/3)
run: pnpm exec playwright test --shard=${{ matrix.shard }}/3
env:
WP_BASE_URL: http://localhost:${{ matrix.wp_env_port }}
WP_ADMIN_USER: admin
WP_ADMIN_PASSWORD: password
CI: true
PLAYWRIGHT_USE_SYSTEM_CHROME: '1'
PLAYWRIGHT_WORKERS: ${{ matrix.playwright_workers }}
- name: Upload Playwright report
uses: actions/upload-artifact@v7
if: always()
with:
# Artifact name includes shard index to avoid name collisions between
# shards of the same WP version.
name: playwright-report-wp${{ matrix.wp }}-shard${{ matrix.shard }}
path: playwright-report/
retention-days: 3
- name: Upload test results
uses: actions/upload-artifact@v7
if: failure()
with:
name: test-results-wp${{ matrix.wp }}-shard${{ matrix.shard }}
path: test-results/
retention-days: 3
- name: Dump PHP error log on failure
if: failure()
run: |
echo "=== PHP debug.log ==="
pnpm exec wp-env run cli cat /var/www/html/wp-content/debug.log 2>/dev/null | tail -100 || echo "(no error log)"
env:
WP_ENV_HOME: /tmp/wp-env
- name: Stop wp-env
if: always()
run: pnpm run wp-env:stop
env:
WP_ENV_HOME: /tmp/wp-env