@intuned/runtime-dev 0.1.0-test.28 → 0.1.0-test.29

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.
@@ -1,189 +0,0 @@
1
- import * as playwright from "@intuned/playwright-core";
2
- import * as path from "path";
3
- import { getExecutionContext } from "@intuned/runtime";
4
- import { setTimeout } from "timers/promises";
5
- export class FunctionNotFoundError extends Error {
6
- constructor(functionName, path) {
7
- const message = `function ${functionName} not found in ${path}`;
8
- super(message);
9
- this.functionName = functionName;
10
- this.path = path;
11
- this.name = "FunctionNotFound";
12
- Object.setPrototypeOf(this, FunctionNotFoundError.prototype);
13
- }
14
- }
15
- export function getIsRetryableError(error) {
16
- if (error?.message) {
17
- return error.message.includes("ERR_NETWORK_CHANGED");
18
- }
19
- return false;
20
- }
21
- export function getErrorResponse(error) {
22
- if (error instanceof FunctionNotFoundError) {
23
- return {
24
- status: 404,
25
- body: {
26
- message: error.message,
27
- error: error.name,
28
- },
29
- };
30
- }
31
- if (error instanceof playwright.errors.TimeoutError) {
32
- return {
33
- status: 500,
34
- body: { message: error.message, error: error.name },
35
- };
36
- }
37
- /**
38
- * here we use error.constructor.name instead of error instanceof RunError
39
- * this is because the error is thrown by importing the runner from the api code on intuned app
40
- * the definition of class RunError which is imported from here is different than the class RunError
41
- * imported from the user.
42
- */
43
- if (error.constructor.name === "RunError") {
44
- return {
45
- status: 200,
46
- body: {
47
- status: error.options.status_code ?? 500,
48
- message: error.message,
49
- error: error.options.error_code ?? error.name,
50
- intunedOptions: error.options,
51
- },
52
- };
53
- }
54
- return {
55
- status: 500,
56
- body: { error: error?.name ?? error, message: error?.message },
57
- };
58
- }
59
- export function handlePlaywrightExecutionError(error, res) {
60
- const { status, body } = getErrorResponse(error);
61
- return res.status(status).json(body);
62
- }
63
- export function errorRetryMiddleware(handler) {
64
- return async (...args) => {
65
- let attempts = 1;
66
- const [req, res, next] = args;
67
- // eslint-disable-next-line no-constant-condition
68
- while (true) {
69
- try {
70
- await handler(req, res, next);
71
- break;
72
- }
73
- catch (error) {
74
- console.log(error?.name, error?.message);
75
- if (!getIsRetryableError(error) || attempts >= 3) {
76
- return handlePlaywrightExecutionError(error, res);
77
- }
78
- attempts++;
79
- }
80
- }
81
- };
82
- }
83
- export function getTraceFilePath(runId, attemptNumber) {
84
- const fileName = `${runId}${attemptNumber ? `_${attemptNumber}` : ""}`;
85
- return path.join(process.env.TRACES_DIRECTORY ?? "", `${fileName}.zip`);
86
- }
87
- export function proxyToUrl(proxy) {
88
- const url = new URL(proxy.server);
89
- url.username = proxy.username;
90
- url.password = proxy.password;
91
- return url.toString();
92
- }
93
- export function isJobRunMachine() {
94
- return process.env.JOB_ID && process.env.JOB_RUN_ID;
95
- }
96
- export function isHeadless() {
97
- return process.env.INTUNED_PLAYWRIGHT_HEADLESS !== "0";
98
- }
99
- export class AsyncRunEndpointController {
100
- static isRunning(taskToken) {
101
- return this.activeRequests.has(taskToken);
102
- }
103
- static addRequest(taskToken) {
104
- this.activeRequests.add(taskToken);
105
- }
106
- static removeRequest(taskToken) {
107
- this.activeRequests.delete(taskToken);
108
- }
109
- static get activeRequestsCount() {
110
- return this.activeRequests.size;
111
- }
112
- }
113
- AsyncRunEndpointController.activeRequests = new Set();
114
- export async function waitWithExtendableTimeout({ initialTimeout, promise, abortController, }) {
115
- const context = getExecutionContext();
116
- if (context.timeoutInfo) {
117
- context.timeoutInfo.timeoutTimestamp = Date.now() + initialTimeout;
118
- }
119
- const timerSymbol = Symbol("timer");
120
- if (!context) {
121
- const result = await Promise.race([
122
- promise,
123
- setTimeout(initialTimeout, timerSymbol),
124
- ]);
125
- if (result === timerSymbol) {
126
- abortController?.abort("Timed out");
127
- return { timedOut: true };
128
- }
129
- return { timedOut: false, result };
130
- }
131
- let taskTimeout = initialTimeout;
132
- while (true) {
133
- const result = await Promise.race([
134
- promise,
135
- setTimeout(taskTimeout, timerSymbol),
136
- ]);
137
- if (result !== timerSymbol) {
138
- break;
139
- }
140
- const remainingTime = (context.timeoutInfo?.timeoutTimestamp ?? 0) - Date.now();
141
- if (remainingTime < 0) {
142
- abortController?.abort("Timed out");
143
- return { timedOut: true };
144
- }
145
- taskTimeout = remainingTime;
146
- }
147
- return {
148
- timedOut: false,
149
- result: await promise,
150
- };
151
- }
152
- export async function importModule(path) {
153
- // cleanup environment variables before running the user code
154
- // cleanEnvironmentVariables();
155
- const [folderName, ...functionNameParts] = path.split("/");
156
- const functionNameDepth = functionNameParts.length;
157
- // string literals should be inline
158
- // currently we support only 5 levels of depth
159
- // rollup dynamic import does not support multiple levels of dynamic imports so we need to specify the possible paths explicitly
160
- try {
161
- let imported = undefined;
162
- switch (functionNameDepth) {
163
- case 1:
164
- imported = await import(`./${folderName}/${functionNameParts[0]}.ts`);
165
- break;
166
- case 2:
167
- imported = await import(`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}.ts`);
168
- break;
169
- case 3:
170
- imported = await import(`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}.ts`);
171
- break;
172
- case 4:
173
- imported = await import(`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}.ts`);
174
- break;
175
- case 5:
176
- imported = await import(`./${folderName}/${functionNameParts[0]}/${functionNameParts[1]}/${functionNameParts[2]}/${functionNameParts[3]}/${functionNameParts[4]}.ts`);
177
- break;
178
- default:
179
- throw new Error("intuned supports maximum 5 levels of depth in the api folder");
180
- }
181
- return imported;
182
- }
183
- catch (error) {
184
- if (error.message.includes("Unknown variable dynamic import")) {
185
- throw new FunctionNotFoundError("", path);
186
- }
187
- throw error;
188
- }
189
- }
package/api/authed.js DELETED
@@ -1,6 +0,0 @@
1
- export default async function authed(params, page, context) {
2
- await page.goto("https://setcookie.net");
3
- return {
4
- cookies: await page.locator("ul li code").allInnerTexts(),
5
- };
6
- }
package/api/test.js DELETED
@@ -1,3 +0,0 @@
1
- export default async function whatever() {
2
- console.log("whatever");
3
- }
package/api/test2.js DELETED
@@ -1,17 +0,0 @@
1
- import { extendTimeout, extendPayload } from "../src/runtime";
2
- export default async function test2({ n }, page, context) {
3
- await page.goto("https://wikipedia.org/");
4
- await page.waitForTimeout(1000);
5
- const titles = [];
6
- for (let i = 0; i < (n ?? 2); i++) {
7
- await page.goto(`https://wikipedia.org/wiki/Special:Random`);
8
- await page.waitForTimeout(1000);
9
- titles.push(await page.locator("h1").innerText());
10
- extendTimeout();
11
- }
12
- extendPayload({
13
- api: "test",
14
- parameters: {},
15
- });
16
- return { titles };
17
- }
@@ -1,6 +0,0 @@
1
- export default async function check(page, _context) {
2
- await page.goto("https://setcookie.net");
3
- const result = (await page.locator("ul li code").all()).length > 0;
4
- console.log("Check result", result);
5
- return result;
6
- }
@@ -1,20 +0,0 @@
1
- // eslint-disable-next-line require-yield
2
- export default async function* create(params, page, context) {
3
- await page.goto("https://setcookie.net/");
4
- await page.locator("#name").fill("intuned");
5
- await page.locator("#value").fill("password");
6
- await page.locator("input[type=submit]").click();
7
- // console.log("Received", yield requestOTP("Enter useless otp"));
8
- // console.log(
9
- // "Received",
10
- // yield requestMultipleChoice("Choose the correct answer", [
11
- // "A",
12
- // "B",
13
- // "C",
14
- // "D",
15
- // ])
16
- // );
17
- await page.goto("http://www.sharonminsuk.com/code/storage-test.html");
18
- await page.locator("#local").fill("intuned");
19
- await page.locator("#local + input[type=button]").click();
20
- }