1- import type { Page } from '@playwright/test' ;
1+ import type { BrowserContext , Page } from '@playwright/test' ;
2+ import { expect } from '@playwright/test' ;
3+
4+ import type { Application } from '../models/application' ;
5+ import { createTestUtils } from './index' ;
26
37/**
48 * Mocks the environment API call to return a claimed instance.
@@ -18,3 +22,127 @@ export const mockClaimedInstanceEnvironmentCall = async (page: Page): Promise<vo
1822 await route . fulfill ( { response, json : newJson } ) ;
1923 } ) ;
2024} ;
25+
26+ /**
27+ * Tests that the keyless popover can be toggled and the claim link opens the dashboard.
28+ */
29+ export async function testToggleCollapsePopoverAndClaim ( {
30+ page,
31+ context,
32+ app,
33+ dashboardUrl,
34+ framework,
35+ } : {
36+ page : Page ;
37+ context : BrowserContext ;
38+ app : Application ;
39+ dashboardUrl : string ;
40+ framework : string ;
41+ } ) : Promise < void > {
42+ const u = createTestUtils ( { app, page, context } ) ;
43+ await u . page . goToAppHome ( ) ;
44+ await u . page . waitForClerkJsLoaded ( ) ;
45+ await u . po . expect . toBeSignedOut ( ) ;
46+
47+ await u . po . keylessPopover . waitForMounted ( ) ;
48+
49+ expect ( await u . po . keylessPopover . isExpanded ( ) ) . toBe ( false ) ;
50+ await u . po . keylessPopover . toggle ( ) ;
51+ expect ( await u . po . keylessPopover . isExpanded ( ) ) . toBe ( true ) ;
52+
53+ const claim = u . po . keylessPopover . promptsToClaim ( ) ;
54+
55+ const [ newPage ] = await Promise . all ( [ context . waitForEvent ( 'page' ) , claim . click ( ) ] ) ;
56+
57+ await newPage . waitForLoadState ( ) ;
58+
59+ await newPage . waitForURL ( url => {
60+ const signInForceRedirectUrl = url . searchParams . get ( 'sign_in_force_redirect_url' ) ;
61+ const signUpForceRedirectUrl = url . searchParams . get ( 'sign_up_force_redirect_url' ) ;
62+
63+ const signInHasRequiredParams =
64+ signInForceRedirectUrl ?. includes ( `${ dashboardUrl } apps/claim` ) &&
65+ signInForceRedirectUrl ?. includes ( 'token=' ) &&
66+ signInForceRedirectUrl ?. includes ( `framework=${ framework } ` ) ;
67+
68+ const signUpRegularCase =
69+ signUpForceRedirectUrl ?. includes ( `${ dashboardUrl } apps/claim` ) &&
70+ signUpForceRedirectUrl ?. includes ( 'token=' ) &&
71+ signUpForceRedirectUrl ?. includes ( `framework=${ framework } ` ) ;
72+
73+ const signUpPrepareAccountCase =
74+ signUpForceRedirectUrl ?. startsWith ( `${ dashboardUrl } prepare-account` ) &&
75+ signUpForceRedirectUrl ?. includes ( encodeURIComponent ( 'apps/claim' ) ) &&
76+ signUpForceRedirectUrl ?. includes ( encodeURIComponent ( 'token=' ) ) &&
77+ signUpForceRedirectUrl ?. includes ( encodeURIComponent ( `framework=${ framework } ` ) ) ;
78+
79+ const signUpHasRequiredParams = signUpRegularCase || signUpPrepareAccountCase ;
80+
81+ return url . pathname === '/apps/claim/sign-in' && signInHasRequiredParams && signUpHasRequiredParams ;
82+ } ) ;
83+ }
84+
85+ /**
86+ * Tests that a claimed application with missing explicit keys shows the popover expanded
87+ * with a prompt to get keys from the dashboard.
88+ */
89+ export async function testClaimedAppWithMissingKeys ( {
90+ page,
91+ context,
92+ app,
93+ dashboardUrl,
94+ } : {
95+ page : Page ;
96+ context : BrowserContext ;
97+ app : Application ;
98+ dashboardUrl : string ;
99+ } ) : Promise < void > {
100+ await mockClaimedInstanceEnvironmentCall ( page ) ;
101+ const u = createTestUtils ( { app, page, context } ) ;
102+ await u . page . goToAppHome ( ) ;
103+ await u . page . waitForClerkJsLoaded ( ) ;
104+
105+ await u . po . keylessPopover . waitForMounted ( ) ;
106+ expect ( await u . po . keylessPopover . isExpanded ( ) ) . toBe ( true ) ;
107+ await expect ( u . po . keylessPopover . promptToUseClaimedKeys ( ) ) . toBeVisible ( ) ;
108+
109+ const [ newPage ] = await Promise . all ( [
110+ context . waitForEvent ( 'page' ) ,
111+ u . po . keylessPopover . promptToUseClaimedKeys ( ) . click ( ) ,
112+ ] ) ;
113+
114+ await newPage . waitForLoadState ( ) ;
115+ await newPage . waitForURL ( url => {
116+ return url . href . startsWith ( `${ dashboardUrl } sign-in?redirect_url=${ encodeURIComponent ( dashboardUrl ) } apps%2Fapp_` ) ;
117+ } ) ;
118+ }
119+
120+ /**
121+ * Tests that the keyless popover is removed after adding keys to .env and restarting the dev server.
122+ */
123+ export async function testKeylessRemovedAfterEnvAndRestart ( {
124+ page,
125+ context,
126+ app,
127+ } : {
128+ page : Page ;
129+ context : BrowserContext ;
130+ app : Application ;
131+ } ) : Promise < void > {
132+ const u = createTestUtils ( { app, page, context } ) ;
133+ await u . page . goToAppHome ( ) ;
134+
135+ await u . po . keylessPopover . waitForMounted ( ) ;
136+ expect ( await u . po . keylessPopover . isExpanded ( ) ) . toBe ( false ) ;
137+
138+ // Copy keys from keyless.json to .env
139+ await app . keylessToEnv ( ) ;
140+
141+ // Restart the dev server to pick up new env vars (Vite doesn't hot-reload .env)
142+ await app . restart ( ) ;
143+
144+ await u . page . goToAppHome ( ) ;
145+
146+ // Keyless popover should no longer be present since we now have explicit keys
147+ await u . po . keylessPopover . waitForUnmounted ( ) ;
148+ }
0 commit comments