@intuned/runtime-dev 1.0.0-udas.5 → 1.0.1-udas.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.
@@ -21,7 +21,6 @@ class JSONUnixSocket {
21
21
  let buffer = Buffer.alloc(0);
22
22
  const endPromise = new Promise((resolve, reject) => {
23
23
  this.socket.once("end", () => {
24
- console.log("end");
25
24
  resolve();
26
25
  });
27
26
  this.socket.once("error", reject);
@@ -179,6 +179,7 @@ function runAutomationCLI(importFunction) {
179
179
  }
180
180
  if (!client.closed) {
181
181
  client.end();
182
+ await Promise.race([new Promise(resolve => client.once("close", resolve)), new Promise(resolve => client.once("error", resolve)), (0, _promises.setTimeout)(5000)]);
182
183
  }
183
184
  process.exit(0);
184
185
  });
@@ -35,11 +35,8 @@ async function getContextStorageState(context) {
35
35
  };
36
36
  }
37
37
  async function setContextStorageState(context, storage) {
38
- console.log("Setting storage state");
39
38
  await context.intunedSetStorageState(storage);
40
- console.log("Storage state set");
41
39
  const sessionStorage = storage.sessionStorage;
42
- console.log("Adding init script session");
43
40
  await context.addInitScript(storage => {
44
41
  for (const {
45
42
  origin,
@@ -47,12 +44,11 @@ async function setContextStorageState(context, storage) {
47
44
  } of storage) {
48
45
  if (window.location.origin === origin) {
49
46
  for (const item of sessionStorage) {
50
- const existingItem = window.sessionStorage.getItem(item.name);
51
- if (existingItem !== null) continue;
47
+ const existingValue = window.sessionStorage.getItem(item.name);
48
+ if (existingValue !== null) continue;
52
49
  window.sessionStorage.setItem(item.name, item.value);
53
50
  }
54
51
  }
55
52
  }
56
53
  }, sessionStorage);
57
- console.log("Added init script session");
58
54
  }
@@ -45,16 +45,9 @@ async function getProductionPlaywrightConstructs({
45
45
  }
46
46
  const executablePath = playwright.chromium.executablePath();
47
47
  const chromium127Path = executablePath.replace("chromium-1117", "chromium-1124");
48
- console.log("Checking if chrome exists at", chromium127Path);
49
48
  const isChrome127There = await (0, _fsExtra.exists)(chromium127Path);
50
- console.log({
51
- isChrome127There
52
- });
53
49
  const userAgent = `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${isChrome127There ? 127 : 125}.0.0.0 Safari/537.36`;
54
- console.log("Creating user dir with preferences");
55
50
  const userDataDir = await createUserDirWithPreferences();
56
- console.log("User data dir created", userDataDir);
57
- console.log("Launching playwright context");
58
51
  const context = await playwright.chromium.launchPersistentContext(userDataDir, {
59
52
  headless,
60
53
  ignoreDefaultArgs: [...getChromiumLaunchArgsToIgnore(), "--headless"],
@@ -64,7 +57,6 @@ async function getProductionPlaywrightConstructs({
64
57
  downloadsPath,
65
58
  userAgent
66
59
  });
67
- console.log("Playwright context launched");
68
60
  context.once("close", async () => {
69
61
  try {
70
62
  await (0, _fsExtra.rm)(userDataDir, {
@@ -78,29 +70,20 @@ async function getProductionPlaywrightConstructs({
78
70
  }
79
71
  });
80
72
  if (storageState) {
81
- console.log("Loading session to context");
82
73
  await loadSessionToContext({
83
74
  context,
84
75
  session: storageState
85
76
  });
86
- console.log("Session loaded to context");
87
- } else {
88
- console.log("No session to load");
89
77
  }
90
- console.log("Adding init script");
91
78
  const assetsFile = _path.default.join(__dirname, "./assets/browser_scripts.js");
92
79
  await context.addInitScript({
93
80
  path: assetsFile
94
81
  });
95
- console.log("Init script added");
96
82
  let page = context.pages().at(0);
97
83
  if (page) {
98
- console.log("Adding script to page");
99
84
  const scriptString = await (0, _fsExtra.readFile)(assetsFile, "utf8");
100
85
  await page.evaluate(scriptString);
101
- console.log("Script added to page");
102
86
  } else {
103
- console.log("Creating new page");
104
87
  page = await context.newPage();
105
88
  }
106
89
  return {
@@ -9,4 +9,4 @@ export declare function runApiGenerator<ResultType = any, _YieldType = any, _Nex
9
9
  }): AsyncGenerator<_YieldType, RunApiResult<ResultType, RunApiResultWithSessionOk>, _NextType>;
10
10
  export declare function runApiGenerator<ResultType = any, _YieldType = any, _NextType = any>(params: ExtendedRunApiParameters): AsyncGenerator<_YieldType, RunApiResult<ResultType>, _NextType>;
11
11
  export declare function runApi<ResultType = any>(params: ExtendedRunApiParameters): Promise<RunApiResult<ResultType>>;
12
- export declare function checkAuthSessionWithRetries(page: Page, context: BrowserContext, importFunction: ExtendedRunApiParameters["importFunction"], retries?: number): Promise<Result<boolean, RunAutomationError>>;
12
+ export declare function checkAuthSessionWithRetries(page: Page, context: BrowserContext, checkFn: (..._: any) => Promise<boolean>, retries?: number): Promise<Result<boolean, RunAutomationError>>;
@@ -64,40 +64,15 @@ async function* runApiGenerator({
64
64
  tracing,
65
65
  auth
66
66
  } = inputParseResult.data;
67
- let page;
67
+ const abortSymbol = Symbol("abort");
68
+ const abortPromise = new Promise(resolve => {
69
+ if (!abortSignal) return;
70
+ abortSignal.addEventListener("abort", () => {
71
+ resolve(abortSymbol);
72
+ });
73
+ });
68
74
  let context;
69
75
  let downloadsPath;
70
- if (runOptions.environment === "standalone") {
71
- downloadsPath = (0, _downloadDirectory.getDownloadDirectoryPath)();
72
- const {
73
- headless,
74
- proxy
75
- } = runOptions;
76
- console.log("Running in standalone mode", {
77
- headless,
78
- proxy,
79
- downloadsPath
80
- });
81
- ({
82
- page,
83
- context
84
- } = await (0, _getPlaywrightConstructs.getProductionPlaywrightConstructs)({
85
- headless,
86
- proxy,
87
- downloadsPath,
88
- storageState: auth === null || auth === void 0 ? void 0 : auth.session
89
- }));
90
- console.log("Got page and context");
91
- } else {
92
- const {
93
- mode,
94
- cdpAddress
95
- } = runOptions;
96
- ({
97
- page,
98
- context
99
- } = await (0, _getPlaywrightConstructs.getPlaywrightConstructsForMode)(mode, cdpAddress, auth === null || auth === void 0 ? void 0 : auth.session));
100
- }
101
76
  async function saveTraceIfNeeded({
102
77
  errorMessage
103
78
  }) {
@@ -105,46 +80,80 @@ async function* runApiGenerator({
105
80
  return;
106
81
  }
107
82
  try {
108
- await context.tracing.stop({
83
+ var _context;
84
+ await ((_context = context) === null || _context === void 0 ? void 0 : _context.tracing.stop({
109
85
  path: tracing.filePath
110
- });
86
+ }));
111
87
  } catch (error) {
112
88
  console.log(errorMessage, error === null || error === void 0 ? void 0 : error.message);
113
89
  await (0, _fsExtra.remove)(tracing.filePath);
114
90
  }
115
91
  }
116
- if (tracing.enabled) {
117
- console.log("Starting trace");
118
- await context.tracing.start({
119
- screenshots: true,
120
- snapshots: true,
121
- sources: true
122
- });
123
- traceStarted = true;
124
- }
125
- const abortSymbol = Symbol("abort");
126
- const abortPromise = new Promise(resolve => {
127
- if (!abortSignal) return;
128
- abortSignal.addEventListener("abort", () => {
129
- resolve(abortSymbol);
130
- });
131
- });
132
- if (auth && auth.session.type === "state") {
133
- const state = auth.session.state;
134
- if (state === undefined || state === null) {
135
- return (0, _neverthrow.err)(new _errors.AuthRequiredError());
136
- }
137
- await (0, _contextStorageStateHelpers.setContextStorageState)(context, state);
138
- }
139
92
  async function* runAutomation() {
140
93
  var _getExecutionContext;
141
- (0, _cleanEnvironmentVariables.cleanEnvironmentVariables)();
94
+ let page;
95
+ const validatedModuleResult = await importUsingImportFunction(automationFunction.name, importFunction);
96
+ if (validatedModuleResult.isErr()) {
97
+ return (0, _neverthrow.err)(validatedModuleResult.error);
98
+ }
99
+ const importedModule = validatedModuleResult.value;
100
+ let checkFn;
142
101
  if (auth !== null && auth !== void 0 && auth.runCheck) {
143
102
  if (!auth.session) {
144
103
  return (0, _neverthrow.err)(new _errors.AuthRequiredError());
145
104
  }
105
+ const checkImportResult = await importUsingImportFunction(`${_constants.AUTH_SESSIONS_FOLDER_NAME}/check`, importFunction);
106
+ if (checkImportResult.isErr()) {
107
+ return (0, _neverthrow.err)(checkImportResult.error);
108
+ }
109
+ if (checkImportResult.value.type !== "async") {
110
+ return (0, _neverthrow.err)(new _errors.InvalidCheckError("Check function is not an async function"));
111
+ }
112
+ checkFn = checkImportResult.value.func;
113
+ }
114
+ if (auth && auth.session.type === "state") {
115
+ const state = auth.session.state;
116
+ if (state === undefined || state === null) {
117
+ return (0, _neverthrow.err)(new _errors.AuthRequiredError());
118
+ }
119
+ }
120
+ if (runOptions.environment === "standalone") {
121
+ downloadsPath = (0, _downloadDirectory.getDownloadDirectoryPath)();
122
+ const {
123
+ headless,
124
+ proxy
125
+ } = runOptions;
126
+ ({
127
+ page,
128
+ context
129
+ } = await (0, _getPlaywrightConstructs.getProductionPlaywrightConstructs)({
130
+ headless,
131
+ proxy,
132
+ downloadsPath,
133
+ storageState: auth === null || auth === void 0 ? void 0 : auth.session
134
+ }));
135
+ } else {
136
+ const {
137
+ mode,
138
+ cdpAddress
139
+ } = runOptions;
140
+ ({
141
+ page,
142
+ context
143
+ } = await (0, _getPlaywrightConstructs.getPlaywrightConstructsForMode)(mode, cdpAddress, auth === null || auth === void 0 ? void 0 : auth.session));
144
+ }
145
+ if (tracing.enabled) {
146
+ await context.tracing.start({
147
+ screenshots: true,
148
+ snapshots: true,
149
+ sources: true
150
+ });
151
+ traceStarted = true;
152
+ }
153
+ (0, _cleanEnvironmentVariables.cleanEnvironmentVariables)();
154
+ if (checkFn !== undefined) {
146
155
  console.log("Running auth check");
147
- const authCheckResult = await checkAuthSessionWithRetries(page, context, importFunction, 2);
156
+ const authCheckResult = await checkAuthSessionWithRetries(page, context, checkFn, 2);
148
157
  if (authCheckResult.isErr()) {
149
158
  const error = authCheckResult.error;
150
159
  if (["APINotFoundError", "InvalidAPIError"].includes(error.code)) {
@@ -157,14 +166,10 @@ async function* runApiGenerator({
157
166
  }
158
167
  }
159
168
  console.log("Running automation");
160
- const args = [...(automationFunction.params !== undefined ? [automationFunction.params] : []), page, context];
161
- const validatedModuleResult = await importUsingImportFunction(automationFunction.name, importFunction);
162
- if (validatedModuleResult.isErr()) {
163
- return validatedModuleResult;
164
- }
169
+ const automationFunctionParameters = [...(automationFunction.params !== undefined ? [automationFunction.params] : []), page, context];
165
170
  let result;
166
- if (validatedModuleResult.value.type === "async-generator") {
167
- const generator = validatedModuleResult.value.generator(...args);
171
+ if (importedModule.type === "async-generator") {
172
+ const generator = importedModule.generator(...automationFunctionParameters);
168
173
  let next = undefined;
169
174
  while (true) {
170
175
  const generatorResult = await generator.next(...(next ? [next] : []));
@@ -176,7 +181,7 @@ async function* runApiGenerator({
176
181
  break;
177
182
  }
178
183
  } else {
179
- result = await validatedModuleResult.value.func(...args);
184
+ result = await importedModule.func(...automationFunctionParameters);
180
185
  }
181
186
  return (0, _neverthrow.ok)({
182
187
  result,
@@ -201,10 +206,11 @@ async function* runApiGenerator({
201
206
  } catch (error) {
202
207
  return (0, _neverthrow.err)(new _errors.AutomationError(error));
203
208
  } finally {
209
+ var _context2;
204
210
  await saveTraceIfNeeded({
205
211
  errorMessage: "failed to save trace"
206
212
  });
207
- await context.close();
213
+ await ((_context2 = context) === null || _context2 === void 0 ? void 0 : _context2.close());
208
214
  if (downloadsPath !== undefined) {
209
215
  await fs.remove(downloadsPath);
210
216
  }
@@ -221,22 +227,14 @@ async function runApi(params) {
221
227
  }
222
228
  return (0, _neverthrow.err)(new _errors.InvalidApiError("Expected API to be async function, got async generator"));
223
229
  }
224
- async function checkAuthSessionWithRetries(page, context, importFunction, retries = 3) {
230
+ async function checkAuthSessionWithRetries(page, context, checkFn, retries = 3) {
225
231
  if (retries === 0) {
226
232
  return (0, _neverthrow.ok)(false);
227
233
  }
228
234
  let tryNumber = 0;
229
235
  console.log("Checking auth session with retries", `${_constants.AUTH_SESSIONS_FOLDER_NAME}/check`);
230
- const importResult = await importUsingImportFunction(`${_constants.AUTH_SESSIONS_FOLDER_NAME}/check`, importFunction);
231
- if (importResult.isErr()) {
232
- return (0, _neverthrow.err)(importResult.error);
233
- }
234
- if (importResult.value.type !== "async") {
235
- return (0, _neverthrow.err)(new _errors.InvalidCheckError("Check function is not an async function"));
236
- }
237
- const check = importResult.value.func;
238
236
  while (retries > tryNumber) {
239
- const result = await check(page, context);
237
+ const result = await checkFn(page, context);
240
238
  if (result) return (0, _neverthrow.ok)(true);
241
239
  tryNumber++;
242
240
  }
@@ -262,7 +260,6 @@ async function importUsingImportFunction(path, importFunction) {
262
260
  }
263
261
  return (0, _neverthrow.err)(new _errors.InvalidApiError("API file path does not have a default async function/generator export"));
264
262
  } catch (error) {
265
- console.error(error);
266
263
  return (0, _neverthrow.err)(new _errors.ApiNotFoundError(path));
267
264
  }
268
265
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intuned/runtime-dev",
3
- "version": "1.0.0-udas.5",
3
+ "version": "1.0.1-udas.0",
4
4
  "description": "Intuned runtime",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
package/Intuned.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "authSessions": {
3
- "enabled": false
4
- }
5
- }
package/api/authed.ts DELETED
@@ -1,12 +0,0 @@
1
- import { Page, BrowserContext } from "@intuned/playwright-core";
2
-
3
- export default async function authed(
4
- params: any,
5
- page: Page,
6
- context: BrowserContext
7
- ) {
8
- await page.goto("https://setcookie.net");
9
- return {
10
- cookies: await page.locator("ul li code").allInnerTexts(),
11
- };
12
- }
package/api/test.ts DELETED
@@ -1,3 +0,0 @@
1
- export default async function whatever() {
2
- console.log("whatever");
3
- }
package/api/test2.ts DELETED
@@ -1,27 +0,0 @@
1
- import { Page, BrowserContext } from "@intuned/playwright-core";
2
- import { extendTimeout, extendPayload } from "../src/runtime";
3
-
4
- export default async function test2(
5
- { n }: { n?: number },
6
- page: Page,
7
- context: BrowserContext
8
- ) {
9
- await page.goto("https://wikipedia.org/");
10
- await page.waitForTimeout(1000);
11
-
12
- const titles: string[] = [];
13
-
14
- for (let i = 0; i < (n ?? 2); i++) {
15
- await page.goto(`https://wikipedia.org/wiki/Special:Random`);
16
- await page.waitForTimeout(1000);
17
- titles.push(await page.locator("h1").innerText());
18
- extendTimeout();
19
- }
20
-
21
- extendPayload({
22
- api: "test",
23
- parameters: {},
24
- });
25
-
26
- return { titles };
27
- }
@@ -1,11 +0,0 @@
1
- import { Page, BrowserContext } from "@intuned/playwright-core";
2
-
3
- export default async function check(
4
- page: Page,
5
- _context: BrowserContext
6
- ): Promise<boolean> {
7
- await page.goto("https://setcookie.net");
8
- const result = (await page.locator("ul li code").all()).length > 0;
9
- console.log("Check result", result);
10
- return result;
11
- }
@@ -1,32 +0,0 @@
1
- import { Page, BrowserContext } from "@intuned/playwright-core";
2
- import {
3
- requestOTP,
4
- requestMultipleChoice,
5
- } from "../src/runtime/requestMoreInfo";
6
-
7
- // eslint-disable-next-line require-yield
8
- export default async function* create(
9
- params: any,
10
- page: Page,
11
- context: BrowserContext
12
- ) {
13
- await page.goto("https://setcookie.net/");
14
- await page.locator("#name").fill("intuned");
15
- await page.locator("#value").fill("password");
16
- await page.locator("input[type=submit]").click();
17
-
18
- // console.log("Received", yield requestOTP("Enter useless otp"));
19
- // console.log(
20
- // "Received",
21
- // yield requestMultipleChoice("Choose the correct answer", [
22
- // "A",
23
- // "B",
24
- // "C",
25
- // "D",
26
- // ])
27
- // );
28
-
29
- await page.goto("http://www.sharonminsuk.com/code/storage-test.html");
30
- await page.locator("#local").fill("intuned");
31
- await page.locator("#local + input[type=button]").click();
32
- }
package/authSessions DELETED
@@ -1 +0,0 @@
1
- {"cookies":[{"name":"intuned","value":"password","domain":"setcookie.net","path":"/","expires":-1,"httpOnly":true,"secure":false,"sameSite":"Lax"}],"origins":[{"origin":"http://www.sharonminsuk.com","localStorage":[{"name":"theirValue","value":"intuned"}]}],"sessionStorage":[{"origin":"http://www.sharonminsuk.com","sessionStorage":[]}]}