[PHP-WEBMASTER] [web-php] master: Fix Playwright E2E test server startup (#2005)

Author: Luffy (sy-records)
Committer: GitHub (web-flow)
Pusher: sy-records
Date: 2026-09-03T10:19:35+08:00

Commit: Fix Playwright E2E test server startup (#2005) · php/web-php@af90899 · GitHub
Raw diff: https://github.com/php/web-php/commit/af90899b6cda24e2e68458c05344633195050630.diff

Fix Playwright E2E test server startup (#2005)

Changed paths:
  M Makefile
  M playwright.config.ts
  M tests/server

Diff:

diff --git a/Makefile b/Makefile
index a99a403775..559f76958b 100644
--- a/Makefile
+++ b/Makefile
@@ -35,9 +35,8 @@ tests: vendor ## Runs unit and end-to-end tests with phpunit/phpunit
   tests/server stop

tests_e2e:
- tests/server start;
- npx playwright test
- tests/server stop
+ tests/server start
+ trap 'tests/server stop' EXIT INT TERM; npx playwright test

vendor: composer.json composer.lock
   composer validate --strict
diff --git a/playwright.config.ts b/playwright.config.ts
index adf514e93b..a138099278 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -27,7 +27,7 @@ export default defineConfig({
         /* Collect trace when retrying the failed test. See Trace viewer | Playwright */
         trace: 'on-first-retry',
     },
- timeout: 0,
+ timeout: 120_000,

     projects: [
         {
diff --git a/tests/server b/tests/server
index 6cae14553d..473b271d4d 100755
--- a/tests/server
+++ b/tests/server
@@ -8,6 +8,9 @@ HOST=localhost
PORT=8080
# script name
NAME=${0##*/}
+# project paths
+PROJECT_ROOT=$(cd "$(dirname "$0")/.." && pwd)
+PUBLIC_ROOT="$PROJECT_ROOT/public"

usage () {
   cat <<EOF
@@ -35,7 +38,7 @@ return 0

setup_colors() {

-if which tput >/dev/null 2>&1; then
+if [ -t 1 ] && [ -n "${TERM:-}" ] && which tput >/dev/null 2>&1; then
       ncolors=$(tput colors)
   fi
   if [ -t 1 ] && [ -n "$ncolors" ] && [ "$ncolors" -ge 8 ]; then
@@ -74,8 +77,8 @@ if [[ $# > 1 ]]; then
fi

# pidfile contents would be hostname:port:pid
-PIDFILE=.build/server/server.pid
-LOGFILE=.build/server/server.log
+PIDFILE="$PROJECT_ROOT/.build/server/server.pid"
+LOGFILE="$PROJECT_ROOT/.build/server/server.log"

validate_server () {
   which php &> /dev/null
@@ -107,12 +110,34 @@ start_server () {
     echo if you are sure no server is running just remove "$PIDFILE" manually and start again
     return 1
   else
- printf "${GREEN}"$NAME" started on $HOST:$PORT${NORMAL}\n"
- mkdir -p $(dirname "$LOGFILE")
- php -S "$HOST":"$PORT" -c tests/php.ini >> "$LOGFILE" 2>&1 &
- mkdir -p $(dirname "$PIDFILE")
- echo "$HOST":"$PORT":$! > $PIDFILE
- return 0
+ mkdir -p "$(dirname "$LOGFILE")"
+ (
+ cd "$PUBLIC_ROOT" || exit 1
+ exec php -S "$HOST":"$PORT" -c "$PROJECT_ROOT/tests/php.ini" .router.php
+ ) >> "$LOGFILE" 2>&1 &
+ SERVER_PID=$!
+ mkdir -p "$(dirname "$PIDFILE")"
+ echo "$HOST":"$PORT":"$SERVER_PID" > "$PIDFILE"
+
+ for _ in {1..50}; do
+ if ! kill -0 "$SERVER_PID" 2>/dev/null; then
+ rm -f "$PIDFILE"
+ printf "${YELLOW}Error: $NAME failed to start. See $LOGFILE for details.${NORMAL}\n"
+ return 1
+ fi
+
+ if php -n -r '$socket = @fsockopen($argv[1], (int) $argv[2], $errorCode, $errorMessage, 0.1); if ($socket === false) { exit(1); } fclose($socket);' "$HOST" "$PORT"; then
+ printf "${GREEN}"$NAME" started on $HOST:$PORT${NORMAL}\n"
+ return 0
+ fi
+
+ sleep 0.1
+ done
+
+ kill "$SERVER_PID" 2>/dev/null
+ rm -f "$PIDFILE"
+ printf "${YELLOW}Error: $NAME did not become ready in time.${NORMAL}\n"
+ return 1
   fi
}