Modernize WordPress Playground testing infrastructure
- Update @wp-playground/cli to v3.0.22 (from deprecated v1.0.28) - Add bin/playground-test.sh for AI assistant CLI testing - Add bin/localwp-setup.sh for LocalWP integration - Create .agents/local-testing-guide.md documentation - Update blueprints to use new installPlugin step format - Add npm scripts for playground:start/stop/status - Add npm scripts for localwp:create/sync/reset - Update GitHub Actions to use new CLI version - Use PHP 8.0 and latest WordPress in blueprints
This commit is contained in:
331
.agents/local-testing-guide.md
Normal file
331
.agents/local-testing-guide.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# Local Testing Guide for AI Assistants
|
||||
|
||||
This guide provides instructions for AI coding assistants to set up and run local
|
||||
WordPress testing environments for this plugin.
|
||||
|
||||
## Overview
|
||||
|
||||
Three testing approaches are available:
|
||||
|
||||
1. **WordPress Playground CLI** - Quick browser-based testing (recommended for AI)
|
||||
2. **LocalWP** - Full local WordPress environment
|
||||
3. **wp-env** - Docker-based WordPress environment
|
||||
|
||||
Each approach has trade-offs. Choose based on the testing needs.
|
||||
|
||||
## Quick Reference
|
||||
|
||||
```bash
|
||||
# Playground CLI (fastest for AI testing)
|
||||
npm run playground:start # Start single site
|
||||
npm run playground:start:multisite # Start multisite
|
||||
npm run playground:stop # Stop server
|
||||
npm run playground:status # Check status
|
||||
|
||||
# LocalWP (full environment)
|
||||
npm run localwp:create # Create single site
|
||||
npm run localwp:create:multisite # Create multisite
|
||||
npm run localwp:sync # Sync plugin changes
|
||||
npm run localwp:reset # Reset to clean state
|
||||
|
||||
# wp-env (Docker-based)
|
||||
npm run start # Start wp-env
|
||||
npm run stop # Stop wp-env
|
||||
```
|
||||
|
||||
## WordPress Playground CLI
|
||||
|
||||
Uses `@wp-playground/cli` version 3.0.22+ for instant WordPress testing.
|
||||
|
||||
### When to Use
|
||||
|
||||
* Quick plugin functionality testing
|
||||
* Verifying admin UI changes
|
||||
* Testing single site vs multisite behavior
|
||||
* CI/CD pipeline testing (note: may be flaky in GitHub Actions)
|
||||
|
||||
### Starting Playground
|
||||
|
||||
```bash
|
||||
# Single site on port 8888
|
||||
npm run playground:start
|
||||
|
||||
# Multisite on port 8889
|
||||
npm run playground:start:multisite
|
||||
```
|
||||
|
||||
### Accessing the Site
|
||||
|
||||
After starting, the script provides access details:
|
||||
|
||||
* **Single Site**: http://localhost:8888
|
||||
* **Multisite**: http://localhost:8889
|
||||
* **Admin Login**: admin / password
|
||||
|
||||
### Blueprint Configuration
|
||||
|
||||
Blueprints define the WordPress setup. Located in `playground/`:
|
||||
|
||||
* `blueprint.json` - Single site configuration
|
||||
* `multisite-blueprint.json` - Multisite configuration
|
||||
|
||||
Blueprints install:
|
||||
* Plugin Toggle (debugging helper)
|
||||
* Kadence Blocks (testing with block plugins)
|
||||
|
||||
### Stopping Playground
|
||||
|
||||
```bash
|
||||
npm run playground:stop
|
||||
```
|
||||
|
||||
### Status Check
|
||||
|
||||
```bash
|
||||
npm run playground:status
|
||||
```
|
||||
|
||||
Shows running processes and port usage.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If Playground fails to start:
|
||||
|
||||
1. Check if ports 8888/8889 are in use: `lsof -i :8888`
|
||||
2. Check logs: `cat .playground.log`
|
||||
3. Stop any orphaned processes: `npm run playground:stop`
|
||||
4. Ensure npm dependencies are installed: `npm install`
|
||||
|
||||
## LocalWP Integration
|
||||
|
||||
LocalWP provides a full WordPress environment with database persistence.
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* LocalWP installed at `/Applications/Local.app` (macOS)
|
||||
* Local Sites directory at `~/Local Sites/`
|
||||
|
||||
### When to Use
|
||||
|
||||
* Testing database migrations
|
||||
* Long-term development environment
|
||||
* Testing with specific PHP/MySQL versions
|
||||
* Network/multisite configuration testing
|
||||
* Testing WP-CLI commands
|
||||
|
||||
### Creating Sites
|
||||
|
||||
LocalWP requires manual site creation through the GUI.
|
||||
|
||||
```bash
|
||||
npm run localwp:create
|
||||
```
|
||||
|
||||
This guides you through:
|
||||
|
||||
1. Opening LocalWP
|
||||
2. Creating a site with standardized name
|
||||
3. Syncing plugin files
|
||||
|
||||
### URL Patterns
|
||||
|
||||
Sites use consistent naming:
|
||||
|
||||
* **Single Site**: `wp-plugin-starter-template-single.local`
|
||||
* **Multisite**: `wp-plugin-starter-template-multisite.local`
|
||||
|
||||
### Syncing Plugin Files
|
||||
|
||||
After making code changes:
|
||||
|
||||
```bash
|
||||
npm run localwp:sync
|
||||
```
|
||||
|
||||
This uses rsync to copy plugin files, excluding:
|
||||
* node_modules
|
||||
* vendor
|
||||
* tests
|
||||
* .git
|
||||
* dist
|
||||
|
||||
### Resetting
|
||||
|
||||
To reset the plugin to a clean state:
|
||||
|
||||
```bash
|
||||
npm run localwp:reset
|
||||
```
|
||||
|
||||
### Site Information
|
||||
|
||||
View all LocalWP sites:
|
||||
|
||||
```bash
|
||||
./bin/localwp-setup.sh info
|
||||
```
|
||||
|
||||
## wp-env (Docker)
|
||||
|
||||
Docker-based environment using `@wordpress/env`.
|
||||
|
||||
### When to Use
|
||||
|
||||
* Consistent environment across machines
|
||||
* PHPUnit testing
|
||||
* WP-CLI operations
|
||||
* CI/CD testing
|
||||
|
||||
### Starting
|
||||
|
||||
```bash
|
||||
npm run start # or: wp-env start
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
npm run test:phpunit # Single site tests
|
||||
npm run test:phpunit:multisite # Multisite tests
|
||||
```
|
||||
|
||||
### Running WP-CLI Commands
|
||||
|
||||
```bash
|
||||
wp-env run cli wp plugin list
|
||||
wp-env run cli wp option get siteurl
|
||||
```
|
||||
|
||||
## Testing Workflows for AI Assistants
|
||||
|
||||
### Verifying a Code Change
|
||||
|
||||
1. Make the code change
|
||||
2. Start Playground: `npm run playground:start`
|
||||
3. Navigate to relevant admin page
|
||||
4. Verify expected behavior
|
||||
5. Stop Playground: `npm run playground:stop`
|
||||
|
||||
### Testing Multisite Functionality
|
||||
|
||||
1. Start multisite: `npm run playground:start:multisite`
|
||||
2. Navigate to Network Admin
|
||||
3. Test network-wide functionality
|
||||
4. Test per-site functionality
|
||||
5. Stop: `npm run playground:stop`
|
||||
|
||||
### Running PHPUnit Tests
|
||||
|
||||
```bash
|
||||
# Single site
|
||||
composer test
|
||||
|
||||
# Multisite
|
||||
WP_MULTISITE=1 composer test
|
||||
|
||||
# Specific test file
|
||||
vendor/bin/phpunit tests/phpunit/test-core.php
|
||||
```
|
||||
|
||||
### Running Cypress E2E Tests
|
||||
|
||||
```bash
|
||||
# With Playground (headless)
|
||||
npm run test:playground:single
|
||||
npm run test:playground:multisite
|
||||
|
||||
# With wp-env (headless)
|
||||
npm run test:e2e:single
|
||||
npm run test:e2e:multisite
|
||||
```
|
||||
|
||||
## Environment Comparison
|
||||
|
||||
| Feature | Playground CLI | LocalWP | wp-env |
|
||||
|---------|---------------|---------|--------|
|
||||
| Setup Time | Instant | 5-10 min | 2-5 min |
|
||||
| Persistence | None | Full | Partial |
|
||||
| PHP Versions | Limited | Many | Limited |
|
||||
| Database | In-memory | MySQL | MySQL |
|
||||
| WP-CLI | Yes | Yes | Yes |
|
||||
| Multisite | Yes | Yes | Yes |
|
||||
| GitHub Actions | Flaky | N/A | Works |
|
||||
| Best For | Quick testing | Full dev | CI/Testing |
|
||||
|
||||
## Common Issues
|
||||
|
||||
### Port Already in Use
|
||||
|
||||
```bash
|
||||
# Check what's using the port
|
||||
lsof -i :8888
|
||||
|
||||
# Kill the process if needed
|
||||
kill $(lsof -t -i :8888)
|
||||
```
|
||||
|
||||
### Playground Won't Start
|
||||
|
||||
1. Ensure dependencies installed: `npm install`
|
||||
2. Check Node.js version: `node --version` (requires 18+)
|
||||
3. Check logs: `cat .playground.log`
|
||||
|
||||
### LocalWP Site Not Found
|
||||
|
||||
The script expects sites at:
|
||||
* `~/Local Sites/wp-plugin-starter-template-single/`
|
||||
* `~/Local Sites/wp-plugin-starter-template-multisite/`
|
||||
|
||||
Verify the site name matches exactly.
|
||||
|
||||
### wp-env Docker Issues
|
||||
|
||||
```bash
|
||||
# Restart Docker
|
||||
wp-env stop
|
||||
docker system prune -f
|
||||
wp-env start
|
||||
```
|
||||
|
||||
## Blueprint Reference
|
||||
|
||||
Blueprints use JSON format. Key steps:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
|
||||
"landingPage": "/wp-admin/",
|
||||
"login": true,
|
||||
"features": {
|
||||
"networking": true,
|
||||
"phpVersion": "7.4"
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
"step": "defineWpConfigConsts",
|
||||
"consts": {
|
||||
"WP_DEBUG": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install plugin-toggle --activate"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
For multisite, add:
|
||||
|
||||
```json
|
||||
{
|
||||
"step": "enableMultisite"
|
||||
}
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
* [WordPress Playground CLI](https://wordpress.github.io/wordpress-playground/)
|
||||
* [WordPress Playground Blueprints](https://wordpress.github.io/wordpress-playground/blueprints)
|
||||
* [LocalWP Documentation](https://localwp.com/help-docs/)
|
||||
* [@wordpress/env Documentation](https://developer.wordpress.org/block-editor/reference-guides/packages/packages-env/)
|
||||
16
.github/workflows/playground-tests.yml
vendored
16
.github/workflows/playground-tests.yml
vendored
@@ -77,11 +77,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Add WordPress Playground CLI to dependencies
|
||||
- name: Verify WordPress Playground CLI
|
||||
run: |
|
||||
echo "Installing WordPress Playground CLI..."
|
||||
npm install --save-dev @wp-playground/cli @wp-playground/blueprints @wp-playground/client
|
||||
echo "WordPress Playground CLI installed"
|
||||
echo "WordPress Playground CLI version:"
|
||||
npx @wp-playground/cli --version
|
||||
|
||||
- name: Create plugin zip
|
||||
@@ -97,7 +95,7 @@ jobs:
|
||||
ls -la playground/
|
||||
cat playground/blueprint.json
|
||||
|
||||
# Start WordPress Playground with our blueprint
|
||||
# Start WordPress Playground with our blueprint (using @wp-playground/cli 3.x syntax)
|
||||
echo "Starting WordPress Playground server..."
|
||||
npx @wp-playground/cli server --blueprint playground/blueprint.json --port 8888 --login &
|
||||
SERVER_PID=$!
|
||||
@@ -157,11 +155,9 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: npm install --legacy-peer-deps
|
||||
|
||||
- name: Add WordPress Playground CLI to dependencies
|
||||
- name: Verify WordPress Playground CLI
|
||||
run: |
|
||||
echo "Installing WordPress Playground CLI..."
|
||||
npm install --save-dev @wp-playground/cli @wp-playground/blueprints @wp-playground/client
|
||||
echo "WordPress Playground CLI installed"
|
||||
echo "WordPress Playground CLI version:"
|
||||
npx @wp-playground/cli --version
|
||||
|
||||
- name: Create plugin zip
|
||||
@@ -177,7 +173,7 @@ jobs:
|
||||
ls -la playground/
|
||||
cat playground/multisite-blueprint.json
|
||||
|
||||
# Start WordPress Playground with our blueprint
|
||||
# Start WordPress Playground with our blueprint (using @wp-playground/cli 3.x syntax)
|
||||
# Use a different port for multisite to avoid conflicts with single site tests
|
||||
echo "Starting WordPress Playground server for multisite..."
|
||||
npx @wp-playground/cli server --blueprint playground/multisite-blueprint.json --port 8889 --login &
|
||||
|
||||
@@ -93,6 +93,8 @@ Always run PHPCS and PHPCBF locally before committing code to ensure it meets th
|
||||
|
||||
For detailed instructions on releases, features, bugs, and testing, see **@.agents/release-process.md**.
|
||||
|
||||
For local testing with WordPress Playground, LocalWP, and wp-env, see **@.agents/local-testing-guide.md**.
|
||||
|
||||
## Avoiding Cross-Repository Confusion
|
||||
|
||||
When working in a multi-repository workspace, follow these guidelines to avoid confusion:
|
||||
|
||||
413
bin/localwp-setup.sh
Executable file
413
bin/localwp-setup.sh
Executable file
@@ -0,0 +1,413 @@
|
||||
#!/bin/bash
|
||||
|
||||
# LocalWP Integration Script for WordPress Plugin Development
|
||||
# For use by AI coding assistants and developers
|
||||
#
|
||||
# This script manages LocalWP sites for testing the plugin.
|
||||
# Creates standardized test sites with consistent URLs.
|
||||
#
|
||||
# URL Patterns:
|
||||
# Single site: {plugin-slug}-single.local
|
||||
# Multisite: {plugin-slug}-multisite.local
|
||||
#
|
||||
# Usage:
|
||||
# ./bin/localwp-setup.sh create [--multisite]
|
||||
# ./bin/localwp-setup.sh sync
|
||||
# ./bin/localwp-setup.sh reset
|
||||
# ./bin/localwp-setup.sh info
|
||||
#
|
||||
# Examples:
|
||||
# npm run localwp:create # Create single site
|
||||
# npm run localwp:create:multisite # Create multisite
|
||||
# npm run localwp:sync # Sync plugin files
|
||||
# npm run localwp:reset # Reset to clean state
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
PLUGIN_SLUG="wp-plugin-starter-template"
|
||||
PLUGIN_TEXT_DOMAIN="wp-plugin-starter-template"
|
||||
|
||||
# LocalWP paths (macOS)
|
||||
LOCAL_SITES_DIR="$HOME/Local Sites"
|
||||
LOCAL_APP="/Applications/Local.app"
|
||||
LOCAL_WP_CLI="$LOCAL_APP/Contents/Resources/extraResources/bin/wp-cli/posix/wp"
|
||||
|
||||
# Site configurations
|
||||
SINGLE_SITE_NAME="${PLUGIN_SLUG}-single"
|
||||
MULTISITE_NAME="${PLUGIN_SLUG}-multisite"
|
||||
SINGLE_SITE_DOMAIN="${SINGLE_SITE_NAME}.local"
|
||||
MULTISITE_DOMAIN="${MULTISITE_NAME}.local"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
log_step() {
|
||||
echo -e "${CYAN}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if LocalWP is installed
|
||||
check_localwp() {
|
||||
if [ ! -d "$LOCAL_APP" ]; then
|
||||
log_error "LocalWP is not installed at $LOCAL_APP"
|
||||
log_info "Download from: https://localwp.com/"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$LOCAL_WP_CLI" ]; then
|
||||
log_error "WP-CLI not found in LocalWP installation"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local version=$("$LOCAL_WP_CLI" --version 2>/dev/null || echo "unknown")
|
||||
log_info "LocalWP WP-CLI version: $version"
|
||||
}
|
||||
|
||||
# Get site path
|
||||
get_site_path() {
|
||||
local site_name="$1"
|
||||
echo "$LOCAL_SITES_DIR/$site_name"
|
||||
}
|
||||
|
||||
# Get WordPress path within site
|
||||
get_wp_path() {
|
||||
local site_name="$1"
|
||||
local site_path=$(get_site_path "$site_name")
|
||||
|
||||
# LocalWP uses app/public for WordPress files
|
||||
echo "$site_path/app/public"
|
||||
}
|
||||
|
||||
# Check if site exists
|
||||
site_exists() {
|
||||
local site_name="$1"
|
||||
local site_path=$(get_site_path "$site_name")
|
||||
[ -d "$site_path" ]
|
||||
}
|
||||
|
||||
# Get plugin destination path
|
||||
get_plugin_path() {
|
||||
local site_name="$1"
|
||||
local wp_path=$(get_wp_path "$site_name")
|
||||
echo "$wp_path/wp-content/plugins/$PLUGIN_SLUG"
|
||||
}
|
||||
|
||||
# Sync plugin files to LocalWP site
|
||||
sync_plugin() {
|
||||
local site_name="$1"
|
||||
local plugin_dest=$(get_plugin_path "$site_name")
|
||||
|
||||
if ! site_exists "$site_name"; then
|
||||
log_error "Site '$site_name' does not exist"
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_info "Syncing plugin to $site_name..."
|
||||
|
||||
# Create plugin directory if it doesn't exist
|
||||
mkdir -p "$plugin_dest"
|
||||
|
||||
# Sync files using rsync (excludes dev files)
|
||||
rsync -av --delete \
|
||||
--exclude 'node_modules' \
|
||||
--exclude 'vendor' \
|
||||
--exclude '.git' \
|
||||
--exclude 'dist' \
|
||||
--exclude 'tests' \
|
||||
--exclude 'cypress' \
|
||||
--exclude '.github' \
|
||||
--exclude '.agents' \
|
||||
--exclude '.wiki' \
|
||||
--exclude 'reference-plugins' \
|
||||
--exclude '*.zip' \
|
||||
--exclude '.playground.*' \
|
||||
--exclude 'composer.lock' \
|
||||
--exclude 'package-lock.json' \
|
||||
"$PROJECT_DIR/" "$plugin_dest/"
|
||||
|
||||
log_success "Plugin synced to: $plugin_dest"
|
||||
}
|
||||
|
||||
# Create a new LocalWP site
|
||||
create_site() {
|
||||
local multisite=false
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--multisite)
|
||||
multisite=true
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local site_name="$SINGLE_SITE_NAME"
|
||||
local domain="$SINGLE_SITE_DOMAIN"
|
||||
local mode="single site"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
site_name="$MULTISITE_NAME"
|
||||
domain="$MULTISITE_DOMAIN"
|
||||
mode="multisite"
|
||||
fi
|
||||
|
||||
check_localwp
|
||||
|
||||
local site_path=$(get_site_path "$site_name")
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
log_warning "Site '$site_name' already exists at: $site_path"
|
||||
log_info "Use 'npm run localwp:reset' to reset it, or 'npm run localwp:sync' to update files"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LocalWP Site Setup ($mode)"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
echo "This script will guide you through creating a"
|
||||
echo "LocalWP site for testing the plugin."
|
||||
echo ""
|
||||
echo "Site Details:"
|
||||
echo " Name: $site_name"
|
||||
echo " Domain: $domain"
|
||||
echo " Path: $site_path"
|
||||
echo ""
|
||||
|
||||
log_step "Creating LocalWP Site"
|
||||
echo ""
|
||||
log_info "LocalWP doesn't have a CLI for site creation."
|
||||
log_info "Please create the site manually in LocalWP:"
|
||||
echo ""
|
||||
echo "1. Open LocalWP application"
|
||||
echo "2. Click the '+' button to create a new site"
|
||||
echo "3. Use these settings:"
|
||||
echo " - Site name: ${CYAN}$site_name${NC}"
|
||||
echo " - Local site domain: ${CYAN}$domain${NC}"
|
||||
echo " - PHP version: 8.0 or higher"
|
||||
echo " - Web server: nginx (preferred)"
|
||||
echo " - MySQL version: 8.0+"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
echo ""
|
||||
echo "4. After site creation, convert to multisite:"
|
||||
echo " - Open Site Shell in LocalWP"
|
||||
echo " - Run: wp core multisite-convert --subdomains=0"
|
||||
echo " - Update wp-config.php if needed"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "After creating the site, run: npm run localwp:sync"
|
||||
echo ""
|
||||
|
||||
# Wait for user to create site
|
||||
read -p "Press Enter after you've created the site in LocalWP..."
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
log_success "Site detected at: $site_path"
|
||||
sync_plugin "$site_name"
|
||||
|
||||
# Install recommended plugins
|
||||
install_recommended_plugins "$site_name"
|
||||
|
||||
show_site_info "$site_name" "$domain" "$multisite"
|
||||
else
|
||||
log_warning "Site not found at expected location"
|
||||
log_info "Expected path: $site_path"
|
||||
log_info "You can run 'npm run localwp:sync' later to sync files"
|
||||
fi
|
||||
}
|
||||
|
||||
# Install recommended plugins (matching Playground blueprint)
|
||||
install_recommended_plugins() {
|
||||
local site_name="$1"
|
||||
local wp_path=$(get_wp_path "$site_name")
|
||||
|
||||
log_info "Note: Install these plugins to match Playground environment:"
|
||||
echo " - Plugin Toggle (plugin-toggle)"
|
||||
echo " - Kadence Blocks (kadence-blocks)"
|
||||
echo ""
|
||||
log_info "You can install them via LocalWP's WP Admin or Site Shell"
|
||||
}
|
||||
|
||||
# Show site information
|
||||
show_site_info() {
|
||||
local site_name="$1"
|
||||
local domain="$2"
|
||||
local multisite="$3"
|
||||
|
||||
local site_path=$(get_site_path "$site_name")
|
||||
local plugin_path=$(get_plugin_path "$site_name")
|
||||
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " LocalWP Site Ready"
|
||||
echo "============================================"
|
||||
echo " Site: $site_name"
|
||||
echo " URL: http://$domain"
|
||||
echo " Admin: http://$domain/wp-admin/"
|
||||
echo " Plugin Path: $plugin_path"
|
||||
echo "============================================"
|
||||
|
||||
if [ "$multisite" = true ]; then
|
||||
echo " Network Admin: http://$domain/wp-admin/network/"
|
||||
echo "============================================"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "Remember to:"
|
||||
echo " 1. Start the site in LocalWP"
|
||||
echo " 2. Activate the plugin in WordPress admin"
|
||||
echo " 3. Run 'npm run localwp:sync' after making changes"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Reset site to clean state
|
||||
reset_site() {
|
||||
local site_name="${1:-$SINGLE_SITE_NAME}"
|
||||
|
||||
if ! site_exists "$site_name"; then
|
||||
log_error "Site '$site_name' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_warning "This will delete the plugin files and resync them."
|
||||
read -p "Continue? (y/n) " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
local plugin_path=$(get_plugin_path "$site_name")
|
||||
|
||||
log_info "Removing plugin files..."
|
||||
rm -rf "$plugin_path"
|
||||
|
||||
log_info "Resyncing plugin..."
|
||||
sync_plugin "$site_name"
|
||||
|
||||
log_success "Site reset complete"
|
||||
else
|
||||
log_info "Reset cancelled"
|
||||
fi
|
||||
}
|
||||
|
||||
# Sync all existing sites
|
||||
sync_all() {
|
||||
local synced=0
|
||||
|
||||
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
|
||||
if site_exists "$site_name"; then
|
||||
sync_plugin "$site_name"
|
||||
synced=$((synced + 1))
|
||||
fi
|
||||
done
|
||||
|
||||
if [ $synced -eq 0 ]; then
|
||||
log_warning "No LocalWP sites found for this plugin"
|
||||
log_info "Run 'npm run localwp:create' to create one"
|
||||
else
|
||||
log_success "Synced $synced site(s)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Show info about all sites
|
||||
show_info() {
|
||||
echo ""
|
||||
echo "LocalWP Sites for $PLUGIN_SLUG"
|
||||
echo "==============================="
|
||||
|
||||
for site_name in "$SINGLE_SITE_NAME" "$MULTISITE_NAME"; do
|
||||
local site_path=$(get_site_path "$site_name")
|
||||
|
||||
if site_exists "$site_name"; then
|
||||
echo ""
|
||||
echo " ${GREEN}✓${NC} $site_name"
|
||||
echo " Path: $site_path"
|
||||
|
||||
local plugin_path=$(get_plugin_path "$site_name")
|
||||
if [ -d "$plugin_path" ]; then
|
||||
echo " Plugin: ${GREEN}Installed${NC}"
|
||||
else
|
||||
echo " Plugin: ${YELLOW}Not synced${NC}"
|
||||
fi
|
||||
else
|
||||
echo ""
|
||||
echo " ${YELLOW}○${NC} $site_name (not created)"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " npm run localwp:create Create single site"
|
||||
echo " npm run localwp:create:multisite Create multisite"
|
||||
echo " npm run localwp:sync Sync plugin files"
|
||||
echo " npm run localwp:reset Reset plugin files"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main command handler
|
||||
case "${1:-}" in
|
||||
create)
|
||||
shift
|
||||
create_site "$@"
|
||||
;;
|
||||
sync)
|
||||
sync_all
|
||||
;;
|
||||
reset)
|
||||
shift
|
||||
reset_site "$@"
|
||||
;;
|
||||
info)
|
||||
show_info
|
||||
;;
|
||||
*)
|
||||
echo "LocalWP Integration Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 create [--multisite] Create a new LocalWP site"
|
||||
echo " $0 sync Sync plugin files to all sites"
|
||||
echo " $0 reset [site-name] Reset site plugin to clean state"
|
||||
echo " $0 info Show info about LocalWP sites"
|
||||
echo ""
|
||||
echo "npm scripts:"
|
||||
echo " npm run localwp:create Create single site"
|
||||
echo " npm run localwp:create:multisite Create multisite"
|
||||
echo " npm run localwp:sync Sync plugin files"
|
||||
echo " npm run localwp:reset Reset plugin files"
|
||||
echo ""
|
||||
echo "URL Patterns:"
|
||||
echo " Single site: http://${PLUGIN_SLUG}-single.local"
|
||||
echo " Multisite: http://${PLUGIN_SLUG}-multisite.local"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
303
bin/playground-test.sh
Executable file
303
bin/playground-test.sh
Executable file
@@ -0,0 +1,303 @@
|
||||
#!/bin/bash
|
||||
|
||||
# WordPress Playground CLI Testing Script
|
||||
# For use by AI coding assistants and developers
|
||||
#
|
||||
# This script provides a simple interface to start/stop WordPress Playground
|
||||
# for local testing with the plugin. Uses @wp-playground/cli 3.0.22+
|
||||
#
|
||||
# Usage:
|
||||
# ./bin/playground-test.sh start [--multisite] [--port PORT]
|
||||
# ./bin/playground-test.sh stop
|
||||
# ./bin/playground-test.sh status
|
||||
#
|
||||
# Examples:
|
||||
# npm run playground:start # Start single site on port 8888
|
||||
# npm run playground:start:multisite # Start multisite on port 8889
|
||||
# npm run playground:stop # Stop all playground instances
|
||||
# npm run playground:status # Check if playground is running
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
||||
PID_FILE="$PROJECT_DIR/.playground.pid"
|
||||
DEFAULT_PORT=8888
|
||||
MULTISITE_PORT=8889
|
||||
PLUGIN_SLUG="wp-plugin-starter-template"
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Helper functions
|
||||
log_info() {
|
||||
echo -e "${BLUE}[INFO]${NC} $1"
|
||||
}
|
||||
|
||||
log_success() {
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||
}
|
||||
|
||||
log_warning() {
|
||||
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[ERROR]${NC} $1"
|
||||
}
|
||||
|
||||
# Check if @wp-playground/cli is installed
|
||||
check_cli() {
|
||||
if ! npx @wp-playground/cli --version > /dev/null 2>&1; then
|
||||
log_error "@wp-playground/cli is not installed"
|
||||
log_info "Run: npm install"
|
||||
exit 1
|
||||
fi
|
||||
local version=$(npx @wp-playground/cli --version 2>/dev/null)
|
||||
log_info "Using @wp-playground/cli version: $version"
|
||||
}
|
||||
|
||||
# Create plugin zip for installation
|
||||
create_plugin_zip() {
|
||||
log_info "Creating plugin zip..."
|
||||
mkdir -p "$PROJECT_DIR/dist"
|
||||
|
||||
cd "$PROJECT_DIR"
|
||||
zip -r "dist/$PLUGIN_SLUG.zip" . \
|
||||
-x "node_modules/*" \
|
||||
-x "dist/*" \
|
||||
-x ".git/*" \
|
||||
-x "vendor/*" \
|
||||
-x "tests/*" \
|
||||
-x "cypress/*" \
|
||||
-x "*.zip" \
|
||||
-x ".github/*" \
|
||||
-x ".agents/*" \
|
||||
-x ".wiki/*" \
|
||||
-x "reference-plugins/*" \
|
||||
> /dev/null 2>&1
|
||||
|
||||
log_success "Plugin zip created: dist/$PLUGIN_SLUG.zip"
|
||||
}
|
||||
|
||||
# Start WordPress Playground
|
||||
start_playground() {
|
||||
local multisite=false
|
||||
local port=$DEFAULT_PORT
|
||||
local blueprint="$PROJECT_DIR/playground/blueprint.json"
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--multisite)
|
||||
multisite=true
|
||||
port=$MULTISITE_PORT
|
||||
blueprint="$PROJECT_DIR/playground/multisite-blueprint.json"
|
||||
shift
|
||||
;;
|
||||
--port)
|
||||
port="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check if already running
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local old_pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$old_pid" 2>/dev/null; then
|
||||
log_warning "Playground is already running (PID: $old_pid)"
|
||||
log_info "Run 'npm run playground:stop' first to restart"
|
||||
exit 1
|
||||
else
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check port availability
|
||||
if lsof -i ":$port" > /dev/null 2>&1; then
|
||||
log_error "Port $port is already in use"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
check_cli
|
||||
create_plugin_zip
|
||||
|
||||
local mode="single site"
|
||||
if [ "$multisite" = true ]; then
|
||||
mode="multisite"
|
||||
fi
|
||||
|
||||
log_info "Starting WordPress Playground ($mode) on port $port..."
|
||||
log_info "Blueprint: $blueprint"
|
||||
|
||||
# Start the server in background
|
||||
cd "$PROJECT_DIR"
|
||||
npx @wp-playground/cli server \
|
||||
--blueprint "$blueprint" \
|
||||
--port "$port" \
|
||||
--login \
|
||||
> "$PROJECT_DIR/.playground.log" 2>&1 &
|
||||
|
||||
local server_pid=$!
|
||||
echo "$server_pid" > "$PID_FILE"
|
||||
|
||||
# Wait for server to be ready
|
||||
log_info "Waiting for server to be ready..."
|
||||
local timeout=120
|
||||
local elapsed=0
|
||||
|
||||
while ! curl -s "http://localhost:$port" > /dev/null 2>&1; do
|
||||
if [ $elapsed -ge $timeout ]; then
|
||||
log_error "Timeout waiting for WordPress Playground to start"
|
||||
log_info "Check logs: cat $PROJECT_DIR/.playground.log"
|
||||
kill "$server_pid" 2>/dev/null || true
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if process is still running
|
||||
if ! kill -0 "$server_pid" 2>/dev/null; then
|
||||
log_error "Server process died unexpectedly"
|
||||
log_info "Check logs: cat $PROJECT_DIR/.playground.log"
|
||||
rm -f "$PID_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
elapsed=$((elapsed + 2))
|
||||
echo -ne "\r${BLUE}[INFO]${NC} Waiting... $elapsed/$timeout seconds"
|
||||
done
|
||||
|
||||
echo ""
|
||||
log_success "WordPress Playground is ready!"
|
||||
echo ""
|
||||
echo "============================================"
|
||||
echo " WordPress Playground ($mode)"
|
||||
echo "============================================"
|
||||
echo " URL: http://localhost:$port"
|
||||
echo " Admin: http://localhost:$port/wp-admin/"
|
||||
echo " Login: admin / password"
|
||||
echo " PID: $server_pid"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
log_info "Run 'npm run playground:stop' to stop the server"
|
||||
log_info "Logs: $PROJECT_DIR/.playground.log"
|
||||
}
|
||||
|
||||
# Stop WordPress Playground
|
||||
stop_playground() {
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_info "Stopping WordPress Playground (PID: $pid)..."
|
||||
kill "$pid" 2>/dev/null || true
|
||||
|
||||
# Wait for process to stop
|
||||
local timeout=10
|
||||
local elapsed=0
|
||||
while kill -0 "$pid" 2>/dev/null && [ $elapsed -lt $timeout ]; do
|
||||
sleep 1
|
||||
elapsed=$((elapsed + 1))
|
||||
done
|
||||
|
||||
# Force kill if still running
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_warning "Force killing process..."
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
log_success "WordPress Playground stopped"
|
||||
else
|
||||
log_warning "Process not running"
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
else
|
||||
log_warning "No PID file found. Playground may not be running."
|
||||
fi
|
||||
|
||||
# Clean up any orphaned processes on common ports
|
||||
for port in $DEFAULT_PORT $MULTISITE_PORT; do
|
||||
local orphan_pid=$(lsof -t -i ":$port" 2>/dev/null || true)
|
||||
if [ -n "$orphan_pid" ]; then
|
||||
log_info "Found process on port $port (PID: $orphan_pid), stopping..."
|
||||
kill "$orphan_pid" 2>/dev/null || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Check status
|
||||
check_status() {
|
||||
echo ""
|
||||
echo "WordPress Playground Status"
|
||||
echo "============================"
|
||||
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
local pid=$(cat "$PID_FILE")
|
||||
if kill -0 "$pid" 2>/dev/null; then
|
||||
log_success "Running (PID: $pid)"
|
||||
else
|
||||
log_warning "PID file exists but process not running"
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
else
|
||||
log_info "Not running (no PID file)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Port Status:"
|
||||
for port in $DEFAULT_PORT $MULTISITE_PORT; do
|
||||
if lsof -i ":$port" > /dev/null 2>&1; then
|
||||
local port_pid=$(lsof -t -i ":$port" 2>/dev/null || echo "unknown")
|
||||
echo " Port $port: ${GREEN}IN USE${NC} (PID: $port_pid)"
|
||||
|
||||
# Test if it's responding
|
||||
if curl -s "http://localhost:$port" > /dev/null 2>&1; then
|
||||
echo " └─ HTTP: ${GREEN}OK${NC}"
|
||||
else
|
||||
echo " └─ HTTP: ${RED}NOT RESPONDING${NC}"
|
||||
fi
|
||||
else
|
||||
echo " Port $port: ${YELLOW}AVAILABLE${NC}"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Main command handler
|
||||
case "${1:-}" in
|
||||
start)
|
||||
shift
|
||||
start_playground "$@"
|
||||
;;
|
||||
stop)
|
||||
stop_playground
|
||||
;;
|
||||
status)
|
||||
check_status
|
||||
;;
|
||||
*)
|
||||
echo "WordPress Playground CLI Testing Script"
|
||||
echo ""
|
||||
echo "Usage:"
|
||||
echo " $0 start [--multisite] [--port PORT] Start WordPress Playground"
|
||||
echo " $0 stop Stop WordPress Playground"
|
||||
echo " $0 status Check playground status"
|
||||
echo ""
|
||||
echo "npm scripts:"
|
||||
echo " npm run playground:start Start single site"
|
||||
echo " npm run playground:start:multisite Start multisite"
|
||||
echo " npm run playground:stop Stop playground"
|
||||
echo " npm run playground:status Check status"
|
||||
echo ""
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
14
package.json
14
package.json
@@ -17,6 +17,14 @@
|
||||
"test:e2e:multisite": "npm run setup:multisite && sleep 5 && npm run test:multisite:headless",
|
||||
"test:playground:single": "cypress run --spec cypress/e2e/playground-single-site.cy.js",
|
||||
"test:playground:multisite": "cypress run --spec cypress/e2e/playground-multisite.cy.js",
|
||||
"playground:start": "bash bin/playground-test.sh start",
|
||||
"playground:start:multisite": "bash bin/playground-test.sh start --multisite",
|
||||
"playground:stop": "bash bin/playground-test.sh stop",
|
||||
"playground:status": "bash bin/playground-test.sh status",
|
||||
"localwp:create": "bash bin/localwp-setup.sh create",
|
||||
"localwp:create:multisite": "bash bin/localwp-setup.sh create --multisite",
|
||||
"localwp:sync": "bash bin/localwp-setup.sh sync",
|
||||
"localwp:reset": "bash bin/localwp-setup.sh reset",
|
||||
"test:phpunit": "composer test",
|
||||
"test:phpunit:multisite": "WP_MULTISITE=1 composer test",
|
||||
"build": "./build.sh",
|
||||
@@ -51,9 +59,9 @@
|
||||
"homepage": "https://github.com/wpallstars/wp-plugin-starter-template-for-ai-coding#readme",
|
||||
"devDependencies": {
|
||||
"@wordpress/env": "^8.12.0",
|
||||
"@wp-playground/blueprints": "^1.0.28",
|
||||
"@wp-playground/client": "^1.0.28",
|
||||
"@wp-playground/cli": "^1.0.28",
|
||||
"@wp-playground/blueprints": "^3.0.22",
|
||||
"@wp-playground/client": "^3.0.22",
|
||||
"@wp-playground/cli": "^3.0.22",
|
||||
"cypress": "^13.17.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-plugin-cypress": "^2.15.1"
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
{
|
||||
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
|
||||
"landingPage": "/wp-admin/",
|
||||
"landingPage": "/wp-admin/plugins.php",
|
||||
"login": true,
|
||||
"preferredVersions": {
|
||||
"php": "8.0",
|
||||
"wp": "latest"
|
||||
},
|
||||
"features": {
|
||||
"networking": true,
|
||||
"phpVersion": "7.4"
|
||||
"networking": true
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
@@ -12,16 +15,29 @@
|
||||
"consts": {
|
||||
"WP_DEBUG": true,
|
||||
"WP_DEBUG_LOG": true,
|
||||
"WP_DEBUG_DISPLAY": true
|
||||
"WP_DEBUG_DISPLAY": true,
|
||||
"SCRIPT_DEBUG": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install plugin-toggle --activate"
|
||||
"step": "installPlugin",
|
||||
"pluginData": {
|
||||
"resource": "wordpress.org/plugins",
|
||||
"slug": "plugin-toggle"
|
||||
},
|
||||
"options": {
|
||||
"activate": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install kadence-blocks --activate"
|
||||
"step": "installPlugin",
|
||||
"pluginData": {
|
||||
"resource": "wordpress.org/plugins",
|
||||
"slug": "kadence-blocks"
|
||||
},
|
||||
"options": {
|
||||
"activate": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
{
|
||||
"$schema": "https://playground.wordpress.net/blueprint-schema.json",
|
||||
"landingPage": "/wp-admin/network/",
|
||||
"landingPage": "/wp-admin/network/plugins.php",
|
||||
"login": true,
|
||||
"preferredVersions": {
|
||||
"php": "8.0",
|
||||
"wp": "latest"
|
||||
},
|
||||
"features": {
|
||||
"networking": {
|
||||
"type": "subdirectory"
|
||||
},
|
||||
"phpVersion": "7.4"
|
||||
"networking": true
|
||||
},
|
||||
"steps": [
|
||||
{
|
||||
@@ -14,7 +15,8 @@
|
||||
"consts": {
|
||||
"WP_DEBUG": true,
|
||||
"WP_DEBUG_LOG": true,
|
||||
"WP_DEBUG_DISPLAY": true
|
||||
"WP_DEBUG_DISPLAY": true,
|
||||
"SCRIPT_DEBUG": true
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -22,23 +24,29 @@
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp site create --slug=testsite"
|
||||
"command": "wp site create --slug=testsite --title='Test Site'"
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install plugin-toggle"
|
||||
"step": "installPlugin",
|
||||
"pluginData": {
|
||||
"resource": "wordpress.org/plugins",
|
||||
"slug": "plugin-toggle"
|
||||
},
|
||||
"options": {
|
||||
"activate": true,
|
||||
"networkActivate": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin install kadence-blocks"
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin activate plugin-toggle --network"
|
||||
},
|
||||
{
|
||||
"step": "wp-cli",
|
||||
"command": "wp plugin activate kadence-blocks --network"
|
||||
"step": "installPlugin",
|
||||
"pluginData": {
|
||||
"resource": "wordpress.org/plugins",
|
||||
"slug": "kadence-blocks"
|
||||
},
|
||||
"options": {
|
||||
"activate": true,
|
||||
"networkActivate": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user