Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
51dc3f8
refactor: refactoring navbars
jderochervlk Feb 8, 2026
be70e99
making progress on the nav
jderochervlk Feb 8, 2026
0808cbc
scrolling works again
jderochervlk Feb 10, 2026
949389f
refactoring
jderochervlk Feb 10, 2026
bd7b348
mobile overlay works
jderochervlk Feb 15, 2026
482b405
tests are passing
jderochervlk Feb 15, 2026
80b836d
done with mobile overlay
jderochervlk Feb 16, 2026
3eb6f20
screenshots
jderochervlk Feb 16, 2026
53682b0
removing top padding
jderochervlk Feb 16, 2026
876486a
fix playground
jderochervlk Feb 16, 2026
57dae95
remove unused open
jderochervlk Feb 16, 2026
b7de7a6
fix issue with homepage reloading nonstop
jderochervlk Feb 16, 2026
86f806b
restor mdx route
jderochervlk Feb 16, 2026
09e42d4
remove dummy page
jderochervlk Feb 16, 2026
f642c1c
fixing docs
jderochervlk Feb 16, 2026
6e0bc9d
fix syntax lookup
jderochervlk Feb 16, 2026
c671d16
remove build errors and warnings
jderochervlk Feb 16, 2026
e0bf40d
commit screenshot changes
jderochervlk Feb 16, 2026
21a333c
chore: update vitest screenshots [skip ci]
jderochervlk Feb 16, 2026
f4ec369
remove unused values
jderochervlk Feb 16, 2026
f66a9f1
remove unused file
jderochervlk Feb 16, 2026
5e5c0e1
tidying up
jderochervlk Feb 16, 2026
76414e8
fix version dropdown
jderochervlk Feb 17, 2026
95b07eb
Update src/components/Search.res
jderochervlk Feb 18, 2026
a15986e
Update src/components/BreadCrumbs.res
jderochervlk Feb 18, 2026
588fc92
Fix mobile overlay not closing on navigation link clicks (#1198)
Copilot Feb 21, 2026
0f26f30
PR feedback.
jderochervlk Feb 21, 2026
17f7d42
PR feedback
jderochervlk Feb 21, 2026
2605d2a
cleanup
jderochervlk Feb 21, 2026
04ba370
Fix sidebar scrolling when it shouldn't
jderochervlk Feb 23, 2026
e578f9c
ci: add Playwright and run tests during CI
jderochervlk Feb 23, 2026
63a5a27
chore: add chromatic
jderochervlk Mar 16, 2026
9057bc3
Merge branch 'master' of github.com:rescript-lang/rescript-lang.org i…
jderochervlk Mar 16, 2026
09be065
add takeSnapshot
jderochervlk Mar 16, 2026
21428dc
fix failing landing page test
jderochervlk Mar 16, 2026
66eed8d
trying to fix playwright
jderochervlk Mar 16, 2026
ff2de6d
trying more ideas
jderochervlk Mar 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 91 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
contents: read
deployments: write
pull-requests: write
outputs:
deployment-url: ${{ steps.set-url.outputs.deployment-url }}
is-pr: ${{ github.event_name == 'pull_request' }}
steps:
- uses: actions/checkout@v4
- name: Setup yarn
Expand All @@ -38,11 +41,12 @@ jobs:

if [[ "$RAW_BRANCH" == "master" ]]; then
echo "VITE_DEPLOYMENT_URL=" >> "$GITHUB_ENV"
echo "SAFE_BRANCH=" >> "$GITHUB_ENV"
else
SAFE_BRANCH="${RAW_BRANCH//\//-}"

SAFE_BRANCH=$(echo "$SAFE_BRANCH" | tr '[:upper:]' '[:lower:]')

echo "SAFE_BRANCH=$SAFE_BRANCH" >> "$GITHUB_ENV"
echo "VITE_DEPLOYMENT_URL=https://${SAFE_BRANCH}.rescript-lang.pages.dev" >> "$GITHUB_ENV"
fi
Expand All @@ -61,6 +65,15 @@ jobs:
wranglerVersion: 4.63.0
env:
FORCE_COLOR: 0
- name: Set deployment URL output
id: set-url
shell: bash
run: |
if [[ "${{ github.ref_name }}" == "master" ]]; then
echo "deployment-url=https://rescript-lang.org" >> "$GITHUB_OUTPUT"
else
echo "deployment-url=${{ env.VITE_DEPLOYMENT_URL }}" >> "$GITHUB_OUTPUT"
fi
- name: Comment PR with deployment link
uses: marocchino/sticky-pull-request-comment@v2
with:
Expand All @@ -72,3 +85,79 @@ jobs:
Deployment Environment: ${{ steps.deploy.outputs.pages-environment }}

${{ steps.deploy.outputs.command-output }}

e2e:
name: E2E Tests
runs-on: ubuntu-latest
needs: [deploy]
# Only run E2E on pull requests from non-fork branches; push-to-master runs
# are excluded here since production smoke tests are a separate concern.
if: ${{ github.event_name == 'pull_request' && needs.deploy.outputs.deployment-url != '' }}
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4

- name: Setup node
uses: actions/setup-node@v4
with:
node-version-file: ".node-version"
cache: yarn

- name: Install dependencies
run: yarn install

# The e2e test files are written in ReScript and must be compiled to .jsx
# before Playwright can discover and run them.
- name: Build ReScript (includes e2e tests)
run: yarn build:res

- name: Install Playwright browsers (Chromium only)
run: yarn playwright install chromium --with-deps

- name: Run Playwright E2E tests
run: yarn e2e
env:
PLAYWRIGHT_BASE_URL: ${{ needs.deploy.outputs.deployment-url }}
CI: true

- name: Run Chromatic visual regression
# Always run Chromatic even when Playwright tests fail so that visual
# diffs are still captured and surfaced on the PR.
if: ${{ always() && needs.deploy.outputs.deployment-url != '' }}
run: yarn e2e:chromatic --exit-zero-on-changes
env:
CHROMATIC_PROJECT_TOKEN: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
PLAYWRIGHT_BASE_URL: ${{ needs.deploy.outputs.deployment-url }}

- name: Upload Playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
retention-days: 30

- name: Upload test results (traces / screenshots / videos)
if: ${{ failure() }}
uses: actions/upload-artifact@v4
with:
name: test-results
path: test-results/
retention-days: 7

- name: Comment PR with Playwright report link
if: ${{ failure() }}
uses: marocchino/sticky-pull-request-comment@v2
with:
recreate: true
header: e2e-report
message: |
## E2E Test Failures

One or more Playwright tests failed against the preview deployment.

**Preview URL:** ${{ needs.deploy.outputs.deployment-url }}

Download the full HTML report from the [workflow run artifacts](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}).
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,15 +43,19 @@ dist
build
.react-router
mdx-manifest.json
build-archive.log

