(totalRuns, options = {})
| 244 | } |
| 245 | |
| 246 | async function autoRunLoop(totalRuns, options = {}) { |
| 247 | let currentRuntime = runtime.get(); |
| 248 | if (currentRuntime.autoRunActive) { |
| 249 | await addLog('自动运行已在进行中', 'warn'); |
| 250 | return; |
| 251 | } |
| 252 | |
| 253 | clearStopRequest(); |
| 254 | runtime.set({ |
| 255 | autoRunActive: true, |
| 256 | autoRunTotalRuns: totalRuns, |
| 257 | autoRunCurrentRun: 0, |
| 258 | autoRunAttemptRun: 0, |
| 259 | }); |
| 260 | currentRuntime = runtime.get(); |
| 261 | |
| 262 | const autoRunSkipFailures = Boolean(options.autoRunSkipFailures); |
| 263 | const initialMode = options.mode === 'continue' ? 'continue' : 'restart'; |
| 264 | const resumeCurrentRun = Number.isInteger(options.resumeCurrentRun) && options.resumeCurrentRun > 0 |
| 265 | ? Math.min(totalRuns, options.resumeCurrentRun) |
| 266 | : 1; |
| 267 | const resumeAttemptRun = Number.isInteger(options.resumeAttemptRun) && options.resumeAttemptRun > 0 |
| 268 | ? Math.min(AUTO_RUN_MAX_RETRIES_PER_ROUND + 1, options.resumeAttemptRun) |
| 269 | : 1; |
| 270 | let continueCurrentOnFirstAttempt = initialMode === 'continue'; |
| 271 | let forceFreshTabsNextRun = false; |
| 272 | let stoppedEarly = false; |
| 273 | let parkedByTimer = false; |
| 274 | const roundSummaries = buildAutoRunRoundSummaries(totalRuns, options.resumeRoundSummaries); |
| 275 | |
| 276 | if (continueCurrentOnFirstAttempt && resumeCurrentRun > 1) { |
| 277 | for (let round = 1; round < resumeCurrentRun; round += 1) { |
| 278 | const summary = roundSummaries[round - 1]; |
| 279 | if (summary.status === 'pending') { |
| 280 | summary.status = 'success'; |
| 281 | if (!summary.attempts) { |
| 282 | summary.attempts = 1; |
| 283 | } |
| 284 | } |
| 285 | } |
| 286 | } |
| 287 | |
| 288 | let successfulRuns = roundSummaries.filter((item) => item.status === 'success').length; |
| 289 | const initialState = await getState(); |
| 290 | const initialPhase = continueCurrentOnFirstAttempt && getRunningSteps(initialState.stepStatuses).length |
| 291 | ? 'waiting_step' |
| 292 | : 'running'; |
| 293 | const showResumePosition = continueCurrentOnFirstAttempt || resumeCurrentRun > 1 || resumeAttemptRun > 1; |
| 294 | |
| 295 | await setState({ |
| 296 | autoRunSkipFailures, |
| 297 | autoRunRoundSummaries: serializeAutoRunRoundSummaries(totalRuns, roundSummaries), |
| 298 | ...getAutoRunStatusPayload(initialPhase, { |
| 299 | currentRun: showResumePosition ? resumeCurrentRun : 0, |
| 300 | totalRuns, |
| 301 | attemptRun: showResumePosition ? resumeAttemptRun : 0, |
| 302 | }), |
| 303 | }); |
no test coverage detected