wordpress-agent-kit 0.3.2 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/blueprint/SKILL.md +418 -0
- package/.agents/skills/wordpress-router/SKILL.md +52 -0
- package/.agents/skills/wordpress-router/references/decision-tree.md +55 -0
- package/.agents/skills/wp-abilities-api/SKILL.md +108 -0
- package/.agents/skills/wp-abilities-api/references/delegate-helper-pattern.md +241 -0
- package/.agents/skills/wp-abilities-api/references/domain-vs-projection.md +113 -0
- package/.agents/skills/wp-abilities-api/references/error-code-vocabulary.md +123 -0
- package/.agents/skills/wp-abilities-api/references/grouping-heuristic.md +89 -0
- package/.agents/skills/wp-abilities-api/references/input-schema-gotchas.md +265 -0
- package/.agents/skills/wp-abilities-api/references/php-registration.md +94 -0
- package/.agents/skills/wp-abilities-api/references/plugin-family-patterns.md +233 -0
- package/.agents/skills/wp-abilities-api/references/rest-api.md +13 -0
- package/.agents/skills/wp-abilities-api/references/shared-core-service.md +184 -0
- package/.agents/skills/wp-abilities-audit/SKILL.md +199 -0
- package/.agents/skills/wp-abilities-audit/references/audit-schema.md +300 -0
- package/.agents/skills/wp-abilities-audit/references/capability-gate-tracing.md +197 -0
- package/.agents/skills/wp-abilities-audit/references/controller-enumeration.md +116 -0
- package/.agents/skills/wp-abilities-verify/SKILL.md +215 -0
- package/.agents/skills/wp-abilities-verify/references/annotation-correctness.md +154 -0
- package/.agents/skills/wp-abilities-verify/references/audit-schema-validation.md +131 -0
- package/.agents/skills/wp-abilities-verify/references/permission-roundtrip.md +190 -0
- package/.agents/skills/wp-abilities-verify/references/runtime-harness.md +462 -0
- package/.agents/skills/wp-abilities-verify/references/schema-lints.md +118 -0
- package/.agents/skills/wp-abilities-verify/references/static-enumeration.md +126 -0
- package/.agents/skills/wp-block-development/SKILL.md +175 -0
- package/.agents/skills/wp-block-development/references/attributes-and-serialization.md +22 -0
- package/.agents/skills/wp-block-development/references/block-json.md +49 -0
- package/.agents/skills/wp-block-development/references/creating-new-blocks.md +46 -0
- package/.agents/skills/wp-block-development/references/debugging.md +36 -0
- package/.agents/skills/wp-block-development/references/deprecations.md +24 -0
- package/.agents/skills/wp-block-development/references/dynamic-rendering.md +23 -0
- package/.agents/skills/wp-block-development/references/inner-blocks.md +25 -0
- package/.agents/skills/wp-block-development/references/registration.md +30 -0
- package/.agents/skills/wp-block-development/references/supports-and-wrappers.md +18 -0
- package/.agents/skills/wp-block-development/references/tooling-and-testing.md +21 -0
- package/.agents/skills/wp-block-development/scripts/list_blocks.mjs +121 -0
- package/.agents/skills/wp-block-themes/SKILL.md +117 -0
- package/.agents/skills/wp-block-themes/references/creating-new-block-theme.md +37 -0
- package/.agents/skills/wp-block-themes/references/debugging.md +24 -0
- package/.agents/skills/wp-block-themes/references/patterns.md +18 -0
- package/.agents/skills/wp-block-themes/references/style-variations.md +14 -0
- package/.agents/skills/wp-block-themes/references/templates-and-parts.md +16 -0
- package/.agents/skills/wp-block-themes/references/theme-json.md +59 -0
- package/.agents/skills/wp-block-themes/scripts/detect_block_themes.mjs +117 -0
- package/.agents/skills/wp-interactivity-api/SKILL.md +180 -0
- package/.agents/skills/wp-interactivity-api/references/debugging.md +29 -0
- package/.agents/skills/wp-interactivity-api/references/directives-quickref.md +30 -0
- package/.agents/skills/wp-interactivity-api/references/server-side-rendering.md +310 -0
- package/.agents/skills/wp-performance/SKILL.md +147 -0
- package/.agents/skills/wp-performance/references/autoload-options.md +24 -0
- package/.agents/skills/wp-performance/references/cron.md +20 -0
- package/.agents/skills/wp-performance/references/database.md +20 -0
- package/.agents/skills/wp-performance/references/http-api.md +15 -0
- package/.agents/skills/wp-performance/references/measurement.md +21 -0
- package/.agents/skills/wp-performance/references/object-cache.md +24 -0
- package/.agents/skills/wp-performance/references/query-monitor-headless.md +38 -0
- package/.agents/skills/wp-performance/references/server-timing.md +22 -0
- package/.agents/skills/wp-performance/references/wp-cli-doctor.md +24 -0
- package/.agents/skills/wp-performance/references/wp-cli-profile.md +32 -0
- package/.agents/skills/wp-performance/scripts/perf_inspect.mjs +128 -0
- package/.agents/skills/wp-phpstan/SKILL.md +98 -0
- package/.agents/skills/wp-phpstan/references/configuration.md +52 -0
- package/.agents/skills/wp-phpstan/references/third-party-classes.md +76 -0
- package/.agents/skills/wp-phpstan/references/wordpress-annotations.md +124 -0
- package/.agents/skills/wp-phpstan/scripts/phpstan_inspect.mjs +263 -0
- package/.agents/skills/wp-playground/SKILL.md +233 -0
- package/.agents/skills/wp-playground/references/blueprints.md +36 -0
- package/.agents/skills/wp-playground/references/cli-commands.md +39 -0
- package/.agents/skills/wp-playground/references/debugging.md +16 -0
- package/.agents/skills/wp-playground/references/e2e-playwright.md +115 -0
- package/.agents/skills/wp-plugin-development/SKILL.md +113 -0
- package/.agents/skills/wp-plugin-development/references/data-and-cron.md +19 -0
- package/.agents/skills/wp-plugin-development/references/debugging.md +19 -0
- package/.agents/skills/wp-plugin-development/references/lifecycle.md +33 -0
- package/.agents/skills/wp-plugin-development/references/security.md +29 -0
- package/.agents/skills/wp-plugin-development/references/settings-api.md +22 -0
- package/.agents/skills/wp-plugin-development/references/structure.md +16 -0
- package/.agents/skills/wp-plugin-development/scripts/detect_plugins.mjs +122 -0
- package/.agents/skills/wp-plugin-directory-guidelines/SKILL.md +133 -0
- package/.agents/skills/wp-plugin-directory-guidelines/references/gpl-compliance.md +217 -0
- package/.agents/skills/wp-plugin-directory-guidelines/references/guideline-review-checklist.md +592 -0
- package/.agents/skills/wp-plugin-directory-guidelines/references/naming-rules.md +121 -0
- package/.agents/skills/wp-project-triage/SKILL.md +39 -0
- package/.agents/skills/wp-project-triage/references/triage.schema.json +143 -0
- package/.agents/skills/wp-project-triage/scripts/detect_wp_project.mjs +610 -0
- package/.agents/skills/wp-rest-api/SKILL.md +115 -0
- package/.agents/skills/wp-rest-api/references/authentication.md +18 -0
- package/.agents/skills/wp-rest-api/references/custom-content-types.md +20 -0
- package/.agents/skills/wp-rest-api/references/discovery-and-params.md +20 -0
- package/.agents/skills/wp-rest-api/references/responses-and-fields.md +30 -0
- package/.agents/skills/wp-rest-api/references/routes-and-endpoints.md +36 -0
- package/.agents/skills/wp-rest-api/references/schema.md +22 -0
- package/.agents/skills/wp-wpcli-and-ops/SKILL.md +126 -0
- package/.agents/skills/wp-wpcli-and-ops/references/automation.md +30 -0
- package/.agents/skills/wp-wpcli-and-ops/references/cron-and-cache.md +23 -0
- package/.agents/skills/wp-wpcli-and-ops/references/debugging.md +17 -0
- package/.agents/skills/wp-wpcli-and-ops/references/multisite.md +22 -0
- package/.agents/skills/wp-wpcli-and-ops/references/packages-and-updates.md +22 -0
- package/.agents/skills/wp-wpcli-and-ops/references/safety.md +30 -0
- package/.agents/skills/wp-wpcli-and-ops/references/search-replace.md +40 -0
- package/.agents/skills/wp-wpcli-and-ops/scripts/wpcli_inspect.mjs +90 -0
- package/.agents/skills/wp-wpengine/SKILL.md +398 -0
- package/.agents/skills/wp-wpengine/references/ci-gate.md +469 -0
- package/.agents/skills/wp-wpengine/references/github-actions-deploy.md +736 -0
- package/.agents/skills/wp-wpengine/scripts/ci-gate.sh +118 -0
- package/.agents/skills/wp-wpengine/scripts/wpe-check.sh +89 -0
- package/.agents/skills/wp-wpengine/scripts/wpe-preflight.sh +104 -0
- package/.agents/skills/wpds/SKILL.md +59 -0
- package/.github/agents/wp-architect.agent.md +1 -2
- package/.github/copilot-instructions.md +1 -1
- package/.github/instructions/wordpress-workflow.instructions.md +3 -3
- package/.github/skills/wp-playground/SKILL.md +132 -1
- package/.github/skills/wp-playground/references/e2e-playwright.md +115 -0
- package/.github/skills/wp-wpengine/SKILL.md +127 -0
- package/AGENTS.md +22 -10
- package/AGENTS.template.md +20 -10
- package/README.md +93 -86
- package/dist/cli.js +5 -1
- package/dist/commands/clean-skills.js +64 -0
- package/dist/commands/setup.js +6 -2
- package/dist/commands/sync-skills.js +3 -0
- package/dist/lib/api.js +176 -4
- package/dist/lib/installer.js +166 -2
- package/extensions/wp-agent-kit/index.ts +185 -10
- package/package.json +10 -14
- package/skills-custom/wp-wpengine/SKILL.md +398 -0
- package/skills-custom/wp-wpengine/references/ci-gate.md +469 -0
- package/skills-custom/wp-wpengine/references/github-actions-deploy.md +736 -0
- package/skills-custom/wp-wpengine/scripts/ci-gate.sh +118 -0
- package/skills-custom/wp-wpengine/scripts/wpe-check.sh +89 -0
- package/skills-custom/wp-wpengine/scripts/wpe-preflight.sh +104 -0
- package/.github/workflows/ci.yml +0 -44
- package/.husky/pre-commit +0 -7
- package/CLI_REVIEW.md +0 -250
- package/biome.json +0 -39
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# ci-gate.sh — run the full CI gate locally before pushing.
|
|
3
|
+
#
|
|
4
|
+
# Mirrors what GitHub Actions ci-gate.yml runs. Use this before any push
|
|
5
|
+
# to a branch that triggers a WP Engine deploy.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash scripts/ci-gate.sh # run both gates
|
|
9
|
+
# bash scripts/ci-gate.sh --php-only # PHP gate only
|
|
10
|
+
# bash scripts/ci-gate.sh --js-only # JS/TS gate only
|
|
11
|
+
#
|
|
12
|
+
# Exit code: 0 = all passed, 1 = at least one check failed.
|
|
13
|
+
|
|
14
|
+
set -uo pipefail
|
|
15
|
+
root="$(git rev-parse --show-toplevel)"
|
|
16
|
+
cd "$root"
|
|
17
|
+
|
|
18
|
+
PHP_ONLY=false
|
|
19
|
+
JS_ONLY=false
|
|
20
|
+
for arg in "$@"; do
|
|
21
|
+
[[ "$arg" == "--php-only" ]] && PHP_ONLY=true
|
|
22
|
+
[[ "$arg" == "--js-only" ]] && JS_ONLY=true
|
|
23
|
+
done
|
|
24
|
+
|
|
25
|
+
PASS=0
|
|
26
|
+
FAIL=0
|
|
27
|
+
|
|
28
|
+
run() {
|
|
29
|
+
local label="$1"; shift
|
|
30
|
+
echo "▶ $label"
|
|
31
|
+
if "$@" 2>&1; then
|
|
32
|
+
echo " ✓ $label"
|
|
33
|
+
((PASS++))
|
|
34
|
+
else
|
|
35
|
+
echo " ✗ FAILED: $label"
|
|
36
|
+
((FAIL++))
|
|
37
|
+
return 1
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# ── PHP gate ──────────────────────────────────────────────────────────────────
|
|
42
|
+
if ! $JS_ONLY; then
|
|
43
|
+
echo ""
|
|
44
|
+
echo "── PHP gate ──────────────────────────────────────────────────────────"
|
|
45
|
+
if command -v composer >/dev/null 2>&1 && [ -f composer.json ]; then
|
|
46
|
+
if [ ! -d vendor ]; then
|
|
47
|
+
echo "▶ composer install"
|
|
48
|
+
composer install --no-interaction --quiet
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
run "php -l (all tracked PHP files)" \
|
|
52
|
+
bash -c 'git ls-files "*.php" | xargs -P4 php -l > /dev/null'
|
|
53
|
+
|
|
54
|
+
if [ -x vendor/bin/phpcs ]; then
|
|
55
|
+
run "phpcs (WordPress coding standards)" composer run phpcs
|
|
56
|
+
else
|
|
57
|
+
echo " ⚠ phpcs not found — run: composer install"
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
if [ -x vendor/bin/phpstan ]; then
|
|
61
|
+
run "phpstan (static analysis)" composer run phpstan
|
|
62
|
+
else
|
|
63
|
+
echo " ⚠ phpstan not found — run: composer install"
|
|
64
|
+
fi
|
|
65
|
+
else
|
|
66
|
+
echo " ⚠ composer not available or no composer.json — skipping PHP gate"
|
|
67
|
+
fi
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# ── JS/TS gate ────────────────────────────────────────────────────────────────
|
|
71
|
+
if ! $PHP_ONLY; then
|
|
72
|
+
echo ""
|
|
73
|
+
echo "── JS/TS gate ────────────────────────────────────────────────────────"
|
|
74
|
+
if [ -f package.json ]; then
|
|
75
|
+
if [ ! -d node_modules ]; then
|
|
76
|
+
echo "▶ npm install"
|
|
77
|
+
npm install --silent
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if [ -x node_modules/.bin/biome ]; then
|
|
81
|
+
run "biome check (lint + format)" npx biome check .
|
|
82
|
+
else
|
|
83
|
+
echo " ⚠ biome not installed — run: npm install"
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if npm run typecheck --if-present 2>/dev/null; then
|
|
87
|
+
((PASS++))
|
|
88
|
+
elif command -v tsc >/dev/null 2>&1 || [ -x node_modules/.bin/tsc ]; then
|
|
89
|
+
run "tsc --noEmit (type check)" npx tsc --noEmit
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if npm run test --if-present 2>/dev/null; then
|
|
93
|
+
((PASS++))
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
if npm run build --if-present 2>/dev/null; then
|
|
97
|
+
((PASS++))
|
|
98
|
+
fi
|
|
99
|
+
else
|
|
100
|
+
echo " ⚠ No package.json — skipping JS/TS gate"
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# ── Summary ───────────────────────────────────────────────────────────────────
|
|
105
|
+
echo ""
|
|
106
|
+
echo "── CI Gate Result ────────────────────────────────────────────────────"
|
|
107
|
+
echo " Passed : $PASS"
|
|
108
|
+
echo " Failed : $FAIL"
|
|
109
|
+
echo ""
|
|
110
|
+
|
|
111
|
+
if [[ "$FAIL" -eq 0 ]]; then
|
|
112
|
+
echo "✅ Gate green — safe to push."
|
|
113
|
+
exit 0
|
|
114
|
+
else
|
|
115
|
+
echo "❌ Gate failed — fix the issues above before pushing."
|
|
116
|
+
echo " --no-verify is not a valid workaround; CI will catch the same failures."
|
|
117
|
+
exit 1
|
|
118
|
+
fi
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# wpe-check.sh — verify SSH connectivity to all configured WP Engine environments.
|
|
3
|
+
#
|
|
4
|
+
# Reads installs from wp-cli.yml @aliases (ssh: field) or from WPE_INSTALLS env var.
|
|
5
|
+
# Useful after first-time machine setup or when debugging SSH issues.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# bash scripts/wpe-check.sh
|
|
9
|
+
# WPE_INSTALLS="mysite mysitestg mysitedev" bash scripts/wpe-check.sh
|
|
10
|
+
#
|
|
11
|
+
# Exit code: 0 = all connected, 1 = at least one failed.
|
|
12
|
+
|
|
13
|
+
set -uo pipefail
|
|
14
|
+
root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
15
|
+
cd "$root"
|
|
16
|
+
|
|
17
|
+
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=8 -o StrictHostKeyChecking=accept-new"
|
|
18
|
+
|
|
19
|
+
# ── Discover installs from wp-cli.yml @aliases ────────────────────────────────
|
|
20
|
+
declare -A ALIAS_MAP # install → alias label
|
|
21
|
+
CURRENT_ALIAS=""
|
|
22
|
+
|
|
23
|
+
if [ -f wp-cli.yml ]; then
|
|
24
|
+
while IFS= read -r line; do
|
|
25
|
+
if [[ "$line" =~ ^@([a-zA-Z0-9_-]+): ]]; then
|
|
26
|
+
CURRENT_ALIAS="${BASH_REMATCH[1]}"
|
|
27
|
+
elif [[ "$line" =~ ^[[:space:]]+ssh:[[:space:]]+([^@[:space:]]+)@[^[:space:]]+ && -n "$CURRENT_ALIAS" ]]; then
|
|
28
|
+
INSTALL="${BASH_REMATCH[1]}"
|
|
29
|
+
ALIAS_MAP["$INSTALL"]="@${CURRENT_ALIAS}"
|
|
30
|
+
CURRENT_ALIAS=""
|
|
31
|
+
fi
|
|
32
|
+
done < wp-cli.yml
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Fallback: WPE_INSTALLS env var
|
|
36
|
+
if [ "${#ALIAS_MAP[@]}" -eq 0 ] && [ -n "${WPE_INSTALLS:-}" ]; then
|
|
37
|
+
for slug in $WPE_INSTALLS; do
|
|
38
|
+
ALIAS_MAP["$slug"]="$slug"
|
|
39
|
+
done
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
if [ "${#ALIAS_MAP[@]}" -eq 0 ]; then
|
|
43
|
+
echo "No WP Engine installs found."
|
|
44
|
+
echo ""
|
|
45
|
+
echo "Options:"
|
|
46
|
+
echo " 1. Add @aliases with 'ssh: <install>@<install>.ssh.wpengine.net' to wp-cli.yml"
|
|
47
|
+
echo " 2. Set WPE_INSTALLS='slug1 slug2 slug3' environment variable"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
echo ""
|
|
52
|
+
echo "── WP Engine SSH connectivity ────────────────────────────────────────"
|
|
53
|
+
printf " %-25s %-15s %-12s %s\n" "Install" "Alias" "Status" "WP version"
|
|
54
|
+
echo " ─────────────────────────────────────────────────────────────────"
|
|
55
|
+
|
|
56
|
+
PASS=0
|
|
57
|
+
FAIL=0
|
|
58
|
+
|
|
59
|
+
for INSTALL in "${!ALIAS_MAP[@]}"; do
|
|
60
|
+
ALIAS="${ALIAS_MAP[$INSTALL]}"
|
|
61
|
+
SSH_HOST="${INSTALL}.ssh.wpengine.net"
|
|
62
|
+
|
|
63
|
+
WP_VERSION=$(ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" \
|
|
64
|
+
wp core version --skip-plugins --skip-themes 2>/dev/null || echo "")
|
|
65
|
+
|
|
66
|
+
if [ -n "$WP_VERSION" ]; then
|
|
67
|
+
printf " %-25s %-15s %-12s %s\n" "$INSTALL" "$ALIAS" "✓ connected" "$WP_VERSION"
|
|
68
|
+
((PASS++))
|
|
69
|
+
else
|
|
70
|
+
printf " %-25s %-15s %-12s %s\n" "$INSTALL" "$ALIAS" "✗ FAILED" "—"
|
|
71
|
+
((FAIL++))
|
|
72
|
+
fi
|
|
73
|
+
done
|
|
74
|
+
|
|
75
|
+
echo ""
|
|
76
|
+
echo " $PASS connected | $FAIL failed"
|
|
77
|
+
|
|
78
|
+
if [[ "$FAIL" -gt 0 ]]; then
|
|
79
|
+
echo ""
|
|
80
|
+
echo "Troubleshooting:"
|
|
81
|
+
echo " • Confirm key exists: ls -la ~/.ssh/wpengine_ed25519"
|
|
82
|
+
echo " • Confirm permissions: chmod 600 ~/.ssh/wpengine_ed25519"
|
|
83
|
+
echo " • Trust the host: ssh-keyscan -H ssh.wpengine.net >> ~/.ssh/known_hosts"
|
|
84
|
+
echo " • Check portal: https://my.wpengine.com/ssh_keys"
|
|
85
|
+
echo " • Verify git access: ssh git@git.wpengine.com info"
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
echo ""
|
|
89
|
+
[[ "$FAIL" -eq 0 ]] && exit 0 || exit 1
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# wpe-preflight.sh — pre-deploy sanity checks for a WP Engine environment.
|
|
3
|
+
#
|
|
4
|
+
# Verifies SSH access, WP-CLI, site URL consistency, HTTP health, and
|
|
5
|
+
# active plugin count before any deploy touches production or staging.
|
|
6
|
+
#
|
|
7
|
+
# Usage:
|
|
8
|
+
# INSTALL=mysite bash scripts/wpe-preflight.sh [staging|production]
|
|
9
|
+
# WPE_INSTALL=mysite bash scripts/wpe-preflight.sh production
|
|
10
|
+
#
|
|
11
|
+
# Exit code: 0 = all checks passed (safe to deploy), 1 = at least one failed.
|
|
12
|
+
|
|
13
|
+
set -uo pipefail
|
|
14
|
+
|
|
15
|
+
ENV="${1:-production}"
|
|
16
|
+
INSTALL="${WPE_INSTALL:-${INSTALL:-}}"
|
|
17
|
+
|
|
18
|
+
if [ -z "$INSTALL" ]; then
|
|
19
|
+
echo "❌ Usage: INSTALL=<slug> bash scripts/wpe-preflight.sh [staging|production]"
|
|
20
|
+
echo " The install slug is the WP Engine environment name (e.g., 'mysite', 'mysitestg')."
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
SSH_HOST="${INSTALL}.ssh.wpengine.net"
|
|
25
|
+
SSH_OPTS="-o BatchMode=yes -o ConnectTimeout=15 -o StrictHostKeyChecking=accept-new"
|
|
26
|
+
WP="ssh $SSH_OPTS ${INSTALL}@${SSH_HOST} wp"
|
|
27
|
+
|
|
28
|
+
PASS=0
|
|
29
|
+
FAIL=0
|
|
30
|
+
|
|
31
|
+
check() {
|
|
32
|
+
local label="$1"; shift
|
|
33
|
+
printf " %-50s" "$label"
|
|
34
|
+
local output
|
|
35
|
+
if output=$("$@" 2>&1); then
|
|
36
|
+
echo "✓ $output"
|
|
37
|
+
((PASS++))
|
|
38
|
+
else
|
|
39
|
+
echo "✗ FAILED"
|
|
40
|
+
echo " $output" >&2
|
|
41
|
+
((FAIL++))
|
|
42
|
+
fi
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
echo ""
|
|
46
|
+
echo "── WP Engine preflight: ${INSTALL} (${ENV}) ─────────────────────"
|
|
47
|
+
echo ""
|
|
48
|
+
|
|
49
|
+
# ── SSH ───────────────────────────────────────────────────────────────────────
|
|
50
|
+
echo "SSH"
|
|
51
|
+
check "SSH gateway reachable" \
|
|
52
|
+
ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" echo "connected"
|
|
53
|
+
|
|
54
|
+
check "WP-CLI available" \
|
|
55
|
+
$WP --info --skip-plugins --skip-themes
|
|
56
|
+
|
|
57
|
+
# ── WordPress ─────────────────────────────────────────────────────────────────
|
|
58
|
+
echo ""
|
|
59
|
+
echo "WordPress"
|
|
60
|
+
check "WP core version" \
|
|
61
|
+
$WP core version --skip-plugins --skip-themes
|
|
62
|
+
|
|
63
|
+
check "siteurl option readable" \
|
|
64
|
+
$WP option get siteurl --skip-plugins --skip-themes
|
|
65
|
+
|
|
66
|
+
check "Active plugins present (count > 0)" \
|
|
67
|
+
bash -c "COUNT=\$(${WP} plugin list --status=active --format=count --skip-plugins --skip-themes 2>&1); echo \"\$COUNT active\"; [[ \"\$COUNT\" -gt 0 ]]"
|
|
68
|
+
|
|
69
|
+
check "No pending DB upgrades" \
|
|
70
|
+
$WP core update-db --dry-run --skip-plugins --skip-themes
|
|
71
|
+
|
|
72
|
+
# ── HTTP health ───────────────────────────────────────────────────────────────
|
|
73
|
+
echo ""
|
|
74
|
+
echo "HTTP health"
|
|
75
|
+
SITE_URL=$(ssh $SSH_OPTS "${INSTALL}@${SSH_HOST}" \
|
|
76
|
+
wp option get home --skip-plugins --skip-themes 2>/dev/null || echo "")
|
|
77
|
+
|
|
78
|
+
if [ -n "$SITE_URL" ]; then
|
|
79
|
+
check "Homepage returns 2xx/3xx" \
|
|
80
|
+
bash -c "STATUS=\$(curl -s -o /dev/null -w '%{http_code}' -L --max-time 15 '${SITE_URL}'); echo \"HTTP \$STATUS\"; [[ \"\$STATUS\" -ge 200 && \"\$STATUS\" -lt 400 ]]"
|
|
81
|
+
|
|
82
|
+
check "No PHP errors in homepage body" \
|
|
83
|
+
bash -c "BODY=\$(curl -sL --max-time 15 '${SITE_URL}'); echo \"\${#BODY} chars\"; ! echo \"\$BODY\" | grep -qi 'fatal error\|parse error\|warning: '"
|
|
84
|
+
|
|
85
|
+
check "wp-json REST API responds" \
|
|
86
|
+
bash -c "STATUS=\$(curl -s -o /dev/null -w '%{http_code}' --max-time 10 '${SITE_URL}/wp-json/wp/v2/'); echo \"HTTP \$STATUS\"; [[ \"\$STATUS\" -ge 200 && \"\$STATUS\" -lt 400 ]]"
|
|
87
|
+
else
|
|
88
|
+
echo " ⚠ Could not retrieve site URL — skipping HTTP checks"
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# ── Result ────────────────────────────────────────────────────────────────────
|
|
92
|
+
echo ""
|
|
93
|
+
echo "── Preflight result ──────────────────────────────────────────────────"
|
|
94
|
+
echo " Passed : $PASS"
|
|
95
|
+
echo " Failed : $FAIL"
|
|
96
|
+
echo ""
|
|
97
|
+
|
|
98
|
+
if [[ "$FAIL" -eq 0 ]]; then
|
|
99
|
+
echo "✅ All checks passed — safe to deploy to ${ENV}."
|
|
100
|
+
exit 0
|
|
101
|
+
else
|
|
102
|
+
echo "❌ Preflight failed — resolve the issues above before deploying to ${ENV}."
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wpds
|
|
3
|
+
description: "Use when building UIs leveraging the WordPress Design System (WPDS) and its components, tokens, patterns, etc."
|
|
4
|
+
license: GPL-2.0-or-later
|
|
5
|
+
compatibility: "Requires WPDS MCP server configured and running. Targets WordPress 6.9+ (PHP 7.2.24+)."
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# WordPress Design System (WPDS)
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
This skill works best with the **WPDS MCP server** installed. The MCP provides access to WordPress Design System documentation and resources, such as components and DS token lists.
|
|
13
|
+
|
|
14
|
+
The following terms should be treated as synonyms:
|
|
15
|
+
- "WordPress" and "WP";
|
|
16
|
+
- "Design System" and "DS";
|
|
17
|
+
- "WordPress Design System" and "WPDS".
|
|
18
|
+
|
|
19
|
+
## When to use
|
|
20
|
+
|
|
21
|
+
Use this skill when the user mentions:
|
|
22
|
+
|
|
23
|
+
- building and/or reviewing any UI in a WordPress-related context (for example, Gutenberg, WooCommerce, WordPress.com, Jetpack, etc etc);
|
|
24
|
+
- WordPress Design System, WPDS, Design System;
|
|
25
|
+
- UI components, Design tokens, color primitives, spacing scales, typography variables and presets;
|
|
26
|
+
- Specific component packages such as @wordpress/components or @wordpress/ui;
|
|
27
|
+
|
|
28
|
+
## Rules
|
|
29
|
+
|
|
30
|
+
### Use the WPDS MCP server to access WPDS-related documentation
|
|
31
|
+
|
|
32
|
+
- Use the WPDS MCP server to retrieve the canonical, authoritative documentation:
|
|
33
|
+
- reference site (`wpds://pages`)
|
|
34
|
+
- list of available components (`wpds://components`) and specific component information (`wpds://components/:name`)
|
|
35
|
+
- list of available tokens (`wpds://design-tokens`)
|
|
36
|
+
- DO NOT search the web for canonical documentation about the WordPress Design System. If asked by the user, push back and ask for confirmation, warning them that the MCP server is the best place to provide information
|
|
37
|
+
|
|
38
|
+
### Required documentation
|
|
39
|
+
|
|
40
|
+
Before working on any WPDS-related tasks, make sure you read relevant documentation on the reference site. This documentation should take the absolute precedence when evaluating the best course of action for any given tasks.
|
|
41
|
+
|
|
42
|
+
### Boundaries
|
|
43
|
+
|
|
44
|
+
- Skip non-UI related aspects of an answer (for example, fetching data from stores, or localizing strings of text).
|
|
45
|
+
- Focus on building UI that adheres as much as possible to the WPDS best practices, uses the most fitting WPDS components/tokens/patterns.
|
|
46
|
+
|
|
47
|
+
### Tech stack
|
|
48
|
+
|
|
49
|
+
- Unless you are told otherwise (or gathered specific information from the local context of the request), assume the following tech stack: TypeScript, React, CSS.
|
|
50
|
+
|
|
51
|
+
### Validation
|
|
52
|
+
|
|
53
|
+
- If the local context in which a task is running provide lint scripts, use them to validate the proposed code output when possible.
|
|
54
|
+
|
|
55
|
+
## Output
|
|
56
|
+
|
|
57
|
+
- As a recap at the end of your response, provide a clear and concise explanation of what the solution does, and add context to why each decision was made.
|
|
58
|
+
- Be explicit about the boundaries, ie. what was explicitly left out of the task because not relevant (eg non-ui related).
|
|
59
|
+
- Provide working code snippets
|
|
@@ -14,8 +14,7 @@ When a task is assigned, you must retrieve information in this sequence:
|
|
|
14
14
|
|
|
15
15
|
1. **Local Project Instructions**: Read `.github/instructions/wordpress-workflow.instructions.md` to understand the specific prefix, folder structure, and dev workflow for this repo.
|
|
16
16
|
|
|
17
|
-
2. **Agent Skills**: Consult the `.
|
|
18
|
-
|
|
17
|
+
2. **Agent Skills**: Consult the `.agents/skills/` directory.
|
|
19
18
|
- Reference `wp-project-triage` to confirm if you are in a Plugin or Theme context.
|
|
20
19
|
- Reference `wp-block-development` for any Gutenberg/React tasks.
|
|
21
20
|
- Reference `wp-playground` to provide testable blueprints for your code.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
@workspace /AGENTS.md
|
|
2
|
-
@workspace / .github/instructions/wordpress-workflow.instructions.md
|
|
2
|
+
@workspace / .github/instructions/wordpress-workflow.instructions.md
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
\# WordPress Agent Skills Workflow
|
|
2
2
|
|
|
3
|
-
This repo uses a local, filesystem-based set of WordPress agent skills under `.
|
|
3
|
+
This repo uses a local, filesystem-based set of WordPress agent skills under `.agents/skills/`. Follow these procedures for every interaction.
|
|
4
4
|
|
|
5
5
|
\## 1. Skill Discovery & Activation
|
|
6
6
|
|
|
7
|
-
\- \*\*Always start by scanning \`.
|
|
7
|
+
\- \*\*Always start by scanning \`.agents/skills/\`\*\* to see which specialized modules are active.
|
|
8
8
|
|
|
9
9
|
\- If the user asks for a Block, explicitly activate the \`wp-block-development\` skill.
|
|
10
10
|
|
|
@@ -38,4 +38,4 @@ Before finalizing a response:
|
|
|
38
38
|
|
|
39
39
|
2\. Check if a [WordPress.org Plugin Handbook]\(https://developer.wordpress.org) rule supersedes a generic community pattern.
|
|
40
40
|
|
|
41
|
-
3\. State which skill was used (e.g., \*"Applied patterns from wp-block-development"\*).
|
|
41
|
+
3\. State which skill was used (e.g., \*"Applied patterns from wp-block-development"\*).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: wp-playground
|
|
3
|
-
description: "Use for WordPress Playground workflows: fast disposable WP instances in the browser or locally via @wp-playground/cli (server, run-blueprint, build-snapshot), auto-mounting plugins/themes, switching WP/PHP versions, blueprints, and debugging (Xdebug)."
|
|
3
|
+
description: "Use for WordPress Playground workflows: fast disposable WP instances in the browser or locally via @wp-playground/cli (server, run-blueprint, build-snapshot), auto-mounting plugins/themes, switching WP/PHP versions, blueprints, PHPUnit testing, E2E Playwright testing, programmatic runCLI API, and debugging (Xdebug)."
|
|
4
4
|
license: GPL-2.0-or-later
|
|
5
5
|
compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Playground CLI requires Node.js 20.18+; runs WP in WebAssembly with SQLite."
|
|
6
6
|
---
|
|
@@ -14,6 +14,9 @@ compatibility: "Targets WordPress 6.9+ (PHP 7.2.24+). Playground CLI requires No
|
|
|
14
14
|
- Build a reproducible snapshot of a site for sharing or CI.
|
|
15
15
|
- Switch WP/PHP versions quickly to reproduce issues.
|
|
16
16
|
- Debug plugin/theme code with Xdebug in an isolated Playground.
|
|
17
|
+
- Run PHPUnit tests without a local database (no Docker, no MySQL).
|
|
18
|
+
- Write E2E Playwright tests against a real WordPress instance.
|
|
19
|
+
- Automate Playground in CI/CD pipelines via the programmatic `runCLI` API.
|
|
17
20
|
|
|
18
21
|
## Inputs required
|
|
19
22
|
|
|
@@ -82,6 +85,134 @@ npx @wp-playground/cli@latest build-snapshot --blueprint=<file> --outfile=./site
|
|
|
82
85
|
- Query: `https://playground.wordpress.net/?blueprint-url=<public-url-or-zip>`
|
|
83
86
|
- Use the live Blueprint Editor (playground.wordpress.net) to author blueprints with schema help; paste JSON and copy a shareable link.
|
|
84
87
|
|
|
88
|
+
### 8) PHPUnit testing (no database required)
|
|
89
|
+
|
|
90
|
+
Run PHPUnit inside Playground — every run starts with a clean WordPress install, fully isolated.
|
|
91
|
+
|
|
92
|
+
Plugin:
|
|
93
|
+
```bash
|
|
94
|
+
npx @wp-playground/cli@latest php \
|
|
95
|
+
--auto-mount \
|
|
96
|
+
-- \
|
|
97
|
+
/wordpress/wp-content/plugins/MY_PLUGIN/vendor/bin/phpunit \
|
|
98
|
+
-c /wordpress/wp-content/plugins/MY_PLUGIN/phpunit.xml.dist
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Theme (replace `plugins/` with `themes/`):
|
|
102
|
+
```bash
|
|
103
|
+
npx @wp-playground/cli@latest php \
|
|
104
|
+
--auto-mount \
|
|
105
|
+
-- \
|
|
106
|
+
/wordpress/wp-content/themes/MY_THEME/vendor/bin/phpunit \
|
|
107
|
+
-c /wordpress/wp-content/themes/MY_THEME/phpunit.xml.dist
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- Requires PHPUnit installed via Composer in the project (`composer require --dev phpunit/phpunit`).
|
|
111
|
+
- `--auto-mount` maps the current directory to the correct WP content path automatically.
|
|
112
|
+
- Use `--php=8.1 --wp=6.5` flags to test against specific versions (PHP 7.4–8.5 supported).
|
|
113
|
+
- Explicit mount: `--mount=.:/wordpress/wp-content/plugins/MY_PLUGIN`.
|
|
114
|
+
|
|
115
|
+
### 9) E2E testing with Playwright
|
|
116
|
+
|
|
117
|
+
Use `runCLI` from `@wp-playground/cli` to start a Playground server programmatically in Playwright tests. No Docker, no database.
|
|
118
|
+
|
|
119
|
+
Install:
|
|
120
|
+
```bash
|
|
121
|
+
npm install --save-dev @playwright/test @wp-playground/cli
|
|
122
|
+
npx playwright install chromium
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Minimal `playwright.config.ts`:
|
|
126
|
+
```ts
|
|
127
|
+
import { defineConfig } from '@playwright/test';
|
|
128
|
+
export default defineConfig({
|
|
129
|
+
testDir: './tests/e2e',
|
|
130
|
+
fullyParallel: false,
|
|
131
|
+
workers: 1, // prevent port conflicts
|
|
132
|
+
timeout: 120_000, // WP boot takes time
|
|
133
|
+
expect: { timeout: 30_000 },
|
|
134
|
+
use: { screenshot: 'only-on-failure', trace: 'on-first-retry' },
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
First test (`tests/e2e/plugin.spec.ts`):
|
|
139
|
+
```ts
|
|
140
|
+
import { test, expect } from '@playwright/test';
|
|
141
|
+
import { runCLI } from '@wp-playground/cli';
|
|
142
|
+
|
|
143
|
+
let cli: Awaited<ReturnType<typeof runCLI>>;
|
|
144
|
+
|
|
145
|
+
test.beforeAll(async () => {
|
|
146
|
+
cli = await runCLI({
|
|
147
|
+
command: 'server',
|
|
148
|
+
blueprint: {
|
|
149
|
+
preferredVersions: { php: '8.3', wp: 'latest' },
|
|
150
|
+
login: true,
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
test.afterAll(async () => { await cli?.server?.close(); });
|
|
156
|
+
|
|
157
|
+
test('dashboard loads', async ({ page }) => {
|
|
158
|
+
await page.goto(`${cli.serverUrl}/wp-admin/`);
|
|
159
|
+
await expect(page.locator('#wpbody-content')).toBeVisible();
|
|
160
|
+
});
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Mount a local plugin:
|
|
164
|
+
```ts
|
|
165
|
+
cli = await runCLI({
|
|
166
|
+
command: 'server',
|
|
167
|
+
mount: { './': '/wordpress/wp-content/plugins/my-plugin' },
|
|
168
|
+
blueprint: {
|
|
169
|
+
preferredVersions: { php: '8.3', wp: 'latest' },
|
|
170
|
+
login: true,
|
|
171
|
+
steps: [{ step: 'activatePlugin', pluginPath: 'my-plugin/my-plugin.php' }],
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Locator priority (most to least preferred):
|
|
177
|
+
1. `page.getByRole()` — buttons, headings, links, inputs
|
|
178
|
+
2. `page.getByLabel()` — labeled form fields
|
|
179
|
+
3. `page.getByText()` — visible text
|
|
180
|
+
4. `page.getByTestId()` — your own `data-testid` attributes
|
|
181
|
+
5. `page.locator()` — CSS/XPath last resort (WP core layout elements like `#wpadminbar`)
|
|
182
|
+
|
|
183
|
+
Version matrix pattern:
|
|
184
|
+
```ts
|
|
185
|
+
const matrix = [{ php: '8.1', wp: '6.5' }, { php: '8.3', wp: 'latest' }];
|
|
186
|
+
for (const { php, wp } of matrix) {
|
|
187
|
+
test.describe(`PHP ${php} + WP ${wp}`, () => {
|
|
188
|
+
// ... beforeAll/afterAll with those versions
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
CI (GitHub Actions): see `references/e2e-playwright.md`.
|
|
194
|
+
|
|
195
|
+
### 10) Programmatic `runCLI` API (scripts / Vitest integration)
|
|
196
|
+
|
|
197
|
+
```ts
|
|
198
|
+
import { runCLI } from '@wp-playground/cli';
|
|
199
|
+
|
|
200
|
+
const server = await runCLI({
|
|
201
|
+
command: 'server',
|
|
202
|
+
php: '8.3',
|
|
203
|
+
wp: 'latest',
|
|
204
|
+
login: true,
|
|
205
|
+
mount: [{ hostPath: './my-plugin', vfsPath: '/wordpress/wp-content/plugins/my-plugin' }],
|
|
206
|
+
blueprint: { steps: [{ step: 'activatePlugin', pluginPath: 'my-plugin/plugin.php' }] },
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// server.serverUrl — the base URL
|
|
210
|
+
// server.server — the HTTP server instance (call .close() in afterEach)
|
|
211
|
+
// server[Symbol.asyncDispose]() — cleanup in Vitest afterEach
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Use `wordpressInstallMode: 'do-not-attempt-installing'` + `skipSqliteSetup: true` when testing pure PHP with no WordPress overhead.
|
|
215
|
+
|
|
85
216
|
## Verification
|
|
86
217
|
|
|
87
218
|
- Verify mounted code is active (plugin listed/active; theme selected).
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# E2E Testing with Playwright + WordPress Playground
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install --save-dev @playwright/test @wp-playground/cli
|
|
7
|
+
npx playwright install chromium
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## playwright.config.ts
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
import { defineConfig } from '@playwright/test';
|
|
14
|
+
export default defineConfig({
|
|
15
|
+
testDir: './tests/e2e',
|
|
16
|
+
fullyParallel: false,
|
|
17
|
+
forbidOnly: !!process.env.CI,
|
|
18
|
+
retries: process.env.CI ? 2 : 0,
|
|
19
|
+
workers: 1,
|
|
20
|
+
reporter: 'html',
|
|
21
|
+
timeout: 120_000,
|
|
22
|
+
expect: { timeout: 30_000 },
|
|
23
|
+
use: { screenshot: 'only-on-failure', trace: 'on-first-retry' },
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Server lifecycle
|
|
28
|
+
|
|
29
|
+
**Shared** (faster, tests can affect each other — use for read-only tests):
|
|
30
|
+
```ts
|
|
31
|
+
test.beforeAll(async () => { cli = await runCLI({ command: 'server', blueprint }); });
|
|
32
|
+
test.afterAll(async () => { await cli?.server?.close(); });
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Per-test** (isolated, slower — use when tests modify state):
|
|
36
|
+
```ts
|
|
37
|
+
test.beforeEach(async () => { cli = await runCLI({ command: 'server', blueprint }); });
|
|
38
|
+
test.afterEach(async () => { await cli?.server?.close(); });
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Blueprint fixtures
|
|
42
|
+
|
|
43
|
+
Installing from wordpress.org:
|
|
44
|
+
```ts
|
|
45
|
+
steps: [{ step: 'installPlugin', pluginData: { resource: 'wordpress.org/plugins', slug: 'contact-form-7' } }]
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Creating content:
|
|
49
|
+
```ts
|
|
50
|
+
steps: [{ step: 'runPHP', code: `<?php require '/wordpress/wp-load.php'; wp_insert_post([...]);` }]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## WordPress-specific locator guidance
|
|
54
|
+
|
|
55
|
+
- `page.getByRole('button', { name: 'Save Changes' })` — works for standard WP buttons
|
|
56
|
+
- `page.getByLabel('API Key')` — works for labeled form fields
|
|
57
|
+
- `page.locator('#wpadminbar')` — CSS required for WP core layout elements (no ARIA)
|
|
58
|
+
- Add `data-testid` to your own plugin markup for stable selectors
|
|
59
|
+
- Run `npx playwright codegen localhost:9400/wp-admin/` to auto-generate locators
|
|
60
|
+
|
|
61
|
+
## Page Object Model
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// tests/e2e/pages/plugin-settings.ts
|
|
65
|
+
export class PluginSettingsPage {
|
|
66
|
+
constructor(readonly page: Page) {}
|
|
67
|
+
async goto(baseUrl: string) { await this.page.goto(`${baseUrl}/wp-admin/options-general.php?page=my-plugin`); }
|
|
68
|
+
async setApiKey(key: string) {
|
|
69
|
+
await this.page.getByLabel('API Key').fill(key);
|
|
70
|
+
await this.page.getByRole('button', { name: 'Save Changes' }).click();
|
|
71
|
+
}
|
|
72
|
+
async expectSaved() { await expect(this.page.getByText('Settings saved')).toBeVisible(); }
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## GitHub Actions CI
|
|
77
|
+
|
|
78
|
+
```yaml
|
|
79
|
+
name: E2E Tests
|
|
80
|
+
on:
|
|
81
|
+
push: { branches: [main] }
|
|
82
|
+
pull_request: { branches: [main] }
|
|
83
|
+
jobs:
|
|
84
|
+
e2e:
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/checkout@v4
|
|
88
|
+
- uses: actions/setup-node@v4
|
|
89
|
+
with: { node-version: 20, cache: 'npm' }
|
|
90
|
+
- run: npm ci
|
|
91
|
+
- uses: actions/cache@v4
|
|
92
|
+
id: playwright-cache
|
|
93
|
+
with:
|
|
94
|
+
path: ~/.cache/ms-playwright
|
|
95
|
+
key: playwright-${{ hashFiles('package-lock.json') }}
|
|
96
|
+
- if: steps.playwright-cache.outputs.cache-hit != 'true'
|
|
97
|
+
run: npx playwright install chromium --with-deps
|
|
98
|
+
- run: npx playwright test
|
|
99
|
+
- uses: actions/upload-artifact@v4
|
|
100
|
+
if: ${{ !cancelled() }}
|
|
101
|
+
with: { name: playwright-report, path: playwright-report/, retention-days: 30 }
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Troubleshooting
|
|
105
|
+
|
|
106
|
+
- **Timeout errors** — increase `timeout` in config; CI needs 120–180s
|
|
107
|
+
- **Port conflicts** — don't hardcode ports; use `cli.serverUrl`
|
|
108
|
+
- **Browser not found** — run `npx playwright install chromium`
|
|
109
|
+
- **Passes locally, fails CI** — increase timeouts, ensure `workers: 1`
|
|
110
|
+
- **Debug** — `npx playwright test --debug` or `--ui` for interactive mode
|
|
111
|
+
|
|
112
|
+
## Docs
|
|
113
|
+
|
|
114
|
+
- https://wordpress.github.io/wordpress-playground/guides/e2e-testing-with-playwright
|
|
115
|
+
- https://wordpress.github.io/wordpress-playground/guides/programmatic-playground-cli
|