@flowriki/agent 0.1.0-beta.24 → 0.1.0-beta.26
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/{chunk-EBT7VSPY.js → chunk-IH7KFCV4.js} +70 -24
- package/dist/cli.js +1 -1
- package/dist/engine.js +1 -1
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ import os from "os";
|
|
|
6
6
|
import path from "path";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
8
|
import { spawnSync } from "child_process";
|
|
9
|
-
var AGENT_VERSION = "0.1.0-beta.
|
|
9
|
+
var AGENT_VERSION = "0.1.0-beta.26";
|
|
10
10
|
async function prepareBrowsers() {
|
|
11
11
|
if (browsersReady()) {
|
|
12
12
|
return { ok: true, already: true, message: "chromium is already installed" };
|
|
@@ -1053,7 +1053,25 @@ var FlowOccurrenceSchema = z22.object({
|
|
|
1053
1053
|
* against the source can line the two up; nothing depends on it to run. */
|
|
1054
1054
|
stepIds: z22.record(z22.string(), z22.string()).default({}),
|
|
1055
1055
|
copiedAt: z22.string()
|
|
1056
|
-
})
|
|
1056
|
+
}),
|
|
1057
|
+
/** WHICH OF THIS ROW'S STEPS ARE WHAT RUNS BEFORE ITS FLOW — the flow's
|
|
1058
|
+
* sign-in and the prerequisites copied in with it — so the row can be shown
|
|
1059
|
+
* folded, the way the Flows screen shows the same flow.
|
|
1060
|
+
*
|
|
1061
|
+
* A description of steps the row already holds, and nothing more: they are
|
|
1062
|
+
* ordinary copies in `steps` and run in order whatever this says. Kept by
|
|
1063
|
+
* id, so editing or deleting one of them leaves the rest still grouped.
|
|
1064
|
+
* Absent on every row copied before this existed, which simply show flat.
|
|
1065
|
+
* Never sent to a machine — see `withoutFolding`. */
|
|
1066
|
+
before: z22.object({
|
|
1067
|
+
/** The flow's own sign-in, when the copy brought one. */
|
|
1068
|
+
signInStepId: z22.string().optional(),
|
|
1069
|
+
flows: z22.array(z22.object({
|
|
1070
|
+
flowId: z22.string(),
|
|
1071
|
+
name: z22.string(),
|
|
1072
|
+
stepIds: z22.array(z22.string())
|
|
1073
|
+
}).strict()).default([])
|
|
1074
|
+
}).strict().optional()
|
|
1057
1075
|
}).strict();
|
|
1058
1076
|
var CASE_SCHEMA_VERSION = 1;
|
|
1059
1077
|
var TestCaseSchema = z22.object({
|
|
@@ -1575,7 +1593,7 @@ function expandForRun(flow, lookup) {
|
|
|
1575
1593
|
|
|
1576
1594
|
// ../engine-playwright/dist/index.js
|
|
1577
1595
|
import { createHmac, randomBytes } from "crypto";
|
|
1578
|
-
import { errors } from "playwright";
|
|
1596
|
+
import { errors as errors2 } from "playwright";
|
|
1579
1597
|
|
|
1580
1598
|
// ../core/dist/index.js
|
|
1581
1599
|
function proposeAssertions(before, after) {
|
|
@@ -1896,7 +1914,7 @@ var STEP_PRESENTATION = {
|
|
|
1896
1914
|
// ../engine-playwright/dist/index.js
|
|
1897
1915
|
import fs4 from "fs";
|
|
1898
1916
|
import path22 from "path";
|
|
1899
|
-
import { chromium, firefox, webkit } from "playwright";
|
|
1917
|
+
import { chromium, errors, firefox, webkit } from "playwright";
|
|
1900
1918
|
|
|
1901
1919
|
// ../recorder/dist/index.js
|
|
1902
1920
|
function openShadowRoots() {
|
|
@@ -3569,8 +3587,11 @@ var RunActors = class {
|
|
|
3569
3587
|
this.sessions.set(id, session);
|
|
3570
3588
|
await this.opts.onCreate?.(session);
|
|
3571
3589
|
}
|
|
3590
|
+
const switching = this.current !== session;
|
|
3572
3591
|
this.current = session;
|
|
3573
3592
|
this.currentId = id;
|
|
3593
|
+
if (switching && this.opts.headless === false) await session.page.bringToFront().catch(() => {
|
|
3594
|
+
});
|
|
3574
3595
|
if (this.initialized.has(id)) return;
|
|
3575
3596
|
if (startUrl) await session.page.goto(startUrl, { waitUntil: "domcontentloaded" });
|
|
3576
3597
|
if (actor?.startSignedIn) {
|
|
@@ -3923,38 +3944,63 @@ function resolveCapture(options = {}) {
|
|
|
3923
3944
|
};
|
|
3924
3945
|
}
|
|
3925
3946
|
var forcedHeadless = () => process.env["FLOWRIKI_FORCE_HEADLESS"] === "1";
|
|
3947
|
+
var LAUNCH_ATTEMPT_MS = () => Number(process.env["FLOWRIKI_LAUNCH_TIMEOUT_MS"] ?? 45e3);
|
|
3948
|
+
var isStartupFailure = (error) => error instanceof errors.TimeoutError || /Target page, context or browser has been closed|Browser has been closed|browser has disconnected/i.test(String(error?.message ?? error));
|
|
3949
|
+
async function launchWithRetry(launch, setUp, { attempts = 2, pauseMs = 1e3 } = {}) {
|
|
3950
|
+
let last;
|
|
3951
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
3952
|
+
let browser = null;
|
|
3953
|
+
try {
|
|
3954
|
+
browser = await launch(LAUNCH_ATTEMPT_MS());
|
|
3955
|
+
return { browser, value: await setUp(browser) };
|
|
3956
|
+
} catch (error) {
|
|
3957
|
+
last = error;
|
|
3958
|
+
await browser?.close().catch(() => {
|
|
3959
|
+
});
|
|
3960
|
+
if (!isStartupFailure(error)) throw error;
|
|
3961
|
+
if (attempt < attempts) await new Promise((r) => setTimeout(r, pauseMs));
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
const seconds = Math.round(LAUNCH_ATTEMPT_MS() / 1e3);
|
|
3965
|
+
const why = String(last?.message ?? last).split("\n")[0];
|
|
3966
|
+
throw new Error(
|
|
3967
|
+
`the browser did not start after ${attempts} attempts of ${seconds}s each (${why}) \u2014 on a Mac this is usually a visible browser that could not open a window; run it again, or run it headless`
|
|
3968
|
+
);
|
|
3969
|
+
}
|
|
3926
3970
|
async function launchSession(environment = {}, headlessRequested = true, slowMo = 0, capture = {}, existingBrowser, storageState) {
|
|
3927
3971
|
const headless = headlessRequested || forcedHeadless();
|
|
3928
3972
|
const config = { ...DEFAULT_ENVIRONMENT, ...ExecutionEnvironmentSchema.parse(environment) };
|
|
3929
3973
|
const fullWindow = config.fullWindow === true && !headless;
|
|
3930
3974
|
const engine = { chromium, firefox, webkit }[config.browser];
|
|
3931
|
-
const
|
|
3975
|
+
const launch = (timeout) => engine.launch({
|
|
3932
3976
|
headless,
|
|
3933
3977
|
slowMo,
|
|
3978
|
+
timeout,
|
|
3934
3979
|
// Chromium's flag. Firefox and WebKit have no equivalent, and `viewport:
|
|
3935
3980
|
// null` still gives them a page that fills their default window — bigger
|
|
3936
3981
|
// than the fixed box, if not maximised.
|
|
3937
3982
|
...fullWindow && config.browser === "chromium" ? { args: ["--start-maximized"] } : {}
|
|
3938
3983
|
});
|
|
3984
|
+
const { viewport, locale, timezoneId, colorScheme } = config;
|
|
3985
|
+
const artifacts = resolveCapture(capture);
|
|
3986
|
+
const makeContext = (browser2) => browser2.newContext({
|
|
3987
|
+
viewport: fullWindow ? null : viewport,
|
|
3988
|
+
locale,
|
|
3989
|
+
timezoneId,
|
|
3990
|
+
colorScheme,
|
|
3991
|
+
...storageState ? { storageState } : {},
|
|
3992
|
+
// Playwright can only be told to record at context creation, so a video
|
|
3993
|
+
// wanted "on failure" is recorded for every run and thrown away when the
|
|
3994
|
+
// run passes. There is no way to start one after the fact.
|
|
3995
|
+
//
|
|
3996
|
+
// The video still needs a fixed size even when the page has none —
|
|
3997
|
+
// `size` is what the file is encoded at, and Playwright scales the frame
|
|
3998
|
+
// to fit it. The configured viewport is the closest thing to an intended
|
|
3999
|
+
// aspect ratio we have.
|
|
4000
|
+
...artifacts.video !== "off" && capture.dir ? { recordVideo: { dir: capture.dir, size: viewport } } : {}
|
|
4001
|
+
});
|
|
4002
|
+
const { browser, value: context } = existingBrowser ? { browser: existingBrowser, value: await makeContext(existingBrowser) } : await launchWithRetry(launch, makeContext);
|
|
3939
4003
|
try {
|
|
3940
|
-
const { viewport, locale, timezoneId, colorScheme } = config;
|
|
3941
|
-
const artifacts = resolveCapture(capture);
|
|
3942
|
-
const context = await browser.newContext({
|
|
3943
|
-
viewport: fullWindow ? null : viewport,
|
|
3944
|
-
locale,
|
|
3945
|
-
timezoneId,
|
|
3946
|
-
colorScheme,
|
|
3947
|
-
...storageState ? { storageState } : {},
|
|
3948
|
-
// Playwright can only be told to record at context creation, so a video
|
|
3949
|
-
// wanted "on failure" is recorded for every run and thrown away when the
|
|
3950
|
-
// run passes. There is no way to start one after the fact.
|
|
3951
|
-
//
|
|
3952
|
-
// The video still needs a fixed size even when the page has none —
|
|
3953
|
-
// `size` is what the file is encoded at, and Playwright scales the frame
|
|
3954
|
-
// to fit it. The configured viewport is the closest thing to an intended
|
|
3955
|
-
// aspect ratio we have.
|
|
3956
|
-
...artifacts.video !== "off" && capture.dir ? { recordVideo: { dir: capture.dir, size: viewport } } : {}
|
|
3957
|
-
});
|
|
3958
4004
|
if (artifacts.trace !== "off" && capture.dir) {
|
|
3959
4005
|
await context.tracing.start({ screenshots: true, snapshots: true, sources: false });
|
|
3960
4006
|
}
|
|
@@ -4839,7 +4885,7 @@ async function runStepsIn(session, steps, opts) {
|
|
|
4839
4885
|
}
|
|
4840
4886
|
} catch (err) {
|
|
4841
4887
|
result.status = "failed";
|
|
4842
|
-
result.failureKind = err.kind ?? (/strict mode violation/.test(String(err)) ? "ambiguous" : err instanceof
|
|
4888
|
+
result.failureKind = err.kind ?? (/strict mode violation/.test(String(err)) ? "ambiguous" : err instanceof errors2.TimeoutError ? "timeout" : "unknown");
|
|
4843
4889
|
result.detail = firstLine2(err);
|
|
4844
4890
|
}
|
|
4845
4891
|
const wantsShot = artifacts.screenshot === "always" || artifacts.screenshot === "on-failure" && result.status === "failed";
|
package/dist/cli.js
CHANGED
package/dist/engine.js
CHANGED
package/package.json
CHANGED