Skip to content

Commit 1509347

Browse files
committed
Merge remote-tracking branch 'origin/master' into vlk/playground-package-split
# Conflicts: # .gitignore # apps/docs/__tests__/LandingPage_.test.res # apps/docs/app/routes/LandingPage.res # apps/docs/package.json # apps/docs/plugins/cm6-reason-mode.js # apps/docs/rescript.json # apps/docs/src/bindings/Babel.res # apps/docs/src/bindings/RescriptCompilerApi.res # apps/docs/src/bindings/RescriptCompilerApi.resi # apps/docs/src/common/Ansi.res # apps/docs/src/common/Ansi.resi # apps/docs/src/common/HighlightJs.res # apps/docs/src/common/HighlightJs.resi # apps/docs/src/common/ScrollLockContext.res # apps/docs/src/common/Semver.res # apps/docs/src/common/Semver.resi # apps/docs/src/common/WarningFlagDescription.res # apps/docs/src/common/WarningFlagDescription.resi # apps/docs/src/components/AnsiPre.res # apps/docs/src/components/AnsiPre.resi # apps/docs/src/components/CodeMirror.res # apps/docs/src/components/CodeMirror.resi # apps/docs/src/components/Icon.res # apps/docs/src/components/Icon.resi # apps/docs/src/components/Text.res # apps/docs/src/components/Text.resi # apps/docs/src/components/ToggleButton.res # apps/docs/src/ffi/loadScript.js # apps/docs/src/playground/CompilerManagerHook.res # apps/docs/src/playground/CompilerManagerHook.resi # apps/docs/src/playground/ConsolePanel.res # apps/docs/src/playground/EvalIFrame.res # apps/docs/src/playground/LzString.res # apps/docs/src/playground/OutputPanel.res # apps/docs/src/playground/Playground.res # apps/docs/src/playground/Playground.resi # apps/docs/src/playground/PlaygroundLazy.res # apps/docs/src/playground/RenderPanel.res # apps/docs/src/playground/RenderPanel.resi # apps/docs/vitest.setup.mjs # packages/playground/ffi/loadScript.js # packages/playground/src/CompilerManagerHook.res # packages/playground/src/CompilerManagerHook.resi # packages/playground/src/ConsolePanel.res # packages/playground/src/EvalIFrame.res # packages/playground/src/LzString.res # packages/playground/src/OutputPanel.res # packages/playground/src/Playground.res # packages/playground/src/Playground.resi # packages/playground/src/PlaygroundLazy.res # packages/playground/src/RenderPanel.res # packages/playground/src/RenderPanel.resi # packages/playground/src/ToggleButton.res # packages/shared/plugins/cm6-reason-mode.js # packages/shared/src/Ansi.res # packages/shared/src/Ansi.resi # packages/shared/src/AnsiPre.res # packages/shared/src/AnsiPre.resi # packages/shared/src/Babel.res # packages/shared/src/CodeMirror.res # packages/shared/src/CodeMirror.resi # packages/shared/src/HighlightJs.res # packages/shared/src/HighlightJs.resi # packages/shared/src/Icon.res # packages/shared/src/Icon.resi # packages/shared/src/RescriptCompilerApi.res # packages/shared/src/RescriptCompilerApi.resi # packages/shared/src/ScrollLockContext.res # packages/shared/src/Semver.res # packages/shared/src/Semver.resi # packages/shared/src/Text.res # packages/shared/src/Text.resi # packages/shared/src/WarningFlagDescription.res # packages/shared/src/WarningFlagDescription.resi # plugins/cm6-reason-mode.js # rescript.json # src/bindings/Babel.res # src/bindings/RescriptCompilerApi.res # src/bindings/RescriptCompilerApi.resi # src/common/Ansi.res # src/common/Ansi.resi # src/common/HighlightJs.res # src/common/HighlightJs.resi # src/common/ScrollLockContext.res # src/common/Semver.res # src/common/Semver.resi # src/common/WarningFlagDescription.res # src/common/WarningFlagDescription.resi # src/components/AnsiPre.res # src/components/AnsiPre.resi # src/components/CodeMirror.res # src/components/CodeMirror.resi # src/components/Icon.res # src/components/Icon.resi # src/components/Text.res # src/components/Text.resi # src/components/ToggleButton.res # src/ffi/loadScript.js # src/playground/CompilerManagerHook.res # src/playground/CompilerManagerHook.resi # src/playground/ConsolePanel.res # src/playground/EvalIFrame.res # src/playground/LzString.res # src/playground/OutputPanel.res # src/playground/Playground.res # src/playground/Playground.resi # src/playground/PlaygroundLazy.res # src/playground/RenderPanel.res # src/playground/RenderPanel.resi # yarn.lock
2 parents 9788098 + a11341c commit 1509347

40 files changed

Lines changed: 811 additions & 138 deletions

File tree

