Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b966e9a
Playground file browser
adamziel Oct 21, 2025
d09b6f0
resizable site panel
adamziel Oct 21, 2025
75f935d
resizable site panel
adamziel Oct 22, 2025
5223de8
Merge
adamziel Oct 23, 2025
6f6bfb3
Don't move the focus back to the file tree too early
adamziel Oct 23, 2025
c9e8507
Double click = focus on the file. Single click = select file
adamziel Oct 23, 2025
6e9934d
Enter = focus on the code editor
adamziel Oct 23, 2025
d04a1f5
Immediately open newly created files
adamziel Oct 23, 2025
2c0686c
Focus on the first context menu item
adamziel Oct 23, 2025
7d69e57
E2E the file picker
adamziel Oct 23, 2025
cb22d52
Long editor
adamziel Oct 23, 2025
c4282d9
Retain cursor position in the code editor
adamziel Oct 23, 2025
2378604
Reopen the last active tab when Playground is reopened
adamziel Oct 23, 2025
bfa8f56
Lint, typecheck
adamziel Oct 23, 2025
41707a5
remove dev artifacts
adamziel Oct 23, 2025
6fa8eee
Merge branch 'trunk' into file-browser
adamziel Oct 23, 2025
43ddc83
Load non-php language extensions asynchronously
adamziel Oct 23, 2025
97c83a6
Simplify logic, improve comments
adamziel Oct 23, 2025
9712e4b
Simplify logic, remove constants file, reuse documentRoot, reuse WP i…
adamziel Oct 23, 2025
63afe2c
Display a clickable download link when editing binary files
adamziel Oct 23, 2025
cd5a154
Reuse php-wasm/util fs helpers instead of reimplementing them
adamziel Oct 23, 2025
402d7f5
Rename isProbablyTextBuffer to seemsLikeBinary
adamziel Oct 23, 2025
bb80aa7
Remove 300ms delay when opening a file
adamziel Oct 24, 2025
2e500e1
lint
adamziel Oct 24, 2025
ac748f3
Add Blueprint editor
adamziel Oct 24, 2025
56e1941
Don't lose focus when typing in the Blueprint editor
adamziel Oct 24, 2025
91d1331
Recreate Playground after clicking the button
adamziel Oct 24, 2025
31f9587
UI improvements
adamziel Oct 24, 2025
0c6aa13
UI improvements
adamziel Oct 24, 2025
29dec41
UI improvements
adamziel Oct 24, 2025
f8fa230
Merge branch 'trunk' into blueprint-editor
adamziel Oct 26, 2025
1182e53
Fix the test
adamziel Oct 27, 2025
3d7d5f2
Add e2e tests
adamziel Oct 28, 2025
9593220
Lint, typecheck
adamziel Oct 28, 2025
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
156 changes: 156 additions & 0 deletions packages/playground/website/playwright/e2e/website-ui.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -557,3 +557,159 @@ test('should keep query arguments when updating settings', async ({
await wordpress.locator('body').evaluate((body) => body.baseURI)
).toMatch('/wp-admin/');
});

