Skip to content

Commit 9754b26

Browse files
authored
fix(react): refresh preview when autoReload: true (#303)
1 parent 98ef05b commit 9754b26

File tree

10 files changed

+85
-15
lines changed

10 files changed

+85
-15
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Before
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
type: lesson
3+
title: Auto Reload From
4+
template: file-server
5+
autoReload: true
6+
previews:
7+
- [8000, "Server"]
8+
---
9+
10+
# Preview test - Auto Reload From
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
After
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
type: lesson
3+
title: Auto Reload To
4+
template: file-server
5+
autoReload: true
6+
previews:
7+
- [8000, "Server"]
8+
---
9+
10+
# Preview test - Auto Reload To
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This should not be visible when navigated to
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
type: lesson
3+
title: Auto Reload Off
4+
template: file-server
5+
autoReload: false
6+
previews:
7+
- [8000, "Server"]
8+
---
9+
10+
# Preview test - Auto Reload Off
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import http from 'node:http';
2+
import fs from 'node:fs';
3+
4+
const server = http.createServer((req, res) => {
5+
if (req.url === '/' || req.url === '/index.html') {
6+
res.writeHead(200, { 'Content-Type': 'text/html' });
7+
res.end(fs.readFileSync('./index.html', 'utf8'));
8+
9+
return;
10+
}
11+
12+
res.writeHead(200, { 'Content-Type': 'text/html' });
13+
res.end('Not found');
14+
});
15+
16+
server.listen(8000);

e2e/test/preview.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,34 @@ test('user can see multiple preview tabs', async ({ page }) => {
2424
await expect(page.frameLocator('[title="First Server"]').getByText('Index page')).toBeVisible({ timeout: 10_000 });
2525
await expect(page.frameLocator('[title="Second Server"]').getByText('About page')).toBeVisible({ timeout: 10_000 });
2626
});
27+
28+
test('user can see new content when "autoReload: true" is set', async ({ page }) => {
29+
await page.goto(`${BASE_URL}/auto-reload-1-from`);
30+
31+
await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload From' })).toBeVisible();
32+
await expect(page.frameLocator('[title="Server"]').getByText('Before')).toBeVisible({ timeout: 10_000 });
33+
34+
await page.getByRole('link', { name: 'Auto Reload To' }).click();
35+
36+
await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload To' })).toBeVisible();
37+
await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 });
38+
});
39+
40+
test('user can see old content when "autoReload: false" is set', async ({ page }) => {
41+
await page.goto(`${BASE_URL}/auto-reload-2-to`);
42+
43+
await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload To' })).toBeVisible();
44+
await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 });
45+
46+
await page.getByRole('link', { name: 'Auto Reload Off' }).click();
47+
await expect(page.getByRole('heading', { level: 1, name: 'Preview test - Auto Reload Off' })).toBeVisible();
48+
49+
// preview content should not change
50+
await expect(page.frameLocator('[title="Server"]').getByText('After')).toBeVisible({ timeout: 10_000 });
51+
52+
// reload page and verify the test case has different content than "Auto Reload To"-page
53+
await page.reload();
54+
await expect(
55+
page.frameLocator('[title="Server"]').getByText('This should not be visible when navigated to'),
56+
).toBeVisible({ timeout: 10_000 });
57+
});

packages/react/src/Panels/PreviewPanel.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,9 @@ export const PreviewPanel = memo(
4848
ref,
4949
() => ({
5050
reload: () => {
51-
// can't use a ref because PanelGroup does not expose the underlying html element
52-
const previewPanel = document.getElementById('preview-panel');
53-
54-
if (previewPanel) {
55-
const iframes = previewPanel.querySelectorAll('iframe');
56-
57-
for (const iframe of iframes) {
58-
iframe.src = iframe.src;
51+
for (const iframe of iframeRefs.current) {
52+
if (iframe.ref) {
53+
iframe.ref.src = iframe.ref.src;
5954
}
6055
}
6156
},
@@ -132,7 +127,7 @@ export const PreviewPanel = memo(
132127
}
133128
}
134129

135-
return createElement(PanelGroup, { id: 'preview-panel', direction: 'horizontal' }, ...children);
130+
return createElement(PanelGroup, { direction: 'horizontal' }, ...children);
136131
}),
137132
);
138133
PreviewPanel.displayName = 'PreviewPanel';

packages/react/src/Panels/WorkspacePanel.tsx

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,7 @@ export function WorkspacePanel({ tutorialStore, theme }: Props) {
7979

8080
const unsubscribe = tutorialStore.lessonFullyLoaded.subscribe((loaded) => {
8181
if (loaded && lesson.data.autoReload) {
82-
/**
83-
* @todo This causes some race with the preview where the iframe can show the "wrong" page.
84-
* I think the reason is that when the ports are different then we render new frames which
85-
* races against the reload which will internally reset the `src` attribute.
86-
*/
87-
// previewRef.current?.reload();
82+
previewRef.current?.reload();
8883
}
8984
});
9085

0 commit comments

Comments
 (0)