@@ -7,67 +7,22 @@ import {findForUrl} from './findForUrl.js'
77
88export default async function ( ) {
99 core . info ( "Starting 'find' action" )
10- const urlConfigInput = core . getInput ( 'url_config' , { required : false } )
11- let urlConfigs : UrlConfig [ ] | undefined
12- if ( urlConfigInput ) {
13- try {
14- const parsed = JSON . parse ( urlConfigInput )
15- if ( ! Array . isArray ( parsed ) ) {
16- throw new Error ( "Input 'url_config' must be a JSON array." )
17- }
18- for ( const item of parsed ) {
19- if ( typeof item !== 'object' || item === null || typeof item . url !== 'string' ) {
20- throw new Error ( "Each entry in 'url_config' must be an object with a 'url' string field." )
21- }
22- }
23- urlConfigs = parsed as UrlConfig [ ]
24- } catch ( e ) {
25- throw new Error ( `Invalid 'url_config' input: ${ ( e as Error ) . message } ` )
26- }
27- }
10+ let urlConfigs = loadUrlConfigs ( )
11+ let urls = loadUrls ( { urlConfigs} )
12+ let reducedMotion = loadReducedMotion ( )
13+ let colorScheme = loadColorScheme ( )
2814
29- let urls : string [ ]
30- if ( urlConfigs ) {
31- core . debug ( `Input: 'url_config: ${ JSON . stringify ( urlConfigs ) } '` )
32- urls = urlConfigs . map ( c => c . url )
33- } else {
34- urls = core . getMultilineInput ( 'urls' , { required : false } )
35- core . debug ( `Input: 'urls: ${ JSON . stringify ( urls ) } '` )
36- if ( urls . length === 0 ) {
37- throw new Error ( "Either 'urls' or 'url_config' input must be provided." )
38- }
39- }
15+ const actualUrls = urlConfigs || urls || [ ]
4016
4117 const authContextInput : AuthContextInput = JSON . parse ( core . getInput ( 'auth_context' , { required : false } ) || '{}' )
4218 const authContext = new AuthContext ( authContextInput )
43-
4419 const includeScreenshots = core . getInput ( 'include_screenshots' , { required : false } ) !== 'false'
45- const reducedMotionInput = core . getInput ( 'reduced_motion' , { required : false } )
46- let reducedMotion : ReducedMotionPreference | undefined
47- if ( reducedMotionInput ) {
48- if ( ! [ 'reduce' , 'no-preference' , null ] . includes ( reducedMotionInput ) ) {
49- throw new Error (
50- "Input 'reduced_motion' must be one of: 'reduce', 'no-preference', or null per Playwright documentation." ,
51- )
52- }
53- reducedMotion = reducedMotionInput as ReducedMotionPreference
54- }
55- const colorSchemeInput = core . getInput ( 'color_scheme' , { required : false } )
56- let colorScheme : ColorSchemePreference | undefined
57- if ( colorSchemeInput ) {
58- if ( ! [ 'light' , 'dark' , 'no-preference' , null ] . includes ( colorSchemeInput ) ) {
59- throw new Error (
60- "Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference', or null per Playwright documentation." ,
61- )
62- }
63- colorScheme = colorSchemeInput as ColorSchemePreference
64- }
6520
6621 const findings = [ ]
67- for ( const url of urls ) {
22+ for ( const urlConfig of actualUrls ) {
23+ const { url} = urlConfig
6824 core . info ( `Preparing to scan ${ url } ` )
69- const excludeSelectors = urlConfigs ?. find ( c => c . url === url ) ?. excludeSelectors
70- const findingsForUrl = await findForUrl ( url , authContext , includeScreenshots , reducedMotion , colorScheme , excludeSelectors )
25+ const findingsForUrl = await findForUrl ( urlConfig , authContext , includeScreenshots , reducedMotion , colorScheme )
7126 if ( findingsForUrl . length === 0 ) {
7227 core . info ( `No accessibility gaps were found on ${ url } ` )
7328 continue
@@ -84,3 +39,67 @@ export default async function () {
8439 core . info ( `Found ${ findings . length } findings in total` )
8540 core . info ( "Finished 'find' action" )
8641}
42+
43+ function loadUrlConfigs ( ) {
44+ const urlConfigInput = core . getInput ( 'url_configs' , { required : false } )
45+
46+ if ( ! urlConfigInput ) return
47+
48+ try {
49+ const parsed = JSON . parse ( urlConfigInput )
50+
51+ if ( ! Array . isArray ( parsed ) ) {
52+ throw new Error ( "Input 'url_configs' must be a JSON array." )
53+ }
54+
55+ for ( const item of parsed ) {
56+ if ( typeof item !== 'object' || item === null || typeof item . url !== 'string' ) {
57+ throw new Error ( "Each entry in 'url_configs' must be an object with a 'url' string field." )
58+ }
59+ }
60+
61+ return parsed as UrlConfig [ ]
62+ } catch ( e ) {
63+ throw new Error ( `Invalid 'url_configs' input: ${ ( e as Error ) . message } ` )
64+ }
65+ }
66+
67+ function loadUrls ( { urlConfigs} : { urlConfigs ?: UrlConfig [ ] } = { } ) {
68+ // - no need to process this input if url_configs is provided
69+ if ( urlConfigs ) return
70+
71+ let urls : string [ ]
72+ urls = core . getMultilineInput ( 'urls' , { required : false } )
73+ core . debug ( `Input: 'urls: ${ JSON . stringify ( urls ) } '` )
74+
75+ if ( urls . length === 0 ) {
76+ throw new Error ( "Either 'urls' or 'url_configs' input must be provided." )
77+ }
78+
79+ return urls . map ( url => ( { url} ) ) as UrlConfig [ ]
80+ }
81+
82+ function loadReducedMotion ( ) {
83+ const reducedMotionInput = core . getInput ( 'reduced_motion' , { required : false } )
84+ if ( ! reducedMotionInput ) return
85+
86+ if ( ! [ 'reduce' , 'no-preference' , null ] . includes ( reducedMotionInput ) ) {
87+ throw new Error (
88+ "Input 'reduced_motion' must be one of: 'reduce', 'no-preference', or null per Playwright documentation." ,
89+ )
90+ }
91+ return reducedMotionInput as ReducedMotionPreference
92+ }
93+
94+ function loadColorScheme ( ) {
95+ const colorSchemeInput = core . getInput ( 'color_scheme' , { required : false } )
96+ if ( ! colorSchemeInput ) return
97+
98+ if ( ! [ 'light' , 'dark' , 'no-preference' , null ] . includes ( colorSchemeInput ) ) {
99+ throw new Error (
100+ "Input 'color_scheme' must be one of: 'light', 'dark', 'no-preference', or null per Playwright documentation." ,
101+ )
102+ }
103+
104+ return colorSchemeInput as ColorSchemePreference
105+ }
0 commit comments