app/**/*.mjs
app/**/*.jsx
functions/**/*.mjs
functions/**/*.jsx
__tests__/**/*.mjs
__tests__/**/*.jsx
e2e/**/*.mjs
e2e/**/*.jsx
!_shims.mjs
!_shims.jsx
!src/bindings/playwright-shim.mjs

# Yarn
.yarn/*
Expand All @@ -72,4 +76,8 @@ _scripts

# Vitest screenshots
!__tests__/__screenshots__/**/*
.vitest-attachments
.vitest-attachments

# Playwright artifacts
playwright-report/
test-results/
4 changes: 4 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
e2e/**/*.mjs
e2e/**/*.jsx
playwright-report/
test-results/
!_shims.mjs
!public/_redirects
.DS_Store
Expand Down
69 changes: 69 additions & 0 deletions e2e/DocsPage.test.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
open Playwright

describe("Docs Page", () => {
test("has the correct page title", async ({page}) => {
let _ = await page->goto("/docs")
await page->expect->toHaveTitle("ReScript Documentation")
})

test("renders the docs overview heading", async ({page}) => {
let _ = await page->goto("/docs")
let heading = page->getByRole("heading", ~options={name: "Documentation"})
await heading->expect->toBeVisible
})

test("docs navigation sidebar is present on the introduction page", async ({page}) => {
let _ = await page->goto("/docs/manual/latest/introduction")
let sidebar = page->getByRole("navigation")
await sidebar->expect->toBeVisible
})

test("can navigate from the overview to the introduction", async ({page}) => {
let _ = await page->goto("/docs")
let introLink = page->getByRole("link", ~options={name: "Introduction"})
await introLink->first->click
await page->expect->toHaveURL("/docs/manual/latest/introduction")
})

test("introduction page renders main content with h1", async ({page}) => {
let _ = await page->goto("/docs/manual/latest/introduction")
let mainContent = page->locator("main")
await mainContent->expect->toBeVisible
let heading = page->getByRole("heading", ~options={name: "Introduction", level: 1})
await heading->expect->toBeVisible
})

test("syntax lookup page loads with heading", async ({page}) => {
let _ = await page->goto("/syntax-lookup")
let heading = page->getByRole("heading", ~options={name: "Syntax Lookup"})
await heading->expect->toBeVisible
})

test("packages page loads", async ({page}) => {
let _ = await page->goto("/packages")
let heading = page->getByRole("heading", ~options={name: "Packages"})
await heading->expect->toBeVisible
})

test("has no accessibility violations on the docs overview", async ({page}) => {
let _ = await page->goto("/docs")
await page->assertNoA11yViolations
})

test("has no accessibility violations on the introduction page", async ({page}) => {
let _ = await page->goto("/docs/manual/latest/introduction")
await page->assertNoA11yViolations
})

test("visual snapshot — docs overview", async ({page}) => {
let _ = await page->goto("/docs")
await page->waitForLoadState("networkidle")
await takeSnapshot(page, "Docs Overview")
})

test("visual snapshot — introduction page", async ({page}) => {
let _ = await page->goto("/docs/manual/latest/introduction")
await page->waitForLoadState("networkidle")
await takeSnapshot(page, "Docs Introduction")
})
})
63 changes: 63 additions & 0 deletions e2e/LandingPageTest.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
open Playwright

