@intuned/runtime-dev 1.2.1-hooks.4 → 1.2.1-hooks.5
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/commands/api/run.js +1 -2
- package/dist/commands/auth-sessions/load.js +3 -3
- package/dist/commands/auth-sessions/run-check.js +1 -2
- package/dist/commands/auth-sessions/run-create.js +12 -35
- package/dist/commands/interface/run.d.ts +1 -1
- package/dist/commands/interface/run.js +14 -40
- package/dist/commands/intuned-cli/controller/api.js +1 -2
- package/dist/commands/intuned-cli/controller/authSession.d.ts +6 -6
- package/dist/commands/intuned-cli/controller/authSession.js +3 -4
- package/dist/commands/intuned-cli/helpers/auth.d.ts +1 -1
- package/dist/commands/intuned-cli/helpers/errors.d.ts +2 -2
- package/dist/commands/intuned-cli/helpers/errors.js +8 -4
- package/dist/common/asyncLocalStorage/index.d.ts +1 -1
- package/dist/common/initializeContextHook.d.ts +16 -0
- package/dist/common/initializeContextHook.js +15 -0
- package/dist/common/playwrightContext.d.ts +49 -0
- package/dist/common/playwrightContext.js +240 -0
- package/dist/common/runApi/importUsingImportFunction.d.ts +9 -0
- package/dist/common/runApi/importUsingImportFunction.js +46 -0
- package/dist/common/runApi/index.d.ts +2 -7
- package/dist/common/runApi/index.js +86 -181
- package/dist/common/runApi/types.d.ts +20 -25
- package/dist/common/runApi/types.js +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js +7 -20
- package/dist/runtime/export.d.ts +49 -43
- package/dist/runtime/index.d.ts +1 -2
- package/dist/runtime/index.js +5 -11
- package/dist/runtime/store.d.ts +2 -0
- package/dist/runtime/store.js +23 -0
- package/package.json +1 -1
- package/.npmrc.wtf +0 -1
- package/dist/common/getPlaywrightConstructs.d.ts +0 -35
- package/dist/common/getPlaywrightConstructs.js +0 -266
- package/dist/runtime/requestMoreInfo.d.ts +0 -18
- package/dist/runtime/requestMoreInfo.js +0 -25
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.browserScriptsFile = void 0;
|
|
7
|
+
exports.getRemotePlaywrightContext = getRemotePlaywrightContext;
|
|
8
|
+
exports.launchChromium = launchChromium;
|
|
9
|
+
exports.loadSessionToContext = loadSessionToContext;
|
|
10
|
+
exports.withPlaywrightContext = withPlaywrightContext;
|
|
11
|
+
var playwright = _interopRequireWildcard(require("playwright"));
|
|
12
|
+
var _fsExtra = _interopRequireWildcard(require("fs-extra"));
|
|
13
|
+
var fs = _fsExtra;
|
|
14
|
+
var _contextStorageStateHelpers = require("./contextStorageStateHelpers");
|
|
15
|
+
var _path = _interopRequireWildcard(require("path"));
|
|
16
|
+
var _fileUtils = require("../commands/common/utils/fileUtils");
|
|
17
|
+
var _waitOn = _interopRequireDefault(require("wait-on"));
|
|
18
|
+
var _errors = require("./runApi/errors");
|
|
19
|
+
var _neverthrow = require("neverthrow");
|
|
20
|
+
var _initializeContextHook = require("./initializeContextHook");
|
|
21
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
23
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
24
|
+
async function createUserDirWithPreferences() {
|
|
25
|
+
const playwrightTempDir = await (0, _fsExtra.mkdtemp)("/tmp/pw-");
|
|
26
|
+
const userDir = (0, _path.join)(playwrightTempDir, "userdir");
|
|
27
|
+
const defaultDir = (0, _path.join)(userDir, "Default");
|
|
28
|
+
await (0, _fsExtra.mkdir)(defaultDir, {
|
|
29
|
+
recursive: true
|
|
30
|
+
});
|
|
31
|
+
const preferences = {
|
|
32
|
+
plugins: {
|
|
33
|
+
always_open_pdf_externally: true
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
await (0, _fsExtra.writeFile)((0, _path.join)(defaultDir, "Preferences"), JSON.stringify(preferences));
|
|
37
|
+
return userDir;
|
|
38
|
+
}
|
|
39
|
+
async function launchChromium({
|
|
40
|
+
proxy,
|
|
41
|
+
headless = true,
|
|
42
|
+
downloadsPath,
|
|
43
|
+
cdpAddress,
|
|
44
|
+
cdpPort
|
|
45
|
+
}) {
|
|
46
|
+
if (cdpAddress) {
|
|
47
|
+
const browser = await playwright.chromium.connectOverCDP(cdpAddress);
|
|
48
|
+
if (browser.contexts().length === 0) {
|
|
49
|
+
throw new Error("No browser contexts found in the connected browser");
|
|
50
|
+
}
|
|
51
|
+
const context = browser.contexts()[0];
|
|
52
|
+
let page = context.pages().at(0);
|
|
53
|
+
if (!page) {
|
|
54
|
+
page = await context.newPage();
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
page,
|
|
58
|
+
context
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const extraArgs = [];
|
|
62
|
+
const userDataDir = await createUserDirWithPreferences();
|
|
63
|
+
if (cdpPort) {
|
|
64
|
+
extraArgs.push(`--remote-debugging-port=${cdpPort}`);
|
|
65
|
+
}
|
|
66
|
+
const context = await playwright.chromium.launchPersistentContext(userDataDir, {
|
|
67
|
+
headless,
|
|
68
|
+
viewport: null,
|
|
69
|
+
proxy,
|
|
70
|
+
downloadsPath,
|
|
71
|
+
args: extraArgs
|
|
72
|
+
});
|
|
73
|
+
if (cdpPort) {
|
|
74
|
+
const createdCdpAddress = getCdpAddress(cdpPort);
|
|
75
|
+
await waitOnCdpAddress(createdCdpAddress);
|
|
76
|
+
}
|
|
77
|
+
context.once("close", async () => {
|
|
78
|
+
try {
|
|
79
|
+
await (0, _fsExtra.rm)(userDataDir, {
|
|
80
|
+
recursive: true,
|
|
81
|
+
force: true,
|
|
82
|
+
retryDelay: 1000,
|
|
83
|
+
maxRetries: 5
|
|
84
|
+
});
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error("Failed to remove user data dir", error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const page = context.pages().at(0) ?? (await context.newPage());
|
|
90
|
+
return {
|
|
91
|
+
page,
|
|
92
|
+
context
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const browserScriptsFile = exports.browserScriptsFile = _path.default.join(__dirname, "./assets/browser_scripts.js");
|
|
96
|
+
async function withPlaywrightContext({
|
|
97
|
+
cdpAddress,
|
|
98
|
+
proxy,
|
|
99
|
+
headless = true,
|
|
100
|
+
downloadsPath,
|
|
101
|
+
importFunction,
|
|
102
|
+
apiName,
|
|
103
|
+
apiParameters
|
|
104
|
+
}, fn) {
|
|
105
|
+
let context;
|
|
106
|
+
let page;
|
|
107
|
+
try {
|
|
108
|
+
const initializeContextHookResult = await (0, _initializeContextHook.loadInitializeContextHook)({
|
|
109
|
+
importFunction
|
|
110
|
+
});
|
|
111
|
+
if (initializeContextHookResult.isErr()) {
|
|
112
|
+
return initializeContextHookResult;
|
|
113
|
+
}
|
|
114
|
+
const initializeContextHook = initializeContextHookResult.value;
|
|
115
|
+
if (initializeContextHook === null) {
|
|
116
|
+
if (cdpAddress !== undefined) {
|
|
117
|
+
({
|
|
118
|
+
page,
|
|
119
|
+
context
|
|
120
|
+
} = await launchChromium({
|
|
121
|
+
cdpAddress
|
|
122
|
+
}));
|
|
123
|
+
} else {
|
|
124
|
+
({
|
|
125
|
+
page,
|
|
126
|
+
context
|
|
127
|
+
} = await launchChromium({
|
|
128
|
+
proxy,
|
|
129
|
+
headless,
|
|
130
|
+
downloadsPath
|
|
131
|
+
}));
|
|
132
|
+
}
|
|
133
|
+
return await fn(context, page);
|
|
134
|
+
}
|
|
135
|
+
let hookCdpUrl = null;
|
|
136
|
+
if (cdpAddress) {
|
|
137
|
+
hookCdpUrl = cdpAddress;
|
|
138
|
+
({
|
|
139
|
+
context,
|
|
140
|
+
page
|
|
141
|
+
} = await launchChromium({
|
|
142
|
+
cdpAddress
|
|
143
|
+
}));
|
|
144
|
+
} else {
|
|
145
|
+
const getPort = (await Promise.resolve().then(() => _interopRequireWildcard(require("get-port")))).default;
|
|
146
|
+
const port = await getPort({
|
|
147
|
+
port: 9222
|
|
148
|
+
});
|
|
149
|
+
hookCdpUrl = getCdpAddress(port);
|
|
150
|
+
({
|
|
151
|
+
context,
|
|
152
|
+
page
|
|
153
|
+
} = await launchChromium({
|
|
154
|
+
proxy,
|
|
155
|
+
headless,
|
|
156
|
+
downloadsPath,
|
|
157
|
+
cdpPort: port
|
|
158
|
+
}));
|
|
159
|
+
}
|
|
160
|
+
let hookResult;
|
|
161
|
+
try {
|
|
162
|
+
hookResult = await initializeContextHook({
|
|
163
|
+
apiName,
|
|
164
|
+
apiParameters,
|
|
165
|
+
cdpUrl: hookCdpUrl
|
|
166
|
+
});
|
|
167
|
+
} catch (error) {
|
|
168
|
+
return (0, _neverthrow.err)(new _errors.AutomationError(error));
|
|
169
|
+
}
|
|
170
|
+
if (!hookResult) {
|
|
171
|
+
return await fn(context, page);
|
|
172
|
+
}
|
|
173
|
+
const {
|
|
174
|
+
page: newPage,
|
|
175
|
+
context: newContext
|
|
176
|
+
} = hookResult;
|
|
177
|
+
try {
|
|
178
|
+
return await fn(newContext, newPage ?? page);
|
|
179
|
+
} finally {
|
|
180
|
+
await newContext.close();
|
|
181
|
+
}
|
|
182
|
+
} finally {
|
|
183
|
+
await context?.close();
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async function loadSessionToContext({
|
|
187
|
+
context,
|
|
188
|
+
session
|
|
189
|
+
}) {
|
|
190
|
+
let sessionToLoad;
|
|
191
|
+
if (session.type === "state") {
|
|
192
|
+
const state = session.state;
|
|
193
|
+
if (state === undefined || state === null) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
sessionToLoad = state;
|
|
197
|
+
} else {
|
|
198
|
+
const fullPath = (0, _fileUtils.getFullPathInProject)(session.path);
|
|
199
|
+
sessionToLoad = await fs.readJson(fullPath);
|
|
200
|
+
}
|
|
201
|
+
await (0, _contextStorageStateHelpers.setStorageState)(context, sessionToLoad);
|
|
202
|
+
}
|
|
203
|
+
function getCdpAddress(port) {
|
|
204
|
+
return `http://localhost:${port}`;
|
|
205
|
+
}
|
|
206
|
+
async function waitOnCdpAddress(cdpAddress) {
|
|
207
|
+
const cdpAddressWithoutProtocol = cdpAddress.replace("http://", "").replace("https://", "").replace("localhost", "127.0.0.1");
|
|
208
|
+
await (0, _waitOn.default)({
|
|
209
|
+
resources: [`http-get://${cdpAddressWithoutProtocol}/json/version`],
|
|
210
|
+
delay: 100,
|
|
211
|
+
interval: 100,
|
|
212
|
+
timeout: 5000,
|
|
213
|
+
tcpTimeout: 1000,
|
|
214
|
+
window: 1000
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
async function getRemotePlaywrightContext(cdpAddress) {
|
|
218
|
+
const playwright = await Promise.resolve().then(() => _interopRequireWildcard(require("playwright")));
|
|
219
|
+
let browser = null;
|
|
220
|
+
if (!cdpAddress) {
|
|
221
|
+
throw new Error("cdpAddress is required");
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
await waitOnCdpAddress(cdpAddress);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.error("Failed to connect to the browser");
|
|
227
|
+
process.exit(128 + 9);
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
browser = await playwright.chromium.connectOverCDP(cdpAddress);
|
|
231
|
+
} catch (e) {
|
|
232
|
+
console.log(e);
|
|
233
|
+
throw new Error("failed to connect to the browser");
|
|
234
|
+
}
|
|
235
|
+
const context = browser.contexts()[0];
|
|
236
|
+
return {
|
|
237
|
+
browser,
|
|
238
|
+
context
|
|
239
|
+
};
|
|
240
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Result } from "neverthrow";
|
|
2
|
+
import { RunAutomationError } from "./errors";
|
|
3
|
+
import { ExtendedRunApiParameters } from "./types";
|
|
4
|
+
export type ImportFunction = ExtendedRunApiParameters["importFunction"];
|
|
5
|
+
export declare function importUsingImportFunction<_ReturnType = any>({ path, allowGenerators, importFunction, }: {
|
|
6
|
+
path: string;
|
|
7
|
+
importFunction: ImportFunction;
|
|
8
|
+
allowGenerators?: boolean;
|
|
9
|
+
}): Promise<Result<(..._: any) => Promise<_ReturnType>, RunAutomationError>>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.importUsingImportFunction = importUsingImportFunction;
|
|
7
|
+
var _neverthrow = require("neverthrow");
|
|
8
|
+
var _errors = require("./errors");
|
|
9
|
+
async function importUsingImportFunction({
|
|
10
|
+
path,
|
|
11
|
+
allowGenerators = true,
|
|
12
|
+
importFunction
|
|
13
|
+
}) {
|
|
14
|
+
try {
|
|
15
|
+
const importedResult = await importFunction(path);
|
|
16
|
+
if (importedResult.isErr()) {
|
|
17
|
+
if (importedResult.error.type === "not_found") {
|
|
18
|
+
return (0, _neverthrow.err)(new _errors.ApiNotFoundError(path));
|
|
19
|
+
}
|
|
20
|
+
return (0, _neverthrow.err)(new _errors.AutomationError(importedResult.error.error));
|
|
21
|
+
}
|
|
22
|
+
const imported = importedResult.value;
|
|
23
|
+
if (!imported || !imported.default || !imported.default.constructor) {
|
|
24
|
+
return (0, _neverthrow.err)(new _errors.InvalidApiError(`${path} does not have a default export`));
|
|
25
|
+
}
|
|
26
|
+
if (imported.default.constructor.name === "AsyncGeneratorFunction") {
|
|
27
|
+
if (!allowGenerators) {
|
|
28
|
+
return (0, _neverthrow.err)(new _errors.InvalidApiError(`${path} default export must be an async function`));
|
|
29
|
+
}
|
|
30
|
+
return (0, _neverthrow.ok)(async (...args) => {
|
|
31
|
+
const generator = imported.default(...args);
|
|
32
|
+
const result = await generator.next();
|
|
33
|
+
if (!result.done) {
|
|
34
|
+
throw new Error("Yield is not supported");
|
|
35
|
+
}
|
|
36
|
+
return result.value;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (imported.default.constructor.name === "AsyncFunction") {
|
|
40
|
+
return (0, _neverthrow.ok)(imported.default);
|
|
41
|
+
}
|
|
42
|
+
return (0, _neverthrow.err)(new _errors.InvalidApiError(`${path} default export must be an async function`));
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return (0, _neverthrow.err)(new _errors.AutomationError(error));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -4,13 +4,8 @@ import { Page, BrowserContext } from "playwright";
|
|
|
4
4
|
import { ExtendedRunApiParameters, RunApiResult, RunApiResultWithSessionOk } from "./types";
|
|
5
5
|
export * from "./types";
|
|
6
6
|
export * from "./errors";
|
|
7
|
-
export declare function
|
|
8
|
-
retrieveSession: true;
|
|
9
|
-
}): AsyncGenerator<_YieldType, RunApiResult<ResultType, RunApiResultWithSessionOk>, _NextType>;
|
|
10
|
-
export declare function runApiGenerator<ResultType = any, _YieldType = any, _NextType = any>(params: ExtendedRunApiParameters): AsyncGenerator<_YieldType, RunApiResult<ResultType>, _NextType>;
|
|
11
|
-
export declare function runApi<ResultType = any>(params: ExtendedRunApiParameters & {
|
|
7
|
+
export declare function runApi<ResultType = any>(input: ExtendedRunApiParameters & {
|
|
12
8
|
retrieveSession: true;
|
|
13
9
|
}): Promise<RunApiResult<ResultType, RunApiResultWithSessionOk>>;
|
|
14
|
-
export declare function runApi<ResultType = any>(
|
|
10
|
+
export declare function runApi<ResultType = any>(input: ExtendedRunApiParameters): Promise<RunApiResult<ResultType>>;
|
|
15
11
|
export declare function checkAuthSessionWithRetries(page: Page, context: BrowserContext, checkFn: (..._: any) => Promise<boolean>, retries?: number): Promise<Result<boolean, RunAutomationError>>;
|
|
16
|
-
export type ImportFunction = ExtendedRunApiParameters["importFunction"];
|
|
@@ -4,13 +4,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
var _exportNames = {
|
|
7
|
-
runApiGenerator: true,
|
|
8
7
|
runApi: true,
|
|
9
8
|
checkAuthSessionWithRetries: true
|
|
10
9
|
};
|
|
11
10
|
exports.checkAuthSessionWithRetries = checkAuthSessionWithRetries;
|
|
12
11
|
exports.runApi = runApi;
|
|
13
|
-
exports.runApiGenerator = runApiGenerator;
|
|
14
12
|
var _downloadDirectory = require("../../runtime/downloadDirectory");
|
|
15
13
|
var _asyncLocalStorage = require("../asyncLocalStorage");
|
|
16
14
|
var _fsExtra = _interopRequireWildcard(require("fs-extra"));
|
|
@@ -30,7 +28,7 @@ Object.keys(_errors).forEach(function (key) {
|
|
|
30
28
|
});
|
|
31
29
|
});
|
|
32
30
|
var _constants = require("../constants");
|
|
33
|
-
var
|
|
31
|
+
var _playwrightContext = require("../playwrightContext");
|
|
34
32
|
var _types = require("./types");
|
|
35
33
|
Object.keys(_types).forEach(function (key) {
|
|
36
34
|
if (key === "default" || key === "__esModule") return;
|
|
@@ -45,12 +43,13 @@ Object.keys(_types).forEach(function (key) {
|
|
|
45
43
|
});
|
|
46
44
|
var _formatZodError = require("../formatZodError");
|
|
47
45
|
var _cleanEnvironmentVariables = require("../cleanEnvironmentVariables");
|
|
46
|
+
var _importUsingImportFunction = require("./importUsingImportFunction");
|
|
48
47
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
49
48
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
50
|
-
async function
|
|
51
|
-
retrieveSession = false,
|
|
49
|
+
async function runApi({
|
|
52
50
|
abortSignal,
|
|
53
51
|
importFunction,
|
|
52
|
+
retrieveSession = false,
|
|
54
53
|
...input
|
|
55
54
|
}) {
|
|
56
55
|
let traceStarted = false;
|
|
@@ -59,7 +58,10 @@ async function* runApiGenerator({
|
|
|
59
58
|
return (0, _neverthrow.err)(new _errors.InternalInvalidInputError("Input validation failed", (0, _formatZodError.formatZodError)(inputParseResult.error)));
|
|
60
59
|
}
|
|
61
60
|
const {
|
|
62
|
-
automationFunction
|
|
61
|
+
automationFunction: {
|
|
62
|
+
name,
|
|
63
|
+
params
|
|
64
|
+
},
|
|
63
65
|
runOptions,
|
|
64
66
|
tracing,
|
|
65
67
|
auth
|
|
@@ -71,170 +73,103 @@ async function* runApiGenerator({
|
|
|
71
73
|
resolve(abortSymbol);
|
|
72
74
|
});
|
|
73
75
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (!tracing.enabled || !traceStarted) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
await context?.tracing.stop({
|
|
84
|
-
path: tracing.filePath
|
|
85
|
-
});
|
|
86
|
-
} catch (error) {
|
|
87
|
-
console.log(errorMessage, error?.message);
|
|
88
|
-
await (0, _fsExtra.remove)(tracing.filePath);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
async function* runAutomation() {
|
|
92
|
-
let page;
|
|
93
|
-
const validatedModuleResult = await importUsingImportFunction(automationFunction.name, importFunction);
|
|
76
|
+
async function runAutomation() {
|
|
77
|
+
const validatedModuleResult = await (0, _importUsingImportFunction.importUsingImportFunction)({
|
|
78
|
+
path: name,
|
|
79
|
+
importFunction
|
|
80
|
+
});
|
|
94
81
|
if (validatedModuleResult.isErr()) {
|
|
95
82
|
return (0, _neverthrow.err)(validatedModuleResult.error);
|
|
96
83
|
}
|
|
97
|
-
const
|
|
98
|
-
let checkFn;
|
|
99
|
-
if (auth?.runCheck) {
|
|
100
|
-
if (!auth.session) {
|
|
101
|
-
return (0, _neverthrow.err)(new _errors.AuthRequiredError());
|
|
102
|
-
}
|
|
103
|
-
const checkImportResult = await importUsingImportFunction(`${_constants.AUTH_SESSIONS_FOLDER_NAME}/check`, importFunction);
|
|
104
|
-
if (checkImportResult.isErr()) {
|
|
105
|
-
return (0, _neverthrow.err)(checkImportResult.error);
|
|
106
|
-
}
|
|
107
|
-
if (checkImportResult.value.type !== "async") {
|
|
108
|
-
return (0, _neverthrow.err)(new _errors.InvalidCheckError("Check function is not an async function"));
|
|
109
|
-
}
|
|
110
|
-
checkFn = checkImportResult.value.func;
|
|
111
|
-
}
|
|
84
|
+
const automationFunction = validatedModuleResult.value;
|
|
112
85
|
if (auth && auth.session.type === "state") {
|
|
113
86
|
const state = auth.session.state;
|
|
114
87
|
if (state === undefined || state === null) {
|
|
115
88
|
return (0, _neverthrow.err)(new _errors.AuthRequiredError());
|
|
116
89
|
}
|
|
117
90
|
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
({
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
proxy,
|
|
130
|
-
downloadsPath,
|
|
131
|
-
storageState: auth?.session,
|
|
132
|
-
hookOptions: {
|
|
133
|
-
apiName: automationFunction.name,
|
|
134
|
-
parameters: automationFunction.params,
|
|
135
|
-
importFunction
|
|
91
|
+
const playwrightContextParameters = {
|
|
92
|
+
apiName: name,
|
|
93
|
+
apiParameters: params,
|
|
94
|
+
importFunction
|
|
95
|
+
};
|
|
96
|
+
const runAutomationWithContext = async (context, page) => {
|
|
97
|
+
async function saveTraceIfNeeded({
|
|
98
|
+
errorMessage
|
|
99
|
+
}) {
|
|
100
|
+
if (!tracing.enabled || !traceStarted) {
|
|
101
|
+
return;
|
|
136
102
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
await context.
|
|
154
|
-
|
|
155
|
-
snapshots: true,
|
|
156
|
-
sources: true
|
|
103
|
+
try {
|
|
104
|
+
await context?.tracing.stop({
|
|
105
|
+
path: tracing.filePath
|
|
106
|
+
});
|
|
107
|
+
} catch (error) {
|
|
108
|
+
console.log(errorMessage, error?.message);
|
|
109
|
+
await (0, _fsExtra.remove)(tracing.filePath);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (auth) {
|
|
113
|
+
await (0, _playwrightContext.loadSessionToContext)({
|
|
114
|
+
context,
|
|
115
|
+
session: auth.session
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
const scriptContent = await fs.readFile(_playwrightContext.browserScriptsFile, "utf-8");
|
|
119
|
+
await context.addInitScript({
|
|
120
|
+
content: scriptContent
|
|
157
121
|
});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
122
|
+
for (const page of context.pages()) {
|
|
123
|
+
await page.evaluate(scriptContent);
|
|
124
|
+
}
|
|
125
|
+
if (tracing.enabled) {
|
|
126
|
+
await context.tracing.start({
|
|
127
|
+
screenshots: true,
|
|
128
|
+
snapshots: true,
|
|
129
|
+
sources: true
|
|
130
|
+
});
|
|
131
|
+
traceStarted = true;
|
|
132
|
+
}
|
|
133
|
+
(0, _cleanEnvironmentVariables.cleanEnvironmentVariables)();
|
|
134
|
+
const automationFunctionParameters = [...(params !== undefined ? [params] : []), page, context];
|
|
162
135
|
try {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
return (0, _neverthrow.err)(new _errors.InvalidCheckError(`Auth session check function failed`, error));
|
|
169
|
-
}
|
|
170
|
-
return authCheckResult;
|
|
171
|
-
}
|
|
172
|
-
if (!authCheckResult.value) {
|
|
173
|
-
return (0, _neverthrow.err)(new _errors.AuthCheckFailedError());
|
|
174
|
-
}
|
|
136
|
+
return (0, _neverthrow.ok)({
|
|
137
|
+
result: await automationFunction(...automationFunctionParameters),
|
|
138
|
+
extendedPayloads: (0, _asyncLocalStorage.getExecutionContext)()?.extendedPayloads,
|
|
139
|
+
session: retrieveSession ? await (0, _contextStorageStateHelpers.getStorageState)(context) : undefined
|
|
140
|
+
});
|
|
175
141
|
} catch (error) {
|
|
176
|
-
return (0, _neverthrow.err)(new _errors.
|
|
142
|
+
return (0, _neverthrow.err)(new _errors.AutomationError(error));
|
|
143
|
+
} finally {
|
|
144
|
+
await saveTraceIfNeeded({
|
|
145
|
+
errorMessage: "failed to save trace"
|
|
146
|
+
});
|
|
177
147
|
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
result = generatorResult.value;
|
|
191
|
-
break;
|
|
148
|
+
};
|
|
149
|
+
if (runOptions.environment === "standalone") {
|
|
150
|
+
const downloadsPath = (0, _downloadDirectory.getDownloadDirectoryPath)();
|
|
151
|
+
try {
|
|
152
|
+
return await (0, _playwrightContext.withPlaywrightContext)({
|
|
153
|
+
headless: runOptions.headless,
|
|
154
|
+
proxy: runOptions.proxy,
|
|
155
|
+
downloadsPath,
|
|
156
|
+
...playwrightContextParameters
|
|
157
|
+
}, runAutomationWithContext);
|
|
158
|
+
} finally {
|
|
159
|
+
await fs.remove(downloadsPath);
|
|
192
160
|
}
|
|
193
161
|
} else {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
extendedPayloads: (0, _asyncLocalStorage.getExecutionContext)()?.extendedPayloads,
|
|
199
|
-
session: retrieveSession ? await (0, _contextStorageStateHelpers.getStorageState)(context) : undefined
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
try {
|
|
203
|
-
const generator = runAutomation();
|
|
204
|
-
let next = undefined;
|
|
205
|
-
while (true) {
|
|
206
|
-
const result = await Promise.race([generator.next(await next), abortPromise]);
|
|
207
|
-
if (result === abortSymbol) {
|
|
208
|
-
return (0, _neverthrow.err)(new _errors.AbortedError());
|
|
209
|
-
}
|
|
210
|
-
if (!result.done) {
|
|
211
|
-
next = yield result.value;
|
|
212
|
-
continue;
|
|
213
|
-
}
|
|
214
|
-
return result.value;
|
|
215
|
-
}
|
|
216
|
-
} catch (error) {
|
|
217
|
-
return (0, _neverthrow.err)(new _errors.AutomationError(error));
|
|
218
|
-
} finally {
|
|
219
|
-
await saveTraceIfNeeded({
|
|
220
|
-
errorMessage: "failed to save trace"
|
|
221
|
-
});
|
|
222
|
-
await context?.close();
|
|
223
|
-
if (downloadsPath !== undefined) {
|
|
224
|
-
await fs.remove(downloadsPath);
|
|
162
|
+
return await (0, _playwrightContext.withPlaywrightContext)({
|
|
163
|
+
cdpAddress: runOptions.cdpAddress,
|
|
164
|
+
...playwrightContextParameters
|
|
165
|
+
}, runAutomationWithContext);
|
|
225
166
|
}
|
|
226
167
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const {
|
|
231
|
-
value,
|
|
232
|
-
done
|
|
233
|
-
} = await generator.next();
|
|
234
|
-
if (done) {
|
|
235
|
-
return value;
|
|
168
|
+
const result = await Promise.race([await runAutomation(), abortPromise]);
|
|
169
|
+
if (result === abortSymbol) {
|
|
170
|
+
return (0, _neverthrow.err)(new _errors.AbortedError());
|
|
236
171
|
}
|
|
237
|
-
return
|
|
172
|
+
return result;
|
|
238
173
|
}
|
|
239
174
|
async function checkAuthSessionWithRetries(page, context, checkFn, retries = 3) {
|
|
240
175
|
if (retries === 0) {
|
|
@@ -248,34 +183,4 @@ async function checkAuthSessionWithRetries(page, context, checkFn, retries = 3)
|
|
|
248
183
|
tryNumber++;
|
|
249
184
|
}
|
|
250
185
|
return (0, _neverthrow.ok)(false);
|
|
251
|
-
}
|
|
252
|
-
async function importUsingImportFunction(path, importFunction) {
|
|
253
|
-
try {
|
|
254
|
-
const importedResult = await importFunction(path);
|
|
255
|
-
if (importedResult.isErr()) {
|
|
256
|
-
if (importedResult.error.type === "not_found") {
|
|
257
|
-
return (0, _neverthrow.err)(new _errors.ApiNotFoundError(path));
|
|
258
|
-
}
|
|
259
|
-
return (0, _neverthrow.err)(new _errors.AutomationError(importedResult.error.error));
|
|
260
|
-
}
|
|
261
|
-
const imported = importedResult.value;
|
|
262
|
-
if (!imported || !imported.default || !imported.default.constructor) {
|
|
263
|
-
return (0, _neverthrow.err)(new _errors.InvalidApiError("API file path does not have a default export"));
|
|
264
|
-
}
|
|
265
|
-
if (imported.default.constructor.name === "AsyncGeneratorFunction") {
|
|
266
|
-
return (0, _neverthrow.ok)({
|
|
267
|
-
type: "async-generator",
|
|
268
|
-
generator: imported.default
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
if (imported.default.constructor.name === "AsyncFunction") {
|
|
272
|
-
return (0, _neverthrow.ok)({
|
|
273
|
-
type: "async",
|
|
274
|
-
func: imported.default
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
return (0, _neverthrow.err)(new _errors.InvalidApiError("API file path does not have a default async function/generator export"));
|
|
278
|
-
} catch (error) {
|
|
279
|
-
return (0, _neverthrow.err)(new _errors.AutomationError(error));
|
|
280
|
-
}
|
|
281
186
|
}
|