kapil971390 · GitHub

Commits on Jun 13, 2026

  1. test(core): characterize promise-core error and hang paths (#5622)

    Adds browser-free characterization tests that pin down the error and
    settle-guarantees of the promise composition core, so it can be fixed or
    refactored safely. No lib/ code is changed — current behavior (including
    known-bad behavior) is frozen.
    - recorder_test.js: errHandler/catch routing, catchWithoutStop terminal
      vs normal errors, ignoreErr, nested-session id semantics, unbalanced
      session restore, and task timeout (success + failure).
    - session_composition_test.js (new): session()/within()/retryTo()/hopeThat()
      composition with a fake helper registered through the real container, a
      settles()/drain() harness that turns deadlocks into fast named failures,
      and hermetic per-test isolation of the recorder singleton.
    - mocha/asyncWrapper_test.js: test() lifecycle (queued-step failure, sync
      throw, test.throws pass) and a rejecting injected() before-hook.
    Characterized divergences (session-id leak on error, within skipping
    _withinEnd, retryTo retrying past rejection, recorder.retries leaking across
    runs, stopped-recorder hang) are documented for the follow-up fix plan.
    Co-authored-by: DavertMik <davert@testomat.io>
    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

    3 people authored

    Jun 13, 2026
    Configuration menu

    Browse the repository at this point in the history

Commits on Jun 14, 2026

  1. fix(pause): remove leaked dispatcher listeners and guard session rest…

    …ore (#5630)
    Every pause() call registered two permanent listeners on the global event
    dispatcher (step.after, test.finished) and never removed them. Repeated
    pauses — now the normal case because the MCP server drives pause()
    programmatically via setPauseHandler/pauseNow — accumulated listeners, fired
    finish() multiple times, and ran an unconditional recorder.session.restore('pause')
    on every test finish even when no pause session was open, unbalancing the
    recorder's session stack (the hang class blocking 4.0).
    - Convert the two anonymous listeners into named handlers (onStepAfter,
      onTestFinished) and register them through an idempotent helper that removes
      any prior registration first, so repeated pause()/pauseNow() keep exactly
      one of each. onTestFinished removes both listeners when the test finishes.
    - Track an open-pause flag and only restore the 'pause' session when one is
      actually open (set on session.start in pauseSession, cleared at all three
      restore sites).
    - pauseNow now performs the same idempotent registration as pause().
    setPauseHandler/pauseNow signatures and resolve semantics are unchanged
    (bin/mcp-server.js untouched). 4 regression tests cover idempotent
    registration, listener removal on finish, the no-double-restore guard, and the
    MCP pauseNow lifecycle; reverting the fix fails the listener tests.
    Co-authored-by: DavertMik <davert@testomat.io>
    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

    3 people authored

    Jun 14, 2026
    Configuration menu

    Browse the repository at this point in the history

  2. fix(core): re-land asyncWrapper + promise-core error-path fixes onto …

    …4.x (#5624, #5633) (#5637)
    * fix(mocha): fail fast when test hook import chain rejects
    In 4.x the per-test setup()/teardown() hooks load ./test.js via a dynamic
    import() with no .catch(). If that import rejects, or the .then body throws
    (e.g. enhanceMochaTest on an undefined test, a listener throwing), done() is
    never called and the mocha hook hangs forever — the silent-hang failure mode
    the 4.0 release is most concerned with.
    This mirrors the existing suiteSetup()/suiteTeardown() shape exactly: append a
    .catch(err => doneFn(err)) to both import chains. No recorder.errHandler is
    added (the per-test handler owns the single errFn slot). makeDoneCallableOnce
    already guards against a double done() call.
    Adds 3 regression tests: setup() and teardown() with a throwing then-body call
    done with the error within 1s instead of hanging, plus a happy-path check.
    Reverting the fix makes the two error-path tests hang (verified).
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    (cherry picked from commit  ac59a40 )
    * fix(core): restore sessions and propagate errors on session/within/retryTo error paths
    Fixes four of the latent error-path divergences characterized in #5622, by
    making the error paths symmetric with the success paths. The characterization
    assertions are updated to the corrected behavior in the same commit.
    - within() async error (lib/effects.js): the catch now calls finishHelpers()
      (so helpers' _withinEnd runs on error, not just success) and returns
      recorder.promise() (so the error propagates through within() instead of being
      detached onto a trailing task that a caller awaiting within() never sees).
    - session() async error (lib/session.js): schedules a recorder task that runs
      recorder.session.restore so the recorder session is restored on error (it
      was only restored on success, leaking the session id). The existing
      restoreVars/listener cleanup is kept as-is — switching to finalize()'s real
      restoreVars() closes the browser context under BROWSER_RESTART=session.
    - session() sync error (lib/session.js): the finally recorder.catch now calls
      recorder.session.restore before re-throwing (the only place that runs on a
      rejected chain).
    - retryTo() (lib/effects.js): a thrown callback no longer reject()s the outer
      promise prematurely — it routes through recorder.throw so the retry logic
      owns the outcome (retry, or reject once maxTries is exhausted). A callback
      that throws then succeeds on a later attempt now resolves instead of
      rejecting. tries now starts at 1 on the first attempt (was 2); the retry
      count is preserved (tries < maxTries).
    Verified: unit 748/0, runner 273/0 (incl. all retryFailedStep/rerun tests),
    acceptance within/session/els green under both BROWSER_RESTART=browser and
    =session.
    Not changed here (would be unsafe or out of scope, see PR):
    recorder.retries clearing (retryFailedStep depends on it), the stopped-recorder
    no-op contract, and nested cross-level restore ordering.
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    (cherry picked from commit  dca7626 )
    ---------
    Co-authored-by: DavertMik <davert@testomat.io>
    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>

    3 people authored

    Jun 14, 2026
    Configuration menu

    Browse the repository at this point in the history

Commits on Jun 15, 2026

  1. Configuration menu

    Browse the repository at this point in the history

Commits on Jun 17, 2026

  1. fix(typescript): unique temp file names to fix run-multiple race (#5642

    …) (#5643)
    Transpiled TypeScript files were written to a fixed "<source>.temp.mjs"
    path next to the source. Under run-multiple, every forked worker transpiles
    the same files to the same temp paths and cleans them up independently, so
    one worker's cleanup deletes files the others still need to import — surfacing
    as "Cannot find module *.temp.mjs".
    Include process.pid plus a random suffix in the temp file name so each worker
    writes (and removes) its own files. The names still end in ".temp.mjs", so
    stack-trace remapping and fixErrorStack keep working.
    Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
    Configuration menu

    Browse the repository at this point in the history

Read the original on github.com ↗