1
1
import axios from "axios" ;
2
2
import config from "../../config.js" ;
3
+ import logger from "../../logger.js" ;
4
+ import {
5
+ isLocalURL ,
6
+ ensureLocalBinarySetup ,
7
+ killExistingBrowserStackLocalProcesses ,
8
+ } from "../../lib/local.js" ;
3
9
4
10
export interface AccessibilityScanResponse {
5
11
success : boolean ;
@@ -23,10 +29,54 @@ export class AccessibilityScanner {
23
29
name : string ,
24
30
urlList : string [ ] ,
25
31
) : 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
+
26
76
try {
27
77
const { data } = await axios . post < AccessibilityScanResponse > (
28
78
"https://api-accessibility.browserstack.com/api/website-scanner/v1/scans" ,
29
- { name , urlList , recurring : false } ,
79
+ requestBody ,
30
80
{ auth : this . auth } ,
31
81
) ;
32
82
if ( ! data . success )
0 commit comments