diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/_files/index.html b/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/_files/index.html new file mode 100644 index 000000000..559bf40a4 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/_files/index.html @@ -0,0 +1 @@ +Before diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/content.md b/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/content.md new file mode 100644 index 000000000..ed0175fb3 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-1-from/content.md @@ -0,0 +1,10 @@ +--- +type: lesson +title: Auto Reload From +template: file-server +autoReload: true +previews: + - [8000, "Server"] +--- + +# Preview test - Auto Reload From diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/_files/index.html b/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/_files/index.html new file mode 100644 index 000000000..90703bd35 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/_files/index.html @@ -0,0 +1 @@ +After diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/content.md b/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/content.md new file mode 100644 index 000000000..1d9c34b2b --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-2-to/content.md @@ -0,0 +1,10 @@ +--- +type: lesson +title: Auto Reload To +template: file-server +autoReload: true +previews: + - [8000, "Server"] +--- + +# Preview test - Auto Reload To diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/_files/index.html b/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/_files/index.html new file mode 100644 index 000000000..d84e911c3 --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/_files/index.html @@ -0,0 +1 @@ +This should not be visible when navigated to diff --git a/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/content.md b/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/content.md new file mode 100644 index 000000000..695ce413d --- /dev/null +++ b/e2e/src/content/tutorial/tests/preview/auto-reload-3-off/content.md @@ -0,0 +1,10 @@ +--- +type: lesson +title: Auto Reload Off +template: file-server +autoReload: false +previews: + - [8000, "Server"] +--- + +# Preview test - Auto Reload Off diff --git a/e2e/src/templates/file-server/index.mjs b/e2e/src/templates/file-server/index.mjs new file mode 100644 index 000000000..406e08585 --- /dev/null +++ b/e2e/src/templates/file-server/index.mjs @@ -0,0 +1,16 @@ +import http from 'node:http'; +import fs from 'node:fs'; + +const server = http.createServer((req, res) => { + if (req.url === '/' || req.url === '/index.html') { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end(fs.readFileSync('./index.html', 'utf8')); + + return; + } + + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end('Not found'); +}); + +server.listen(8000); diff --git a/e2e/test/preview.test.ts b/e2e/test/preview.test.ts index 7ebe4b841..def45692e 100644 --- a/e2e/test/preview.test.ts +++ b/e2e/test/preview.test.ts @@ -24,3 +24,34 @@ test('user can see multiple preview tabs', async ({ page }) => { await expect(page.frameLocator('[title="First Server"]').getByText('Index page')).toBeVisible({ timeout: 10_000 }); await expect(page.frameLocator('[title="Second Server"]').getByText('About page')).toBeVisible({ timeout: 10_000 }); }); + +test('user can see new content when "autoReload: true" is set', async ({ page }) => { + await page.goto(`${BASE_URL}/auto-reload-1-from`); + + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload From' })).toBeVisible(); + await expect(page.frameLocator('[title="Server"]').getByText('Before')).toBeVisible({ timeout: 10_000 }); + + await page.getByRole('link', { name: 'Auto Reload To' }).click(); + + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload To' })).toBeVisible(); + await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 }); +}); + +test('user can see old content when "autoReload: false" is set', async ({ page }) => { + await page.goto(`${BASE_URL}/auto-reload-2-to`); + + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload To' })).toBeVisible(); + await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 }); + + await page.getByRole('link', { name: 'Auto Reload Off' }).click(); + await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload Off' })).toBeVisible(); + + // preview content should not change + await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 }); + + // reload page and verify the test case has different content than "Auto Reload To"-page + await page.reload(); + await expect( + page.frameLocator('[title="Server"]').getByText('This should not be visible when navigated to'), + ).toBeVisible({ timeout: 10_000 }); +}); diff --git a/packages/react/src/Panels/PreviewPanel.tsx b/packages/react/src/Panels/PreviewPanel.tsx index 11e7b73e7..591e8d158 100644 --- a/packages/react/src/Panels/PreviewPanel.tsx +++ b/packages/react/src/Panels/PreviewPanel.tsx @@ -48,14 +48,9 @@ export const PreviewPanel = memo( ref, () => ({ reload: () => { - // can't use a ref because PanelGroup does not expose the underlying html element - const previewPanel = document.getElementById('preview-panel'); - - if (previewPanel) { - const iframes = previewPanel.querySelectorAll('iframe'); - - for (const iframe of iframes) { - iframe.src = iframe.src; + for (const iframe of iframeRefs.current) { + if (iframe.ref) { + iframe.ref.src = iframe.ref.src; } } }, @@ -132,7 +127,7 @@ export const PreviewPanel = memo( } } - return createElement(PanelGroup, { id: 'preview-panel', direction: 'horizontal' }, ...children); + return createElement(PanelGroup, { direction: 'horizontal' }, ...children); }), ); PreviewPanel.displayName = 'PreviewPanel'; diff --git a/packages/react/src/Panels/WorkspacePanel.tsx b/packages/react/src/Panels/WorkspacePanel.tsx index bb3f028b7..3fb8a3328 100644 --- a/packages/react/src/Panels/WorkspacePanel.tsx +++ b/packages/react/src/Panels/WorkspacePanel.tsx @@ -79,12 +79,7 @@ export function WorkspacePanel({ tutorialStore, theme }: Props) { const unsubscribe = tutorialStore.lessonFullyLoaded.subscribe((loaded) => { if (loaded && lesson.data.autoReload) { - /** - * @todo This causes some race with the preview where the iframe can show the "wrong" page. - * I think the reason is that when the ports are different then we render new frames which - * races against the reload which will internally reset the `src` attribute. - */ - // previewRef.current?.reload(); + previewRef.current?.reload(); } });