@@ -18,6 +18,7 @@ export const REPLAY_SPECIAL_ACTION_TYPES: ReadonlySet<string> = new Set([
1818 "complete" ,
1919 "refreshPage" ,
2020 "wait" ,
21+ "waitForLoadState" ,
2122 "extract" ,
2223 "analyzePdf" ,
2324] ) ;
@@ -55,6 +56,10 @@ function asNumber(value: unknown): number | undefined {
5556 return undefined ;
5657}
5758
59+ function asFiniteNumber ( value : unknown ) : number | undefined {
60+ return typeof value === "number" && Number . isFinite ( value ) ? value : undefined ;
61+ }
62+
5863function normalizeWaitMs ( value : unknown ) : number {
5964 const parsed = asNumber ( value ) ;
6065 if ( parsed === undefined ) {
@@ -163,14 +168,28 @@ export async function executeReplaySpecialAction(
163168 }
164169 try {
165170 const extracted = await extractPage . extract ( extractInstruction ) ;
171+ let serializedExtracted = "" ;
172+ if ( typeof extracted === "string" ) {
173+ serializedExtracted = extracted ;
174+ } else {
175+ try {
176+ serializedExtracted = JSON . stringify ( extracted ) ;
177+ } catch ( error ) {
178+ const message = error instanceof Error ? error . message : String ( error ) ;
179+ return {
180+ taskId,
181+ status : TaskStatus . FAILED ,
182+ steps : [ ] ,
183+ output : `Extract failed: could not serialize extracted output (${ message } )` ,
184+ replayStepMeta : createReplayMeta ( retries ) ,
185+ } ;
186+ }
187+ }
166188 return {
167189 taskId,
168190 status : TaskStatus . COMPLETED ,
169191 steps : [ ] ,
170- output :
171- typeof extracted === "string"
172- ? extracted
173- : JSON . stringify ( extracted ) ,
192+ output : serializedExtracted ,
174193 replayStepMeta : createReplayMeta ( retries ) ,
175194 } ;
176195 } catch ( error ) {
@@ -195,5 +214,24 @@ export async function executeReplaySpecialAction(
195214 } ;
196215 }
197216
217+ if ( actionType === "waitForLoadState" ) {
218+ const waitUntil = asNonEmptyTrimmedString ( actionArgs ?. [ 0 ] ) ?? "domcontentloaded" ;
219+ const timeoutMs = asFiniteNumber ( actionArgs ?. [ 1 ] ) ;
220+ const options =
221+ timeoutMs !== undefined ? { timeout : timeoutMs } : undefined ;
222+ await page . waitForLoadState (
223+ waitUntil as "domcontentloaded" | "load" | "networkidle" ,
224+ options
225+ ) ;
226+ markDomSnapshotDirty ( page ) ;
227+ return {
228+ taskId,
229+ status : TaskStatus . COMPLETED ,
230+ steps : [ ] ,
231+ output : `Waited for load state: ${ waitUntil } ` ,
232+ replayStepMeta : createReplayMeta ( retries ) ,
233+ } ;
234+ }
235+
198236 return null ;
199237}
0 commit comments