@percy/core
Advanced tools
@@ -5,2 +5,15 @@ import fs from 'fs'; | ||
| // Root under which BrowserStack App Automate hosts write Maestro session | ||
| // artifacts (screenshots + debug output). Historically /tmp; hosts that | ||
| // relocate it inject PERCY_APP_AUTOMATE_TMP_DIR with the new root, so the | ||
| // location is never hardcoded here and can move again without a CLI release. | ||
| // Trailing separators are trimmed so glob patterns and the realpath prefix | ||
| // check compose cleanly; a non-absolute value falls back to /tmp rather than | ||
| // producing a cwd-relative glob. BrowserStack-mode only — self-hosted scoping | ||
| // stays on PERCY_MAESTRO_SCREENSHOT_DIR. | ||
| export function appAutomateTmpDir() { | ||
| let dir = (process.env.PERCY_APP_AUTOMATE_TMP_DIR || '/tmp').replace(/[/\\]+$/, ''); | ||
| return path.isAbsolute(dir) ? dir : '/tmp'; | ||
| } | ||
| /* istanbul ignore next — defensive manual directory walker invoked only when | ||
@@ -16,3 +29,3 @@ fast-glob import fails (broken install / FS corruption). Unit tests | ||
| if (platform === 'ios') { | ||
| const sessionDir = `/tmp/${sessionId}`; | ||
| const sessionDir = `${appAutomateTmpDir()}/${sessionId}`; | ||
| const walk = async (dir, depth) => { | ||
@@ -39,3 +52,3 @@ if (depth > 15) return; // sanity cap | ||
| } else { | ||
| const baseDir = `/tmp/${sessionId}_test_suite/logs`; | ||
| const baseDir = `${appAutomateTmpDir()}/${sessionId}_test_suite/logs`; | ||
| const logDirs = await fs.promises.readdir(baseDir); | ||
@@ -77,5 +90,5 @@ for (const dir of logDirs) { | ||
| } else { | ||
| // Glob pattern depends on deployment shape: | ||
| // BrowserStack Android: /tmp/{sid}_test_suite/logs/*/screenshots/{name}.png | ||
| // BrowserStack iOS: /tmp/{sid}/<maestro_debug_dir>/**/{name}.png | ||
| // Glob pattern depends on deployment shape (TMP = appAutomateTmpDir()): | ||
| // BrowserStack Android: {TMP}/{sid}_test_suite/logs/*/screenshots/{name}.png | ||
| // BrowserStack iOS: {TMP}/{sid}/<maestro_debug_dir>/**/{name}.png | ||
| // (realmobile builds a deeply nested {device}_maestro_debug_ tree; `**` | ||
@@ -95,3 +108,6 @@ // handles any depth, exact {name}.png filters Maestro's emoji-prefixed | ||
| } else { | ||
| searchPattern = platform === 'ios' ? `/tmp/${sessionId}/*_maestro_debug_*/**/${name}.png` : `/tmp/${sessionId}_test_suite/logs/*/screenshots/${name}.png`; | ||
| // Same forward-slash normalization as the self-hosted branch — the env | ||
| // override could carry backslashes when exercised on Windows CI. | ||
| const tmpRoot = appAutomateTmpDir().replace(/\\/g, '/'); | ||
| searchPattern = platform === 'ios' ? `${tmpRoot}/${sessionId}/*_maestro_debug_*/**/${name}.png` : `${tmpRoot}/${sessionId}_test_suite/logs/*/screenshots/${name}.png`; | ||
| } | ||
@@ -153,3 +169,4 @@ let files; | ||
| // Defeats symlink swaps where the root points elsewhere. Both ends are | ||
| // realpath'd because /tmp is a symlink on macOS (where iOS hosts run). The | ||
| // realpath'd because the tmp root can resolve through a symlink (as /tmp | ||
| // does on macOS, where iOS hosts run). The | ||
| // trailing `/` on the prefix is load-bearing — it prevents sibling-prefix | ||
@@ -156,0 +173,0 @@ // bypass (e.g. /x/.maestro vs /x/.maestro-secrets). Both sides are |
@@ -7,3 +7,3 @@ import fs from 'fs'; | ||
| import { handleSyncJob } from './snapshot.js'; | ||
| import { locateScreenshot } from './maestro-screenshot-file.js'; | ||
| import { locateScreenshot, appAutomateTmpDir } from './maestro-screenshot-file.js'; | ||
| import { validateRegionInputs, resolveRegions } from './maestro-regions.js'; | ||
@@ -99,3 +99,4 @@ import { deriveDeviceInsets } from './maestro-hierarchy.js'; | ||
| // Resolve the file-find scope root. On BrowserStack (sessionId present), the | ||
| // root is the BS host's /tmp/{sessionId}{_test_suite} convention. Self-hosted | ||
| // root is the BS host's {appAutomateTmpDir()}/{sessionId}{_test_suite} | ||
| // convention (PERCY_APP_AUTOMATE_TMP_DIR, defaulting to /tmp). Self-hosted | ||
| // (sessionId absent) requires PERCY_MAESTRO_SCREENSHOT_DIR (read from | ||
@@ -138,3 +139,3 @@ // process.env, never the request body) to be an absolute, existing directory | ||
| } else { | ||
| scopeRoot = platform === 'ios' ? `/tmp/${sessionId}` : `/tmp/${sessionId}_test_suite`; | ||
| scopeRoot = platform === 'ios' ? `${appAutomateTmpDir()}/${sessionId}` : `${appAutomateTmpDir()}/${sessionId}_test_suite`; | ||
| } | ||
@@ -141,0 +142,0 @@ |
+10
-10
| { | ||
| "name": "@percy/core", | ||
| "version": "1.32.5-beta.1", | ||
| "version": "1.32.5", | ||
| "license": "MIT", | ||
@@ -12,3 +12,3 @@ "repository": { | ||
| "access": "public", | ||
| "tag": "beta" | ||
| "tag": "latest" | ||
| }, | ||
@@ -50,8 +50,8 @@ "engines": { | ||
| "@grpc/proto-loader": "^0.8.0", | ||
| "@percy/client": "1.32.5-beta.1", | ||
| "@percy/config": "1.32.5-beta.1", | ||
| "@percy/dom": "1.32.5-beta.1", | ||
| "@percy/logger": "1.32.5-beta.1", | ||
| "@percy/monitoring": "1.32.5-beta.1", | ||
| "@percy/webdriver-utils": "1.32.5-beta.1", | ||
| "@percy/client": "1.32.5", | ||
| "@percy/config": "1.32.5", | ||
| "@percy/dom": "1.32.5", | ||
| "@percy/logger": "1.32.5", | ||
| "@percy/monitoring": "1.32.5", | ||
| "@percy/webdriver-utils": "1.32.5", | ||
| "adm-zip": "^0.6.0", | ||
@@ -72,5 +72,5 @@ "busboy": "^1.6.0", | ||
| "optionalDependencies": { | ||
| "@percy/cli-doctor": "1.32.5-beta.1" | ||
| "@percy/cli-doctor": "1.32.5" | ||
| }, | ||
| "gitHead": "ef91ddef69f7e693bff6cfa3d4136e38450d635a" | ||
| "gitHead": "1c83908c5913e3fab1cdd7207db49a2e0c27a3e9" | ||
| } |
Potential vulnerability
Supply chain riskInitial human review suggests the presence of a vulnerability in this package. It is pending further analysis and confirmation.
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Potential vulnerability
Supply chain riskInitial human review suggests the presence of a vulnerability in this package. It is pending further analysis and confirmation.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
706025
0.16%12086
0.14%1
-50%54
1.89%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated