Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eighty-bananas-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@clerk/clerk-js': patch
---

Display free trial badge `<PricingTable/>`.
2 changes: 1 addition & 1 deletion integration/tests/pricing-table.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ testAgainstRunningApps({ withEnv: [appConfigs.envs.withBilling] })('pricing tabl

// Verify the user is now shown as having an active free trial
// The pricing table should show their current plan as active
await u.po.pricingTable.waitToBeActive({ planSlug: 'trial' });
await u.po.pricingTable.waitToBeFreeTrial({ planSlug: 'trial' });

await u.po.page.goToRelative('/user');
await u.po.userProfile.waitForMounted();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,11 @@ function Card(props: CardProps) {
isCompact={isCompact}
planPeriod={planPeriod}
setPlanPeriod={setPlanPeriod}
badge={showStatusRow ? <SubscriptionBadge subscription={subscription} /> : undefined}
badge={
showStatusRow ? (
<SubscriptionBadge subscription={subscription.isFreeTrial ? { status: 'free_trial' } : subscription} />
) : undefined
}
/>
<Box
elementDescriptor={descriptors.pricingTableCardBody}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ export const createPricingTablePageObject = (testArgs: { page: EnhancedPage }) =
waitToBeActive: async ({ planSlug }: { planSlug: string }) => {
return locators.badge(planSlug).getByText('Active').waitFor({ state: 'visible' });
},
waitToBeFreeTrial: async ({ planSlug }: { planSlug: string }) => {
return locators.badge(planSlug).getByText('Free trial').waitFor({ state: 'visible' });
},
Comment on lines +62 to +64
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Harden locator and add explicit return type per TS guidelines

Use case-insensitive match and declare an explicit return type to satisfy our **/*.ts,tsx rules for public APIs.

Apply this diff:

-    waitToBeFreeTrial: async ({ planSlug }: { planSlug: string }) => {
-      return locators.badge(planSlug).getByText('Free trial').waitFor({ state: 'visible' });
+    waitToBeFreeTrial: async ({ planSlug }: { planSlug: string }): Promise<void> => {
+      return locators.badge(planSlug).getByText(/free trial/i).waitFor({ state: 'visible' });
     },

Optionally add JSDoc above the method for public API clarity:

/**
 * Waits for the "Free trial" badge to be visible for the given plan.
 * Useful after starting a trial to assert the PricingTable reflects trial state.
 */
🤖 Prompt for AI Agents
In packages/testing/src/playwright/unstable/page-objects/pricingTable.ts around
lines 62-64, the waitToBeFreeTrial locator should be made case-insensitive and
the function must declare an explicit TypeScript return type; change the matcher
to a case-insensitive regex (e.g. getByText(/free trial/i)) and update the
signature to include the return type Promise<void> (async ({ planSlug }: {
planSlug: string }): Promise<void>), and optionally add the provided JSDoc above
the method for public API clarity.

getPlanCardCTA: ({ planSlug }: { planSlug: string }) => {
return locators.footer(planSlug).getByRole('button', {
name: /get|switch|subscribe/i,
Expand Down
Loading