1+ import { APP_THEMES } from '../../src/lib/themes' ;
2+
3+ const optionalThemes = APP_THEMES . filter ( ( theme ) => ! [ 'light' , 'dark' , 'system' ] . includes ( theme ) ) ;
14const featureCode =
2- / T H R E E \. W e b G L R e n d e r e r | W e b G L R e n d e r e r : | L O S S A N T O S 3 D | m i n e c r a f t - c l i c k \. m p 3 | e n d e r - d r a g o n \. m p 3 | L o a d i n g L u i g i C i r c u i t | i n f e r e n c e x - m i n e c r a f t - w o r l d s | m c - p a n o r a m a - c u b e | \. m c - h o t b a r - w r a p | \. c s g o - s c e n e | \. g t a - s c e n e | \. m c - d r a g o n - f l y a c r o s s | \. k a r t - s c e n e | \. h a l o - s c e n e | f o n t - f a m i l y : \s * [ " ' ] ? (?: M o n o c r a f t | P r i c e d o w n | C h a l e t C o m p r i m e | I n d u s t r y ) / i;
3- const featureAsset =
4- / \/ d e c o r a t i v e \/ (?: m i n e c r a f t | c s g o | g t a | k a r t | h a l o ) \/ | m i n e c r a f t - c l i c k \. m p 3 | M o n o c r a f t - | P r i c e d o w n | C h a l e t C o m p r i m e | I n d u s t r y - | y o u t u b e (?: - n o c o o k i e ) ? \. c o m | y t i m g \. c o m / i;
5+ / T H R E E \. W e b G L R e n d e r e r | W e b G L R e n d e r e r : | L O S S A N T O S 3 D | m i n e c r a f t - c l i c k \. m p 3 | e n d e r - d r a g o n \. m p 3 | L o a d i n g L u i g i C i r c u i t | i n f e r e n c e x - m i n e c r a f t - w o r l d s | m c - p a n o r a m a - c u b e | \. m c - h o t b a r - w r a p | \. c s g o - s c e n e | \. g t a - s c e n e | \. m c - d r a g o n - f l y a c r o s s | \. k a r t - s c e n e | \. h a l o - s c e n e | h a l o - t h e m e \. c s s | f o n t - f a m i l y : \s * [ " ' ] ? (?: M o n o c r a f t | P r i c e d o w n | C h a l e t C o m p r i m e | I n d u s t r y | H a l o ) / i;
6+ const featureAsset = new RegExp (
7+ `/decorative/(?:${ optionalThemes . join ( '|' ) } )/|minecraft-click\\.mp3|Monocraft-|Pricedown|ChaletComprime|Industry-|halo[^/]*\\.(?:woff2?|ttf|otf|mp3|ogg|wav)|youtube(?:-nocookie)?\\.com|ytimg\\.com` ,
8+ 'i' ,
9+ ) ;
510const featureElements =
611 '[data-testid="minecraft-game"], [data-testid="minecraft-play-banner"], [data-testid="kart-game"], [data-testid$="-theme-banner"], .mc-dragon-flyacross' ;
712const isFeatureAsset = ( url : string ) => featureAsset . test ( decodeURIComponent ( url ) ) ;
813
14+ function saveMediaOptIns ( win : Window , enabled : boolean ) {
15+ for ( const theme of optionalThemes ) {
16+ win . localStorage . setItem ( `${ theme } -music` , String ( enabled ) ) ;
17+ win . localStorage . setItem ( `${ theme } -sound` , String ( enabled ) ) ;
18+ }
19+ }
20+
921function expectNoOptionalResources ( requests : string [ ] ) {
1022 cy . window ( ) . then ( ( win ) => {
1123 // Request interception catches in-flight requests too; resource timing only lists completed ones.
1224 expect ( requests . filter ( isFeatureAsset ) , 'optional requests started' ) . to . deep . equal ( [ ] ) ;
1325 const resources = win . performance . getEntriesByType ( 'resource' ) ;
1426 expect ( resources . filter ( ( entry ) => isFeatureAsset ( entry . name ) ) ) . to . have . length ( 0 ) ;
1527 expect (
16- [ ...win . document . fonts ] . filter ( ( font ) => / m o n o c r a f t | p r i c e d o w n | c h a l e t / i. test ( font . family ) ) ,
28+ [ ...win . document . fonts ] . filter ( ( font ) =>
29+ / m o n o c r a f t | p r i c e d o w n | c h a l e t | i n d u s t r y | h a l o / i. test ( font . family ) ,
30+ ) ,
1731 ) . to . have . length ( 0 ) ;
1832 for ( const resource of resources . filter ( ( entry ) => / \. (?: j s | c s s ) (?: \? | $ ) / . test ( entry . name ) ) )
1933 cy . request ( resource . name ) . its ( 'body' ) . should ( 'not.match' , featureCode ) ;
2034 } ) ;
2135 cy . get ( featureElements ) . should ( 'not.exist' ) ;
36+ cy . get ( 'audio, video, iframe[src*="youtube"]' ) . should ( 'not.exist' ) ;
2237}
2338const seo = ( doc : Document ) => [
2439 doc . title ,
2540 doc . querySelector ( 'meta[name="description"]' ) ?. getAttribute ( 'content' ) ,
2641 doc . querySelector ( 'link[rel="canonical"]' ) ?. getAttribute ( 'href' ) ,
42+ ...[
43+ ...doc . querySelectorAll ( 'meta[name="robots"], meta[property^="og:"], meta[name^="twitter:"]' ) ,
44+ ] . map ( ( node ) => node . outerHTML ) ,
2745 ...[ ...doc . querySelectorAll ( 'link[hreflang], script[type="application/ld+json"]' ) ] . map (
2846 ( node ) => node . outerHTML ,
2947 ) ,
@@ -50,8 +68,7 @@ describe('optional themes stay off the default page', () => {
5068 if ( theme === 'default' ) win . localStorage . removeItem ( 'theme' ) ;
5169 else win . localStorage . setItem ( 'theme' , theme ) ;
5270 // Stored opt-ins must not start media outside the selected theme.
53- win . localStorage . setItem ( 'minecraft-music' , 'true' ) ;
54- win . localStorage . setItem ( 'minecraft-sound' , 'true' ) ;
71+ saveMediaOptIns ( win , true ) ;
5572 } ,
5673 } ) ;
5774 if ( theme === 'light' || theme === 'dark' ) cy . get ( 'html' ) . should ( 'have.class' , theme ) ;
@@ -71,7 +88,7 @@ describe('optional themes stay off the default page', () => {
7188 } ) ;
7289 }
7390
74- for ( const theme of [ 'minecraft' , 'csgo' , 'gta' , 'kart' , 'halo' ] ) {
91+ for ( const theme of optionalThemes ) {
7592 for ( const prefix of [ '' , '/zh' ] ) {
7693 it ( `${ prefix || 'English' } embed ignores saved ${ theme } before and after hydration` , ( ) => {
7794 const requests : string [ ] = [ ] ;
@@ -81,9 +98,7 @@ describe('optional themes stay off the default page', () => {
8198 cy . visit ( `${ prefix } /embed/model/deepseek-v4?theme=light` , {
8299 onBeforeLoad ( win ) {
83100 win . localStorage . setItem ( 'theme' , theme ) ;
84- win . localStorage . setItem ( 'minecraft-music' , 'true' ) ;
85- win . localStorage . setItem ( 'minecraft-sound' , 'true' ) ;
86- win . localStorage . setItem ( 'halo-music' , 'true' ) ;
101+ saveMediaOptIns ( win , true ) ;
87102 } ,
88103 } ) ;
89104 cy . get ( 'html' ) . should ( 'have.class' , 'light' ) . and ( 'have.attr' , 'data-inferencex-embed' ) ;
@@ -116,11 +131,7 @@ describe('optional themes stay off the default page', () => {
116131 ( link ) => isFeatureAsset ( link . getAttribute ( 'href' ) ?? '' ) ,
117132 ) ,
118133 ) . to . have . length ( 0 ) ;
119- expect (
120- doc . querySelector (
121- '[data-testid="kart-game"], [data-testid="gta-theme-banner"], [data-testid="csgo-theme-banner"], [data-testid="halo-theme-banner"]' ,
122- ) ,
123- ) . to . equal ( null ) ;
134+ expect ( doc . querySelector ( featureElements ) ) . to . equal ( null ) ;
124135 // Metadata and indexable headings are in raw HTML, without running JavaScript.
125136 cy . request ( route ) . then ( ( normal ) => {
126137 const normalDoc = new DOMParser ( ) . parseFromString ( normal . body , 'text/html' ) ;
@@ -135,9 +146,7 @@ describe('optional themes stay off the default page', () => {
135146 cy . visit ( '/about' , {
136147 onBeforeLoad ( win ) {
137148 win . localStorage . setItem ( 'theme' , 'light' ) ;
138- win . localStorage . setItem ( 'minecraft-music' , 'false' ) ;
139- win . localStorage . setItem ( 'minecraft-sound' , 'false' ) ;
140- win . localStorage . setItem ( 'halo-music' , 'false' ) ;
149+ saveMediaOptIns ( win , false ) ;
141150 } ,
142151 } ) ;
143152 // The server-rendered trigger is visible before its click handler hydrates.
@@ -146,7 +155,7 @@ describe('optional themes stay off the default page', () => {
146155 . and ( 'contain' , 'currently' ) ;
147156 cy . document ( ) . then ( ( doc ) => {
148157 const baseline = seo ( doc ) ;
149- for ( const theme of [ 'csgo' , 'gta' , 'minecraft' , 'kart' , 'halo' ] ) {
158+ for ( const theme of optionalThemes ) {
150159 cy . get ( '[data-testid="theme-toggle"]' ) . click ( ) ;
151160 cy . get ( `[data-testid="theme-option-${ theme } "]` ) . click ( ) ;
152161 if ( theme === 'minecraft' ) cy . get ( 'canvas' ) . should ( 'exist' ) ;
0 commit comments