@@ -4,6 +4,7 @@ const http = require("node:http");
44const net = require ( "node:net" ) ;
55const os = require ( "node:os" ) ;
66const path = require ( "node:path" ) ;
7+ const { pathToFileURL } = require ( "node:url" ) ;
78
89const puppeteer = require (
910 path . resolve ( __dirname , ".." , "website" , "node_modules" , "puppeteer" ) ,
@@ -37,6 +38,16 @@ const FOUNDATIONS_FIRST_DOC = "/how-llms-work";
3738const TRACE_DIR = path . join ( path . resolve ( __dirname , ".." , "website" ) , "browser-contracts-traces" ) ;
3839
3940const websiteDir = path . resolve ( __dirname , ".." , "website" ) ;
41+ // The build-time star snapshot and its canonical formatter, read by the
42+ // no-JavaScript homepage contract below.
43+ const STARS_SNAPSHOT = path . join ( websiteDir , "src" , "generated" , "github-stars.json" ) ;
44+ const FORMAT_STARS = path . join (
45+ websiteDir ,
46+ "src" ,
47+ "components" ,
48+ "GitHubSocialProof" ,
49+ "formatStars.ts" ,
50+ ) ;
4051// CI builds once and points us at the artifact; local runs self-build.
4152const providedBuildDir = process . env . BROWSER_TEST_BUILD_DIR
4253 ? path . resolve ( process . env . BROWSER_TEST_BUILD_DIR )
@@ -361,17 +372,37 @@ function linksInHtml(html) {
361372 } ) ) ;
362373}
363374
364- async function inspectNoJavaScriptSidebar ( ) {
375+ // The homepage's no-JavaScript contract: navigation works and the trust band's
376+ // build-time star counts are baked into the HTML. One fetch feeds both checks.
377+ async function inspectNoJavaScriptHomepage ( ) {
365378 const response = await fetch ( siteUrl ( ) ) ;
366379 if ( ! response . ok ) fail ( `no-JavaScript homepage returned ${ response . status } ` ) ;
367- const foundation = linksInHtml ( await response . text ( ) ) . find (
380+ const html = await response . text ( ) ;
381+ inspectNoJavaScriptSidebar ( html ) ;
382+ await inspectNoJavaScriptStars ( html ) ;
383+ }
384+
385+ function inspectNoJavaScriptSidebar ( html ) {
386+ const foundation = linksInHtml ( html ) . find (
368387 ( link ) => link . label === LABEL_FOUNDATIONS ,
369388 ) ;
370389 if ( ! foundation ) fail ( "collapsed Foundations group has no SSR fallback link" ) ;
371390 if ( new URL ( foundation . href , siteUrl ( ) ) . pathname !== FOUNDATIONS_FIRST_DOC )
372391 fail ( `${ LABEL_FOUNDATIONS } SSR fallback points to ${ foundation . href } ` ) ;
373392}
374393
394+ // Asserts each count is rendered server-side from the committed snapshot, tied
395+ // to its "stars" label so a stray number elsewhere cannot satisfy the check.
396+ async function inspectNoJavaScriptStars ( html ) {
397+ const { formatStars } = await import ( pathToFileURL ( FORMAT_STARS ) . href ) ;
398+ const { projects } = JSON . parse ( fs . readFileSync ( STARS_SNAPSHOT , "utf8" ) ) ;
399+ for ( const { repo, stars } of projects ) {
400+ const count = formatStars ( stars ) . replace ( / [ . * + ? ^ $ { } ( ) | [ \] \\ ] / g, "\\$&" ) ;
401+ if ( ! new RegExp ( `>${ count } </span>[^<]*<span[^>]*>stars</span>` ) . test ( html ) )
402+ fail ( `SSR homepage is missing the baked-in star count for ${ repo } ` ) ;
403+ }
404+ }
405+
375406// Scoped to the desktop docs sidebar. Keep in sync with the theme's canonical
376407// scroller selector (DocSidebar/Desktop/index.tsx SIDEBAR_NAV_SELECTOR): the
377408// aria-label is a translated theme string, the class is stable markup.
@@ -506,7 +537,6 @@ async function inspectMobileDrawerSidebar() {
506537}
507538
508539async function inspectSidebarNavigation ( ) {
509- await inspectNoJavaScriptSidebar ( ) ;
510540 const page = await browser . newPage ( ) ;
511541 await page . setViewport ( { width : 1440 , height : 900 , deviceScaleFactor : 1 } ) ;
512542 await page . emulateMediaFeatures ( [
@@ -668,6 +698,7 @@ async function main() {
668698
669699 fs . mkdirSync ( TRACE_DIR , { recursive : true } ) ;
670700 browser = await puppeteer . launch ( { headless : true } ) ;
701+ await withRetry ( ( ) => inspectNoJavaScriptHomepage ( ) , "inspectNoJavaScriptHomepage" ) ;
671702 await withRetry ( ( ) => inspectSidebarNavigation ( ) , "inspectSidebarNavigation" ) ;
672703 await withRetry ( ( ) => inspectMobileDrawerSidebar ( ) , "inspectMobileDrawerSidebar" ) ;
673704 await withRetry ( ( ) => inspectActiveChapterScroll ( ) , "inspectActiveChapterScroll" ) ;
0 commit comments