11import axios from "axios" ;
22import config from "../../config.js" ;
3+ import logger from "../../logger.js" ;
4+ import {
5+ isLocalURL ,
6+ ensureLocalBinarySetup ,
7+ killExistingBrowserStackLocalProcesses ,
8+ } from "../../lib/local.js" ;
39
410export interface AccessibilityScanResponse {
511 success : boolean ;
@@ -23,10 +29,54 @@ export class AccessibilityScanner {
2329 name : string ,
2430 urlList : string [ ] ,
2531 ) : Promise < AccessibilityScanResponse > {
32+
33+ // Check if any URL is local
34+ const hasLocal = urlList . some ( isLocalURL ) ;
35+ const localIdentifier = crypto . randomUUID ( ) ;
36+ const LOCAL_IP = "127.0.0.1" ;
37+ const BS_LOCAL_DOMAIN = "bs-local.com" ;
38+
39+ if ( hasLocal ) {
40+ await ensureLocalBinarySetup ( localIdentifier ) ;
41+ } else {
42+ await killExistingBrowserStackLocalProcesses ( ) ;
43+ }
44+
45+ const transformedUrlList = urlList . map ( ( url ) => {
46+ try {
47+ const parsed = new URL ( url ) ;
48+ if ( parsed . hostname === LOCAL_IP ) {
49+ parsed . hostname = BS_LOCAL_DOMAIN ;
50+ return parsed . toString ( ) ;
51+ }
52+ return url ;
53+ } catch ( e ) {
54+ logger . warn ( `[AccessibilityScan] Invalid URL skipped: ${ url } ` ) ;
55+ return url ;
56+ }
57+ } ) ;
58+
59+ const baseRequestBody = {
60+ name,
61+ urlList : transformedUrlList ,
62+ recurring : false ,
63+ } ;
64+
65+ let requestBody = baseRequestBody ;
66+ if ( hasLocal ) {
67+ const localConfig = {
68+ localTestingInfo : {
69+ localIdentifier,
70+ localEnabled : true ,
71+ }
72+ } ;
73+ requestBody = { ...baseRequestBody , ...localConfig } ;
74+ }
75+
2676 try {
2777 const { data } = await axios . post < AccessibilityScanResponse > (
2878 "https://api-accessibility.browserstack.com/api/website-scanner/v1/scans" ,
29- { name , urlList , recurring : false } ,
79+ requestBody ,
3080 { auth : this . auth } ,
3181 ) ;
3282 if ( ! data . success )
0 commit comments