@@ -124,6 +124,65 @@ describe("Navbar mobile menu", () => {
124124 expect ( document . getElementById ( "mobile-navigation-panel" ) ) . not . toBeInTheDocument ( ) ;
125125 expect ( localStorage . getItem ( "language" ) ) . toBe ( "en" ) ;
126126 } ) ;
127+
128+ it . each ( [
129+ {
130+ language : "es" ,
131+ expectedLabels : [
132+ "Sobre mí" ,
133+ "Por qué elegirme" ,
134+ "Servicios" ,
135+ "Portfolio" ,
136+ "Contacto" ,
137+ "FAQ" ,
138+ ] ,
139+ servicesHref : "/servicios" ,
140+ } ,
141+ {
142+ language : "en" ,
143+ expectedLabels : [
144+ "About me" ,
145+ "Why choose me" ,
146+ "Services" ,
147+ "Portfolio" ,
148+ "Contact" ,
149+ "FAQ" ,
150+ ] ,
151+ servicesHref : "/en/services" ,
152+ } ,
153+ ] as const ) (
154+ "keeps $language desktop, mobile, and no-JavaScript navigation in parity" ,
155+ async ( { language, expectedLabels, servicesHref } ) => {
156+ const user = userEvent . setup ( ) ;
157+ renderNavbar ( { initialEntry : language === "es" ? "/" : "/en" , language } ) ;
158+
159+ const desktop = getRequiredElement < HTMLElement > ( "[data-navbar-desktop]" ) ;
160+ const trigger = screen . getByRole ( "button" , {
161+ name : language === "es" ? "Abrir menú" : "Open menu" ,
162+ } ) ;
163+ const fallback = getRequiredElement < HTMLElement > ( "[data-nojs-mobile-nav]" ) ;
164+ const fallbackLinks = fallback . firstElementChild ?. querySelectorAll ( "a" ) ;
165+
166+ await user . click ( trigger ) ;
167+
168+ const panel = getRequiredElement < HTMLElement > ( "#mobile-navigation-panel" ) ;
169+ const desktopLinks = [ ...desktop . children ] . filter (
170+ ( element ) : element is HTMLAnchorElement =>
171+ element instanceof HTMLAnchorElement ,
172+ ) ;
173+ const mobileLinks = [ ...panel . children ] . filter (
174+ ( element ) : element is HTMLAnchorElement =>
175+ element instanceof HTMLAnchorElement ,
176+ ) ;
177+ const noJavaScriptLinks = [ ...( fallbackLinks ?? [ ] ) ] ;
178+
179+ for ( const links of [ desktopLinks , mobileLinks , noJavaScriptLinks ] ) {
180+ expect ( links . map ( ( link ) => link . textContent ) ) . toEqual ( expectedLabels ) ;
181+ expect ( links . filter ( ( link ) => link . getAttribute ( "href" ) === servicesHref ) )
182+ . toHaveLength ( 1 ) ;
183+ }
184+ } ,
185+ ) ;
127186} ) ;
128187
129188describe ( "Navbar color tokens" , ( ) => {
@@ -156,6 +215,29 @@ describe("Navbar color tokens", () => {
156215 expect ( spanishButton ) . toHaveClass ( "text-white" , "hover:text-primary" ) ;
157216 expect ( englishButton ) . toHaveClass ( "text-primary" , "hover:text-primary" ) ;
158217 } ) ;
218+
219+ it ( "keeps one approved translucent surface around the mobile panels" , async ( ) => {
220+ const user = userEvent . setup ( ) ;
221+ renderNavbar ( ) ;
222+ const navbar = getRequiredElement < HTMLElement > ( "nav[data-nojs-navbar]" ) ;
223+ const trigger = screen . getByRole ( "button" , { name : "Abrir menú" } ) ;
224+ const fallback = getRequiredElement < HTMLElement > ( "[data-nojs-mobile-nav]" ) ;
225+
226+ expect ( navbar ) . toHaveClass (
227+ "bg-black/70" ,
228+ "backdrop-blur-xl" ,
229+ "backdrop-saturate-150" ,
230+ ) ;
231+ expect ( fallback . parentElement ) . toBe ( navbar ) ;
232+ expect ( fallback ) . not . toHaveClass ( "bg-black/90" , "backdrop-blur-sm" ) ;
233+
234+ await user . click ( trigger ) ;
235+
236+ const panel = getRequiredElement < HTMLElement > ( "#mobile-navigation-panel" ) ;
237+ expect ( panel . parentElement ) . toBe ( navbar ) ;
238+ expect ( panel ) . not . toHaveClass ( "bg-black/90" , "backdrop-blur-sm" ) ;
239+ expect ( navbar . querySelectorAll ( '[class*="backdrop-blur"]' ) ) . toHaveLength ( 0 ) ;
240+ } ) ;
159241} ) ;
160242
161243describe ( "Navbar no-JavaScript fallback" , ( ) => {
0 commit comments