@applitools/core 4.65.2 → 4.66.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applitools/core",
3
- "version": "4.65.2",
3
+ "version": "4.66.0",
4
4
  "homepage": "https://applitools.com",
5
5
  "bugs": {
6
6
  "url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
@@ -61,39 +61,41 @@
61
61
  "setup:standalone": "sh -c 'yarn chromedriver --port=4444 --verbose &'"
62
62
  },
63
63
  "dependencies": {
64
- "@applitools/core-base": "1.35.3",
65
- "@applitools/dom-capture": "11.8.2",
66
- "@applitools/dom-snapshot": "4.17.4",
67
- "@applitools/driver": "1.26.4",
68
- "@applitools/ec-client": "1.12.35",
69
- "@applitools/logger": "2.2.13",
70
- "@applitools/nml-client": "1.11.33",
71
- "@applitools/req": "1.11.1",
72
- "@applitools/screenshoter": "3.12.23",
64
+ "@applitools/core-base": "1.36.0",
65
+ "@applitools/dom-capture": "11.8.3",
66
+ "@applitools/dom-snapshot": "4.17.5",
67
+ "@applitools/driver": "1.26.5",
68
+ "@applitools/ec-client": "1.12.36",
69
+ "@applitools/logger": "2.3.0",
70
+ "@applitools/nml-client": "1.11.34",
71
+ "@applitools/req": "1.11.2",
72
+ "@applitools/screenshoter": "3.12.24",
73
73
  "@applitools/snippets": "2.9.3",
74
- "@applitools/socket": "1.3.14",
75
- "@applitools/ufg-client": "1.22.4",
76
- "@applitools/utils": "1.15.0",
74
+ "@applitools/socket": "1.3.15",
75
+ "@applitools/ufg-client": "1.22.5",
76
+ "@applitools/utils": "1.15.1",
77
77
  "abort-controller": "3.0.0",
78
78
  "chalk": "4.1.2",
79
79
  "node-fetch": "2.6.7",
80
80
  "semver": "7.6.2",
81
+ "shell-quote": "^1.8.4",
81
82
  "throat": "6.0.2"
82
83
  },
