Skip to content

[ xdebug ] Add --experimental-devtools option in Playground CLI #2411

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 24, 2025

Conversation

mho22
Copy link
Collaborator

@mho22 mho22 commented Jul 24, 2025

Motivation for the change, related issues

This pull request adds a --experimental-devtools option in wp-playground/cli.

Roadmap

Related issues and pull requests

Implementation details

  • Simple implementation of a Devtools option. It checks for a experimentalDevtools argument that starts the xdebug-to-cdp-bridge process.
  • Changes the StartBridgeConfig getPHPFile property type from (path: string) => string to (path: string) => Promise<string> and adapt the related code.

Testing Instructions

In WordPress-Playground repository

  1. Write a script like the following cli.ts :
import { runCLI } from "./packages/playground/cli/src/run-cli";

const script = `
<?php

$test = 42;

echo "Output!\n";

function test() {
	echo "Hello Xdebug World!\n";
}

test();
`;

const cliServer = await runCLI({command: 'server', xdebug: true, experimentalDevtools: true});

cliServer.playground.writeFile('xdebug.php', script);

const result = await cliServer.playground.run({scriptPath: `xdebug.php`});

console.log(result.text);
  1. Run the following command :
> node --no-warnings --experimental-wasm-stack-switching --experimental-wasm-jspi --loader=./packages/meta/src/node-es-module-loader/loader.mts cli.ts

Starting a PHP server...
Setting up WordPress undefined
Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip
Fetching SQLite integration plugin...
Booting WordPress...
Booted!
Running the Blueprint...
Running the Blueprint – 100%
Finished running the blueprint
WordPress is running on http://127.0.0.1:61290
Connect Chrome DevTools to CDP at:
devtools://devtools/bundled/inspector.html?ws=localhost:9229

...

Chrome connected! Initializing Xdebug receiver...
XDebug receiver running on port 9003
Running a PHP script with Xdebug enabled...

In a non-related Playground project

  1. Install dependencies
npm install @wp-playground/cli
  1. Write a script like the following cli.ts :
import { runCLI } from "@wp-playground/cli";

const script = `
<?php

$test = 42;

echo "Output!\n";

function test() {
	echo "Hello Xdebug World!\n";
}

test();
`;

const cliServer = await runCLI({command: 'server',  xdebug: true, experimentalDevtools: true});

await cliServer.playground.writeFile(`xdebug.php`, script);

const result = await cliServer.playground.run({scriptPath: `xdebug.php`});

console.log(result.text);
  1. Run command :
> node cli.js

Starting a PHP server...
Setting up WordPress undefined
Resolved WordPress release URL: https://downloads.w.org/release/wordpress-6.8.2.zip
Fetching SQLite integration plugin...
Booting WordPress...
Booted!
Running the Blueprint...
Running the Blueprint – 100%
Finished running the blueprint
WordPress is running on http://127.0.0.1:61859
Connect Chrome DevTools to CDP at:
devtools://devtools/bundled/inspector.html?ws=localhost:9229

...

Chrome connected! Initializing Xdebug receiver...
XDebug receiver running on port 9003
Running a PHP script with Xdebug enabled...
screencapture

Note: It will need 23 step overs before leaving the auto_prepend_file.php and entering the xdebug.php script.

@mho22
Copy link
Collaborator Author

mho22 commented Jul 24, 2025

@adamziel I'm not sure if the result I got is what you expected. I assume we should find a way to avoid going through the internal/shared files maybe to debug the given file directly? I'm not entirely sure. But having to click the step over button 23 times every time isn't very practical.

@mho22 mho22 added the XDebug label Jul 24, 2025
@adamziel
Copy link
Collaborator

@mho22 good question! Let's think about the user journey – they likely want to debug a plugin. That may involve making multiple requests but they're likely only interested in one of them. In an IDE, you'd see all your code you'd put a breakpoint in one of the files directly. In here, we don't have that code preview upfront.

One helpful workflows would be to break on the first line of a non-internal executed PHP file.

Technically, that's tricky. We need to run the /internal file via php.auto_prepend_file, but the XDebug feature we rely on is "break on the first executed line of code". But maybe we can find a way to still do that? E.g. use a path pattern to exclude a directory from debugging?

If there's no way around that, we could add a comment at the top of the /internal file to tell XDebug users what happened and that they need to navigate to their plugin file in the file explorer and put a breakpoint in the appropriate location.

cc @brandonpayton and @zaerl for thoughts. Also CC @sejas @wojtekn since that's relevant for Studio as well.

@wojtekn
Copy link
Collaborator

wojtekn commented Jul 24, 2025

@adamziel does the above mean we use break_on_first_line so debugging session breaks at first line and requires the user to manually step over? Shouldn't we use an approach in which it stops at first breakpoint by default?

@adamziel
Copy link
Collaborator

This is about a browser webtools integration. You need to start the devtools before you can set the breakpoint.

@mho22
Copy link
Collaborator Author

mho22 commented Jul 24, 2025

One helpful workflows would be to break on the first line of a non-internal executed PHP file.

@adamziel I think I found a way for cdp and dbgp to ignore certain commands and continue running as if nothing happened, when those commands are executed in specific URIs.
This opens up a lot of possibilities! We could skip files in the stack and step over them entirely:

screencapture

(Sorry about the disabled breakpoints — I can't remove them anymore. I added a checkbox for that bug in the follow-up.)

Anyway, I was thinking of separating this pull request from my current findings. Granting access to this PR would let more people experiment with the "experimental devtools", right?

@adamziel
Copy link
Collaborator

Yay 🎉! Sounds good - LMK when we're good to review and merge

@mho22
Copy link
Collaborator Author

mho22 commented Jul 24, 2025

@adamziel I think we're good now! Let's review and merge, possibly!

@adamziel adamziel merged commit 94fd429 into trunk Jul 24, 2025
49 of 50 checks passed
@adamziel adamziel deleted the add-experimental-devtools-option-in-playground-cli branch July 24, 2025 22:23
adamziel pushed a commit that referenced this pull request Jul 25, 2025
#2422)

## Motivation for the change, related issues

Resolves the [problem
introduced](https://github.com/WordPress/wordpress-playground/pull/2411/files#r2229819528)
in #2411:

> The promise returned by `getPHPFile()` is never resolved and the PHP
source code never loads in devtools
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants