Skip to content

Commit e103323

Browse files
committed
refactor(browser): share playwright download wait/save flow
1 parent 7bf9b6e commit e103323

File tree

1 file changed

+38
-39
lines changed

1 file changed

+38
-39
lines changed

src/browser/pw-tools-core.downloads.ts

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,42 @@ function createPageDownloadWaiter(page: Page, timeoutMs: number) {
102102
};
103103
}
104104

105+
type DownloadPayload = {
106+
url?: () => string;
107+
suggestedFilename?: () => string;
108+
saveAs?: (outPath: string) => Promise<void>;
109+
};
110+
111+
async function saveDownloadPayload(download: DownloadPayload, outPath: string) {
112+
const suggested = download.suggestedFilename?.() || "download.bin";
113+
const resolvedOutPath = outPath?.trim() || buildTempDownloadPath(suggested);
114+
await fs.mkdir(path.dirname(resolvedOutPath), { recursive: true });
115+
await download.saveAs?.(resolvedOutPath);
116+
return {
117+
url: download.url?.() || "",
118+
suggestedFilename: suggested,
119+
path: path.resolve(resolvedOutPath),
120+
};
121+
}
122+
123+
async function awaitDownloadPayload(params: {
124+
waiter: ReturnType<typeof createPageDownloadWaiter>;
125+
state: ReturnType<typeof ensurePageState>;
126+
armId: number;
127+
outPath?: string;
128+
}) {
129+
try {
130+
const download = (await params.waiter.promise) as DownloadPayload;
131+
if (params.state.armIdDownload !== params.armId) {
132+
throw new Error("Download was superseded by another waiter");
133+
}
134+
return await saveDownloadPayload(download, params.outPath ?? "");
135+
} catch (err) {
136+
params.waiter.cancel();
137+
throw err;
138+
}
139+
}
140+
105141
export async function armFileUploadViaPlaywright(opts: {
106142
cdpUrl: string;
107143
targetId?: string;
@@ -200,28 +236,7 @@ export async function waitForDownloadViaPlaywright(opts: {
200236
const armId = state.armIdDownload;
201237

202238
const waiter = createPageDownloadWaiter(page, timeout);
203-
try {
204-
const download = (await waiter.promise) as {
205-
url?: () => string;
206-
suggestedFilename?: () => string;
207-
saveAs?: (outPath: string) => Promise<void>;
208-
};
209-
if (state.armIdDownload !== armId) {
210-
throw new Error("Download was superseded by another waiter");
211-
}
212-
const suggested = download.suggestedFilename?.() || "download.bin";
213-
const outPath = opts.path?.trim() || buildTempDownloadPath(suggested);
214-
await fs.mkdir(path.dirname(outPath), { recursive: true });
215-
await download.saveAs?.(outPath);
216-
return {
217-
url: download.url?.() || "",
218-
suggestedFilename: suggested,
219-
path: path.resolve(outPath),
220-
};
221-
} catch (err) {
222-
waiter.cancel();
223-
throw err;
224-
}
239+
return await awaitDownloadPayload({ waiter, state, armId, outPath: opts.path });
225240
}
226241

227242
export async function downloadViaPlaywright(opts: {
@@ -257,23 +272,7 @@ export async function downloadViaPlaywright(opts: {
257272
} catch (err) {
258273
throw toAIFriendlyError(err, ref);
259274
}
260-
261-
const download = (await waiter.promise) as {
262-
url?: () => string;
263-
suggestedFilename?: () => string;
264-
saveAs?: (outPath: string) => Promise<void>;
265-
};
266-
if (state.armIdDownload !== armId) {
267-
throw new Error("Download was superseded by another waiter");
268-
}
269-
const suggested = download.suggestedFilename?.() || "download.bin";
270-
await fs.mkdir(path.dirname(outPath), { recursive: true });
271-
await download.saveAs?.(outPath);
272-
return {
273-
url: download.url?.() || "",
274-
suggestedFilename: suggested,
275-
path: path.resolve(outPath),
276-
};
275+
return await awaitDownloadPayload({ waiter, state, armId, outPath });
277276
} catch (err) {
278277
waiter.cancel();
279278
throw err;

0 commit comments

Comments
 (0)