Skip to content

Commit 4de21b4

Browse files
authored
[Website] IDE-like PHP playground (#2699)
## Motivation for the change, related issues Introduces a beta version of PHP Playground that has a file explorer and a built-in terminal with `php`, `wp`, and `composer` commands available: <img width="3450" height="1988" alt="CleanShot 2025-09-29 at 01 55 42@2x (1)" src="https://github.com/user-attachments/assets/a54c85aa-322c-4025-82b6-44c733c90f3f" /> It does not replace the existing PHP Playground, only introduces a new beta version. We won't replace the existing one until a few people confirm the new one is useful and stable. After merging and deploying, it will be available at https://playground.wordpress.net/beta-php-playground.html This PR supersedes #2694 ## Implementation details This PR ships mostly new code and updates code unused anywhere else. The few changes it makes to the shared configuration are non-destructive and mostly don't affect the existing packages. ### FilePickerTree component Ships a substantial update to the FilePickerTree component to: * Accept an asynchronous filesystem * Consider asynchronous nature of operations in interactions such as initial loading, expanding tree nodes, renaming files * Have contextual menu with delete, rename, create file/dir operations * Support moving nodes via drag&drop * Support "uploading" files from the desktop via drag&drop It seems like it breaks the "type to focus" interaction. That's fine, we'll fix it in a follow-up. That component isn't used anywhere else at the moment so we're not breaking any other page. It also ships a few e2e tests to be expanded ### New package This PR ships an additional `website-extras` package with the beta version of PHP Playground. Why a new package? Because the `website` packages is built offline-first. We have manifest.json automations in place for PWAs so browsers can download and cache most of the built files. Maintaining a clear separation between required and optional files is a substantial burden. Hence, this PR takes another approach entirely and clearly separates the offline-first parts from the parts we don't need to ask the client to download pre-emptively. The nx build pipeline will build the `remote` package, the `website` package, build the list of assets required for offline mode, prepare the website deployment, and only then it will merge the `website-extras` into that deployment directory. ## Testing Instructions (or ideally a Blueprint) Go to http://127.0.0.1:5400/website-extras/beta-php-playground.html and play with the beta PHP Playground.
1 parent da23203 commit 4de21b4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+6928
-422
lines changed

.eslintrc.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@
2929
"no-inner-declarations": 0,
3030
"no-use-before-define": "off",
3131
"react/prop-types": 0,
32+
"react-hooks/exhaustive-deps": 0,
3233
"no-console": 1,
3334
"no-empty": 0,
3435
"no-async-promise-executor": 0,
3536
"no-constant-condition": 0,
3637
"no-nested-ternary": 0,
38+
"jsx-a11y/accessible-emoji": 0,
3739
"jsx-a11y/click-events-have-key-events": 0,
3840
"jsx-a11y/no-static-element-interactions": 0,
3941
"comment-length/limit-single-line-comments": [

package-lock.json

Lines changed: 792 additions & 259 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@
6666
},
6767
"private": true,
6868
"dependencies": {
69+
"@codemirror/autocomplete": "6.19.0",
70+
"@codemirror/commands": "6.8.1",
71+
"@codemirror/lang-css": "6.3.1",
72+
"@codemirror/lang-html": "6.4.10",
73+
"@codemirror/lang-javascript": "6.2.4",
74+
"@codemirror/lang-json": "6.0.2",
75+
"@codemirror/lang-markdown": "6.3.4",
76+
"@codemirror/lang-php": "6.0.2",
77+
"@codemirror/language": "6.11.3",
78+
"@codemirror/search": "6.5.11",
79+
"@codemirror/state": "6.5.2",
80+
"@codemirror/view": "6.38.3",
6981
"@preact/signals-react": "1.3.6",
7082
"@reduxjs/toolkit": "2.6.1",
7183
"@types/xml2js": "0.4.14",
@@ -87,6 +99,7 @@
8799
"react-dom": "18.3.1",
88100
"react-hook-form": "7.53.0",
89101
"react-redux": "8.1.3",
102+
"react-resizable-panels": "3.0.6",
90103
"react-transition-group": "4.4.5",
91104
"sha.js": "2.4.11",
92105
"tmp-promise": "3.0.3",
@@ -183,6 +196,7 @@
183196
"react": "18.3.1",
184197
"react-dom": "18.3.1",
185198
"typescript": "5.4.5",
199+
"@playwright/test": "1.47.1",
186200
"ws": "^8.18.0"
187201
},
188202
"workspaces": [

packages/playground/build-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ export const remoteDevServerPort = 4400;
33

44
export const websiteDevServerHost = '127.0.0.1';
55
export const websiteDevServerPort = 5400;
6+
7+
export const websiteExtrasDevServerHost = '127.0.0.1';
8+
export const websiteExtrasDevServerPort = 6400;
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import {
2+
defineConfig,
3+
devices,
4+
type PlaywrightTestConfig,
5+
} from '@playwright/test';
6+
7+
const baseURL =
8+
process.env.PLAYWRIGHT_TEST_BASE_URL || 'http://127.0.0.1:5174/';
9+
10+
export const playwrightConfig: PlaywrightTestConfig = {
11+
testDir: './tests',
12+
/* Run tests in files in parallel */
13+
fullyParallel: false,
14+
/* Fail the build on CI if you accidentally left test.only in the source code. */
15+
forbidOnly: !!process.env.CI,
16+
retries: 3,
17+
workers: 3,
18+
19+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
20+
reporter: [['html'], ['list', { printSteps: true }]],
21+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
22+
use: {
23+
/* Base URL to use in actions like `await page.goto('/')`. */
24+
baseURL,
25+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
26+
trace: 'on-first-retry',
27+
actionTimeout: 120000,
28+
navigationTimeout: 120000,
29+
},
30+
31+
timeout: 300000,
32+
expect: { timeout: 60000 },
33+
34+
/* Configure projects for major browsers */
35+
projects: [
36+
{
37+
name: 'chromium',
38+
use: {
39+
...devices['Desktop Chrome'],
40+
},
41+
},
42+
],
43+
44+
/* Run your local dev server before starting the tests */
45+
webServer: {
46+
command:
47+
'npx nx run playground-components:dev -- --host 127.0.0.1 --port 5174',
48+
url: 'http://127.0.0.1:5174/',
49+
reuseExistingServer: !process.env.CI,
50+
},
51+
};
52+
53+
/**
54+
* See https://playwright.dev/docs/test-configuration.
55+
*/
56+
export default defineConfig(playwrightConfig);

0 commit comments

Comments
 (0)