[php-snippet] Highlight PHP snippet reruns - #3594
Merged
Merged
Conversation
adamziel
force-pushed
the
adamziel/run-once-highlight
branch
2 times, most recently
from
May 3, 2026 17:05
147f4a1 to
59e5cbb
Compare
adamziel
force-pushed
the
adamziel/run-once-highlight
branch
from
May 3, 2026 19:42
59e5cbb to
70641ab
Compare
…ghlight # Conflicts: # packages/playground/wordpress/tests/test-legacy-wp-version-boot.mjs
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
Adds more visible run-state feedback to the embedded PHP snippet UI and updates tests around snippet execution behavior.
Changes:
- Reworks the Run button to show inline busy state with spinner, status text, and percent while execution is in flight.
- Adds a short output flash on each completed run and refactors execution into
_run()/_runOnce(code). - Updates Playwright coverage for snippet runtime behavior and adds a timeout adjustment in a remote worker test.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.
| File | Description |
|---|---|
| packages/playground/website/public/php-code-snippet.js | Adds busy-button UI, output flash animation, and refactors run execution flow. |
| packages/playground/website/playwright/e2e/php-code-snippet.spec.ts | Updates snippet E2E tests for shared-runtime behavior and adds a busy-button regression test. |
| packages/playground/remote/src/lib/playground-worker-endpoint.spec.ts | Extends timeout for an OPFS-related worker endpoint test. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+579
to
+586
| .run-spinner { | ||
| display: none; | ||
| width: 12px; | ||
| height: 12px; | ||
| border: 2px solid rgba(255, 255, 255, 0.45); | ||
| border-top-color: #ffffff; | ||
| border-radius: 50%; | ||
| animation: php-snippet-spin 700ms linear infinite; |
Comment on lines
+969
to
+980
| * The class is cleared on animationend so the DOM doesn't carry stale | ||
| * state between runs. | ||
| */ | ||
| _flashOutput(outputBody) { | ||
| outputBody.classList.remove('flash'); | ||
| outputBody.getBoundingClientRect(); | ||
| outputBody.classList.add('flash'); | ||
| const clear = () => { | ||
| outputBody.classList.remove('flash'); | ||
| outputBody.removeEventListener('animationend', clear); | ||
| }; | ||
| outputBody.addEventListener('animationend', clear); |
Comment on lines
940
to
+941
| outputWrap.classList.add('visible'); | ||
| this._flashOutput(outputBody); |
Comment on lines
+147
to
+155
| // Third snippet — same shared runtime. It should still show its own | ||
| // run progress, but it should not create a second runtime iframe. | ||
| const thirdStart = Date.now(); | ||
| await third.locator('.run').click(); | ||
| await expect(third.locator('.output')).toBeVisible({ | ||
| timeout: 60_000, | ||
| }); | ||
| const thirdProgressWasVisible = await third.evaluate( | ||
| (snippet: HTMLElement) => { | ||
| const state = (snippet as any).__progressVisibilityState; | ||
| state.observer.disconnect(); | ||
| return state.wasVisible; | ||
| } | ||
| ); | ||
| expect(thirdProgressWasVisible).toBe(false); | ||
| const thirdElapsed = Date.now() - thirdStart; | ||
| expect(thirdElapsed).toBeLessThan(60_000); |
Comment on lines
921
to
+933
| const rounded = Math.round(pct); | ||
| fill.style.width = rounded + '%'; | ||
| percent.textContent = rounded + '%'; | ||
| if (cap) caption.textContent = cap; | ||
| this._setRunButtonProgress(cap || 'Loading', rounded); | ||
| if (cap) { | ||
| caption.textContent = cap; | ||
| } | ||
| } | ||
| ); | ||
| caption.textContent = 'Running…'; | ||
| fill.style.width = '100%'; | ||
| percent.textContent = '100%'; | ||
| const response = await client.run({ code: this._code }); | ||
| this._setRunButtonProgress('Running', 100); |
Comment on lines
+725
to
+742
| /* | ||
| * Brief blue wash that fades to transparent every time the output is | ||
| * refreshed. Re-running an idempotent snippet produces the same text, so | ||
| * without a visible cue the click feels like a no-op — users were clicking | ||
| * Run twice. The animation is purely cosmetic, ~700ms, with reduced-motion | ||
| * users getting an instant on/off swap instead. | ||
| */ | ||
| .output-body.flash { | ||
| animation: php-snippet-flash 700ms ease-out; | ||
| } | ||
| @keyframes php-snippet-flash { | ||
| 0% { background-color: rgba(56, 139, 253, 0.35); } | ||
| 100% { background-color: transparent; } | ||
| } | ||
| @media (prefers-reduced-motion: reduce) { | ||
| .output-body.flash { | ||
| animation: php-snippet-flash 200ms steps(2, end); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
Adds a brief output flash to the embedded PHP snippet component each time a
Run completes, including repeated runs that produce identical output.
Shows the running state directly inside the Run button while an execution is in
flight. The button is disabled during that window, but now displays a spinner,
status label, and percent so the click does not look ignored.
Adds a Playwright regression test that exercises the busy button state and
verifies the button returns to a normal single-click Run state afterwards.
Why
When a snippet produced the same output on a subsequent run, the UI could feel
like the Run click did nothing. The visible flash gives users immediate
feedback.
There was also a confusing disabled-button path: clicking while the previous
run was still finishing did nothing visible, so users could think the rerun
required another click. The inline busy indicator makes that state explicit.
Validation
npm exec nx run playground-website:lintnpm exec nx run playground-website:e2e:playwright -- --grep "Run button shows progress"