diff --git a/.changeset/gentle-gorillas-sit.md b/.changeset/gentle-gorillas-sit.md new file mode 100644 index 000000000000..10f75d19ff37 --- /dev/null +++ b/.changeset/gentle-gorillas-sit.md @@ -0,0 +1,5 @@ +--- +"astro": patch +--- + +Fixes an issue where dev toolbar x-ray didn't escape props content. diff --git a/packages/astro/e2e/dev-toolbar.test.js b/packages/astro/e2e/dev-toolbar.test.js index b30d2709819d..ac8d7b4dff59 100644 --- a/packages/astro/e2e/dev-toolbar.test.js +++ b/packages/astro/e2e/dev-toolbar.test.js @@ -100,6 +100,34 @@ test.describe('Dev Toolbar', () => { await expect(xrayHighlightTooltip).not.toBeVisible(); }); + test('xray escapes props content', async ({ page, astro }) => { + let isAlertCalled = false; + page.on('dialog', async (dialog) => { + isAlertCalled = true; + await dialog.accept(); + }); + + await page.goto(astro.resolveUrl('/xray-props-escape')); + + const toolbar = page.locator('astro-dev-toolbar'); + const appButton = toolbar.locator('button[data-app-id="astro:xray"]'); + await appButton.click(); + + const xrayCanvas = toolbar.locator('astro-dev-toolbar-app-canvas[data-app-id="astro:xray"]'); + const xrayHighlight = xrayCanvas.locator('astro-dev-toolbar-highlight'); + await expect(xrayHighlight).toBeVisible(); + + await xrayHighlight.hover(); + const xrayHighlightTooltip = xrayHighlight.locator('astro-dev-toolbar-tooltip'); + await expect(xrayHighlightTooltip).toBeVisible(); + + const code = xrayHighlightTooltip.locator('pre > code'); + await expect(code).toHaveText( + JSON.stringify({ name: `` }, undefined, 2) + ); + expect(isAlertCalled).toBe(false); + }); + test('xray shows no islands message when there are none', async ({ page, astro }) => { await page.goto(astro.resolveUrl('/xray-no-islands')); diff --git a/packages/astro/e2e/fixtures/dev-toolbar/src/pages/xray-props-escape.astro b/packages/astro/e2e/fixtures/dev-toolbar/src/pages/xray-props-escape.astro new file mode 100644 index 000000000000..f2e5049dc4ef --- /dev/null +++ b/packages/astro/e2e/fixtures/dev-toolbar/src/pages/xray-props-escape.astro @@ -0,0 +1,9 @@ +--- +import { HelloWorld } from '../components/HelloWorld'; +--- + +
${JSON.stringify(
- Object.fromEntries(islandPropsEntries.map((prop: any) => [prop[0], prop[1][1]])),
- undefined,
- 2
- )}
`,
+ content: `${escapeHTML(stringifiedProps)}
`,
});
}