apps/docs/__tests__/BlogArticle_.test.res

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ let mockFrontmatterWithArticleImg: BlogFrontmatter.t = {
141141
co_authors: [],
142142
date: DateStr.fromString("2025-06-01"),
143143
previewImg: Nullable.null,
144-
articleImg: Nullable.Value("https://rescript-lang.org/brand/rescript-brandmark.svg"),
144+
articleImg: Nullable.Value("/brand/rescript-brandmark.svg"),
145145
title: "Blog Post With Article Image",
146146
badge: Nullable.Value(Release),
147147
description: Nullable.Value("A post with an article image."),
@@ -166,6 +166,7 @@ test("desktop blog article with article image shows image", async () => {
166166
await element(title)->toBeVisible
167167

168168
let wrapper = await screen->getByTestId("blog-article-wrapper")
169+
await waitForImages("[data-testid='blog-article-wrapper']")
169170
await element(wrapper)->toMatchScreenshot("desktop-blog-article-with-image")
170171
})
171172

apps/docs/__tests__/LandingPage_.test.res

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
open ReactRouter
22
open Vitest
33

4+
@module("vitest")
5+
external testWithTimeout: (string, unit => promise<unit>, int) => unit = "test"
6+
47
let expectedExample = `module Button = {
58
@react.component
69
let make = (~count) => {
@@ -15,6 +18,127 @@ let expectedExample = `module Button = {
1518
}
1619
}`
1720

21+
let snapshotSection = async (~width, ~height, ~sectionTestId, ~screenshotName) => {
22+
await viewport(width, height)
23+
24+
let screen = await render(
25+
<MemoryRouter initialEntries=["/"]>
26+
<LandingPage />
27+
</MemoryRouter>,
28+
)
29+
30+
let sourceSection = switch document->WebAPI.Document.querySelector(
31+
`[data-testid="${sectionTestId}"]`,
32+
) {
33+
| Value(section) => section
34+
| Null => failwith(`expected to find section ${sectionTestId}`)
35+
}
36+
37+
let sandboxTestId = `${sectionTestId}-snapshot`
38+
let snapshotHtml = sourceSection.outerHTML
39+
await screen->unmount
40+
41+
let snapshotScreen = await render(
42+
<div
43+
dataTestId=sandboxTestId
44+
style={{width: `${width->Int.toString}px`, margin: "0"}}
45+
dangerouslySetInnerHTML={"__html": snapshotHtml}
46+
/>,
47+
)
48+
49+
let snapshotTarget = await snapshotScreen->getByTestId(sandboxTestId)
50+
await element(snapshotTarget)->toBeVisible
51+
await waitForImages(`[data-testid="${sandboxTestId}"]`)
52+
await element(snapshotTarget)->toMatchScreenshot(screenshotName)
53+
await snapshotScreen->unmount
54+
}
55+
56+
let snapshotResponsive = async (~sectionTestId, ~screenshotBase) => {
57+
await snapshotSection(
58+
~width=1440,
59+
~height=1800,
60+
~sectionTestId,
61+
~screenshotName={`${screenshotBase}-desktop`},
62+
)
63+
64+
await snapshotSection(
65+
~width=900,
66+
~height=1800,
67+
~sectionTestId,
68+
~screenshotName={`${screenshotBase}-tablet`},
69+
)
70+
71+
await snapshotSection(
72+
~width=600,
73+
~height=1800,
74+
~sectionTestId,
75+
~screenshotName={`${screenshotBase}-mobile`},
76+
)
77+
}
78+
79+
testWithTimeout(
80+
"landing intro snapshots",
81+
async () => {
82+
await snapshotResponsive(~sectionTestId="landing-intro", ~screenshotBase="landing-page-intro")
83+
},
84+
30000,
85+
)
86+
87+
testWithTimeout(
88+
"landing playground hero snapshots",
89+
async () => {
90+
await snapshotResponsive(
91+
~sectionTestId="landing-playground-hero",
92+
~screenshotBase="landing-page-playground-hero",
93+
)
94+
},
95+
30000,
96+
)
97+
98+
testWithTimeout(
99+
"landing quick install snapshots",
100+
async () => {
101+
await snapshotResponsive(
102+
~sectionTestId="landing-quick-install",
103+
~screenshotBase="landing-page-quick-install",
104+
)
105+
},
106+
30000,
107+
)
108+
109+
testWithTimeout(
110+
"landing other selling points snapshots",
111+
async () => {
112+
await snapshotResponsive(
113+
~sectionTestId="landing-other-selling-points",
114+
~screenshotBase="landing-page-other-selling-points",
115+
)
116+
},
117+
30000,
118+
)
119+
120+
testWithTimeout(
121+
"landing trusted by snapshots",
122+
async () => {
123+
await snapshotResponsive(
124+
~sectionTestId="landing-trusted-by",
125+
~screenshotBase="landing-page-trusted-by",
126+
)
127+
},
128+
30000,
129+
)
130+
131+
testWithTimeout(
132+
"landing curated resources snapshots",
133+
async () => {
134+
await snapshotResponsive(
135+
~sectionTestId="landing-curated-resources",
136+
~screenshotBase="landing-page-curated-resources",
137+
)
138+
},
139+
30000,
140+
)
141+
18142
test(
19143
"landing page playground link uses compressed code that the playground can decode",
20144
async () => {
@@ -53,3 +177,94 @@ test(
53177
expect(decodedCode->Option.getOrThrow)->toBe(expectedExample)
54178
},
55179
)
180+
181+
test("landing page playground hero renders highlighted code tokens", async () => {
182+
let screen = await render(
183+
<MemoryRouter initialEntries=["/"]>
184+
<LandingPage />
185+
</MemoryRouter>,
186+
)
187+
188+
let _ = await screen->getByText("Write in ReScript")
189+
190+
let rescriptCodeBlock = switch document->WebAPI.Document.querySelector(
191+
"[data-testid='landing-playground-hero'] code.lang-res",
192+
) {
193+
| Value(codeBlock) => codeBlock
194+
| Null => failwith("expected landing playground hero to render the ReScript code block")
195+
}
196+
197+
let javascriptCodeBlock = switch document->WebAPI.Document.querySelector(
198+
"[data-testid='landing-playground-hero'] code.lang-js",
199+
) {
200+
| Value(codeBlock) => codeBlock
201+
| Null => failwith("expected landing playground hero to render the JavaScript code block")
202+
}
203+
204+
expect(rescriptCodeBlock.innerHTML->String.includes("<span"))->toBe(true)
205+
expect(javascriptCodeBlock.innerHTML->String.includes("<span"))->toBe(true)
206+
})
207+
208+
test(
209+
"landing page playground hero keeps highlight styling in the sandboxed snapshot copy",
210+
async () => {
211+
await viewport(1440, 1800)
212+
213+
let screen = await render(
214+
<MemoryRouter initialEntries=["/"]>
215+
<LandingPage />
216+
</MemoryRouter>,
217+
)
218+
219+
let sourceSection = switch document->WebAPI.Document.querySelector(
220+
"[data-testid='landing-playground-hero']",
221+
) {
222+
| Value(section) => section
223+
| Null => failwith("expected to find the landing playground hero section")
224+
}
225+
226+
let sandboxTestId = "landing-playground-hero-sandbox"
227+
let snapshotHtml = sourceSection.outerHTML
228+
await screen->unmount
229+
230+
let snapshotScreen = await render(
231+
<div
232+
dataTestId=sandboxTestId
233+
style={{width: "1440px", margin: "0"}}
234+
dangerouslySetInnerHTML={"__html": snapshotHtml}
235+
/>,
236+
)
237+
238+
let _ = await snapshotScreen->getByTestId(sandboxTestId)
239+
240+
let sandbox = switch document->WebAPI.Document.querySelector(
241+
"[data-testid='landing-playground-hero-sandbox']",
242+
) {
243+
| Value(sandbox) => sandbox
244+
| Null => failwith("expected to find the sandboxed landing playground hero")
245+
}
246+
247+
let sandboxRect: WebAPI.DOMAPI.domRect = sandbox->WebAPI.Element.getBoundingClientRect
248+
249+
let rescriptCodeBlock = switch document->WebAPI.Document.querySelector(
250+
"[data-testid='landing-playground-hero-sandbox'] code.lang-res",
251+
) {
252+
| Value(codeBlock) => codeBlock
253+
| Null =>
254+
failwith("expected sandboxed landing playground hero to render the ReScript code block")
255+
}
256+
257+
let javascriptCodeBlock = switch document->WebAPI.Document.querySelector(
258+
"[data-testid='landing-playground-hero-sandbox'] code.lang-js",
259+
) {
260+
| Value(codeBlock) => codeBlock
261+
| Null =>
262+
failwith("expected sandboxed landing playground hero to render the JavaScript code block")
263+
}
264+
265+
expect(sandboxRect.width > 1000.0)->toBe(true)
266+
expect(rescriptCodeBlock.innerHTML->String.includes("<span"))->toBe(true)
267+
expect(javascriptCodeBlock.innerHTML->String.includes("<span"))->toBe(true)
268+
await snapshotScreen->unmount
269+
},
270+
)

apps/docs/__tests__/MarkdownComponents_.test.res

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ test("renders Image with caption", async () => {
204204
<div dataTestId="image-wrapper">
205205
<Markdown.Image
206206
className="rounded-lg border border-gray-90/5 text-gray-60"
207-
src="https://rescript-lang.org/lp/community-3.avif"
207+
src="/lp/community-3.avif"
208208
caption="A sample image caption"
209209
/>
210210
</div>,
@@ -214,6 +214,7 @@ test("renders Image with caption", async () => {
214214
await element(caption)->toBeVisible
215215

216216
let wrapper = await screen->getByTestId("image-wrapper")
217+
await waitForImages("[data-testid='image-wrapper']")
217218
await element(wrapper)->toMatchScreenshot("markdown-image")
218219
})
219220

32.5 KB
Loading
28.9 KB
Loading
32.1 KB
Loading
26.2 KB
Loading
22.8 KB
Loading
26 KB
Loading
126 KB
Loading

0 commit comments

Comments
 (0)