@applitools/core 4.59.2 → 4.59.4-debug.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/dist/cli/cli.js +160 -0
- package/dist/offline/run-offline-snapshots.js +9 -26
- package/dist/ufg/get-base-eyes.js +2 -2
- package/dist/ufg/take-snapshots.js +15 -0
- package/dist/ufg/utils/to-generated-selectors.js +6 -1
- package/dist/universal/core-server-process.js +31 -0
- package/dist/universal/core-server.js +216 -0
- package/dist/universal/history.js +90 -0
- package/dist/universal/refer.js +67 -0
- package/dist/universal/spec-driver.js +189 -0
- package/dist/universal/types.js +2 -0
- package/dist/universal/ws-server.js +66 -0
- package/dist/utils/extract-git-info.js +80 -2
- package/dist/utils/populate-eyes-server-settings.js +1 -0
- package/package.json +21 -21
- package/types/cli/cli.d.ts +2 -0
- package/types/ufg/utils/to-generated-selectors.d.ts +2 -1
- package/types/universal/core-server-process.d.ts +9 -0
- package/types/universal/core-server.d.ts +18 -0
- package/types/universal/history.d.ts +2 -0
- package/types/universal/refer.d.ts +8 -0
- package/types/universal/spec-driver.d.ts +15 -0
- package/types/universal/types.d.ts +205 -0
- package/types/universal/ws-server.d.ts +15 -0
- package/CHANGELOG.md +0 -6574
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.makeRefer = void 0;
|
|
27
|
+
const utils = __importStar(require("@applitools/utils"));
|
|
28
|
+
const REF_ID = 'applitools-ref-id';
|
|
29
|
+
function makeRefer() {
|
|
30
|
+
const store = new Map();
|
|
31
|
+
const relation = new Map();
|
|
32
|
+
return { isRef, ref, deref, destroy };
|
|
33
|
+
function isRef(ref) {
|
|
34
|
+
return Boolean(ref[REF_ID]);
|
|
35
|
+
}
|
|
36
|
+
function ref(value, parentRef) {
|
|
37
|
+
const ref = utils.general.guid();
|
|
38
|
+
store.set(ref, value);
|
|
39
|
+
if (parentRef) {
|
|
40
|
+
let childRefs = relation.get(parentRef[REF_ID]);
|
|
41
|
+
if (!childRefs) {
|
|
42
|
+
childRefs = new Set();
|
|
43
|
+
relation.set(parentRef[REF_ID], childRefs);
|
|
44
|
+
}
|
|
45
|
+
childRefs.add({ [REF_ID]: ref });
|
|
46
|
+
}
|
|
47
|
+
return { [REF_ID]: ref };
|
|
48
|
+
}
|
|
49
|
+
function deref(ref) {
|
|
50
|
+
if (isRef(ref)) {
|
|
51
|
+
return store.get(ref[REF_ID]);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
return ref;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function destroy(ref) {
|
|
58
|
+
if (!isRef(ref))
|
|
59
|
+
return;
|
|
60
|
+
const childRefs = relation.get(ref[REF_ID]);
|
|
61
|
+
if (childRefs) {
|
|
62
|
+
childRefs.forEach(childRef => destroy(childRef));
|
|
63
|
+
}
|
|
64
|
+
store.delete(ref[REF_ID]);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.makeRefer = makeRefer;
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.makeSpec = void 0;
|
|
27
|
+
const utils = __importStar(require("@applitools/utils"));
|
|
28
|
+
function makeSpec({ socket, spec, }) {
|
|
29
|
+
const commands = {
|
|
30
|
+
isDriver(driver) {
|
|
31
|
+
return utils.types.has(driver, 'applitools-ref-id');
|
|
32
|
+
},
|
|
33
|
+
isContext(context) {
|
|
34
|
+
return utils.types.has(context, 'applitools-ref-id');
|
|
35
|
+
},
|
|
36
|
+
isElement(element) {
|
|
37
|
+
return utils.types.has(element, ['applitools-ref-id', 'type']) && element.type === 'element';
|
|
38
|
+
},
|
|
39
|
+
isSelector(selector) {
|
|
40
|
+
return ((utils.types.has(selector, ['applitools-ref-id', 'type']) && selector.type === 'selector') ||
|
|
41
|
+
utils.types.isString(selector) ||
|
|
42
|
+
(utils.types.isPlainObject(selector) &&
|
|
43
|
+
utils.types.has(selector, 'selector') &&
|
|
44
|
+
(utils.types.isString(selector.selector) || utils.types.has(selector, 'applitools-ref-id'))));
|
|
45
|
+
},
|
|
46
|
+
async isEqualElements(context, element1, element2) {
|
|
47
|
+
return socket.request('Driver.isEqualElements', { context, element1, element2 });
|
|
48
|
+
},
|
|
49
|
+
isStaleElementError(error) {
|
|
50
|
+
return error === null || error === void 0 ? void 0 : error.isStaleElementError;
|
|
51
|
+
},
|
|
52
|
+
extractContext(driver) {
|
|
53
|
+
return driver.context;
|
|
54
|
+
},
|
|
55
|
+
extractSelector(element) {
|
|
56
|
+
return element.selector;
|
|
57
|
+
},
|
|
58
|
+
async executeScript(context, script, arg) {
|
|
59
|
+
return socket.request('Driver.executeScript', { context, script: script.toString(), arg });
|
|
60
|
+
},
|
|
61
|
+
async findElement(context, selector, parent) {
|
|
62
|
+
return socket.request('Driver.findElement', { context, selector, parent });
|
|
63
|
+
},
|
|
64
|
+
async findElements(context, selector, parent) {
|
|
65
|
+
return socket.request('Driver.findElements', { context, selector, parent });
|
|
66
|
+
},
|
|
67
|
+
async waitForSelector(context, selector, parent, options) {
|
|
68
|
+
return socket.request('Driver.waitForSelector', { context, selector, parent, options });
|
|
69
|
+
},
|
|
70
|
+
async getElementText(context, element) {
|
|
71
|
+
return socket.request('Driver.getElementText', { context, element });
|
|
72
|
+
},
|
|
73
|
+
async setElementText(context, element, text) {
|
|
74
|
+
return socket.request('Driver.setElementText', { context, element, text });
|
|
75
|
+
},
|
|
76
|
+
async getElementRegion(context, element) {
|
|
77
|
+
return socket.request('Driver.getElementRegion', { context, element });
|
|
78
|
+
},
|
|
79
|
+
async getElementAttribute(context, element, attr) {
|
|
80
|
+
return socket.request('Driver.getElementAttribute', { context, element, attr });
|
|
81
|
+
},
|
|
82
|
+
async hover(context, element) {
|
|
83
|
+
return socket.request('Driver.hover', { context, element });
|
|
84
|
+
},
|
|
85
|
+
async click(context, element) {
|
|
86
|
+
return socket.request('Driver.click', { context, element });
|
|
87
|
+
},
|
|
88
|
+
async mainContext(context) {
|
|
89
|
+
return socket.request('Driver.mainContext', { context });
|
|
90
|
+
},
|
|
91
|
+
async parentContext(context) {
|
|
92
|
+
return socket.request('Driver.parentContext', { context });
|
|
93
|
+
},
|
|
94
|
+
async childContext(context, element) {
|
|
95
|
+
return socket.request('Driver.childContext', { context, element });
|
|
96
|
+
},
|
|
97
|
+
async getCapabilities(driver) {
|
|
98
|
+
return socket.request('Driver.getCapabilities', { driver });
|
|
99
|
+
},
|
|
100
|
+
async getDriverInfo(driver) {
|
|
101
|
+
return socket.request('Driver.getDriverInfo', { driver });
|
|
102
|
+
},
|
|
103
|
+
async getWindowSize(driver) {
|
|
104
|
+
return socket.request('Driver.getWindowSize', { driver });
|
|
105
|
+
},
|
|
106
|
+
async setWindowSize(driver, size) {
|
|
107
|
+
return socket.request('Driver.setWindowSize', { driver, size });
|
|
108
|
+
},
|
|
109
|
+
async getViewportSize(driver) {
|
|
110
|
+
return socket.request('Driver.getViewportSize', { driver });
|
|
111
|
+
},
|
|
112
|
+
async setViewportSize(driver, size) {
|
|
113
|
+
return socket.request('Driver.setViewportSize', { driver, size });
|
|
114
|
+
},
|
|
115
|
+
async getSystemBars(driver) {
|
|
116
|
+
return socket.request('Driver.getSystemBars', { driver });
|
|
117
|
+
},
|
|
118
|
+
async getOrientation(driver) {
|
|
119
|
+
return socket.request('Driver.getOrientation', { driver });
|
|
120
|
+
},
|
|
121
|
+
async setOrientation(driver, orientation) {
|
|
122
|
+
return socket.request('Driver.setOrientation', { driver, orientation });
|
|
123
|
+
},
|
|
124
|
+
async getCookies(driver, context) {
|
|
125
|
+
return socket.request('Driver.getCookies', { driver, context });
|
|
126
|
+
},
|
|
127
|
+
async getTitle(driver) {
|
|
128
|
+
return socket.request('Driver.getTitle', { driver });
|
|
129
|
+
},
|
|
130
|
+
async getUrl(driver) {
|
|
131
|
+
return socket.request('Driver.getUrl', { driver });
|
|
132
|
+
},
|
|
133
|
+
async takeScreenshot(driver) {
|
|
134
|
+
return socket.request('Driver.takeScreenshot', { driver });
|
|
135
|
+
},
|
|
136
|
+
async performAction(driver, steps) {
|
|
137
|
+
return socket.request('Driver.performAction', { driver, steps });
|
|
138
|
+
},
|
|
139
|
+
async visit(driver, url) {
|
|
140
|
+
return socket.request('Driver.visit', { driver, url });
|
|
141
|
+
},
|
|
142
|
+
async getCurrentWorld(driver) {
|
|
143
|
+
return socket.request('Driver.getCurrentWorld', { driver });
|
|
144
|
+
},
|
|
145
|
+
async getWorlds(driver) {
|
|
146
|
+
return socket.request('Driver.getWorlds', { driver });
|
|
147
|
+
},
|
|
148
|
+
async switchWorld(driver, name) {
|
|
149
|
+
return socket.request('Driver.switchWorld', { driver, name });
|
|
150
|
+
},
|
|
151
|
+
async reload(driver) {
|
|
152
|
+
return socket.request('Driver.reload', { driver });
|
|
153
|
+
},
|
|
154
|
+
async isUserFunction(ref) {
|
|
155
|
+
return utils.types.has(ref, 'applitools-ref-id');
|
|
156
|
+
},
|
|
157
|
+
async executeUserFunction(userFunction) {
|
|
158
|
+
return socket.request('Driver.executeUserFunction', userFunction);
|
|
159
|
+
},
|
|
160
|
+
async executeBrowserCommands(driver, commands) {
|
|
161
|
+
return socket.request('Driver.executeBrowserCommands', { driver, commands });
|
|
162
|
+
},
|
|
163
|
+
async bringToFront(driver) {
|
|
164
|
+
return socket.request('Driver.bringToFront', { driver });
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
// add default commands to spec (if not already there) such as `isUserFunction`
|
|
168
|
+
spec = addDefaultCommands(spec);
|
|
169
|
+
return spec.reduce((spec, name) => {
|
|
170
|
+
return Object.assign(spec, { [name]: commands[name] });
|
|
171
|
+
}, {});
|
|
172
|
+
}
|
|
173
|
+
exports.makeSpec = makeSpec;
|
|
174
|
+
// returns a new clone of the spec commands array with additional commands universal can support even if the spec doesn't
|
|
175
|
+
function addDefaultCommands(spec) {
|
|
176
|
+
const defaultCommands = [
|
|
177
|
+
{
|
|
178
|
+
command: 'isUserFunction',
|
|
179
|
+
dependsOn: ['executeUserFunction'],
|
|
180
|
+
},
|
|
181
|
+
];
|
|
182
|
+
const commands = spec.slice();
|
|
183
|
+
defaultCommands.forEach(({ command, dependsOn }) => {
|
|
184
|
+
if (!commands.includes(command) && dependsOn.every(dep => commands.includes(dep))) {
|
|
185
|
+
commands.push(command);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
return commands;
|
|
189
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makeServer = void 0;
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
const https_1 = require("https");
|
|
6
|
+
const ws_1 = require("ws");
|
|
7
|
+
const { name, version } = require('../../package.json');
|
|
8
|
+
const TOKEN_HEADER = 'x-eyes-universal-token';
|
|
9
|
+
const TOKEN = `${name}@${version}`;
|
|
10
|
+
async function makeServer(options = {}, logger) {
|
|
11
|
+
const { port = 21077, singleton = true, debug = false, portResolutionMode = 'next', cert, key } = options;
|
|
12
|
+
const secure = Boolean(cert && key);
|
|
13
|
+
const http = secure ? new https_1.Server({ cert, key }) : new http_1.Server();
|
|
14
|
+
http.on('request', (request, response) => {
|
|
15
|
+
if (request.url === '/handshake') {
|
|
16
|
+
const token = debug ? request.headers[TOKEN_HEADER] : TOKEN;
|
|
17
|
+
if (request.headers[TOKEN_HEADER] === token) {
|
|
18
|
+
response.writeHead(200, { [TOKEN_HEADER]: token });
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
response.writeHead(400);
|
|
22
|
+
}
|
|
23
|
+
response.end();
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const hostName = process.env.APPLITOOLS_UNIVERSAL_HOST_NAME || 'localhost';
|
|
27
|
+
http.listen(port, hostName);
|
|
28
|
+
return new Promise((resolve, reject) => {
|
|
29
|
+
http.on('listening', () => {
|
|
30
|
+
const ws = new ws_1.Server({ server: http, path: '/eyes', maxPayload: 256 * 1024 * 1024 });
|
|
31
|
+
ws.on('close', () => {
|
|
32
|
+
logger.log('Core universal server is closed');
|
|
33
|
+
http.close();
|
|
34
|
+
});
|
|
35
|
+
ws.on('error', err => {
|
|
36
|
+
logger.log('Core universal server error', err);
|
|
37
|
+
});
|
|
38
|
+
resolve({ server: ws, port: http.address().port });
|
|
39
|
+
});
|
|
40
|
+
http.on('error', async (err) => {
|
|
41
|
+
if (portResolutionMode !== 'lazy' && err.code === 'EADDRINUSE') {
|
|
42
|
+
if (singleton && (await isHandshakable({ port, secure }))) {
|
|
43
|
+
return resolve({ port });
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return resolve(await makeServer({ ...options, port: portResolutionMode === 'next' ? port + 1 : 0 }, logger));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
reject(err);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
exports.makeServer = makeServer;
|
|
54
|
+
async function isHandshakable({ port, secure }) {
|
|
55
|
+
const request = secure ? https_1.request : http_1.request;
|
|
56
|
+
return new Promise(resolve => {
|
|
57
|
+
const handshake = request(`${secure ? 'https' : 'http'}://localhost:${port}/handshake`, {
|
|
58
|
+
headers: { [TOKEN_HEADER]: TOKEN },
|
|
59
|
+
});
|
|
60
|
+
handshake.on('response', ({ statusCode, headers }) => {
|
|
61
|
+
resolve(statusCode === 200 && headers[TOKEN_HEADER] === TOKEN);
|
|
62
|
+
});
|
|
63
|
+
handshake.on('error', () => resolve(false));
|
|
64
|
+
handshake.end();
|
|
65
|
+
});
|
|
66
|
+
}
|
|
@@ -39,14 +39,23 @@ exports.cacheKey = 'default';
|
|
|
39
39
|
* Prefers 'origin' if it exists, otherwise uses the first available remote
|
|
40
40
|
*/
|
|
41
41
|
exports.getPrimaryRemoteName = utils.general.cachify(async function ({ execOptions, logger = (0, logger_1.makeLogger)() }) {
|
|
42
|
+
const fnStart = Date.now();
|
|
43
|
+
if (isDebugMode())
|
|
44
|
+
logger.log(`[DEBUG] getPrimaryRemoteName: started`);
|
|
42
45
|
const result = await executeWithLog('git remote show', { execOptions, logger });
|
|
43
46
|
if (result.stderr) {
|
|
44
47
|
logger.log(`Error during extracting remotes from git`, result.stderr);
|
|
48
|
+
if (isDebugMode())
|
|
49
|
+
logger.log(`[DEBUG] getPrimaryRemoteName: falling back to 'origin' after error in ${Date.now() - fnStart}ms`);
|
|
45
50
|
return 'origin'; // Fallback to 'origin' if we can't determine remotes
|
|
46
51
|
}
|
|
47
52
|
const remotes = result.stdout.trim().split(/\s+/);
|
|
53
|
+
if (isDebugMode())
|
|
54
|
+
logger.log(`[DEBUG] getPrimaryRemoteName: parsed remotes: [${remotes.join(', ')}]`);
|
|
48
55
|
const remote = remotes.includes('origin') ? 'origin' : remotes[0] || 'origin';
|
|
49
56
|
logger.log(`Primary remote name: ${remote}`);
|
|
57
|
+
if (isDebugMode())
|
|
58
|
+
logger.log(`[DEBUG] getPrimaryRemoteName: completed in ${Date.now() - fnStart}ms`);
|
|
50
59
|
return remote;
|
|
51
60
|
}, args => {
|
|
52
61
|
var _a;
|
|
@@ -55,9 +64,14 @@ exports.getPrimaryRemoteName = utils.general.cachify(async function ({ execOptio
|
|
|
55
64
|
});
|
|
56
65
|
});
|
|
57
66
|
exports.extractLatestCommitInfo = utils.general.cachify(async function ({ execOptions, logger = (0, logger_1.makeLogger)(), }) {
|
|
67
|
+
const fnStart = Date.now();
|
|
68
|
+
if (isDebugMode())
|
|
69
|
+
logger.log(`[DEBUG] extractLatestCommitInfo: started`);
|
|
58
70
|
let result;
|
|
59
71
|
try {
|
|
60
72
|
const githubPullRequestLastCommitSha = await extractGithubPullRequestLastCommitSha();
|
|
73
|
+
if (isDebugMode())
|
|
74
|
+
logger.log(`[DEBUG] extractLatestCommitInfo: githubPullRequestLastCommitSha = ${githubPullRequestLastCommitSha !== null && githubPullRequestLastCommitSha !== void 0 ? githubPullRequestLastCommitSha : '(none)'}`);
|
|
61
75
|
result = await executeWithLog(`git log ${githubPullRequestLastCommitSha !== null && githubPullRequestLastCommitSha !== void 0 ? githubPullRequestLastCommitSha : ''} -1 --format="%aI %H"`, {
|
|
62
76
|
execOptions,
|
|
63
77
|
logger,
|
|
@@ -67,7 +81,11 @@ exports.extractLatestCommitInfo = utils.general.cachify(async function ({ execOp
|
|
|
67
81
|
}
|
|
68
82
|
else {
|
|
69
83
|
const [timestamp, sha] = result.stdout.trim().split(' ');
|
|
84
|
+
if (isDebugMode())
|
|
85
|
+
logger.log(`[DEBUG] extractLatestCommitInfo: parsed timestamp=${timestamp}, sha=${sha}`);
|
|
70
86
|
if (isISODate(timestamp)) {
|
|
87
|
+
if (isDebugMode())
|
|
88
|
+
logger.log(`[DEBUG] extractLatestCommitInfo: completed in ${Date.now() - fnStart}ms`);
|
|
71
89
|
return { sha, timestamp };
|
|
72
90
|
}
|
|
73
91
|
else {
|
|
@@ -78,6 +96,8 @@ exports.extractLatestCommitInfo = utils.general.cachify(async function ({ execOp
|
|
|
78
96
|
catch (err) {
|
|
79
97
|
logger.log(`Error during parsing commit hash from git`, err, result === null || result === void 0 ? void 0 : result.stdout);
|
|
80
98
|
}
|
|
99
|
+
if (isDebugMode())
|
|
100
|
+
logger.log(`[DEBUG] extractLatestCommitInfo: returning undefined after ${Date.now() - fnStart}ms`);
|
|
81
101
|
async function extractGithubPullRequestLastCommitSha() {
|
|
82
102
|
var _a, _b, _c;
|
|
83
103
|
if (((_a = process.env.GITHUB_EVENT_NAME) === null || _a === void 0 ? void 0 : _a.startsWith('pull_request')) && process.env.GITHUB_EVENT_PATH) {
|
|
@@ -89,12 +109,19 @@ exports.extractLatestCommitInfo = utils.general.cachify(async function ({ execOp
|
|
|
89
109
|
}
|
|
90
110
|
}, () => exports.cacheKey);
|
|
91
111
|
exports.extractGitBranch = utils.general.cachify(async function ({ execOptions, logger = (0, logger_1.makeLogger)() }) {
|
|
112
|
+
const fnStart = Date.now();
|
|
113
|
+
if (isDebugMode())
|
|
114
|
+
logger.log(`[DEBUG] extractGitBranch: started`);
|
|
92
115
|
// 1. Try CI environment variables first (fast, no subprocess, handles detached HEAD in CI)
|
|
93
116
|
const ciBranch = extractCIBranchName();
|
|
94
117
|
if (ciBranch) {
|
|
95
118
|
logger.log(`Extracted branch name from CI environment: "${ciBranch}"`);
|
|
119
|
+
if (isDebugMode())
|
|
120
|
+
logger.log(`[DEBUG] extractGitBranch: completed via CI env in ${Date.now() - fnStart}ms`);
|
|
96
121
|
return ciBranch;
|
|
97
122
|
}
|
|
123
|
+
if (isDebugMode())
|
|
124
|
+
logger.log(`[DEBUG] extractGitBranch: no CI branch env found, falling back to git command`);
|
|
98
125
|
// 2. Fall back to git command (works when on an actual branch locally)
|
|
99
126
|
const result = await executeWithLog('git branch --show-current', { execOptions, logger });
|
|
100
127
|
if (result.stderr) {
|
|
@@ -102,26 +129,42 @@ exports.extractGitBranch = utils.general.cachify(async function ({ execOptions,
|
|
|
102
129
|
}
|
|
103
130
|
else {
|
|
104
131
|
const branch = result.stdout.trim();
|
|
132
|
+
if (isDebugMode())
|
|
133
|
+
logger.log(`[DEBUG] extractGitBranch: git branch --show-current returned: "${branch}"`);
|
|
105
134
|
if (branch) {
|
|
106
135
|
logger.log(`Extracted current git branch: "${branch}"`);
|
|
136
|
+
if (isDebugMode())
|
|
137
|
+
logger.log(`[DEBUG] extractGitBranch: completed via git in ${Date.now() - fnStart}ms`);
|
|
107
138
|
return branch;
|
|
108
139
|
}
|
|
109
140
|
logger.log('git branch --show-current returned empty (detached HEAD), no branch name available');
|
|
110
141
|
}
|
|
142
|
+
if (isDebugMode())
|
|
143
|
+
logger.log(`[DEBUG] extractGitBranch: returning undefined after ${Date.now() - fnStart}ms`);
|
|
111
144
|
}, args => { var _a, _b, _c; return ({ cwd: (_b = (_a = args[0]) === null || _a === void 0 ? void 0 : _a.execOptions) === null || _b === void 0 ? void 0 : _b.cwd, ignoreGitBranching: (_c = args[0]) === null || _c === void 0 ? void 0 : _c.ignoreGitBranching }); });
|
|
112
145
|
exports.extractGitRepo = utils.general.cachify(async function ({ execOptions, logger = (0, logger_1.makeLogger)() }) {
|
|
146
|
+
const fnStart = Date.now();
|
|
147
|
+
if (isDebugMode())
|
|
148
|
+
logger.log(`[DEBUG] extractGitRepo: started`);
|
|
113
149
|
const remotes = await extractRemotes();
|
|
114
150
|
logger.log(`Extracted remotes from git: ${remotes}`);
|
|
115
151
|
const remote = remotes.includes('origin') ? 'origin' : remotes[0];
|
|
152
|
+
if (isDebugMode())
|
|
153
|
+
logger.log(`[DEBUG] extractGitRepo: selected remote: "${remote}"`);
|
|
116
154
|
const result = await executeWithLog(`git remote get-url ${remote}`, { execOptions, logger });
|
|
117
155
|
if (result.stderr) {
|
|
118
156
|
logger.log(`Error during extracting remote url from git`, result.stderr);
|
|
157
|
+
if (isDebugMode())
|
|
158
|
+
logger.log(`[DEBUG] extractGitRepo: returning {} after error in ${Date.now() - fnStart}ms`);
|
|
119
159
|
return {};
|
|
120
160
|
}
|
|
121
161
|
else {
|
|
122
162
|
const remoteUrl = result.stdout.trim();
|
|
123
163
|
logger.log(`Extracted url for git remote ${remote}: ${remoteUrl}`);
|
|
124
|
-
|
|
164
|
+
const parsed = extractRepoFromRemoteUrl(remoteUrl);
|
|
165
|
+
if (isDebugMode())
|
|
166
|
+
logger.log(`[DEBUG] extractGitRepo: parsed repo: owner="${parsed.owner}", name="${parsed.name}" in ${Date.now() - fnStart}ms`);
|
|
167
|
+
return parsed;
|
|
125
168
|
}
|
|
126
169
|
async function extractRemotes() {
|
|
127
170
|
const result = await executeWithLog('git remote show', { execOptions, logger });
|
|
@@ -162,7 +205,10 @@ async function extractBuildIdFromCI() {
|
|
|
162
205
|
exports.extractBuildIdFromCI = extractBuildIdFromCI;
|
|
163
206
|
exports.extractBranchingTimestamp = utils.general.cachify(async function ({ branchName, parentBranchName, execOptions, logger = (0, logger_1.makeLogger)(), }) {
|
|
164
207
|
var _a;
|
|
208
|
+
const fnStart = Date.now();
|
|
165
209
|
logger = logger.extend({ tags: [`extract-branching-timestamp-${utils.general.shortid()}`] });
|
|
210
|
+
if (isDebugMode())
|
|
211
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: started (branch=${branchName}, parent=${parentBranchName})`);
|
|
166
212
|
// Get the primary remote name (cached)
|
|
167
213
|
const remoteName = await (0, exports.getPrimaryRemoteName)({ execOptions, logger });
|
|
168
214
|
const shallowCheckResult = await executeWithLog('git rev-parse --is-shallow-repository', {
|
|
@@ -170,6 +216,8 @@ exports.extractBranchingTimestamp = utils.general.cachify(async function ({ bran
|
|
|
170
216
|
logger,
|
|
171
217
|
});
|
|
172
218
|
const isShallow = shallowCheckResult.stdout.trim() === 'true';
|
|
219
|
+
if (isDebugMode())
|
|
220
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: isShallow=${isShallow}`);
|
|
173
221
|
if (isShallow) {
|
|
174
222
|
logger.log('extractBranchingTimestamp - Repository is a shallow clone, attempting to unshallow');
|
|
175
223
|
await executeFetchStrategy(isShallow, execOptions, logger);
|
|
@@ -177,10 +225,14 @@ exports.extractBranchingTimestamp = utils.general.cachify(async function ({ bran
|
|
|
177
225
|
// Step 1: Try with remote refs first (fast path - uses already-fetched remote data)
|
|
178
226
|
const command = `HASH=$(git merge-base ${branchName} ${parentBranchName}) && git show -q --format=%aI $HASH`;
|
|
179
227
|
let result = await executeWithLog(command, { execOptions, logger });
|
|
228
|
+
if (isDebugMode())
|
|
229
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: step 1 (local refs) stderr=${!!result.stderr}`);
|
|
180
230
|
// Step 2: If remote refs failed, try local refs
|
|
181
231
|
if (result.stderr) {
|
|
182
232
|
const commandWithRemoteRefs = `HASH=$(git merge-base ${remoteName}/${branchName} ${remoteName}/${parentBranchName}) && git show -q --format=%aI $HASH`;
|
|
183
233
|
result = await executeWithLog(commandWithRemoteRefs, { execOptions, logger });
|
|
234
|
+
if (isDebugMode())
|
|
235
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: step 2 (remote refs) stderr=${!!result.stderr}`);
|
|
184
236
|
}
|
|
185
237
|
// Step 3: Handle missing branches with smart fetch (check remote existence first)
|
|
186
238
|
// Fetch remote branches list once if there's an error (cached call - virtually free)
|
|
@@ -217,10 +269,14 @@ exports.extractBranchingTimestamp = utils.general.cachify(async function ({ bran
|
|
|
217
269
|
const timestamp = result.stdout.replace(/\s/g, '');
|
|
218
270
|
if (isISODate(timestamp)) {
|
|
219
271
|
logger.log('git branching timestamp successfully extracted', timestamp);
|
|
272
|
+
if (isDebugMode())
|
|
273
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: completed in ${Date.now() - fnStart}ms`);
|
|
220
274
|
return timestamp;
|
|
221
275
|
}
|
|
222
276
|
else {
|
|
223
277
|
logger.log(`Error during extracting merge timestamp: git branching timestamp is an invalid ISO date string: ${timestamp}. stderr: ${result.stderr}, stdout: ${result.stdout}`);
|
|
278
|
+
if (isDebugMode())
|
|
279
|
+
logger.log(`[DEBUG] extractBranchingTimestamp: returning undefined after ${Date.now() - fnStart}ms`);
|
|
224
280
|
}
|
|
225
281
|
}, args => {
|
|
226
282
|
var _a;
|
|
@@ -234,8 +290,15 @@ async function executeWithLog(command, { execOptions, logger = (0, logger_1.make
|
|
|
234
290
|
execOptions: {},
|
|
235
291
|
logger: (0, logger_1.makeLogger)(),
|
|
236
292
|
}) {
|
|
293
|
+
var _a;
|
|
237
294
|
logger.log(`executing command: ${command}`);
|
|
295
|
+
const cmdStart = Date.now();
|
|
238
296
|
const result = await utils.process.execute(command, execOptions);
|
|
297
|
+
if (isDebugMode()) {
|
|
298
|
+
const duration = Date.now() - cmdStart;
|
|
299
|
+
const preview = ((_a = result.stdout) === null || _a === void 0 ? void 0 : _a.trim().slice(0, 300)) || '(empty)';
|
|
300
|
+
logger.log(`[DEBUG] command took ${duration}ms | code: ${result.code} | stdout: ${preview}`);
|
|
301
|
+
}
|
|
239
302
|
if (result.stderr && result.code) {
|
|
240
303
|
logger.log(`exit code: ${result.code}, stderr: ${result.stderr}`);
|
|
241
304
|
}
|
|
@@ -335,6 +398,9 @@ args => { var _a; return ({ cwd: (_a = args[0].execOptions) === null || _a === v
|
|
|
335
398
|
* Determine fetch strategy and execute appropriate fetch operation
|
|
336
399
|
*/
|
|
337
400
|
async function executeFetchStrategy(isShallow, execOptions, logger) {
|
|
401
|
+
const fnStart = Date.now();
|
|
402
|
+
if (isDebugMode())
|
|
403
|
+
logger.log(`[DEBUG] executeFetchStrategy: started (isShallow=${isShallow})`);
|
|
338
404
|
const remoteName = await (0, exports.getPrimaryRemoteName)({ execOptions, logger });
|
|
339
405
|
if (isShallow) {
|
|
340
406
|
// Shallow clone needs full unshallow for initial topology discovery
|
|
@@ -354,6 +420,8 @@ async function executeFetchStrategy(isShallow, execOptions, logger) {
|
|
|
354
420
|
});
|
|
355
421
|
logger.log(`All remote branches fetched successfully`);
|
|
356
422
|
}
|
|
423
|
+
if (isDebugMode())
|
|
424
|
+
logger.log(`[DEBUG] executeFetchStrategy: completed in ${Date.now() - fnStart}ms`);
|
|
357
425
|
}
|
|
358
426
|
/**
|
|
359
427
|
* Helper function to check if we're dealing with a remote branch scenario
|
|
@@ -366,6 +434,9 @@ async function executeFetchStrategy(isShallow, execOptions, logger) {
|
|
|
366
434
|
* @param logger - Logger instance
|
|
367
435
|
*/
|
|
368
436
|
async function ensureRemoteBranchesAvailable(branchName, isShallow, execOptions, logger) {
|
|
437
|
+
const fnStart = Date.now();
|
|
438
|
+
if (isDebugMode())
|
|
439
|
+
logger.log(`[DEBUG] ensureRemoteBranchesAvailable: started (branch=${branchName}, isShallow=${isShallow})`);
|
|
369
440
|
try {
|
|
370
441
|
// Get the primary remote name (cached)
|
|
371
442
|
const remoteName = await (0, exports.getPrimaryRemoteName)({ execOptions, logger });
|
|
@@ -374,8 +445,13 @@ async function ensureRemoteBranchesAvailable(branchName, isShallow, execOptions,
|
|
|
374
445
|
execOptions,
|
|
375
446
|
logger,
|
|
376
447
|
});
|
|
377
|
-
const
|
|
448
|
+
const upstream = symbolicResult.stdout.trim();
|
|
449
|
+
const isRemoteBranch = upstream.startsWith(`${remoteName}/`);
|
|
450
|
+
if (isDebugMode())
|
|
451
|
+
logger.log(`[DEBUG] ensureRemoteBranchesAvailable: upstream="${upstream}", isRemoteBranch=${isRemoteBranch}`);
|
|
378
452
|
if (!isRemoteBranch) {
|
|
453
|
+
if (isDebugMode())
|
|
454
|
+
logger.log(`[DEBUG] ensureRemoteBranchesAvailable: not a remote branch, skipping fetch in ${Date.now() - fnStart}ms`);
|
|
379
455
|
return;
|
|
380
456
|
}
|
|
381
457
|
logger.log(`Detected remote branch scenario, fetching ancestor branches...`);
|
|
@@ -387,6 +463,8 @@ async function ensureRemoteBranchesAvailable(branchName, isShallow, execOptions,
|
|
|
387
463
|
// Execute appropriate fetch strategy
|
|
388
464
|
await executeFetchStrategy(isShallow, execOptions, logger);
|
|
389
465
|
logger.log(`Remote branches fetched successfully for complete ancestor check`);
|
|
466
|
+
if (isDebugMode())
|
|
467
|
+
logger.log(`[DEBUG] ensureRemoteBranchesAvailable: completed in ${Date.now() - fnStart}ms`);
|
|
390
468
|
}
|
|
391
469
|
catch (err) {
|
|
392
470
|
logger.log('Note: Could not determine if branch is remote, continuing with topology discovery', err);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applitools/core",
|
|
3
|
-
"version": "4.59.
|
|
3
|
+
"version": "4.59.4-debug.0",
|
|
4
4
|
"homepage": "https://applitools.com",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/applitools/eyes.sdk.javascript1/issues"
|
|
@@ -60,19 +60,19 @@
|
|
|
60
60
|
"setup:standalone": "sh -c 'yarn chromedriver --port=4444 --verbose &'"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@applitools/core-base": "
|
|
64
|
-
"@applitools/dom-capture": "
|
|
65
|
-
"@applitools/dom-snapshot": "
|
|
66
|
-
"@applitools/driver": "
|
|
67
|
-
"@applitools/ec-client": "
|
|
68
|
-
"@applitools/logger": "
|
|
69
|
-
"@applitools/nml-client": "
|
|
70
|
-
"@applitools/req": "
|
|
71
|
-
"@applitools/screenshoter": "
|
|
72
|
-
"@applitools/snippets": "
|
|
73
|
-
"@applitools/socket": "
|
|
74
|
-
"@applitools/ufg-client": "
|
|
75
|
-
"@applitools/utils": "
|
|
63
|
+
"@applitools/core-base": "workspace:*",
|
|
64
|
+
"@applitools/dom-capture": "workspace:*",
|
|
65
|
+
"@applitools/dom-snapshot": "workspace:*",
|
|
66
|
+
"@applitools/driver": "workspace:*",
|
|
67
|
+
"@applitools/ec-client": "workspace:*",
|
|
68
|
+
"@applitools/logger": "workspace:*",
|
|
69
|
+
"@applitools/nml-client": "workspace:*",
|
|
70
|
+
"@applitools/req": "workspace:*",
|
|
71
|
+
"@applitools/screenshoter": "workspace:*",
|
|
72
|
+
"@applitools/snippets": "workspace:*",
|
|
73
|
+
"@applitools/socket": "workspace:*",
|
|
74
|
+
"@applitools/ufg-client": "workspace:*",
|
|
75
|
+
"@applitools/utils": "workspace:*",
|
|
76
76
|
"abort-controller": "3.0.0",
|
|
77
77
|
"chalk": "4.1.2",
|
|
78
78
|
"node-fetch": "2.6.7",
|
|
@@ -80,12 +80,12 @@
|
|
|
80
80
|
"throat": "6.0.2"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@applitools/bongo": "
|
|
84
|
-
"@applitools/spec-driver-puppeteer": "
|
|
85
|
-
"@applitools/spec-driver-selenium": "
|
|
86
|
-
"@applitools/test-server": "
|
|
87
|
-
"@applitools/test-utils": "
|
|
88
|
-
"@applitools/tunnel-client": "
|
|
83
|
+
"@applitools/bongo": "workspace:^",
|
|
84
|
+
"@applitools/spec-driver-puppeteer": "workspace:^",
|
|
85
|
+
"@applitools/spec-driver-selenium": "workspace:^",
|
|
86
|
+
"@applitools/test-server": "workspace:^",
|
|
87
|
+
"@applitools/test-utils": "workspace:^",
|
|
88
|
+
"@applitools/tunnel-client": "workspace:^",
|
|
89
89
|
"@types/mocha": "^10.0.7",
|
|
90
90
|
"@types/node": "^12.20.55",
|
|
91
91
|
"@types/selenium-webdriver": "^4.1.2",
|
|
@@ -114,4 +114,4 @@
|
|
|
114
114
|
"selenium-webdriver>ws>utf-8-validate": false
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
}
|
|
117
|
+
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { type SpecType, type ElementReference } from '@applitools/driver';
|
|
2
2
|
import type { Logger } from '@applitools/logger';
|
|
3
3
|
import { type Selector as UFGSelector } from '@applitools/ufg-client';
|
|
4
|
-
export declare function toGeneratedSelectors<TSpec extends SpecType>({ elementReferences, logger, }: {
|
|
4
|
+
export declare function toGeneratedSelectors<TSpec extends SpecType>({ elementReferences, logger, logDeprecations, }: {
|
|
5
5
|
elementReferences: {
|
|
6
6
|
target?: ElementReference<TSpec>;
|
|
7
7
|
scrolling?: ElementReference<TSpec>;
|
|
8
8
|
calculate?: ElementReference<TSpec>[];
|
|
9
9
|
};
|
|
10
10
|
logger: Logger;
|
|
11
|
+
logDeprecations: (...args: string[]) => void;
|
|
11
12
|
}): {
|
|
12
13
|
elementReferencesToMark: (string | TSpec["element"] | TSpec["secondary"]["element"] | TSpec["selector"] | TSpec["secondary"]["selector"] | {
|
|
13
14
|
selector: string | TSpec["selector"] | TSpec["secondary"]["selector"];
|