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
155 changes: 155 additions & 0 deletions .github/workflows/wokwi-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: Wokwi ESP32 Simulation Test

on:
push:
branches: [ "mdev", "copilot/**" ]
pull_request:
branches: [ "mdev" ]
workflow_dispatch:

jobs:
wokwi-test:
name: Test WLED with Wokwi Simulator
runs-on: ubuntu-22.04

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-

- name: Cache PlatformIO
uses: actions/cache@v4
with:
path: ~/.platformio
key: ${{ runner.os }}-pio-esp32dev_compat

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.9'

- name: Install PlatformIO
run: pip install -r requirements.txt

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install Node.js dependencies
run: npm ci

- name: Build web UI
run: npm run build

- name: Build firmware for ESP32
env:
WLED_RELEASE: True
run: pio run -e esp32dev_compat

- name: Install Wokwi CLI
run: curl -L https://wokwi.com/ci/install.sh | sh

- name: Prepare firmware for Wokwi
run: ./test/wokwi/prepare-firmware.sh esp32dev_compat

- name: Install Playwright browsers
run: npx playwright install --with-deps chromium

- name: Debug - Verify token is set
run: |
if [ -z "$WOKWI_CLI_TOKEN" ]; then
echo "❌ ERROR: WOKWI_CLI_TOKEN is not set"
echo "Please configure WOKWI_CLI_TOKEN as a repository secret"
exit 1
else
echo "✅ WOKWI_CLI_TOKEN is set (length: ${#WOKWI_CLI_TOKEN} characters)"
fi
env:
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }}

- name: Start Wokwi simulator in background
env:
WOKWI_CLI_TOKEN: ${{ secrets.WOKWI_CLI_TOKEN }}
run: |
cd test/wokwi
# Create log directory
mkdir -p logs

# Export the token so it's available to child processes
export WOKWI_CLI_TOKEN

# Start simulator in background with a 180 second timeout
WOKWI_TIMEOUT=180 ./run-simulator.sh > logs/wokwi.log 2>&1 &
WOKWI_PID=$!
echo "WOKWI_PID=$WOKWI_PID" >> $GITHUB_ENV
echo "Started Wokwi simulator with PID $WOKWI_PID"

# Wait for simulator to start and web server to be ready
echo "Waiting for WLED web server to be ready..."
max_wait=120
elapsed=0
while [ $elapsed -lt $max_wait ]; do
if curl -s -f http://localhost:8080 > /dev/null 2>&1; then
echo "Web server is ready after $elapsed seconds!"
break
fi
if ! kill -0 $WOKWI_PID 2>/dev/null; then
echo "Error: Wokwi simulator process died"
echo "Last 50 lines of Wokwi log:"
tail -50 logs/wokwi.log || true
exit 1
fi
echo "Still waiting... ($elapsed seconds)"
sleep 5
elapsed=$((elapsed + 5))
done

if [ $elapsed -ge $max_wait ]; then
echo "Error: Web server did not start within $max_wait seconds"
echo "Last 50 lines of Wokwi log:"
tail -50 logs/wokwi.log || true
kill $WOKWI_PID || true
exit 1
fi

echo "WLED is ready for testing!"

- name: Run Playwright tests
run: npm run test:wokwi
env:
CI: true

- name: Upload Playwright report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/
retention-days: 7

- name: Stop Wokwi simulator
if: always()
run: |
if [ ! -z "$WOKWI_PID" ]; then
kill $WOKWI_PID || true
fi

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: wokwi-test-results
path: |
test/wokwi/logs/
test-results/
playwright-report/
retention-days: 7
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,15 @@ compile_commands.json
/wled00/wled00.ino.cpp
/wled00/html_*.h
_codeql_detected_source_root

# Playwright and test artifacts
/test-results/
/playwright-report/
/playwright/.cache/

# Wokwi runtime files
/test/wokwi/firmware.bin
/test/wokwi/firmware.elf
/test/wokwi/.wokwi/
/test/wokwi/logs/

76 changes: 76 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
},
"scripts": {
"build": "node tools/cdata.js",
"dev": "nodemon -e js,html,htm,css,png,jpg,gif,ico,js -w tools/ -w wled00/data/ -x node tools/cdata.js"
"dev": "nodemon -e js,html,htm,css,png,jpg,gif,ico,js -w tools/ -w wled00/data/ -x node tools/cdata.js",
"test": "npm run test:cdata",
"test:cdata": "node tools/cdata-test.js",
"test:wokwi": "playwright test test/playwright/wokwi-basic.spec.js"
},
"repository": {
"type": "git",
Expand All @@ -27,5 +30,8 @@
"inliner": "^1.13.1",
"nodemon": "^2.0.20",
"zlib": "^1.0.5"
},
"devDependencies": {
"@playwright/test": "^1.40.0"
}
}
52 changes: 52 additions & 0 deletions playwright.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
const { defineConfig, devices } = require('@playwright/test');

/**
* Playwright configuration for WLED-MM Wokwi testing
* See https://playwright.dev/docs/test-configuration.
*/
module.exports = defineConfig({
testDir: './test/playwright',

/* Run tests in files in parallel */
fullyParallel: false,

/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,

/* Retry on CI only */
retries: process.env.CI ? 2 : 0,

/* Opt out of parallel tests on CI. */
workers: 1,

/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',

/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: 'http://localhost:8080',

/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: 'on-first-retry',

/* Screenshot on failure */
screenshot: 'only-on-failure',
},

/* Configure projects for major browsers */
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],

/* Run your local dev server before starting the tests */
webServer: {
command: 'echo "Wokwi simulator should be started separately"',
url: 'http://localhost:8080',
reuseExistingServer: !process.env.CI,
timeout: 120000,
},
});
Loading
Loading