@wdio/browserstack-service 9.33.2 → 9.34.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,7 +23,20 @@ export declare class CLIUtils {
23
23
  static isBinaryBusy(binaryPath: string): boolean;
24
24
  static requestToUpdateCLI: (queryParams: Record<string, string>, config: Options.Testrunner) => Promise<any>;
25
25
  static runShellCommand(cmdCommand: string, workingDir?: string): Promise<string>;
26
- static downloadLatestBinary: (binDownloadUrl: string, cliDir: string) => Promise<string | null>;
26
+ /**
27
+ * Version encoded in a binary download URL, e.g.
28
+ * `.../binary-macos-arm64-1.48.0.zip` -> `1.48.0`. Null when the URL does
29
+ * not carry one (custom BROWSERSTACK_BINARY_URL).
30
+ */
31
+ static getVersionFromBinaryUrl(binDownloadUrl: string): string | null;
32
+ /**
33
+ * Whether the binary on disk is already the version we were asked to fetch.
34
+ * A peer worker winning the download race leaves the *target* version here;
35
+ * a merely-pre-existing binary is stale. Only the former may short-circuit
36
+ * the download — see `downloadLatestBinary`.
37
+ */
38
+ static isBinaryAtVersion(binaryPath: string, expectedVersion: string | null): Promise<boolean>;
39
+ static downloadLatestBinary: (binDownloadUrl: string, cliDir: string, expectedVersion?: string | null) => Promise<string | null>;
27
40
  static downloadFileStream(downloadedFileStream: fs.WriteStream, zipFilePath: string, cliDir: string, resolve: (path: string) => void, reject: (reason?: Error) => void): void;
28
41
  static getTestFrameworkDetail(): any;
29
42
  static getAutomationFrameworkDetail(): any;
@@ -12,6 +12,11 @@ export default class AutomateModule extends BaseModule {
12
12
  constructor(browserStackConfig: Options.Testrunner);
13
13
  getModuleName(): string;
14
14
  onBeforeTest(args: Record<string, unknown>): Promise<void>;
15
+ /**
16
+ * PUT the session's current name if it has not already been applied.
17
+ * De-duped via `appliedName` so the onAfterExecute sweep does not re-send it.
18
+ */
19
+ private flushSessionName;
15
20
  onAfterTest(args: Record<string, unknown>): Promise<void>;
16
21
  onAfterExecute(): Promise<void>;
17
22
  private isAppAutomate;
@@ -43,7 +43,7 @@ export default class TestHubModule extends BaseModule {
43
43
  sendTestFrameworkEvent(args: Record<string, unknown>, stateOverride?: {
44
44
  testFrameworkState: string;
45
45
  testHookState: string;
46
- }): Promise<void>;
46
+ }): Promise<boolean>;
47
47
  /**
48
48
  * Send test session event to the service
49
49
  * @param args containing test session data
@@ -0,0 +1,117 @@
1
+ import type { Options } from '@wdio/types';
2
+ export interface CapturedFile {
3
+ name: string;
4
+ sourcePath: string;
5
+ content: string;
6
+ }
7
+ export interface ConfigPathResolution {
8
+ configPath?: string;
9
+ strategy?: string;
10
+ reason?: string;
11
+ }
12
+ /**
13
+ * cwd-relative form of a FILE path, for anything that gets uploaded.
14
+ *
15
+ * The basename fallback is safe here only because `path.relative` is never empty for a file —
16
+ * a file is never equal to cwd. Do NOT pass a directory: see `relativeDirToCwd`.
17
+ */
18
+ export declare const relativeToCwd: (filePath: string) => string;
19
+ /**
20
+ * cwd-relative form of a DIRECTORY path.
21
+ *
22
+ * `path.relative(cwd, cwd)` is `''`, which is the COMMON case here (a manifest at the project
23
+ * root), so a basename fallback would report the folder name — and for a project checked out
24
+ * directly in `$HOME` that folder name is the OS username, which is the exact exposure the
25
+ * relative-path handling exists to prevent. Empty means "cwd", so render it as `.`.
26
+ */
27
+ export declare const relativeDirToCwd: (dir: string) => string;
28
+ /**
29
+ * Resolve the absolute path of the user's wdio config file.
30
+ *
31
+ * WDIO keeps the real path in `ConfigParser`'s private `#configFilePath`, which no service can
32
+ * reach, so this reconstructs it from the values the CLI does leave on the merged config —
33
+ * mirroring how `@wdio/cli` itself resolves it. The CLI never searches: it takes one candidate
34
+ * and probes one stem across the supported extensions, so neither does this.
35
+ *
36
+ * 1. BROWSERSTACK_WDIO_CONFIG_FILE_PATH — explicit override / support escape hatch
37
+ * 2. config['config-path'] — yargs' kebab alias of the `run <configPath>`
38
+ * positional (v8 and v9 alike)
39
+ * 3. config._[0] — the bare `wdio <config>` form, which `run.ts`
40
+ * itself resolves from `params._[0]`
41
+ * 4. rootDir + wdio.conf.<ext> — no-arg `wdio`, and programmatic `new Launcher()`
42
+ * 5. cwd + wdio.conf.<ext> — when the user overrides `rootDir` in their config
43
+ *
44
+ * `config._` is read rather than raw `process.argv`: it is the same positional AFTER yargs has
45
+ * applied wdio's own option declarations. Scanning argv means re-implementing that with a
46
+ * heuristic that cannot know which flags are boolean — and `wdio --watch ./a.conf.ts` puts the
47
+ * real config in `_[0]` while any "skip a flag's value" rule throws it away.
48
+ */
49
+ export declare function resolveWdioConfigPath(config?: Options.Testrunner): ConfigPathResolution;
50
+ /**
51
+ * Resolve once, as early as possible, and publish the answer on the environment so the
52
+ * upload path (and any worker) reads the SAME value instead of re-deriving it from cwd.
53
+ *
54
+ * Re-resolving at archive time is precisely the bug SDK-5993 fixed in the Node SDK: the
55
+ * archive step read `cwd/browserstack.yml` while startup had resolved a different path,
56
+ * silently dropping the config for every monorepo / subdir CI run.
57
+ */
58
+ export declare function initWdioConfigPath(config?: Options.Testrunner): ConfigPathResolution;
59
+ /**
60
+ * Opt-out for auto-captured logs. Service option first, env var as the CI escape hatch
61
+ * (customers cannot always edit a committed config). Name matches the Node SDK's
62
+ * `disableAutoCaptureLogs` so the flag means the same thing across BrowserStack SDKs.
63
+ */
64
+ export declare function isAutoCaptureLogsDisabled(options?: {
65
+ disableAutoCaptureLogs?: boolean;
66
+ }): boolean;
67
+ /**
68
+ * Mirror the service option onto the environment so the opt-out survives into the
69
+ * DETACHED cleanup process, which gets no options object.
70
+ *
71
+ * Without this the opt-out is worse than useless: skipping the upload leaves
72
+ * `logsUploaded` false, which is exactly the condition that arms the exit-time
73
+ * `--uploadLogs` rescue — so every opted-out run had its config read and POSTed by the
74
+ * cleanup child. Returns whether auto-capture is disabled.
75
+ */
76
+ export declare function publishAutoCaptureDisabled(options?: {
77
+ disableAutoCaptureLogs?: boolean;
78
+ }): boolean;
79
+ /**
80
+ * Line-level credential scrub, ported from the Node SDK's `redactSensitiveContent`.
81
+ *
82
+ * Any line mentioning a sensitive key collapses to `<key>: [REDACTED]`. Word boundaries
83
+ * keep `hotkey` / `keyword` from tripping the bare `key` entry that WDIO's top-level
84
+ * credential options force us to carry. `.` is intentionally NOT part of the boundary
85
+ * class so `bstackOptions.accessKey = '...'` still matches.
86
+ */
87
+ export declare function redactSensitiveContent(text: string): string;
88
+ /**
89
+ * Give every archive entry a unique name. Two configs can share a basename
90
+ * (`configs/wdio.conf.ts` + `shared/wdio.conf.ts`); without this the second silently
91
+ * overwrites the first, since archive entries are keyed by basename.
92
+ *
93
+ * Shared with `uploadLogs`, which de-dupes the copied log files against these entries —
94
+ * one implementation so the two can never disagree.
95
+ */
96
+ export declare function dedupeEntryName(filePath: string, taken: Set<string>): string;
97
+ /**
98
+ * Build the redacted config entries added to the auto-captured log archive.
99
+ *
100
+ * Best effort by contract: any failure returns what was gathered so far and a reason
101
+ * string for the SDK_UPLOAD_LOGS event. It must never throw — a debug artifact is never
102
+ * worth failing a customer's test run over.
103
+ */
104
+ export declare function collectConfigFilesForUpload(config?: Options.Testrunner): {
105
+ files: CapturedFile[];
106
+ failures: string[];
107
+ strategy?: string;
108
+ };
109
+ /**
110
+ * `package.json` for the project the config belongs to — framework and service versions
111
+ * are the first thing triage needs, and the archive carried neither before.
112
+ *
113
+ * Walks UP from the config's directory, because `configs/wdio.conf.ts` (a very common
114
+ * layout) puts the manifest one or more levels above the config, not beside it.
115
+ * Archived verbatim: it is a manifest, not a secret store.
116
+ */
117
+ export declare function findPackageJsonForUpload(): string | undefined;
@@ -23,6 +23,40 @@ export declare const CLI_DEBUG_LOGS_FILE = "log/sdk-cli-debug.log";
23
23
  export declare const UPLOAD_LOGS_ADDRESS = "https://upload-observability.browserstack.com";
24
24
  export declare const UPLOAD_LOGS_ENDPOINT = "client-logs/upload";
25
25
  export declare const PERCY_LOGS_FILE = "logs/percy.log";
26
+ /**
27
+ * Auto-capture of the user's wdio config file (SDK-7250).
28
+ */
29
+ export declare const AUTOLOGCAPTURE_NOTIFICATION = "Your wdio config file, the local config files it imports and package.json are captured with the debug logs at the end of the run, with values under known credential keys removed. To disable, set disableAutoCaptureLogs: true in the browserstack service options.";
30
+ export declare const BROWSERSTACK_WDIO_CONFIG_FILE_PATH = "BROWSERSTACK_WDIO_CONFIG_FILE_PATH";
31
+ export declare const BROWSERSTACK_DISABLE_AUTO_CAPTURE_LOGS = "BROWSERSTACK_DISABLE_AUTO_CAPTURE_LOGS";
32
+ export declare const BROWSERSTACK_WDIO_CONFIG_STRATEGY = "BROWSERSTACK_WDIO_CONFIG_STRATEGY";
33
+ export declare const SUPPORTED_WDIO_CONFIG_EXTENSIONS: string[];
34
+ export declare const DEFAULT_WDIO_CONFIG_BASENAME = "wdio.conf";
35
+ export declare const WDIO_CLI_SUBCOMMANDS: string[];
36
+ export declare const MAX_CAPTURED_CONFIG_FILE_BYTES: number;
37
+ export declare const MAX_CAPTURED_CONFIG_FILES = 6;
38
+ export declare const CAPTURE_CONFIG_IMPORT_DEPTH = 1;
39
+ export declare const MAX_PACKAGE_JSON_WALK_UP = 5;
40
+ /**
41
+ * Keys whose line is scrubbed before a config file enters the archive.
42
+ * `user` / `key` are WDIO's own top-level credential options, hence the bare entries.
43
+ */
44
+ /**
45
+ * Word families that make an identifier sensitive when they appear as its SUFFIX —
46
+ * `clientSecret`, `refreshToken`, `privateKey`, `client_secret`. Split by case so the
47
+ * camelCase form requires a capital (distinguishing `privateKey` from `hotkey`) and the
48
+ * snake_case form requires an explicit `_` (distinguishing `client_secret` from `keyword`).
49
+ */
50
+ export declare const COMPOUND_SECRET_SUFFIXES_CAMEL = "Key|Token|Secret|Password|Passwd|Credential";
51
+ export declare const COMPOUND_SECRET_SUFFIXES_SNAKE = "key|token|secret|password|passwd|credential";
52
+ /**
53
+ * Secrets that span lines or hide inside a value, which a line/key-anchored scrub cannot
54
+ * reach. Applied as whole-block passes before the line passes.
55
+ */
56
+ export declare const PEM_BLOCK_REGEX: RegExp;
57
+ export declare const PEM_UNTERMINATED_REGEX: RegExp;
58
+ export declare const URL_USERINFO_REGEX: RegExp;
59
+ export declare const REDACTED_KEYS: string[];
26
60
  export declare const PERCY_DOM_CHANGING_COMMANDS_ENDPOINTS: string[];
27
61
  export declare const CAPTURE_MODES: string[];
28
62
  export declare const LOG_KIND_USAGE_MAP: {
@@ -69,6 +103,10 @@ export declare const MAX_SPAWN_RETRIES = 3;
69
103
  export declare const SPAWN_RETRY_DELAY_MS = 1000;
70
104
  export declare const WDIO_NAMING_PREFIX = "WebdriverIO-";
71
105
  export declare const PERF_METRICS_WAIT_TIME = 2000;
106
+ export declare const STOP_BUILD_MAX_ATTEMPTS = 4;
107
+ export declare const STOP_BUILD_ATTEMPT_TIMEOUT_MS = 10000;
108
+ export declare const STOP_BUILD_TOTAL_BUDGET_MS = 30000;
109
+ export declare const STOP_BUILD_BACKOFF_BASE_MS = 1000;
72
110
  export declare const UPDATED_CLI_ENDPOINT = "sdk/v1/update_cli";
73
111
  /**
74
112
  * Module Hook Events - Performance event names for module lifecycle tracking