Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 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
bdcd709
Make the Blueprints editor component optional for the offline mode
adamziel Nov 21, 2025
f18b5c3
Remove the "View Blueprint" menu item
adamziel Nov 21, 2025
29f0b84
Merge branch 'trunk' into blueprint-editor
adamziel Nov 21, 2025
c001fa4
Merge branch 'trunk' into blueprint-editor
adamziel Nov 21, 2025
7bbe613
Merge branch 'trunk' into blueprint-editor
adamziel Nov 21, 2025
2d29dc0
reenable firefox proejct
adamziel Nov 21, 2025
4a4bf00
restore headless option
adamziel Nov 21, 2025
d438d33
Merge branch 'trunk' into blueprint-editor
adamziel Nov 25, 2025
46deac5
revert docs changes
adamziel Nov 25, 2025
8055241
Reformat
adamziel Nov 25, 2025
4bbc1ac
reformat
adamziel Nov 25, 2025
dd5d6f8
reformat
adamziel Nov 25, 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
84 changes: 29 additions & 55 deletions package-lock.json

Large diffs are not rendered by default.

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,
});
});
Loading