Skip to content

Conversation

kettanaito
Copy link
Member

@kettanaito kettanaito commented Aug 25, 2025

I'm adding a new Playwright fixture called navigate(). The purpose of this fixture is to provide type-safe navigation experience in tests by inferring the available page URLs from react-router's codegen. This means less mechanical mistakes when testing your app.

Test Plan

Verified by updating the existing E2E test suite and seeing it passing.

Checklist

  • Tests updated
  • Docs updated

Screenshots

Screenshot 2025-08-25 at 10 58 18

Brainstorming

Why not override the default page.goto()?

TL;DR navigate() is a higher-level abstraction over page.goto(), not its replacement.

  1. To allow visiting external websites.
  2. Because page.goto() has a different call signature (i.e. custom options argument).

How to ensure navigate() usage over page.goto()?

You don't. As I mentioned above, the two are not equivalent and aren't meant to be used interchangeably. Our job is to show the best practices of type-safe navigation in tests, then it's the developer's job to adhere to them.

How to navigate to a dynamically generated URL?

Throughout the test suite, there are cases when the navigation target is created dynamically, e.g. extracted from the "Forgot password" email text. In those cases, the best course of action is to type cast the extracted URL to be of the most permissive type:

import { type AppPages } from '#tests/playwright-utils.ts'
const resetPasswordUrl = extractUrl(email.text) as AppPages
await navigate(resetPasswordUrl)

By doing this, you are saying "I expect this dynamic URL to be one of my app's URLs", which is an even more type-safe way to approach such URLs in tests.

How to provide page.goto() options, like waitUntil?

Ideally, don't. navigate() is an opinionated wrapper that provisions the same navigation behavior. Keep in mind that some options, like waitUntil, are being deprecated by Playwright themselves in favor of more deterministic state await mechanisms (i.e. don't wait until network is idle, add an assertion over what UI state to expect).

We can expand the navigate() utility in the future if there's a need to pass other navigation options. For now, I believe it works sufficiently.

Copy link
Member

@kentcdodds kentcdodds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's really handy. Thanks!

@kentcdodds kentcdodds merged commit 2eb613f into main Aug 25, 2025
6 checks passed
@kentcdodds kentcdodds deleted the test/type-safe-navigation branch August 25, 2025 17:49
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.

2 participants