@flowriki/agent 0.1.0-beta.48 → 0.1.0-beta.49
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.
|
@@ -649,6 +649,7 @@ import { z as z6 } from "zod";
|
|
|
649
649
|
import { z as z7 } from "zod";
|
|
650
650
|
import { z as z8 } from "zod";
|
|
651
651
|
import { z as z9 } from "zod";
|
|
652
|
+
import { z as z10 } from "zod";
|
|
652
653
|
var EngineSchema = z3.enum(["chromium", "firefox", "webkit", "android", "ios"]);
|
|
653
654
|
var CapabilitySchema = z3.object({
|
|
654
655
|
id: z3.string(),
|
|
@@ -1742,6 +1743,29 @@ var CaseUpdateRequestSchema = z9.object({
|
|
|
1742
1743
|
createdAt: z9.string(),
|
|
1743
1744
|
updatedAt: z9.string()
|
|
1744
1745
|
}).strict();
|
|
1746
|
+
var RUN_PLACES = ["local", "cloud"];
|
|
1747
|
+
var RunWhereSchema = z10.object({
|
|
1748
|
+
web: z10.enum(RUN_PLACES).default("local"),
|
|
1749
|
+
android: z10.enum(RUN_PLACES).default("local"),
|
|
1750
|
+
ios: z10.enum(RUN_PLACES).default("local")
|
|
1751
|
+
}).strict();
|
|
1752
|
+
var runWhereOf = (config) => {
|
|
1753
|
+
const parsed = RunWhereSchema.safeParse(config?.runWhere ?? {});
|
|
1754
|
+
return parsed.success ? parsed.data : RunWhereSchema.parse({});
|
|
1755
|
+
};
|
|
1756
|
+
var WEB_CLOUD_PROVIDERS = ["browserstack", "lambdatest"];
|
|
1757
|
+
var WEB_CLOUD_BROWSERS = ["chrome", "edge", "firefox", "webkit"];
|
|
1758
|
+
var WEB_CLOUD_BROWSER_NAME = { chrome: "Chrome", edge: "Edge", firefox: "Firefox", webkit: "Safari (WebKit)" };
|
|
1759
|
+
var WEB_CLOUD_SYSTEMS = ["Windows 11", "Windows 10", "macOS Sonoma", "macOS Ventura"];
|
|
1760
|
+
var WebCloudSchema = z10.object({
|
|
1761
|
+
provider: z10.enum(WEB_CLOUD_PROVIDERS),
|
|
1762
|
+
browser: z10.enum(WEB_CLOUD_BROWSERS).default("chrome"),
|
|
1763
|
+
system: z10.enum(WEB_CLOUD_SYSTEMS).default("Windows 11")
|
|
1764
|
+
}).strict();
|
|
1765
|
+
var webCloudOf = (config) => {
|
|
1766
|
+
const parsed = WebCloudSchema.safeParse(config?.webCloud);
|
|
1767
|
+
return parsed.success ? parsed.data : null;
|
|
1768
|
+
};
|
|
1745
1769
|
|
|
1746
1770
|
// ../engine-appium/dist/index.js
|
|
1747
1771
|
import path5 from "path";
|
|
@@ -3723,8 +3747,14 @@ async function finishVideo(session, policy, evidenceDir, passed, name = "phone")
|
|
|
3723
3747
|
const saved = await session.stopVideo(keep ? path6.join(evidenceDir, `video-${name}.mp4`) : null).catch(() => null);
|
|
3724
3748
|
return saved ? [{ kind: "video", relPath: saved.relPath, bytes: saved.bytes }] : [];
|
|
3725
3749
|
}
|
|
3726
|
-
async function chooseDevice(platform, mobile, asked) {
|
|
3727
|
-
const
|
|
3750
|
+
async function chooseDevice(platform, mobile, asked, where) {
|
|
3751
|
+
const name = platform === "ios" ? "iOS" : "Android";
|
|
3752
|
+
if (where === "cloud") {
|
|
3753
|
+
const cloud = [asked, mobile.devices[platform]].find((d) => d?.kind === "cloud");
|
|
3754
|
+
if (cloud) return cloud;
|
|
3755
|
+
throw new Error(mobile.cloud.length ? `${name} tests run in the cloud, but no cloud phone is chosen \u2014 pick one in Settings \u2192 Platforms.` : `${name} tests run in the cloud, but no cloud device farm is connected \u2014 connect one in Settings \u2192 Platforms.`);
|
|
3756
|
+
}
|
|
3757
|
+
const chosen = where === "local" ? [asked, mobile.devices[platform]].find((d) => d?.kind === "local") : asked ?? mobile.devices[platform];
|
|
3728
3758
|
if (chosen) return chosen;
|
|
3729
3759
|
const devices = await listDevices();
|
|
3730
3760
|
const picked = pickDevice(devices, platform);
|
|
@@ -3734,7 +3764,7 @@ async function chooseDevice(platform, mobile, asked) {
|
|
|
3734
3764
|
throw new Error(platform === "ios" ? "No iPhone or simulator is available \u2014 install Xcode for simulators, or plug in an iPhone." : "No Android phone or emulator is available \u2014 start an emulator in Android Studio, or plug in a phone with USB debugging on.");
|
|
3735
3765
|
}
|
|
3736
3766
|
async function openMobileSession(opts) {
|
|
3737
|
-
const device = await chooseDevice(opts.platform, opts.mobile, opts.device);
|
|
3767
|
+
const device = await chooseDevice(opts.platform, opts.mobile, opts.device, opts.where);
|
|
3738
3768
|
return MobileSession.open(
|
|
3739
3769
|
{ platform: opts.platform, device, mobile: opts.mobile, ...opts.fresh ? { fresh: true } : {} },
|
|
3740
3770
|
{ ...opts.resolveSecret ? { resolveSecret: opts.resolveSecret } : {}, ...opts.onProgress ? { onProgress: opts.onProgress } : {} }
|
|
@@ -3893,6 +3923,7 @@ var MobileLane = class {
|
|
|
3893
3923
|
session = await openMobileSession({
|
|
3894
3924
|
platform,
|
|
3895
3925
|
mobile: this.opts.mobile,
|
|
3926
|
+
...this.opts.runWhere?.[platform] ? { where: this.opts.runWhere[platform] } : {},
|
|
3896
3927
|
...this.opts.devices?.[platform] ? { device: this.opts.devices[platform] } : {},
|
|
3897
3928
|
...this.opts.resolveSecret ? { resolveSecret: this.opts.resolveSecret } : {}
|
|
3898
3929
|
});
|
|
@@ -4040,6 +4071,9 @@ export {
|
|
|
4040
4071
|
PrerequisiteProblem,
|
|
4041
4072
|
expandForRun,
|
|
4042
4073
|
DeliveredHelperSchema,
|
|
4074
|
+
runWhereOf,
|
|
4075
|
+
WEB_CLOUD_BROWSER_NAME,
|
|
4076
|
+
webCloudOf,
|
|
4043
4077
|
proposeAssertions,
|
|
4044
4078
|
hasObservableChange,
|
|
4045
4079
|
normalizeStartUrl,
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
ArtifactPolicySchema,
|
|
4
4
|
AuthReferenceSchema,
|
|
5
5
|
CHECKS,
|
|
6
|
+
CLOUD_PROVIDER_NAME,
|
|
6
7
|
CURRENT_SCHEMA_VERSION,
|
|
7
8
|
CapabilitySchema,
|
|
8
9
|
DeliveredAuthSchema,
|
|
@@ -19,6 +20,7 @@ import {
|
|
|
19
20
|
SCOPE_ROLES,
|
|
20
21
|
STEP_PRESENTATION,
|
|
21
22
|
TestCaseSchema,
|
|
23
|
+
WEB_CLOUD_BROWSER_NAME,
|
|
22
24
|
actorIdsUsed,
|
|
23
25
|
actorPreparations,
|
|
24
26
|
adjacentLabelPattern,
|
|
@@ -52,6 +54,7 @@ import {
|
|
|
52
54
|
resolveStartUrl,
|
|
53
55
|
restoreDebugCase,
|
|
54
56
|
runMobileSteps,
|
|
57
|
+
runWhereOf,
|
|
55
58
|
sameIdentity,
|
|
56
59
|
screenLines,
|
|
57
60
|
sessionLanes,
|
|
@@ -60,8 +63,9 @@ import {
|
|
|
60
63
|
stepRefusedOn,
|
|
61
64
|
targetFor,
|
|
62
65
|
textIndependent,
|
|
63
|
-
validateActors
|
|
64
|
-
|
|
66
|
+
validateActors,
|
|
67
|
+
webCloudOf
|
|
68
|
+
} from "./chunk-4VJVDGF5.js";
|
|
65
69
|
|
|
66
70
|
// src/engine/machine.ts
|
|
67
71
|
import fs from "fs";
|
|
@@ -69,7 +73,7 @@ import os from "os";
|
|
|
69
73
|
import path from "path";
|
|
70
74
|
import { createRequire } from "module";
|
|
71
75
|
import { spawnSync } from "child_process";
|
|
72
|
-
var AGENT_VERSION = "0.1.0-beta.
|
|
76
|
+
var AGENT_VERSION = "0.1.0-beta.49";
|
|
73
77
|
async function prepareBrowsers() {
|
|
74
78
|
if (browsersReady()) {
|
|
75
79
|
return { ok: true, already: true, message: "chromium is already installed" };
|
|
@@ -129,7 +133,7 @@ async function checkMachine() {
|
|
|
129
133
|
}
|
|
130
134
|
} catch {
|
|
131
135
|
}
|
|
132
|
-
const { mobileDoctor: mobileDoctor2 } = await import("./dist-
|
|
136
|
+
const { mobileDoctor: mobileDoctor2 } = await import("./dist-Y36FF3R3.js");
|
|
133
137
|
return {
|
|
134
138
|
agentVersion: AGENT_VERSION,
|
|
135
139
|
node: process.versions.node,
|
|
@@ -2078,6 +2082,8 @@ import "playwright";
|
|
|
2078
2082
|
import fs32 from "fs";
|
|
2079
2083
|
import "playwright";
|
|
2080
2084
|
import fs42 from "fs";
|
|
2085
|
+
import { createRequire as createRequire22 } from "module";
|
|
2086
|
+
import { chromium as chromium2, firefox as firefox2, webkit as webkit2 } from "playwright";
|
|
2081
2087
|
function makeUnique(now = Date.now()) {
|
|
2082
2088
|
return `${now.toString(36)}${randomBytes(3).toString("hex")}`;
|
|
2083
2089
|
}
|
|
@@ -3677,6 +3683,7 @@ async function replayFlow(opts) {
|
|
|
3677
3683
|
opts.actors?.find((a) => a.id === (opts.defaultActorId ?? "default"))?.startSignedIn
|
|
3678
3684
|
);
|
|
3679
3685
|
const session = await openRunSession({
|
|
3686
|
+
...opts.browser ? { browser: opts.browser } : {},
|
|
3680
3687
|
steps: [...steps, ...actorPreparations(opts.actors)],
|
|
3681
3688
|
...hydrated?.state ? { storageState: hydrated.state } : {},
|
|
3682
3689
|
...opts.resolveAuth ? { resolveAuth: opts.resolveAuth } : {},
|
|
@@ -3932,6 +3939,7 @@ async function replayCase(opts) {
|
|
|
3932
3939
|
opts.actors?.find((a) => a.id === (opts.defaultActorId ?? "default"))?.startSignedIn
|
|
3933
3940
|
);
|
|
3934
3941
|
const session = await openRunSession({
|
|
3942
|
+
...opts.browser ? { browser: opts.browser } : {},
|
|
3935
3943
|
steps: allSteps,
|
|
3936
3944
|
...caseHydrated?.state ? { storageState: caseHydrated.state } : {},
|
|
3937
3945
|
...opts.resolveAuth ? { resolveAuth: opts.resolveAuth } : {},
|
|
@@ -5234,6 +5242,59 @@ async function fieldNames(page) {
|
|
|
5234
5242
|
return found;
|
|
5235
5243
|
}).catch(() => []);
|
|
5236
5244
|
}
|
|
5245
|
+
var playwrightVersion2 = () => {
|
|
5246
|
+
try {
|
|
5247
|
+
return createRequire22(import.meta.url)("playwright/package.json").version;
|
|
5248
|
+
} catch {
|
|
5249
|
+
return "1.latest";
|
|
5250
|
+
}
|
|
5251
|
+
};
|
|
5252
|
+
function cloudBrowserEndpoint(account, key, choice, name) {
|
|
5253
|
+
const type = choice.browser === "firefox" ? "firefox" : choice.browser === "webkit" ? "webkit" : "chromium";
|
|
5254
|
+
const build = `Flowriki ${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`;
|
|
5255
|
+
const mac = choice.system.startsWith("macOS");
|
|
5256
|
+
if (account.provider === "browserstack") {
|
|
5257
|
+
const caps = {
|
|
5258
|
+
browser: choice.browser === "chrome" ? "chrome" : choice.browser === "edge" ? "edge" : `playwright-${type}`,
|
|
5259
|
+
os: mac ? "OS X" : "Windows",
|
|
5260
|
+
os_version: mac ? choice.system.replace("macOS ", "") : choice.system.replace("Windows ", ""),
|
|
5261
|
+
name,
|
|
5262
|
+
build,
|
|
5263
|
+
project: "Flowriki",
|
|
5264
|
+
"browserstack.username": account.username,
|
|
5265
|
+
"browserstack.accessKey": key,
|
|
5266
|
+
"client.playwrightVersion": playwrightVersion2()
|
|
5267
|
+
};
|
|
5268
|
+
return { type, wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}` };
|
|
5269
|
+
}
|
|
5270
|
+
if (account.provider === "lambdatest") {
|
|
5271
|
+
const caps = {
|
|
5272
|
+
browserName: choice.browser === "chrome" ? "Chrome" : choice.browser === "edge" ? "MicrosoftEdge" : choice.browser === "firefox" ? "pw-firefox" : "pw-webkit",
|
|
5273
|
+
browserVersion: "latest",
|
|
5274
|
+
"LT:Options": {
|
|
5275
|
+
platform: mac ? choice.system : choice.system,
|
|
5276
|
+
build,
|
|
5277
|
+
name,
|
|
5278
|
+
project: "Flowriki",
|
|
5279
|
+
user: account.username,
|
|
5280
|
+
accessKey: key,
|
|
5281
|
+
playwrightClientVersion: playwrightVersion2()
|
|
5282
|
+
}
|
|
5283
|
+
};
|
|
5284
|
+
return { type, wsEndpoint: `wss://cdp.lambdatest.com/playwright?capabilities=${encodeURIComponent(JSON.stringify(caps))}` };
|
|
5285
|
+
}
|
|
5286
|
+
throw new Error(`${CLOUD_PROVIDER_NAME[account.provider]} cannot run a website's tests remotely \u2014 choose BrowserStack or LambdaTest for the web`);
|
|
5287
|
+
}
|
|
5288
|
+
async function connectCloudBrowser(account, key, choice, name) {
|
|
5289
|
+
const { type, wsEndpoint } = cloudBrowserEndpoint(account, key, choice, name);
|
|
5290
|
+
const engine = { chromium: chromium2, firefox: firefox2, webkit: webkit2 }[type];
|
|
5291
|
+
try {
|
|
5292
|
+
return await engine.connect(wsEndpoint, { timeout: 12e4 });
|
|
5293
|
+
} catch (error) {
|
|
5294
|
+
const said = error.message.split("\n")[0] ?? "";
|
|
5295
|
+
throw new Error(`${CLOUD_PROVIDER_NAME[account.provider]} could not open ${WEB_CLOUD_BROWSER_NAME[choice.browser]} on ${choice.system}: ${said.replace(key, "\u2022\u2022\u2022\u2022")}`);
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5237
5298
|
|
|
5238
5299
|
// ../results/dist/chunk-LYCTVHPR.js
|
|
5239
5300
|
import { z as z3 } from "zod";
|
|
@@ -6096,7 +6157,7 @@ function toSummary(row) {
|
|
|
6096
6157
|
};
|
|
6097
6158
|
}
|
|
6098
6159
|
|
|
6099
|
-
// ../repository-store/dist/chunk-
|
|
6160
|
+
// ../repository-store/dist/chunk-7ZZULR2K.js
|
|
6100
6161
|
var FLOWRIKI_DIR = ".flowriki";
|
|
6101
6162
|
var FEATURES_DIR = `${FLOWRIKI_DIR}/features`;
|
|
6102
6163
|
var CONFIG_PATH = `${FLOWRIKI_DIR}/config.json`;
|
|
@@ -6148,7 +6209,9 @@ function parseConfig(raw) {
|
|
|
6148
6209
|
artifacts: ArtifactPolicySchema.parse(source["artifacts"] ?? {}),
|
|
6149
6210
|
flakinessRepeat: clampRepeat(source["flakinessRepeat"]),
|
|
6150
6211
|
platforms: platformsOf(source),
|
|
6151
|
-
mobile: mobileOf(source)
|
|
6212
|
+
mobile: mobileOf(source),
|
|
6213
|
+
runWhere: runWhereOf(source),
|
|
6214
|
+
...webCloudOf(source) ? { webCloud: webCloudOf(source) } : {}
|
|
6152
6215
|
};
|
|
6153
6216
|
}
|
|
6154
6217
|
function readEnvironments(raw) {
|
|
@@ -7095,6 +7158,17 @@ async function runHelper(helper, ctx) {
|
|
|
7095
7158
|
// ../execution/dist/index.js
|
|
7096
7159
|
import fs24 from "fs";
|
|
7097
7160
|
import crypto3 from "crypto";
|
|
7161
|
+
async function cloudBrowserFor(config, secrets, name) {
|
|
7162
|
+
const settings = config ?? {};
|
|
7163
|
+
if (runWhereOf(settings).web !== "cloud") return null;
|
|
7164
|
+
const choice = webCloudOf(settings);
|
|
7165
|
+
if (!choice) throw new Error("This project runs websites in the cloud, but no cloud browser is chosen \u2014 pick one in Settings \u2192 Platforms.");
|
|
7166
|
+
const account = mobileOf(settings).cloud.find((c) => c.provider === choice.provider);
|
|
7167
|
+
if (!account) throw new Error(`${CLOUD_PROVIDER_NAME[choice.provider]} is not connected to this project \u2014 connect it in Settings \u2192 Platforms.`);
|
|
7168
|
+
const key = secrets[account.keyRef];
|
|
7169
|
+
if (!key) throw new Error(`The ${CLOUD_PROVIDER_NAME[choice.provider]} access key was not sent with this run \u2014 set it again in Settings \u2192 Platforms.`);
|
|
7170
|
+
return connectCloudBrowser(account, key, choice, name);
|
|
7171
|
+
}
|
|
7098
7172
|
var LOCAL_CHROMIUM = { id: "chromium", provider: "local", engine: "chromium" };
|
|
7099
7173
|
async function executeFlow(opts) {
|
|
7100
7174
|
const { store, storage = null, flowId, trigger, watch = false, onEvent } = opts;
|
|
@@ -7151,6 +7225,7 @@ async function executeFlow(opts) {
|
|
|
7151
7225
|
mobile: mobileOf(store.readConfig()),
|
|
7152
7226
|
steps: o.steps,
|
|
7153
7227
|
startPath: flow.startPath,
|
|
7228
|
+
where: runWhereOf(store.readConfig())[platform],
|
|
7154
7229
|
...opts.device ? { device: opts.device } : {},
|
|
7155
7230
|
resolveSecret: o.resolveSecret,
|
|
7156
7231
|
resolveAuth: o.resolveAuth,
|
|
@@ -7160,7 +7235,21 @@ async function executeFlow(opts) {
|
|
|
7160
7235
|
screenshots: o.artifacts?.screenshot ?? "on-failure",
|
|
7161
7236
|
signal: o.signal,
|
|
7162
7237
|
video: { mode: o.artifacts?.video ?? "off", allowUnmasked: o.artifacts?.allowUnmaskedArtifacts === true }
|
|
7163
|
-
}) :
|
|
7238
|
+
}) : runWebsite(o);
|
|
7239
|
+
const runWebsite = async (o) => {
|
|
7240
|
+
let cloud = null;
|
|
7241
|
+
try {
|
|
7242
|
+
cloud = await cloudBrowserFor(store.readConfig(), secrets, flow.name);
|
|
7243
|
+
} catch (error) {
|
|
7244
|
+
return { status: "errored", error: error.message, durationMs: 0, stepsRun: 0, stepsTotal: o.steps.length, steps: [] };
|
|
7245
|
+
}
|
|
7246
|
+
if (!cloud) return replayFlow(o);
|
|
7247
|
+
try {
|
|
7248
|
+
return await replayFlow({ ...o, browser: cloud, artifacts: { ...o.artifacts, video: "off", trace: "off" } });
|
|
7249
|
+
} finally {
|
|
7250
|
+
await cloud.close().catch(() => void 0);
|
|
7251
|
+
}
|
|
7252
|
+
};
|
|
7164
7253
|
const byId = new Map(flow.steps.map((s2) => [s2.id, s2]));
|
|
7165
7254
|
const attempts = [];
|
|
7166
7255
|
const perStep = /* @__PURE__ */ new Map();
|
|
@@ -7521,12 +7610,23 @@ async function executeCase(opts) {
|
|
|
7521
7610
|
...config.artifacts?.screenshot ? { screenshots: config.artifacts.screenshot } : {},
|
|
7522
7611
|
...opts.signal ? { signal: opts.signal } : {},
|
|
7523
7612
|
video: { mode: config.artifacts?.video ?? "off", allowUnmasked: config.artifacts?.allowUnmaskedArtifacts === true },
|
|
7524
|
-
allSteps: phoneRows.flatMap((o) => o.steps)
|
|
7613
|
+
allSteps: phoneRows.flatMap((o) => o.steps),
|
|
7614
|
+
runWhere: runWhereOf(config)
|
|
7525
7615
|
};
|
|
7526
7616
|
const lane = phoneRows.length && phoneRows.length < testCase.occurrences.length ? new MobileLane(laneOptions) : null;
|
|
7617
|
+
let cloud = null;
|
|
7618
|
+
let cloudProblem = null;
|
|
7619
|
+
if (phoneRows.length < testCase.occurrences.length) {
|
|
7620
|
+
try {
|
|
7621
|
+
cloud = await cloudBrowserFor(config, secrets, testCase.name);
|
|
7622
|
+
} catch (error) {
|
|
7623
|
+
cloudProblem = error.message;
|
|
7624
|
+
}
|
|
7625
|
+
}
|
|
7527
7626
|
const opened = /* @__PURE__ */ new Set();
|
|
7528
7627
|
let outcome;
|
|
7529
7628
|
try {
|
|
7629
|
+
if (cloudProblem) throw new Error(cloudProblem);
|
|
7530
7630
|
if (phoneRows.length === testCase.occurrences.length) {
|
|
7531
7631
|
outcome = await replayMobileCase({
|
|
7532
7632
|
...laneOptions,
|
|
@@ -7535,6 +7635,7 @@ async function executeCase(opts) {
|
|
|
7535
7635
|
onStepResult: recordStep
|
|
7536
7636
|
});
|
|
7537
7637
|
} else outcome = await replayCase({
|
|
7638
|
+
...cloud ? { browser: cloud } : {},
|
|
7538
7639
|
...lane ? {
|
|
7539
7640
|
runElsewhere: (occurrence, ctx) => {
|
|
7540
7641
|
if (!isMobile(occurrence.platform)) return null;
|
|
@@ -7556,7 +7657,7 @@ async function executeCase(opts) {
|
|
|
7556
7657
|
...opts.watch ? { slowMo: 400 } : {},
|
|
7557
7658
|
resolveSecret: (ref) => secrets[ref],
|
|
7558
7659
|
...opts.resolveFile ? { resolveFile: opts.resolveFile } : {},
|
|
7559
|
-
...config.artifacts ? { artifacts: config.artifacts } : {},
|
|
7660
|
+
...config.artifacts ? { artifacts: cloud ? { ...config.artifacts, video: "off", trace: "off" } : config.artifacts } : {},
|
|
7560
7661
|
...runDir ? { evidenceDir: runDir } : {},
|
|
7561
7662
|
...opts.signal ? { signal: opts.signal } : {},
|
|
7562
7663
|
onStepResult: recordStep
|
|
@@ -7585,6 +7686,7 @@ async function executeCase(opts) {
|
|
|
7585
7686
|
}))
|
|
7586
7687
|
};
|
|
7587
7688
|
}
|
|
7689
|
+
await cloud?.close().catch(() => void 0);
|
|
7588
7690
|
if (lane) outcome = { ...outcome, artifacts: [...outcome.artifacts ?? [], ...await lane.close(outcome.status === "passed")] };
|
|
7589
7691
|
await Promise.all(writes);
|
|
7590
7692
|
if (storage && run) {
|
|
@@ -8069,6 +8171,7 @@ async function verifyFlowSteps(deps, opts) {
|
|
|
8069
8171
|
mobile: mobileOf(store.readConfig()),
|
|
8070
8172
|
steps,
|
|
8071
8173
|
startPath: flow.startPath,
|
|
8174
|
+
where: runWhereOf(store.readConfig())[flow.platform],
|
|
8072
8175
|
...store.resolveAuth ? { resolveAuth: store.resolveAuth } : {},
|
|
8073
8176
|
...store.runHelper ? { runHelper: store.runHelper } : {},
|
|
8074
8177
|
resolveSecret: (ref) => secrets[ref],
|
|
@@ -9731,7 +9834,13 @@ function mobileHandlers(ctx) {
|
|
|
9731
9834
|
const config = command.args["config"] ?? {};
|
|
9732
9835
|
const secrets = command.args["secrets"] ?? {};
|
|
9733
9836
|
const device = command.args["device"] ? DeviceChoiceSchema.parse(command.args["device"]) : void 0;
|
|
9734
|
-
const session = await openMobileSession({
|
|
9837
|
+
const session = await openMobileSession({
|
|
9838
|
+
platform,
|
|
9839
|
+
mobile: mobileOf(config),
|
|
9840
|
+
...device ? { device } : {},
|
|
9841
|
+
resolveSecret: (ref) => secrets[ref],
|
|
9842
|
+
where: runWhereOf(config)[platform]
|
|
9843
|
+
});
|
|
9735
9844
|
const typed = /* @__PURE__ */ new Map();
|
|
9736
9845
|
const l2 = {
|
|
9737
9846
|
id: randomUUID2(),
|
package/dist/cli.js
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
runtimeValue,
|
|
24
24
|
start,
|
|
25
25
|
status
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-YXTWKSJ4.js";
|
|
27
27
|
import {
|
|
28
28
|
CLOUD_PROVIDERS,
|
|
29
29
|
CLOUD_PROVIDER_NAME,
|
|
@@ -46,7 +46,7 @@ import {
|
|
|
46
46
|
screenLines,
|
|
47
47
|
stepRefusedOn,
|
|
48
48
|
targetFor
|
|
49
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-4VJVDGF5.js";
|
|
50
50
|
|
|
51
51
|
// src/cli.ts
|
|
52
52
|
import { parseArgs } from "util";
|
|
@@ -988,6 +988,7 @@ Review and publish it here: ${review}`;
|
|
|
988
988
|
this.mobile = await openMobileSession({
|
|
989
989
|
platform,
|
|
990
990
|
mobile,
|
|
991
|
+
...catalog.runWhere ? { where: catalog.runWhere[platform] } : {},
|
|
991
992
|
...draft.device ? { device: draft.device } : {},
|
|
992
993
|
...resolvers ? { resolveSecret: resolvers.resolveSecret } : {}
|
|
993
994
|
});
|
|
@@ -1407,12 +1408,12 @@ It is now the project these tools work on. Open it: ${service.origin}/projects/$
|
|
|
1407
1408
|
const chosen = c.mobile?.devices[p];
|
|
1408
1409
|
return `${p === "android" ? "Android" : "iOS"} app: ${app ?? "(not set up \u2014 Settings \u2192 Mobile)"}
|
|
1409
1410
|
Phones on this computer: ${here.length ? here.map((d) => `${d.name}${d.state === "ready" ? "" : ` (${d.state})`}`).join(", ") : "none"}` + (farms.length ? `
|
|
1410
|
-
Cloud device farms: ${farms.join(", ")}` : "") +
|
|
1411
|
-
Runs
|
|
1411
|
+
Cloud device farms: ${farms.join(", ")}` : "") + `
|
|
1412
|
+
Runs: ${c.runWhere?.[p] === "cloud" ? "in the cloud" : "on this computer"}` + (chosen ? ` \u2014 ${chosen.kind === "local" ? chosen.name || chosen.id : `${CLOUD_PROVIDER_NAME[chosen.provider]}: ${chosen.device}`}` : "");
|
|
1412
1413
|
});
|
|
1413
1414
|
return text([
|
|
1414
1415
|
`Project ${projectId}. Tests: ${[platforms.web && "web", platforms.android && "Android app", platforms.ios && "iOS app"].filter(Boolean).join(", ")}.`,
|
|
1415
|
-
platforms.web ? `Base URL: ${c.baseUrl || "(not set)"}` : "",
|
|
1416
|
+
platforms.web ? `Base URL: ${c.baseUrl || "(not set)"}${c.runWhere?.web === "cloud" ? " \u2014 test runs use a cloud browser; recording is on this computer" : ""}` : "",
|
|
1416
1417
|
...phoneLines,
|
|
1417
1418
|
c.environments.length ? `Environments: ${c.environments.map((e) => `${e.name} ${e.baseUrl}`).join(", ")}` : "",
|
|
1418
1419
|
`
|
package/dist/engine.js
CHANGED
package/package.json
CHANGED