-
Notifications
You must be signed in to change notification settings - Fork 437
Description
Preliminary Checks
- I have reviewed the documentation: https://clerk.com/docs
- I have searched for existing issues: https://github.com/clerk/javascript/issues
- I have not already reached out to Clerk support via email or Discord (if you have, no need to open an issue here)
- This issue is not a question, general help request, or anything other than a bug report directly related to Clerk. Please ask questions in our Discord community: https://clerk.com/discord.
Reproduction
Minimal Reproduction Repository: N/A (general compatibility issue)
A minimal reproduction can be created by:
- Creating a new React app (e.g., Vite + React + TypeScript)
- Installing
@clerk/reactand@clerk/testing/playwright - Setting up ClerkProvider in the app
- Attempting to use
clerk.loaded({ page })in a Playwright test
Publishable Key: pk_test_placeholder (for issue reporting purposes)
Description
Steps to reproduce
- Install
@clerk/reactand@clerk/testing/playwrightin a React project - Set up Playwright with
@clerk/testing/playwrightaccording to the documentation at https://clerk.com/docs/testing/playwright - Attempt to use
clerk.loaded({ page })from@clerk/testing/playwrightin a Playwright test - Observe that the function times out because
window.Clerkis never defined
Expected behavior
clerk.loaded({ page }) should detect when Clerk is ready, regardless of whether the app uses @clerk/clerk-js (vanilla) or @clerk/react (React SDK).
Actual behavior
clerk.loaded() relies on checking for window.Clerk:
// From @clerk/testing/dist/playwright/index.js (line ~137)
var C = async ({page:e}) => {
await e.waitForFunction(() => window.Clerk !== void 0),
await e.waitForFunction(() => window.Clerk.loaded)
}Technical Details:
@clerk/reactloads Clerk JS dynamically from Clerk's CDN vialoadClerkJSScript()from@clerk/shared- While
window.Clerkeventually gets created asynchronously when Clerk JS loads, there is no guarantee it will be available at test runtime whenclerk.loaded()checks for it @clerk/reactdoes not exposewindow.Clerkin the same synchronous, reliable way as the vanilla@clerk/clerk-jsSDK- Instead,
@clerk/reactuses React Context internally viauseClerk()hook
This makes @clerk/testing/playwright completely incompatible with @clerk/react, which is one of the most popular ways to integrate Clerk in modern web applications.
Impact
- Cannot use
clerk.loaded()to wait for Clerk readiness in React apps - Cannot use
clerk.signIn()for automated testing (relies onwindow.Clerk.client.signIn.create()andwindow.Clerk.setActive()) - Cannot use
clerk.signOut()for automated testing (relies onwindow.Clerk.signOut()) - Users must write custom solutions to detect Clerk loading state in React apps
- No documentation warning about this limitation in the testing docs
Suggested Fix
- Option A: Add React-specific testing utilities to
@clerk/testingthat detect Clerk loading via alternative signals (e.g., React-rendered elements,window.__CLERK_JS__) - Option B: Document prominently that
@clerk/testingonly works with@clerk/clerk-jsand is incompatible with framework SDKs like@clerk/react,@clerk/nextjs, etc. - Option C: Add a method in
@clerk/testingthat polls forwindow.Clerkwith retry logic to handle async loading in framework SDKs
Environment
npmPackages:
@clerk/react: ^6.x (tested with 6.1.0)
@clerk/testing: ^2.x (tested with 2.0.1)
@clerk/shared: ^4.x
@playwright/test: ^1.x
react: ^18.x
vite: ^5.x
Additional Context
This issue was discovered while implementing E2E tests for a React application using @clerk/react. The testing documentation at https://clerk.com/docs/testing/playwright does not mention any limitations regarding framework SDKs.
Related existing issue: #7891 (signIn() times out with concurrent Playwright workers) - different but related to testing reliability.