From 1d0abf27e6a47e68dc8ce76e75a12f5bfd589687 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 13 Apr 2026 18:02:52 +0200 Subject: [PATCH 01/10] Tests hardening for Windows --- features/server.feature | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/features/server.feature b/features/server.feature index a551e0e..d99e5ee 100644 --- a/features/server.feature +++ b/features/server.feature @@ -12,9 +12,11 @@ Feature: Serve WordPress locally Just another WordPress site """ - When I run `curl -sS localhost:8181/license.txt > /tmp/license.txt` - And I run `cmp /tmp/license.txt license.txt` - Then STDOUT should be empty + When I run `curl -sS localhost:8181/license.txt` + Then STDOUT should contain: + """ + WordPress - Web publishing software + """ Scenario: Passthrough arguments to PHP binary Given a WP install @@ -43,8 +45,7 @@ Feature: Serve WordPress locally Scenario: Pretty permalinks Given a WP install And I launch in the background `wp server --host=localhost --port=8183` - And I run `wp option update permalink_structure '/%postname%/'` - And I run `wp rewrite flush` + And I run `wp rewrite structure '/%postname%/'` When I run `curl -sSL http://localhost:8183/hello-world/` Then STDOUT should contain: From 10d89c05ea9d5a1cce2cc8aad6cba8de72360198 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Mon, 13 Apr 2026 21:49:28 +0200 Subject: [PATCH 02/10] Apply suggestion from @swissspidy --- features/server.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/server.feature b/features/server.feature index d99e5ee..e43f57a 100644 --- a/features/server.feature +++ b/features/server.feature @@ -12,7 +12,7 @@ Feature: Serve WordPress locally Just another WordPress site """ - When I run `curl -sS localhost:8181/license.txt` + When I run `curl -sSL http://localhost:8181/license.txt` Then STDOUT should contain: """ WordPress - Web publishing software From 7e50de8bd3369bf91cb9f3ab10793a835b07c685 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 09:05:03 +0200 Subject: [PATCH 03/10] Set `PATH_INFO` --- router.php | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/router.php b/router.php index 68bae24..a0c22df 100644 --- a/router.php +++ b/router.php @@ -137,21 +137,25 @@ static function ( $buffer ) { // phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url $wpcli_server_path = '/' . ltrim( parse_url( urldecode( $_SERVER['REQUEST_URI'] ) )['path'], '/' ); -if ( file_exists( $wpcli_server_root . $wpcli_server_path ) ) { - if ( is_dir( $wpcli_server_root . $wpcli_server_path ) && substr( $wpcli_server_path, -1 ) !== '/' ) { +$wpcli_server_file = $wpcli_server_root . $wpcli_server_path; +// Normalize slashes for file operations +$wpcli_server_file = str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $wpcli_server_file ); + +if ( file_exists( $wpcli_server_file ) ) { + if ( is_dir( $wpcli_server_file ) && substr( $wpcli_server_path, -1 ) !== '/' ) { header( "Location: $wpcli_server_path/" ); exit; } // Check if this is a PHP file by examining the extension - if ( pathinfo( $wpcli_server_path, PATHINFO_EXTENSION ) === 'php' ) { + if ( pathinfo( $wpcli_server_file, PATHINFO_EXTENSION ) === 'php' ) { // Set $_SERVER variables to mimic direct access to the PHP file $_SERVER['SCRIPT_NAME'] = $wpcli_server_path; $_SERVER['PHP_SELF'] = $wpcli_server_path; - $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_root . $wpcli_server_path; + $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_file; - chdir( dirname( $wpcli_server_root . $wpcli_server_path ) ); - require_once $wpcli_server_root . $wpcli_server_path; + chdir( dirname( $wpcli_server_file ) ); + require_once $wpcli_server_file; } else { return false; } @@ -159,7 +163,8 @@ static function ( $buffer ) { // File doesn't exist - route to index.php for pretty permalinks $_SERVER['SCRIPT_NAME'] = '/index.php'; $_SERVER['PHP_SELF'] = '/index.php'; - $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_root . '/index.php'; + $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_root . DIRECTORY_SEPARATOR . 'index.php'; + $_SERVER['PATH_INFO'] = $wpcli_server_path; // Help WordPress parse request chdir( $wpcli_server_root ); require_once 'index.php'; From 9840307ad17764583bb62e87d037174ed92acea5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 11:32:51 +0200 Subject: [PATCH 04/10] add debug output --- features/server.feature | 6 ++++++ router.php | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/features/server.feature b/features/server.feature index e43f57a..909fae5 100644 --- a/features/server.feature +++ b/features/server.feature @@ -47,6 +47,12 @@ Feature: Serve WordPress locally And I launch in the background `wp server --host=localhost --port=8183` And I run `wp rewrite structure '/%postname%/'` + When I run `curl -sSL http://localhost:8183/__debug` + Then STDOUT should contain: + """ + FORCE_FAIL_TO_SEE_OUTPUT + """ + When I run `curl -sSL http://localhost:8183/hello-world/` Then STDOUT should contain: """ diff --git a/router.php b/router.php index a0c22df..c6e3c45 100644 --- a/router.php +++ b/router.php @@ -141,6 +141,18 @@ static function ( $buffer ) { // Normalize slashes for file operations $wpcli_server_file = str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $wpcli_server_file ); +if ( $wpcli_server_path === '/__debug' ) { + header( 'Content-Type: application/json' ); + echo json_encode( + array( + 'SERVER' => $_SERVER, + 'wpcli_server_path' => $wpcli_server_path, + 'wpcli_server_file' => $wpcli_server_file, + ) + ); + exit; +} + if ( file_exists( $wpcli_server_file ) ) { if ( is_dir( $wpcli_server_file ) && substr( $wpcli_server_path, -1 ) !== '/' ) { header( "Location: $wpcli_server_path/" ); From 2936cc79b993ec03f585858acd2154e12c420dcf Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 12:37:50 +0200 Subject: [PATCH 05/10] more debugging --- features/server.feature | 6 ------ router.php | 12 ++++++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/features/server.feature b/features/server.feature index 909fae5..e43f57a 100644 --- a/features/server.feature +++ b/features/server.feature @@ -47,12 +47,6 @@ Feature: Serve WordPress locally And I launch in the background `wp server --host=localhost --port=8183` And I run `wp rewrite structure '/%postname%/'` - When I run `curl -sSL http://localhost:8183/__debug` - Then STDOUT should contain: - """ - FORCE_FAIL_TO_SEE_OUTPUT - """ - When I run `curl -sSL http://localhost:8183/hello-world/` Then STDOUT should contain: """ diff --git a/router.php b/router.php index c6e3c45..9f274f1 100644 --- a/router.php +++ b/router.php @@ -178,6 +178,18 @@ static function ( $buffer ) { $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_root . DIRECTORY_SEPARATOR . 'index.php'; $_SERVER['PATH_INFO'] = $wpcli_server_path; // Help WordPress parse request + if ( str_contains( $_SERVER['REQUEST_URI'], 'hello-world' ) ) { + header( 'Content-Type: application/json' ); + echo json_encode( + array( + 'SERVER' => $_SERVER, + 'wpcli_server_path' => $wpcli_server_path, + 'wpcli_server_file' => $wpcli_server_file, + ) + ); + exit; + } + chdir( $wpcli_server_root ); require_once 'index.php'; } From 60b6e94e8ff47aad54589b3a14485ca9912c5b38 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 13:59:40 +0200 Subject: [PATCH 06/10] more debugging --- features/server.feature | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/features/server.feature b/features/server.feature index e43f57a..5d24e3b 100644 --- a/features/server.feature +++ b/features/server.feature @@ -47,6 +47,12 @@ Feature: Serve WordPress locally And I launch in the background `wp server --host=localhost --port=8183` And I run `wp rewrite structure '/%postname%/'` + When I run `wp rewrite list` + Then STDOUT should contain: + """ + FORCE_FAIL_TO_SEE_RULES + """ + When I run `curl -sSL http://localhost:8183/hello-world/` Then STDOUT should contain: """ From dbe6503cdedf10888885c63a284d8209fa6a4dc8 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 14:25:28 +0200 Subject: [PATCH 07/10] use double quotes --- features/server.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/server.feature b/features/server.feature index 5d24e3b..5eb2e85 100644 --- a/features/server.feature +++ b/features/server.feature @@ -45,7 +45,7 @@ Feature: Serve WordPress locally Scenario: Pretty permalinks Given a WP install And I launch in the background `wp server --host=localhost --port=8183` - And I run `wp rewrite structure '/%postname%/'` + And I run `wp rewrite structure "/%postname%/"` When I run `wp rewrite list` Then STDOUT should contain: From ef30a2fc88687d1d0eb5db5a4fe7698753475276 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 14:37:05 +0200 Subject: [PATCH 08/10] remove leding slash --- features/server.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/server.feature b/features/server.feature index 5eb2e85..c435529 100644 --- a/features/server.feature +++ b/features/server.feature @@ -45,7 +45,7 @@ Feature: Serve WordPress locally Scenario: Pretty permalinks Given a WP install And I launch in the background `wp server --host=localhost --port=8183` - And I run `wp rewrite structure "/%postname%/"` + And I run `wp rewrite structure "%postname%/"` When I run `wp rewrite list` Then STDOUT should contain: From 3339e59eac1a1d1472ecea34589dea0fd6d1c853 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 15:15:06 +0200 Subject: [PATCH 09/10] remove debug cruft --- features/server.feature | 6 ------ router.php | 12 ------------ 2 files changed, 18 deletions(-) diff --git a/features/server.feature b/features/server.feature index c435529..582ed70 100644 --- a/features/server.feature +++ b/features/server.feature @@ -47,12 +47,6 @@ Feature: Serve WordPress locally And I launch in the background `wp server --host=localhost --port=8183` And I run `wp rewrite structure "%postname%/"` - When I run `wp rewrite list` - Then STDOUT should contain: - """ - FORCE_FAIL_TO_SEE_RULES - """ - When I run `curl -sSL http://localhost:8183/hello-world/` Then STDOUT should contain: """ diff --git a/router.php b/router.php index 9f274f1..c6e3c45 100644 --- a/router.php +++ b/router.php @@ -178,18 +178,6 @@ static function ( $buffer ) { $_SERVER['SCRIPT_FILENAME'] = $wpcli_server_root . DIRECTORY_SEPARATOR . 'index.php'; $_SERVER['PATH_INFO'] = $wpcli_server_path; // Help WordPress parse request - if ( str_contains( $_SERVER['REQUEST_URI'], 'hello-world' ) ) { - header( 'Content-Type: application/json' ); - echo json_encode( - array( - 'SERVER' => $_SERVER, - 'wpcli_server_path' => $wpcli_server_path, - 'wpcli_server_file' => $wpcli_server_file, - ) - ); - exit; - } - chdir( $wpcli_server_root ); require_once 'index.php'; } From 90e4781d22a9a131e82e17c050116afcc64b36d5 Mon Sep 17 00:00:00 2001 From: Pascal Birchler Date: Tue, 14 Apr 2026 15:52:00 +0200 Subject: [PATCH 10/10] Remove debug leftover --- features/server.feature | 1 + router.php | 12 ------------ 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/features/server.feature b/features/server.feature index 582ed70..963720e 100644 --- a/features/server.feature +++ b/features/server.feature @@ -45,6 +45,7 @@ Feature: Serve WordPress locally Scenario: Pretty permalinks Given a WP install And I launch in the background `wp server --host=localhost --port=8183` + # No leading slash for Windows compatibility on CI. And I run `wp rewrite structure "%postname%/"` When I run `curl -sSL http://localhost:8183/hello-world/` diff --git a/router.php b/router.php index c6e3c45..a0c22df 100644 --- a/router.php +++ b/router.php @@ -141,18 +141,6 @@ static function ( $buffer ) { // Normalize slashes for file operations $wpcli_server_file = str_replace( array( '/', '\\' ), DIRECTORY_SEPARATOR, $wpcli_server_file ); -if ( $wpcli_server_path === '/__debug' ) { - header( 'Content-Type: application/json' ); - echo json_encode( - array( - 'SERVER' => $_SERVER, - 'wpcli_server_path' => $wpcli_server_path, - 'wpcli_server_file' => $wpcli_server_file, - ) - ); - exit; -} - if ( file_exists( $wpcli_server_file ) ) { if ( is_dir( $wpcli_server_file ) && substr( $wpcli_server_path, -1 ) !== '/' ) { header( "Location: $wpcli_server_path/" );