describe("Landing Page", () => {
test("has the correct page title", async ({page}) => {
let _ = await page->goto("/")
await page
->expect
->toHaveTitle(
"ReScript - A robustly typed language that compiles to efficient and human-readable JavaScript.",
)
})

test("renders the hero section heading", async ({page}) => {
let _ = await page->goto("/")
let hero =
page->getByRole(
"heading",
~options={name: "Fast, Simple, Fully Typed JavaScript from the Future"},
)
await hero->expect->toBeVisible
})

test("primary navigation links are present and visible", async ({page}) => {
let _ = await page->goto("/")

await page->getByRole("link", ~options={name: "Docs"})->expect->toBeVisible
await page->getByRole("link", ~options={name: "Playground"})->expect->toBeVisible
await page->getByRole("link", ~options={name: "Blog"})->expect->toBeVisible
await page->getByRole("link", ~options={name: "Community"})->expect->toBeVisible
})

test("Get Started link navigates to the installation guide", async ({page}) => {
let _ = await page->goto("/")

let getStarted = page->getByRole("link", ~options={name: "Get Started"})
await getStarted->first->click

await page->expect->toHaveURL("/docs/manual/installation")
})

test("GitHub social link is present", async ({page}) => {
let _ = await page->goto("/")
let githubLink = page->getByRole("link", ~options={name: "GitHub"})
await githubLink->expect->toBeVisible
})

test("has no accessibility violations", async ({page}) => {
let _ = await page->goto("/")
await page->assertNoA11yViolations
})

test("visual snapshot — desktop", async ({page}) => {
let _ = await page->goto("/")
await page->waitForLoadState("networkidle")
await takeSnapshot(page, "Landing Page — Desktop")
})

test("visual snapshot — mobile", async ({page}) => {
let _ = await page->goto("/")
await page->waitForLoadState("networkidle")
await takeSnapshot(page, "Landing Page — Mobile")
})
})
Binary file added functions/yoga.wasm
Binary file not shown.
12 changes: 10 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
{
"name": "rescript-lang.org",
"private": true,
"version": "1.0.0",
"author": "Patrick Ecker <ryyppy@users.noreply.github.com>",
"license": "MIT",
Expand All @@ -12,13 +11,16 @@
"scripts": {
"build:scripts": "yarn dlx tsdown@0.20.0 scripts/*.jsx -d _scripts --no-clean --ext .mjs",
"build:generate-llms": "node _scripts/generate_llms.mjs",
"build:res": "rescript build --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110",
"build:res": "rescript build --warn-error +3+8+11+12+26+27+31+32+33+34+35+39+44+45+110 && node scripts/postprocess-e2e.mjs",
"build:sync-bundles": "node scripts/sync-playground-bundles.mjs",
"build:update-index": "yarn build:generate-llms && node _scripts/generate_feed.mjs > public/blog/feed.xml",
"build:vite": "react-router build",
"build": "yarn build:res && yarn build:scripts && yarn build:update-index && yarn build:vite",
"ci:format": "prettier . --check --experimental-cli",
"ci:test": "yarn vitest --run --browser.headless --update",
"e2e": "playwright test",
"e2e:chromatic": "yarn chromatic --playwright --project-token=chpt_e92d16169d30db1",
"e2e:report": "playwright show-report",
"clean:res": "rescript clean",
"convert-images": "auto-convert-images",
"dev:res": "rescript watch",
Expand Down Expand Up @@ -77,10 +79,15 @@
"remark-gfm": "^4.0.1",
"remark-validate-links": "^13.1.0",
"rescript": "^12.0.0",
"satori": "^0.19.2",
"shiki": "^3.22.0",
"unified": "^11.0.5",
"vfile-matter": "^5.0.0"
},
"devDependencies": {
"@axe-core/playwright": "^4.11.1",
"@chromatic-com/playwright": "^0.12.8",
"@playwright/test": "^1.58.2",
"@prettier/plugin-oxc": "^0.0.4",
"@react-router/dev": "^7.8.1",
"@tailwindcss/vite": "^4.1.13",
Expand All @@ -89,6 +96,7 @@
"@vitest/browser-playwright": "^4.0.18",
"auto-image-converter": "^2.1.2",
"chokidar": "^4.0.3",
"chromatic": "^15.1.1",
"dotenv": "^16.4.7",
"jsdom": "^26.1.0",
"lefthook": "^2.0.4",
Expand Down
Loading
Loading