Skip to content

Commit 101a47b

Browse files
committed
dpr eval / screenshot retries
1 parent ae31415 commit 101a47b

File tree

1 file changed

+27
-23
lines changed

1 file changed

+27
-23
lines changed

packages/magnitude-core/src/web/harness.ts

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,40 +103,44 @@ export class WebHarness { // implements StateComponent
103103
/**
104104
* Get b64 encoded string of screenshot (PNG) with screen dimensions
105105
*/
106-
const dpr = await this.page.evaluate(() => window.devicePixelRatio);
107-
//console.log("DPR:", dpr);
108-
//const viewportSize = this.page.viewportSize();
109-
const buffer = await this.page.screenshot({ type: 'png', ...options }, );
110-
111-
// if (!viewportSize) {
112-
// throw Error("Invalid viewport for screenshot");
113-
// }
114-
106+
107+
// Target page, context or browser has been closed
108+
109+
let dpr!: number;
110+
let buffer!: Buffer<ArrayBufferLike>;
111+
112+
const retries = 3;
113+
114+
for (let attempt = 0; attempt <= retries; attempt++) {
115+
try {
116+
dpr = await this.page.evaluate(() => window.devicePixelRatio)
117+
buffer = await this.page.screenshot({ type: 'png', ...options }, );
118+
} catch (err) {
119+
// A few possibilities:
120+
// 1. Target page, context or browser has been closed
121+
// 2. Page navigation in progress
122+
// In theory 2 shouldn't shouldn't happen during typical execution as we wait for page load - unless screenshot is triggered at an usual time.
123+
const error = err as Error;
124+
if (error.message.includes('Target page, context or browser has been closed')) {
125+
// Irrecoverable, no point in retrying
126+
throw new Error("Attempted to take screenshot but page, context or browser is closed");
127+
}
128+
if (attempt >= retries) {
129+
throw new Error(`Unable to capture screenshot after retries, error: ${error.message}`);
130+
}
131+
}
132+
}
115133
const base64data = buffer.toString('base64');
116134

117-
//console.log("Screenshot DATA:", base64data.substring(0, 100));
118135
const image = Image.fromBase64(base64data);
119136

120137
// Now, need to rescale the image based on DPR. This is so that:
121138
// (1) Save on tokens, dont need huge high res images
122139
// (2) More importantly, clicks happen in the standard resolution space, so need to do this for coordinates to be correct
123140
// for any agent not using a virtual screen space (e.g. those that aren't Claude)
124141
const { width, height } = await image.getDimensions();
125-
//console.log("Original screenshot dims:", { width, height });
126-
//console.log("DPR-scaled dims:", { width: width / dpr, height: height / dpr });
127142
const rescaledImage = await image.resize(width / dpr, height / dpr);
128-
//console.log("screenshot() final dims:", await rescaledImage.getDimensions());
129-
130-
//console.log("_locateTarget dims:", await screenshot.getDimensions());
131143
return rescaledImage;
132-
133-
// return {
134-
// image: `data:image/png;base64,${base64data}`,//buffer.toString('base64'),
135-
// dimensions: {
136-
// width: viewportSize.width,
137-
// height: viewportSize.height
138-
// }
139-
// };
140144
}
141145

142146
// async goto(url: string) {

0 commit comments

Comments
 (0)