83
84
  "devDependencies": {
84
85
  "@applitools/bongo": "^5.10.0",
85
- "@applitools/spec-driver-playwright": "^1.9.4",
86
- "@applitools/spec-driver-puppeteer": "^1.8.4",
87
- "@applitools/spec-driver-selenium": "^1.8.4",
88
- "@applitools/spec-driver-webdriver": "^1.6.4",
89
- "@applitools/test-server": "^1.4.5",
86
+ "@applitools/spec-driver-playwright": "^1.9.5",
87
+ "@applitools/spec-driver-puppeteer": "^1.8.5",
88
+ "@applitools/spec-driver-selenium": "^1.8.5",
89
+ "@applitools/spec-driver-webdriver": "^1.6.5",
90
+ "@applitools/test-server": "^1.4.6",
90
91
  "@applitools/test-utils": "^1.5.17",
91
- "@applitools/tunnel-client": "^1.12.1",
92
+ "@applitools/tunnel-client": "^1.12.2",
92
93
  "@swc-node/register": "^1.6.8",
93
94
  "@types/mocha": "^10.0.7",
94
95
  "@types/node": "^12.20.55",
95
96
  "@types/selenium-webdriver": "^4.1.2",
96
97
  "@types/semver": "^7.5.8",
98
+ "@types/shell-quote": "^1",
97
99
  "chai": "^4.2.0",
98
100
  "chromedriver": "^131.0.5",
99
101
  "crypto": "^1.0.1",
@@ -17,11 +17,92 @@ type ExtractCurrentCommitTimestampOptions = {
17
17
  logger?: Logger;
18
18
  };
19
19
  export declare const cacheKey = "default";
20
+ /** Primary remote name (cached). Prefers `origin`, else the first remote. */
21
+ export declare const getPrimaryRemoteName: (({ execOptions, logger }: {
22
+ execOptions?: ExecOptions | undefined;
23
+ logger?: Logger | undefined;
24
+ }) => Promise<string>) & {
25
+ getCachedValues(): Promise<string>[];
26
+ setCachedValue(key: any, value: Promise<string>): void;
27
+ clearCache(): void;
28
+ TTL?: number | undefined;
29
+ };
20
30
  /**
21
- * Get the primary remote name (cached for performance)
22
- * Prefers 'origin' if it exists, otherwise uses the first available remote
31
+ * Resolve `branchName` to a local bare ref so later `git merge-base`/`rev-parse`
32
+ * calls don't fatal in single-branch/shallow clones where the branch lives only
33
+ * on the remote.
34
+ *
35
+ * Resolution order (cheap → expensive):
36
+ * 1. `refs/heads/<name>` — already a local branch.
37
+ * 2. `refs/remotes/<remote>/<name>` — remote-tracking ref; alias it locally
38
+ * via `git branch <name> <remote>/<name>`.
39
+ * 3. `git ls-remote --heads <remote> <name>` — remote-only; fetch it in as
40
+ * a local-branch ref.
41
+ * 4. `undefined` — unknown branch.
42
+ *
43
+ * Never throws. NOT cachified — it has filesystem side-effects.
23
44
  */
24
- export declare const getPrimaryRemoteName: (({ execOptions, logger }: {
45
+ export declare function resolveBranchToLocalRef({ branchName, remoteName, execOptions, logger, }: {
46
+ branchName: string;
47
+ remoteName: string;
48
+ execOptions?: ExecOptions;
49
+ logger?: Logger;
50
+ }): Promise<string | undefined>;
51
+ export type GitEnvironmentResult = {
52
+ /** `git` binary is on PATH and executable. */
53
+ gitInstalled: boolean;
54
+ /** Current working directory is inside a git work tree. */
55
+ insideRepo: boolean;
56
+ /** A primary remote is configured AND reachable. */
57
+ remoteAccessible: boolean;
58
+ /**
59
+ * `gitInstalled && insideRepo` — sufficient for local-only git operations
60
+ * (commit lookups, local branch detection, local merge-base). Does NOT
61
+ * imply remote ops will succeed — callers that need the remote must
62
+ * additionally check `remoteAccessible`.
63
+ */
64
+ ok: boolean;
65
+ /** Human-readable explanation of the sub-checks; used in skip-logs. */
66
+ reason: string;
67
+ /** Resolved primary remote name, when one is configured. */
68
+ remoteName?: string;
69
+ };
70
+ /**
71
+ * One-shot, cached probe of the git environment, staged cheap → expensive:
72
+ * 1. git installed? (`git --version`)
73
+ * 2. inside a work tree? (`git rev-parse --is-inside-work-tree`)
74
+ * 3. remote configured? (`git remote`)
75
+ * 4. remote reachable? (`git ls-remote <r> HEAD`)
76
+ *
77
+ * Outermost guard for any path that shells out to git; each step short-circuits
78
+ * the rest. Callers consult `ok` for local-only features, `remoteAccessible`
79
+ * for network ops. Cached per `cwd`; first call emits a grep-friendly
80
+ * `APPLITOOLS GIT ENVIRONMENT CHECK` banner, later calls return silently.
81
+ */
82
+ export declare const checkGitEnvironment: (({ execOptions, logger, }: {
83
+ execOptions?: ExecOptions | undefined;
84
+ logger?: Logger | undefined;
85
+ }) => Promise<GitEnvironmentResult>) & {
86
+ getCachedValues(): Promise<GitEnvironmentResult>[];
87
+ setCachedValue(key: any, value: Promise<GitEnvironmentResult>): void;
88
+ clearCache(): void;
89
+ TTL?: number | undefined;
90
+ };
91
+ /**
92
+ * Detect the repo's default branch. Fallback chain (short-circuits on success;
93
+ * never throws):
94
+ * 1. `APPLITOOLS_DEFAULT_BRANCH` — explicit override.
95
+ * 2. `git symbolic-ref --short refs/remotes/<remote>/HEAD` — authoritative
96
+ * once fetched; `<remote>/` prefix stripped.
97
+ * 3. `git ls-remote --symref <remote> HEAD` — works when the local symref was
98
+ * never set up (single-branch clones, older CI git).
99
+ * 4. `git config --get init.defaultBranch` — user-global preference.
100
+ * 5. Literal `'main'` — last resort.
101
+ *
102
+ * Steps 2-3 catch non-standard defaults (e.g. `team/.../v1.x-rc`).
103
+ * Cached per `cwd`.
104
+ */
105
+ export declare const extractDefaultBranch: (({ execOptions, logger }: {
25
106
  execOptions?: ExecOptions | undefined;
26
107
  logger?: Logger | undefined;
27
108
  }) => Promise<string>) & {
@@ -68,6 +149,20 @@ export declare const extractGitRepo: (({ execOptions, logger }: Options) => Prom
68
149
  };
69
150
  export declare function extractCIBranchName(): string | undefined;
70
151
  export declare function extractBuildIdFromCI(): Promise<string | undefined>;
152
+ /**
153
+ * Extract the ISO-8601 timestamp at which `branchName` branched off
154
+ * `parentBranchName`. Steps short-circuit on success; returns `undefined` on
155
+ * total failure — never throws.
156
+ * 1. Shallow clone → unshallow so topology is visible to `git merge-base`.
157
+ * 2. `git merge-base <remote>/<branch> <remote>/<parent>` — remote refs first
158
+ * (CI usually only has these).
159
+ * 3. Local refs fallback (`git merge-base <branch> <parent>`).
160
+ * 4. Still none → if the parent is on the remote, fetch it by name and retry;
161
+ * else give up (branch exists nowhere).
162
+ * 5. Resolve the hash's date via `git show -s --format=%aI`.
163
+ *
164
+ * Cached per (branchName, parentBranchName, cwd).
165
+ */
71
166
  export declare const extractBranchingTimestamp: (({ branchName, parentBranchName, execOptions, logger, }: ExtractGitBranchingTimestampOptions) => Promise<string | undefined>) & {
72
167
  getCachedValues(): Promise<string | undefined>[];
73
168
  setCachedValue(key: any, value: Promise<string | undefined>): void;
@@ -75,21 +170,64 @@ export declare const extractBranchingTimestamp: (({ branchName, parentBranchName
75
170
  TTL?: number | undefined;
76
171
  };
77
172
  export declare function isISODate(str: string): boolean;
173
+ type BranchAncestryOptions = {
174
+ gitBranchName: string;
175
+ defaultBranch: string;
176
+ execOptions?: ExecOptions;
177
+ logger?: Logger;
178
+ };
179
+ /**
180
+ * Enumerate ancestor branches in MERGE_BASE..gitBranchName by walking each
181
+ * commit in the window and unioning the branches that contain it. Returns a
182
+ * sorted, deduped list (no `refs/` prefix). Never throws — `[]` on git failure.
183
+ *
184
+ * Inclusion contract (fork-depth — shares semantics with
185
+ * {@link getBranchAncestryByLocalBranches}):
186
+ * - `gitBranchName` is **always excluded** by the self check.
187
+ * - `defaultBranch` is **always kept** as the base: it defines the floor
188
+ * (`merge-base(HEAD, defaultBranch)`), so its own merge-base with HEAD equals
189
+ * the floor and would fail the strict fork-depth test by construction.
190
+ * - Descendants of HEAD are dropped (built on top of us; cannot be baselines).
191
+ * - A candidate `C` is kept iff it forked from HEAD's history **strictly later**
192
+ * than the default branch did — i.e. some `merge-base(HEAD, C)` is a strict
193
+ * descendant of the floor. Cousins that share only the floor (diverged no
194
+ * later than the default branch) are dropped. This prunes the over-inclusive
195
+ * candidate seed (the per-commit `--contains` walk pulls in cousins via
196
+ * criss-cross/ghost merges).
197
+ *
198
+ * Use {@link getBranchAncestryByLocalBranches} if you need both refs pinned.
199
+ */
200
+ export declare function getBranchAncestryByCommits({ gitBranchName, defaultBranch, execOptions, logger, }: BranchAncestryOptions): Promise<string[]>;
201
+ /**
202
+ * Enumerate ancestor branches by iterating every branch ref and applying
203
+ * Rule 1 (fork-depth: candidate must have forked from HEAD strictly later than
204
+ * the default branch did — some merge-base with HEAD is a strict descendant of
205
+ * the primary MERGE_BASE) and Rule 2 (HEAD must not be an ancestor of the
206
+ * candidate). Rule 1 shares the fork-depth semantics of
207
+ * {@link getBranchAncestryByCommits}: cousins sharing only the floor are dropped
208
+ * in BOTH strategies, while the default branch and genuine lineage points are
209
+ * kept in both.
210
+ *
211
+ * Walks `refs/heads/` AND `refs/remotes/<remote>/` (stripping the prefix), since
212
+ * CI typically has one local branch and dozens of remote refs.
213
+ *
214
+ * Returns a sorted, deduped list. Never throws — `[]` on git failure. Always
215
+ * includes `defaultBranch` and `gitBranchName`.
216
+ */
217
+ export declare function getBranchAncestryByLocalBranches({ gitBranchName, defaultBranch, execOptions, logger, }: BranchAncestryOptions): Promise<string[]>;
78
218
  /**
79
- * Extracts a list of ancestor branches for the given branch, ordered by most recent commit timestamp.
219
+ * List ancestor branches for `gitBranchName`, ordered by most-recent timestamp.
80
220
  *
81
- * Algorithm:
82
- * 1. Check if shallow clone and should skip (via APPLITOOLS_SKIP_BRANCH_LOOKUP_IN_SHALLOW_CLONE)
83
- * 2. Ensure remote branches are available (fetch if needed for single-branch/shallow clones)
84
- * 3. Use git topology to discover ancestor branches efficiently (O(log N) via --first-parent --simplify-by-decoration)
85
- * 4. For each discovered branch, extract the branching timestamp (latest viable commit where branch existed)
86
- * 5. Sort results by timestamp descending (most recent first)
87
- * 6. Return cached results (5-minute TTL) to avoid redundant git operations
221
+ * 1. Shallow-clone gate (skip via `enableShallowClone`, from server account-info).
222
+ * 2. Fetch remote branches if needed (single-branch/shallow clones).
223
+ * 3. Detect the actual default branch (`extractDefaultBranch` non-standard names).
224
+ * 4. Discover ancestors via `APPLITOOLS_BRANCH_ANCESTRY_STRATEGY`:
225
+ * `commits` (default, walks MERGE_BASE..HEAD) | `local` (iterates refs).
226
+ * 5. Extract each branch's branching timestamp.
227
+ * 6. Sort by timestamp desc, tie-break by name.
228
+ * 7. Root-branch safety net: fall back to the detected default branch.
88
229
  *
89
- * @param gitBranchName - The branch to analyze
90
- * @param execOptions - Git execution options (e.g., cwd)
91
- * @param logger - Logger instance for debugging
92
- * @returns Array of ancestor branches with timestamps, or undefined if skipped
230
+ * @returns ancestor branches with timestamps, or undefined if skipped.
93
231
  */
94
232
  export declare const extractBranchLookupFallbackList: (({ gitBranchName, execOptions, logger, enableShallowClone, }: {
95
233
  gitBranchName: string;