test('should edit a file in the code editor and see changes in the viewport', async ({
website,
wordpress,
}) => {
await website.goto('./');

// Open site manager
await website.ensureSiteManagerIsOpen();

// Navigate to File Browser tab
await website.page.getByRole('tab', { name: 'File Browser' }).click();

// Wait for file tree to load
await website.page.locator('[data-path="/wordpress"]').waitFor();

// Expand /wordpress folder
const wordpressFolder = website.page.locator(
'button[data-path="/wordpress"]'
);
if ((await wordpressFolder.getAttribute('data-expanded')) !== 'true') {
await wordpressFolder.click();
}

// Double-click index.php to open it in the editor
await website.page
.locator('button[data-path="/wordpress/index.php"]')
.dblclick();

// Wait for CodeMirror editor to load
const editor = website.page.locator('[class*="file-browser"] .cm-editor');
await editor.waitFor({ timeout: 10000 });

// Click on the editor to focus it
await website.page.waitForTimeout(50);

await editor.click();

await website.page.waitForTimeout(250);

// Select all content in the editor (Cmd+A or Ctrl+A)
await website.page.keyboard.press(
process.platform === 'darwin' ? 'Meta+A' : 'Control+A'
);

await website.page.keyboard.press('Backspace');
await website.page.waitForTimeout(200);

// Type the new content with a delay between keystrokes
await website.page.keyboard.type('Edited file', { delay: 50 });

// Wait a moment for the change to be processed
await website.page.waitForTimeout(500);

// Save the file (Cmd+S or Ctrl+S)
await website.page.keyboard.press(
process.platform === 'darwin' ? 'Meta+S' : 'Control+S'
);

// Wait for save to complete (look for save indicator if there is one)
await website.page.waitForTimeout(1000);

// Close the site manager to see the viewport
await website.ensureSiteManagerIsClosed();

// Reload just the WordPress iframe to see the changes
const playgroundViewport = website.page.frameLocator(
'#playground-viewport:visible,.playground-viewport:visible'
);
await playgroundViewport
.locator('#wp')
.evaluate((iframe: HTMLIFrameElement) => {
iframe.contentWindow?.location.reload();
});

// Verify the page shows "Edited file"
await expect(wordpress.locator('body')).toContainText('Edited file', {
timeout: 10000,
});
});

test('should edit a blueprint in the blueprint editor and recreate the playground', async ({
website,
wordpress,
}) => {
await website.goto('./');

// Open site manager
await website.ensureSiteManagerIsOpen();

// Navigate to Blueprint tab
await website.page.getByRole('tab', { name: 'Blueprint' }).click();

// Wait for CodeMirror editor to load
const editor = website.page.locator(
'[class*="blueprint-editor"] .cm-editor'
);
await editor.waitFor({ timeout: 10000 });

await editor.click();

// Delete all content in the editor (Cmd+A or Ctrl+A)
await website.page.keyboard.press(
process.platform === 'darwin' ? 'Meta+A' : 'Control+A'
);

await website.page.keyboard.press('Backspace');
await website.page.waitForTimeout(200);

// Create a simple blueprint that writes "Blueprint test" to index.php
const blueprint = JSON.stringify(
{
landingPage: '/index.php',
steps: [
{
step: 'writeFile',
path: '/wordpress/index.php',
data: 'Blueprint test',
},
],
},
null,
2
);

// Type the new blueprint with a delay between keystrokes
await website.page.keyboard.type(blueprint, { delay: 50 });

// Remove the autoinserted brackets until the end of the Blueprint
await website.page.keyboard.down('Shift');
for (let i = 0; i < 4; i++) {
await website.page.keyboard.press('ArrowDown');
}

// Delete the selected lines
await website.page.keyboard.press('Backspace');

// Wait a moment for the change to be processed
await website.page.waitForTimeout(500);

// Click the "Recreate Playground from this Blueprint" button
await website.page
.getByRole('button', {
name: 'Recreate Playground from this Blueprint',
})
.click();

await website.page.waitForTimeout(1500);
// Wait for the playground to recreate
await website.waitForNestedIframes();

// Verify the page shows "Blueprint test"
await expect(wordpress.locator('body')).toContainText('Blueprint test', {
timeout: 10000,
});
});
11 changes: 6 additions & 5 deletions packages/playground/website/playwright/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export const playwrightConfig: PlaywrightTestConfig = {
fullyParallel: false,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
retries: 3,
retries: 0,
workers: 3,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [['html'], ['list', { printSteps: true }]],
Expand All @@ -23,6 +23,7 @@ export const playwrightConfig: PlaywrightTestConfig = {
trace: 'on-first-retry',
actionTimeout: 120000,
navigationTimeout: 120000,
headless: false,
},

timeout: 300000,
Expand All @@ -40,10 +41,10 @@ export const playwrightConfig: PlaywrightTestConfig = {
},
},

{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
// {
// name: 'firefox',
// use: { ...devices['Desktop Firefox'] },
// },

// Safari runner is disabled in CI – it used to be enabled but the tests
// failed randomly without any obvious reason.
Expand Down
Loading
Loading