@@ -136,4 +136,311 @@ describe("lighthouseSchema", () => {
136136 const result = lighthouseSchema . safeParse ( input ) ;
137137 expect ( result . success ) . toBe ( false ) ;
138138 } ) ;
139+
140+ // Threshold boundary tests
141+ test ( "should accept thresholds at minimum (0)" , ( ) => {
142+ const input = {
143+ url : "https://example.com" ,
144+ viewport : "mobile" ,
145+ thresholds : {
146+ performance : 0 ,
147+ accessibility : 0 ,
148+ "best-practices" : 0 ,
149+ seo : 0 ,
150+ pwa : 0 ,
151+ } ,
152+ } ;
153+
154+ const result = lighthouseSchema . safeParse ( input ) ;
155+ expect ( result . success ) . toBe ( true ) ;
156+ } ) ;
157+
158+ test ( "should accept thresholds at maximum (100)" , ( ) => {
159+ const input = {
160+ url : "https://example.com" ,
161+ viewport : "mobile" ,
162+ thresholds : {
163+ performance : 100 ,
164+ accessibility : 100 ,
165+ "best-practices" : 100 ,
166+ seo : 100 ,
167+ pwa : 100 ,
168+ } ,
169+ } ;
170+
171+ const result = lighthouseSchema . safeParse ( input ) ;
172+ expect ( result . success ) . toBe ( true ) ;
173+ } ) ;
174+
175+ test ( "should reject threshold below minimum" , ( ) => {
176+ const input = {
177+ url : "https://example.com" ,
178+ viewport : "mobile" ,
179+ thresholds : {
180+ performance : - 1 ,
181+ } ,
182+ } ;
183+
184+ const result = lighthouseSchema . safeParse ( input ) ;
185+ expect ( result . success ) . toBe ( false ) ;
186+ } ) ;
187+
188+ test ( "should accept partial thresholds" , ( ) => {
189+ const input = {
190+ url : "https://example.com" ,
191+ viewport : "mobile" ,
192+ thresholds : {
193+ performance : 90 ,
194+ } ,
195+ } ;
196+
197+ const result = lighthouseSchema . safeParse ( input ) ;
198+ expect ( result . success ) . toBe ( true ) ;
199+ } ) ;
200+
201+ test ( "should reject threshold exceeding maximum for accessibility" , ( ) => {
202+ const input = {
203+ url : "https://example.com" ,
204+ viewport : "mobile" ,
205+ thresholds : {
206+ accessibility : 101 ,
207+ } ,
208+ } ;
209+
210+ const result = lighthouseSchema . safeParse ( input ) ;
211+ expect ( result . success ) . toBe ( false ) ;
212+ } ) ;
213+
214+ test ( "should reject threshold exceeding maximum for seo" , ( ) => {
215+ const input = {
216+ url : "https://example.com" ,
217+ viewport : "mobile" ,
218+ thresholds : {
219+ seo : 150 ,
220+ } ,
221+ } ;
222+
223+ const result = lighthouseSchema . safeParse ( input ) ;
224+ expect ( result . success ) . toBe ( false ) ;
225+ } ) ;
226+
227+ // Report format combination tests
228+ test ( "should support json and html formats together" , ( ) => {
229+ const input = {
230+ url : "https://example.com" ,
231+ viewport : "mobile" ,
232+ json : true ,
233+ html : true ,
234+ csv : false ,
235+ } ;
236+
237+ const result = lighthouseSchema . safeParse ( input ) ;
238+ expect ( result . success ) . toBe ( true ) ;
239+ if ( result . success ) {
240+ expect ( result . data . json ) . toBe ( true ) ;
241+ expect ( result . data . html ) . toBe ( true ) ;
242+ expect ( result . data . csv ) . toBe ( false ) ;
243+ }
244+ } ) ;
245+
246+ test ( "should support json and csv formats together" , ( ) => {
247+ const input = {
248+ url : "https://example.com" ,
249+ viewport : "mobile" ,
250+ json : true ,
251+ html : false ,
252+ csv : true ,
253+ } ;
254+
255+ const result = lighthouseSchema . safeParse ( input ) ;
256+ expect ( result . success ) . toBe ( true ) ;
257+ if ( result . success ) {
258+ expect ( result . data . json ) . toBe ( true ) ;
259+ expect ( result . data . html ) . toBe ( false ) ;
260+ expect ( result . data . csv ) . toBe ( true ) ;
261+ }
262+ } ) ;
263+
264+ test ( "should support html and csv formats together" , ( ) => {
265+ const input = {
266+ url : "https://example.com" ,
267+ viewport : "mobile" ,
268+ json : false ,
269+ html : true ,
270+ csv : true ,
271+ } ;
272+
273+ const result = lighthouseSchema . safeParse ( input ) ;
274+ expect ( result . success ) . toBe ( true ) ;
275+ if ( result . success ) {
276+ expect ( result . data . json ) . toBe ( false ) ;
277+ expect ( result . data . html ) . toBe ( true ) ;
278+ expect ( result . data . csv ) . toBe ( true ) ;
279+ }
280+ } ) ;
281+
282+ test ( "should support all formats disabled" , ( ) => {
283+ const input = {
284+ url : "https://example.com" ,
285+ viewport : "mobile" ,
286+ json : false ,
287+ html : false ,
288+ csv : false ,
289+ } ;
290+
291+ const result = lighthouseSchema . safeParse ( input ) ;
292+ expect ( result . success ) . toBe ( true ) ;
293+ if ( result . success ) {
294+ expect ( result . data . json ) . toBe ( false ) ;
295+ expect ( result . data . html ) . toBe ( false ) ;
296+ expect ( result . data . csv ) . toBe ( false ) ;
297+ }
298+ } ) ;
299+
300+ // Timeout boundary tests
301+ test ( "should accept timeout at minimum (0)" , ( ) => {
302+ const input = {
303+ url : "https://example.com" ,
304+ viewport : "mobile" ,
305+ timeout : 0 ,
306+ } ;
307+
308+ const result = lighthouseSchema . safeParse ( input ) ;
309+ expect ( result . success ) . toBe ( true ) ;
310+ } ) ;
311+
312+ test ( "should accept timeout at maximum (120000)" , ( ) => {
313+ const input = {
314+ url : "https://example.com" ,
315+ viewport : "mobile" ,
316+ timeout : 120000 ,
317+ } ;
318+
319+ const result = lighthouseSchema . safeParse ( input ) ;
320+ expect ( result . success ) . toBe ( true ) ;
321+ } ) ;
322+
323+ test ( "should reject timeout exceeding maximum" , ( ) => {
324+ const input = {
325+ url : "https://example.com" ,
326+ viewport : "mobile" ,
327+ timeout : 120001 ,
328+ } ;
329+
330+ const result = lighthouseSchema . safeParse ( input ) ;
331+ expect ( result . success ) . toBe ( false ) ;
332+ } ) ;
333+
334+ test ( "should reject negative timeout" , ( ) => {
335+ const input = {
336+ url : "https://example.com" ,
337+ viewport : "mobile" ,
338+ timeout : - 1 ,
339+ } ;
340+
341+ const result = lighthouseSchema . safeParse ( input ) ;
342+ expect ( result . success ) . toBe ( false ) ;
343+ } ) ;
344+
345+ // Timezone validation tests
346+ test ( "should accept valid IANA timezones" , ( ) => {
347+ const timezones = [
348+ "America/New_York" ,
349+ "Europe/London" ,
350+ "Asia/Tokyo" ,
351+ "UTC/GMT" ,
352+ ] ;
353+
354+ for ( const timezoneId of timezones ) {
355+ const input = {
356+ url : "https://example.com" ,
357+ viewport : "mobile" ,
358+ timezoneId,
359+ } ;
360+
361+ const result = lighthouseSchema . safeParse ( input ) ;
362+ expect ( result . success ) . toBe ( true ) ;
363+ }
364+ } ) ;
365+
366+ test ( "should reject invalid timezone format" , ( ) => {
367+ const input = {
368+ url : "https://example.com" ,
369+ viewport : "mobile" ,
370+ timezoneId : "InvalidTimezone" ,
371+ } ;
372+
373+ const result = lighthouseSchema . safeParse ( input ) ;
374+ expect ( result . success ) . toBe ( false ) ;
375+ } ) ;
376+
377+ test ( "should reject timezone without region" , ( ) => {
378+ const input = {
379+ url : "https://example.com" ,
380+ viewport : "mobile" ,
381+ timezoneId : "America" ,
382+ } ;
383+
384+ const result = lighthouseSchema . safeParse ( input ) ;
385+ expect ( result . success ) . toBe ( false ) ;
386+ } ) ;
387+
388+ // Theme validation tests
389+ test ( "should accept both theme options" , ( ) => {
390+ const lightInput = {
391+ url : "https://example.com" ,
392+ viewport : "mobile" ,
393+ theme : "light" ,
394+ } ;
395+
396+ const lightResult = lighthouseSchema . safeParse ( lightInput ) ;
397+ expect ( lightResult . success ) . toBe ( true ) ;
398+
399+ const darkInput = {
400+ url : "https://example.com" ,
401+ viewport : "mobile" ,
402+ theme : "dark" ,
403+ } ;
404+
405+ const darkResult = lighthouseSchema . safeParse ( darkInput ) ;
406+ expect ( darkResult . success ) . toBe ( true ) ;
407+ } ) ;
408+
409+ test ( "should reject invalid theme" , ( ) => {
410+ const input = {
411+ url : "https://example.com" ,
412+ viewport : "mobile" ,
413+ theme : "blue" ,
414+ } ;
415+
416+ const result = lighthouseSchema . safeParse ( input ) ;
417+ expect ( result . success ) . toBe ( false ) ;
418+ } ) ;
419+
420+ // waitUntil validation tests
421+ test ( "should accept all valid waitUntil options" , ( ) => {
422+ const options = [ "load" , "domcontentloaded" , "networkidle" , "commit" ] ;
423+
424+ for ( const waitUntil of options ) {
425+ const input = {
426+ url : "https://example.com" ,
427+ viewport : "mobile" ,
428+ waitUntil,
429+ } ;
430+
431+ const result = lighthouseSchema . safeParse ( input ) ;
432+ expect ( result . success ) . toBe ( true ) ;
433+ }
434+ } ) ;
435+
436+ test ( "should reject invalid waitUntil option" , ( ) => {
437+ const input = {
438+ url : "https://example.com" ,
439+ viewport : "mobile" ,
440+ waitUntil : "complete" ,
441+ } ;
442+
443+ const result = lighthouseSchema . safeParse ( input ) ;
444+ expect ( result . success ) . toBe ( false ) ;
445+ } ) ;
139446} ) ;
0 commit comments