@nightwatch/browserstack
Advanced tools
+3
-2
| { | ||
| "name": "@nightwatch/browserstack", | ||
| "version": "3.7.0", | ||
| "version": "3.7.1", | ||
| "description": "Nightwatch plugin for integration with browserstack.", | ||
@@ -48,3 +48,4 @@ "main": "index.js", | ||
| "winston-transport": "^4.5.0", | ||
| "uuid": "^9.0.0" | ||
| "uuid": "^9.0.0", | ||
| "glob": "^7.2.0" | ||
| }, | ||
@@ -51,0 +52,0 @@ "devDependencies": { |
+12
-107
@@ -5,2 +5,3 @@ const os = require('os'); | ||
| const path = require('path'); | ||
| const glob = require('glob'); | ||
| const {promisify} = require('util'); | ||
@@ -892,82 +893,5 @@ const gitRepoInfo = require('git-repo-info'); | ||
| exports.isGlobPattern = (pattern) => { | ||
| return pattern.includes('*') || pattern.includes('?') || pattern.includes('['); | ||
| return glob.hasMagic(pattern); | ||
| }; | ||
| // Helper function to recursively find files matching a pattern | ||
| exports.findFilesRecursively = (dir, pattern) => { | ||
| const files = []; | ||
| try { | ||
| if (!fs.existsSync(dir)) { | ||
| return files; | ||
| } | ||
| const entries = fs.readdirSync(dir, {withFileTypes: true}); | ||
| for (const entry of entries) { | ||
| const fullPath = path.join(dir, entry.name); | ||
| if (entry.isDirectory()) { | ||
| // Recursively search subdirectories | ||
| files.push(...exports.findFilesRecursively(fullPath, pattern)); | ||
| } else if (entry.isFile()) { | ||
| const relativePath = path.relative(process.cwd(), fullPath); | ||
| // Enhanced pattern matching for glob patterns | ||
| if (exports.matchesGlobPattern(relativePath, pattern)) { | ||
| files.push(relativePath); | ||
| } | ||
| } | ||
| } | ||
| } catch (err) { | ||
| Logger.debug(`Error reading directory ${dir}: ${err.message}`); | ||
| } | ||
| return files; | ||
| }; | ||
| // Helper function to match a file path against a glob pattern | ||
| exports.matchesGlobPattern = (filePath, pattern) => { | ||
| // Normalize paths to use forward slashes | ||
| const normalizedPath = filePath.replace(/\\/g, '/'); | ||
| const normalizedPattern = pattern.replace(/\\/g, '/'); | ||
| // Convert glob pattern to regex step by step | ||
| let regexPattern = normalizedPattern; | ||
| // First, handle ** patterns (must be done before single *) | ||
| // ** should match zero or more directories | ||
| regexPattern = regexPattern.replace(/\*\*/g, '§DOUBLESTAR§'); | ||
| // Escape regex special characters except the placeholders | ||
| regexPattern = regexPattern.replace(/[.+^${}()|[\]\\]/g, '\\$&'); | ||
| // Now handle single * and ? patterns | ||
| regexPattern = regexPattern.replace(/\*/g, '[^/]*'); // * matches anything except path separators | ||
| regexPattern = regexPattern.replace(/\?/g, '[^/]'); // ? matches single character except path separator | ||
| // Finally, replace ** placeholder with regex for any path (including zero directories) | ||
| regexPattern = regexPattern.replace(/§DOUBLESTAR§/g, '.*?'); | ||
| // Special case: if pattern ends with /**/* we need to handle direct files in the base directory | ||
| // Convert patterns like "dir/**/*" to also match "dir/*" | ||
| if (normalizedPattern.includes('/**/')) { | ||
| const baseRegex = regexPattern; | ||
| const alternativeRegex = regexPattern.replace(/\/\.\*\?\//g, '/'); | ||
| regexPattern = `(?:${baseRegex}|${alternativeRegex})`; | ||
| } | ||
| // Ensure pattern matches from start to end | ||
| regexPattern = '^' + regexPattern + '$'; | ||
| try { | ||
| const regex = new RegExp(regexPattern); | ||
| return regex.test(normalizedPath); | ||
| } catch (err) { | ||
| Logger.debug(`Error in glob pattern matching: ${err.message}`); | ||
| return false; | ||
| } | ||
| }; | ||
| // Helper function to resolve and collect test files from a path/pattern | ||
@@ -1044,32 +968,13 @@ exports.collectTestFiles = (testPath, source = 'unknown') => { | ||
| // Extract the base directory from the pattern | ||
| const parts = pattern.split(/[/\\]/); | ||
| let baseDir = '.'; | ||
| let patternStart = 0; | ||
| // Find the first part that contains glob characters | ||
| for (let i = 0; i < parts.length; i++) { | ||
| if (exports.isGlobPattern(parts[i])) { | ||
| patternStart = i; | ||
| break; | ||
| } | ||
| if (i === 0 && parts[i] !== '.') { | ||
| baseDir = parts[i]; | ||
| } else if (i > 0) { | ||
| baseDir = path.join(baseDir, parts[i]); | ||
| } | ||
| try { | ||
| const files = glob.sync(pattern); | ||
| Logger.debug(`Found ${files.length} files matching pattern: ${pattern}`); | ||
| return files; | ||
| } catch (err) { | ||
| Logger.debug(`Error expanding glob pattern: ${err.message}`); | ||
| return []; | ||
| } | ||
| // If baseDir doesn't exist, try current directory | ||
| if (!fs.existsSync(baseDir)) { | ||
| Logger.debug(`Base directory ${baseDir} doesn't exist, using current directory`); | ||
| baseDir = '.'; | ||
| } | ||
| Logger.debug(`Base directory: ${baseDir}, Pattern: ${pattern}`); | ||
| const files = exports.findFilesRecursively(baseDir, pattern); | ||
| Logger.debug(`Found ${files.length} files matching pattern: ${pattern}`); | ||
| return files; | ||
| }; | ||
@@ -1076,0 +981,0 @@ |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 32 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 32 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
173013
-1.88%9
12.5%4210
-1.77%139
0.72%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added