Skip to content

Move disableForTesting to NavigationGuardProvider; add mockConfirm#60

Open
ypresto wants to merge 4 commits into
mainfrom
feat/disable-for-testing-on-provider
Open

Move disableForTesting to NavigationGuardProvider; add mockConfirm#60
ypresto wants to merge 4 commits into
mainfrom
feat/disable-for-testing-on-provider

Conversation

@ypresto
Copy link
Copy Markdown
Member

@ypresto ypresto commented Apr 28, 2026

Summary

Reshapes disableForTesting (introduced but never released as 0.3.0) from a per-hook boolean option into a NavigationGuardProvider prop with a richer contract.

disableForTesting is now boolean | { mockConfirm }:

  • true — library skips its host-environment hooks (no popstate / beforeunload / capture-phase click listeners, no window.history augmentation, no Next.js 15.3+ link-click interceptor). The App Router / Pages Router context overrides remain in place, so navigation through Next.js routers (incl. mock routers in tests) still evaluates registered guards with the user's real confirm.
  • { mockConfirm } — same as above, plus replaces every registered guard's confirm during evaluation. Per-guard enabled predicates still run. Useful for asserting on navigation attempts in tests without rendering the confirmation UI.

The hook-side disableForTesting option (committed as part of the unshipped 0.3.0 in e65773a) is removed; useNavigationGuard once again throws if there is no provider.

Also extracts a shared evaluateGuards util used by useInterceptedAppRouter, useInterceptedPagesRouter, and useInterceptPopState.

Release prep folded in

Since 0.3.0 was bumped in package.json / CHANGELOG but never tagged or published to npm, this PR also tidies up the 0.3.0 release notes:

Test plan

  • pnpm run build (tsc) — clean
  • pnpm run check:packaging — all four resolution modes 🟢
  • pnpm e2e against the matrix — please run in CI (this branch does not yet add automated tests for the mockConfirm shape; manual sanity check recommended in App Router and Pages Router examples)
  • Verify a downstream test using disableForTesting (boolean) renders without touching window.history
  • Verify disableForTesting={{ mockConfirm }} causes navigation through a mocked Next.js router to call mockConfirm with the right params

🤖 Generated with Claude Code

ypresto and others added 4 commits April 28, 2026 15:55
Refactor: disableForTesting becomes a boolean prop on the provider; when
set, the library installs none of its host-environment hooks (popstate,
beforeunload, capture-phase click, history augmentation, App/Pages
Router context overrides). useNavigationGuard keeps registering as
usual, so enabled / confirm / active / accept / reject continue to work
for component-level tests and storybook. Hook-side disableForTesting
option is removed.

Extract evaluateGuards util shared by router and popstate intercepts.

Release prep: bump next devDep to ^14.2.35, redate 0.3.0 to 2026-04-28,
add Fixed entries for #48 (null history.state) and #38 (import types),
record v16.2 CI addition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
disableForTesting now accepts boolean | { mockConfirm }. The router
context overrides stay on in both forms so navigation through Next.js
routers (incl. mock routers in tests) keeps evaluating guards. When
mockConfirm is provided, every registered guard's confirm is replaced
during evaluation; per-guard enabled predicates still run, so tests can
assert on navigation attempts without rendering the confirmation UI.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Match the wording the original useInterceptedAppRouter loop emitted so
DEBUG output stays byte-identical for that interceptor:
- Calling guard callback for ${type} to ${to}
- Guard callback returned: ${confirm}
- All guards passed, proceeding with navigation

Pages Router intercept now emits these (was silent before) and popstate
loses its per-guard "listener index N" line — both intentional drift
from centralizing the loop.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Popstate's old per-guard log included the listener index; centralizing
the loop dropped it. Append "(listener index N)" to the per-guard log
across all interceptors so popstate keeps that hint and App Router /
Pages Router pick it up too.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant