fix: improve browser upload triggering
This commit is contained in:
@@ -93,6 +93,7 @@ export async function browserArmFileChooser(
|
||||
baseUrl: string,
|
||||
opts: {
|
||||
paths: string[];
|
||||
ref?: string;
|
||||
targetId?: string;
|
||||
timeoutMs?: number;
|
||||
},
|
||||
@@ -104,6 +105,7 @@ export async function browserArmFileChooser(
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
paths: opts.paths,
|
||||
ref: opts.ref,
|
||||
targetId: opts.targetId,
|
||||
timeoutMs: opts.timeoutMs,
|
||||
}),
|
||||
|
||||
@@ -283,6 +283,20 @@ export async function armFileUploadViaPlaywright(opts: {
|
||||
return;
|
||||
}
|
||||
await fileChooser.setFiles(opts.paths);
|
||||
try {
|
||||
const input =
|
||||
typeof fileChooser.element === "function"
|
||||
? await fileChooser.element()
|
||||
: null;
|
||||
if (input) {
|
||||
await input.evaluate((el) => {
|
||||
el.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
el.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
});
|
||||
}
|
||||
} catch {
|
||||
// Best-effort for sites that don't react to setFiles alone.
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Ignore timeouts; the chooser may never appear.
|
||||
|
||||
@@ -338,6 +338,7 @@ export function registerBrowserAgentRoutes(
|
||||
app.post("/hooks/file-chooser", async (req, res) => {
|
||||
const body = readBody(req);
|
||||
const targetId = toStringOrEmpty(body.targetId) || undefined;
|
||||
const ref = toStringOrEmpty(body.ref) || undefined;
|
||||
const paths = toStringArray(body.paths) ?? [];
|
||||
const timeoutMs = toNumber(body.timeoutMs);
|
||||
if (!paths.length) return jsonError(res, 400, "paths are required");
|
||||
@@ -351,6 +352,13 @@ export function registerBrowserAgentRoutes(
|
||||
paths,
|
||||
timeoutMs: timeoutMs ?? undefined,
|
||||
});
|
||||
if (ref) {
|
||||
await pw.clickViaPlaywright({
|
||||
cdpPort: ctx.state().cdpPort,
|
||||
targetId: tab.targetId,
|
||||
ref,
|
||||
});
|
||||
}
|
||||
res.json({ ok: true });
|
||||
} catch (err) {
|
||||
handleRouteError(ctx, res, err);
|
||||
|
||||
@@ -475,6 +475,24 @@ describe("browser control server", () => {
|
||||
timeoutMs: 1234,
|
||||
});
|
||||
|
||||
const uploadWithRef = await realFetch(`${base}/hooks/file-chooser`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ paths: ["/tmp/b.txt"], ref: "e12" }),
|
||||
}).then((r) => r.json());
|
||||
expect(uploadWithRef).toMatchObject({ ok: true });
|
||||
expect(pwMocks.armFileUploadViaPlaywright).toHaveBeenCalledWith({
|
||||
cdpPort: testPort + 1,
|
||||
targetId: "abcd1234",
|
||||
paths: ["/tmp/b.txt"],
|
||||
timeoutMs: undefined,
|
||||
});
|
||||
expect(pwMocks.clickViaPlaywright).toHaveBeenCalledWith({
|
||||
cdpPort: testPort + 1,
|
||||
targetId: "abcd1234",
|
||||
ref: "e12",
|
||||
});
|
||||
|
||||
const dialog = await realFetch(`${base}/hooks/dialog`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
|
||||
Reference in New Issue
Block a user