Skip to content

feat(billing): add credits sheet to unlock gated LLM template#3240

Merged
ygrishajev merged 1 commit into
mainfrom
feat/add-credits-sheet
Jun 1, 2026
Merged

feat(billing): add credits sheet to unlock gated LLM template#3240
ygrishajev merged 1 commit into
mainfrom
feat/add-credits-sheet

Conversation

@ygrishajev
Copy link
Copy Markdown
Contributor

@ygrishajev ygrishajev commented May 29, 2026

Closes CON-366

Why

Onboarding gates the LLM template behind a credits purchase. This PR adds the Add Credits sheet (amount selection + Stripe payment method) and wires it into the onboarding picker so the gated CTA prompts the user to top up before they can deploy.

What

  • New AddCreditsSheet with AddCreditsForm (amount + new payment method fields) under apps/deploy-web/src/components/auth/AddCreditsSheet/.
  • AddCreditsForm is built as an orchestrator/container: it owns the purchase lifecycle (setup intent, payment-method confirmation, wallet-ready wait, 3D Secure handoff, payment polling) and delegates the visible pieces to swappable children (AddCreditsAmountFields, AddCreditsNewPaymentMethodFields) via the dependencies prop. As the new flow spreads, the same form can opt into additional sections — a saved-payment-method picker, coupon code input, transaction summary, alternative amount widgets — without reworking the orchestration layer.
  • Onboarding picker LLM template CTA flips between "Unlock full trial to deploy" → opens the sheet, and "Deploy now" once the trial is active.
  • useEnsureTrialStarted adjusted to feed the gated state.
  • Shared sheet + field primitives added to packages/ui/components.
  • Playwright spec onboarding-picker-unlock-trial.spec.ts covers passwordless sign-in → gated CTA → $100 purchase → trial flips → CTA unlocks, plus a Page Object for the sheet.
Screen.Recording.2026-05-29.at.10.11.18.1080.mov

Summary by CodeRabbit

  • New Features

    • In-app Add Credits flow: sheet modal, amount selection (predefined/custom), billing & payment collection, 3D Secure handling, and new form primitives (fields & sheet components)
    • Onboarding: LLM Chatbot template gated by trial/credits; CTA and recommended marker updates
  • Bug Fixes / UX

    • Prevent closing Add Credits sheet while payment is processing; hide close control and show processing/error states
  • Tests

    • Expanded unit and Playwright e2e tests for purchase/payment flows and gated onboarding interactions

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 29, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Sheet/Field UI primitives, a Stripe-backed Add Credits flow (amount selection, payment-method collection, 3DS/polling orchestration), onboarding LLM gating by wallet/trial state, a wallet refresh hook, unit tests, and Playwright E2E/page objects.

Changes

UI Primitives: Sheet and Field Components

Layer / File(s) Summary
Sheet component library
packages/ui/components/sheet.tsx
Radix Dialog-based sheet primitives with side positioning, overlay animations, content wrapper, optional hideCloseButton, and header/footer/title/description subcomponents.
Field form component library
packages/ui/components/field.tsx
Composable field primitives (set, group, legend, label, title, description, separator, error) with orientation/variant styling and aggregated error rendering.
Component library exports
packages/ui/components/index.tsx
Re-exports new field and sheet modules from the UI components barrel.

Payment Flow Components

Layer / File(s) Summary
Credit amount selection
apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/*
Controlled amount selector with predefined radio options (50/100/500) and a custom numeric input (min={20}), switching modes and emitting a normalized value.
Stripe payment method collection
apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/*
Stripe Elements wrapper (AddressElement + PaymentElement tabs) exposing imperative addPaymentMethod() that confirms a SetupIntent and returns `{ paymentMethodId, organization }
Payment orchestration form
apps/deploy-web/src/components/billing-usage/AddCreditsForm/*
Orchestrates setup intent creation, submit via child ref, pending/charging lifecycle, wallet-readiness gating, confirmPayment + 3DS handling, polling, failure finalization, onDone callback, and reporting processing state to parent; includes extensive unit tests.

Sheet Container and Onboarding Integration

Layer / File(s) Summary
Add credits sheet container
apps/deploy-web/src/components/auth/AddCreditsSheet/*
Right-side sheet that conditionally renders AddCreditsForm, tracks isProcessing to block closing and hide close button during processing, and forwards onDone/isWalletReady.
Onboarding picker LLM gating
apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
Adds AddCreditsSheet and useWallet dependencies, computes isLlmAvailable from wallet/trial state, changes LLM CTA behavior to open sheet when gated, and wires sheet onOpen/onDone.
Wallet refresh in trial hook
apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
Returns refreshWallet (useManagedWallet.refetch) so callers can refresh wallet state after trial/payment events.

Testing & Test Utilities

Layer / File(s) Summary
Component unit tests
apps/deploy-web/src/components/*/*.spec.tsx
Vitest suites for amount selection, payment-method ref behavior and errors, AddCreditsForm flows (setup intent, confirm, 3DS, polling, processing), and AddCreditsSheet closing gating.
Playwright page objects
apps/deploy-web/tests/ui/pages/*
AddCreditsSheetPage helper to interact with dialog, select amounts, fill Stripe frames, and submit; OnboardingPickerPage extended with LLM card/CTA helpers.
End-to-end UI test
apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts
E2E test that purchases credits to unlock the gated LLM template, verifies processing UI/snackbar, waits for trial flip and sheet close, and confirms CTA updates to "Deploy now".
Playwright config
apps/deploy-web/playwright.config.ts
Conditional video and slowMo driven by PW_SLOW_MO env var.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

Suggested reviewers

  • baktun14
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-credits-sheet

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 29, 2026

Codecov Report

❌ Patch coverage is 96.89441% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.64%. Comparing base (ef633f7) to head (a8e79c7).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...ts/billing-usage/AddCreditsForm/AddCreditsForm.tsx 95.29% 4 Missing ⚠️
...tMethodFields/AddCreditsNewPaymentMethodFields.tsx 97.87% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3240      +/-   ##
==========================================
- Coverage   66.68%   65.64%   -1.05%     
==========================================
  Files        1065      985      -80     
  Lines       26123    24224    -1899     
  Branches     6292     5921     -371     
==========================================
- Hits        17421    15901    -1520     
+ Misses       7609     7257     -352     
+ Partials     1093     1066      -27     
Flag Coverage Δ *Carryforward flag
api 84.67% <ø> (ø) Carriedforward from ef633f7
deploy-web 51.07% <96.89%> (+0.52%) ⬆️
log-collector ?
notifications 90.99% <ø> (ø) Carriedforward from ef633f7
provider-console 81.38% <ø> (ø)
provider-inventory ?
provider-proxy 86.08% <ø> (ø) Carriedforward from ef633f7
tx-signer ?

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...omponents/auth/AddCreditsSheet/AddCreditsSheet.tsx 100.00% <100.00%> (ø)
.../AddCreditsAmountFields/AddCreditsAmountFields.tsx 100.00% <100.00%> (ø)
...ponents/onboarding-picker/OnboardingPickerPage.tsx 100.00% <100.00%> (ø)
apps/deploy-web/src/hooks/useEnsureTrialStarted.ts 100.00% <100.00%> (ø)
...tMethodFields/AddCreditsNewPaymentMethodFields.tsx 97.87% <97.87%> (ø)
...ts/billing-usage/AddCreditsForm/AddCreditsForm.tsx 95.29% <95.29%> (ø)

... and 88 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (3)
apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts (2)

65-81: 💤 Low value

Fragile iframe selection using parent traversal.

Both getAddressFrame and getCardFrame use .locator("..") to traverse up from a heading and then select .first() iframe. If the DOM structure changes (e.g., wrapper divs added) or multiple iframes exist in the parent, these selectors will break.

♻️ More robust iframe selection

Consider using test IDs or more specific selectors that don't rely on DOM structure:

private getAddressFrame(): FrameLocator {
  // Option 1: Use iframe title/name if Stripe provides it
  return this.page.frameLocator('iframe[title*="billing"]').first().contentFrame();
  
  // Option 2: Use a more specific ancestor selector
  return this.page
    .locator('[data-testid="billing-address-section"]') // if you can add test IDs
    .locator('iframe')
    .first()
    .contentFrame();
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts` around lines 65 - 81,
getAddressFrame and getCardFrame are fragile because they use .locator("..") and
.first() which break if DOM wrappers or multiple iframes are added; instead
select the iframe more robustly by targeting an intrinsic iframe attribute or a
dedicated test hook: update getAddressFrame and getCardFrame to use
frameLocator('iframe[title*="billing"]') /
frameLocator('iframe[title*="payment"]') or to locate a specific ancestor with a
stable data attribute (e.g., '[data-testid="billing-address-section"]' or
'[data-testid="payment-method-section"]') and then select its iframe, and if
necessary add those data-testid attributes in the component markup so the tests
can reliably find the correct iframe without parent traversal.

25-25: 💤 Low value

Hardcoded country limits address test coverage.

The method accepts name, line1, city, state, zip from the caller but always selects "United States". If you later need to test international billing addresses, you'll have to modify this method.

🌍 Optional: parameterize country selection
-async fillStripeAddress(input: { name: string; line1: string; city: string; state: string; zip: string }) {
+async fillStripeAddress(input: { name: string; country?: string; line1: string; city: string; state: string; zip: string }) {
   const addressFrame = this.getAddressFrame();
   
   const nameInput = addressFrame.getByLabel("Full name");
   await nameInput.click();
   await nameInput.pressSequentially(input.name);
   
-  await addressFrame.getByLabel("Country or region").selectOption("United States");
+  await addressFrame.getByLabel("Country or region").selectOption(input.country ?? "United States");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts` at line 25, The
address selection is hardcoded to "United States" in AddCreditsSheetPage; update
the method that fills the address (the method accepting name, line1, city,
state, zip in AddCreditsSheetPage) to accept an optional country parameter
(defaulting to "United States") and replace the hardcoded
addressFrame.getByLabel("Country or region").selectOption("United States") with
selectOption(country). Propagate the new parameter to callers/tests that need
non-US addresses and leave callers that don't pass it unaffected by the default.
apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts (1)

32-32: 💤 Low value

Loose button selectors risk selecting the wrong element.

Line 32 filters the card by "has any button" without specifying which button, and line 37 retrieves "any button" from the card. If the LLM card gains additional buttons (info, menu, etc.) in the future, these selectors could return the wrong container or button.

🎯 More specific button selection
 getLlmChatbotCard(): Locator {
   const heading = this.page.getByRole("heading", { name: "LLM Chatbot", exact: true });
   return this.page
     .locator("div")
     .filter({ has: heading })
-    .filter({ has: this.page.getByRole("button") })
+    .filter({ has: this.page.getByRole("button", { name: /deploy|unlock/i }) })
     .last();
 }

 getLlmChatbotCta(): Locator {
-  return this.getLlmChatbotCard().getByRole("button");
+  return this.getLlmChatbotCard().getByRole("button", { name: /deploy|unlock/i });
 }

Also applies to: 37-37

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts` at line 32, The
current selector in OnboardingPickerPage uses a broad filter and retrieval via
filter({ has: this.page.getByRole("button") }) and later
this.page.getByRole("button"), which is fragile if cards gain extra buttons;
narrow the selectors to target the exact button (e.g., use getByRole("button", {
name: /choose|select|LLM name/i }) or a data-testid/aria-label) and update both
the filter call and the subsequent getByRole call to use the specific accessible
name or test id so you reliably select the intended card and button.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx`:
- Line 89: The form currently only checks amount <= 0 (e.g., in
AddCreditsForm.tsx at the early guard) but the UI indicates a minimum of 20;
update all validation points (the initial guard where it checks user?.id and
amount, the submit handler(s) around lines ~166 and ~222) to enforce amount >=
20 (i.e., reject if amount < 20), return early to prevent charging, and surface
a clear validation error message (e.g., "Minimum 20 credits") via the same error
state/handler the component uses so the user sees why submission was blocked.

In `@apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx`:
- Around line 133-135: The CTA label gating uses "isTrialing || !isWalletReady"
but the CTA icon only checks "isTrialing", causing a mismatch when wallet is not
ready; update the ctaIcon prop in OnboardingPickerPage (the JSX that sets
ctaLabel and ctaIcon) to use the same condition (isTrialing || !isWalletReady)
so the icon (lock vs arrow) matches the label state.

In `@apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts`:
- Around line 23-24: Update the test step description so it matches the amount
being selected: change the test.step string that currently reads "submit a $50
credit purchase with a test card" to reflect "$100" (or alternatively change
addCreditsSheet.pickPredefinedAmount("100") to "50" if you intended $50); ensure
the human-readable step text and the call to
addCreditsSheet.pickPredefinedAmount(...) are consistent.

In `@packages/ui/components/field.tsx`:
- Around line 146-155: The rendered error block currently returns an empty <ul>
when errors exists but none have a truthy message; update the logic in the
component (around the filtered variable and the errors handling in
Field/component) to check if filtered.length === 0 and return null instead of
rendering the <ul>, keeping the existing early-return for filtered.length === 1
and the mapped <li> path unchanged.

---

Nitpick comments:
In `@apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts`:
- Around line 65-81: getAddressFrame and getCardFrame are fragile because they
use .locator("..") and .first() which break if DOM wrappers or multiple iframes
are added; instead select the iframe more robustly by targeting an intrinsic
iframe attribute or a dedicated test hook: update getAddressFrame and
getCardFrame to use frameLocator('iframe[title*="billing"]') /
frameLocator('iframe[title*="payment"]') or to locate a specific ancestor with a
stable data attribute (e.g., '[data-testid="billing-address-section"]' or
'[data-testid="payment-method-section"]') and then select its iframe, and if
necessary add those data-testid attributes in the component markup so the tests
can reliably find the correct iframe without parent traversal.
- Line 25: The address selection is hardcoded to "United States" in
AddCreditsSheetPage; update the method that fills the address (the method
accepting name, line1, city, state, zip in AddCreditsSheetPage) to accept an
optional country parameter (defaulting to "United States") and replace the
hardcoded addressFrame.getByLabel("Country or region").selectOption("United
States") with selectOption(country). Propagate the new parameter to
callers/tests that need non-US addresses and leave callers that don't pass it
unaffected by the default.

In `@apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts`:
- Line 32: The current selector in OnboardingPickerPage uses a broad filter and
retrieval via filter({ has: this.page.getByRole("button") }) and later
this.page.getByRole("button"), which is fragile if cards gain extra buttons;
narrow the selectors to target the exact button (e.g., use getByRole("button", {
name: /choose|select|LLM name/i }) or a data-testid/aria-label) and update both
the filter call and the subsequent getByRole call to use the specific accessible
name or test id so you reliably select the intended card and button.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9f4077eb-18f5-4d13-8e33-8221b7440c70

📥 Commits

Reviewing files that changed from the base of the PR and between ef633f7 and a3d46a0.

📒 Files selected for processing (17)
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsx
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
  • apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts
  • apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts
  • apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts
  • packages/ui/components/field.tsx
  • packages/ui/components/index.tsx
  • packages/ui/components/sheet.tsx

Comment thread apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx Outdated
Comment thread apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx Outdated
Comment thread apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts Outdated
Comment thread packages/ui/components/field.tsx
@ygrishajev ygrishajev force-pushed the feat/add-credits-sheet branch from a3d46a0 to c08d1e7 Compare May 29, 2026 08:36
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/deploy-web/playwright.config.ts`:
- Around line 30-33: Parse process.env.PW_SLOW_MO once to a numeric value and
use that numeric check for both the video setting and launchOptions.slowMo:
replace the current string-truthy check in the video property with a numeric
comparison (use slowMo > 0 ? "on" : "retain-on-failure") and set
launchOptions.slowMo to the parsed numeric slowMo value (instead of Number(...)
|| 0 inline) so PW_SLOW_MO="0" behaves correctly; apply these changes where the
video and launchOptions objects are defined.

In
`@apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx`:
- Around line 322-323: Replace the unsafe double-casts by providing proper typed
mocks: change the assignment for makePaymentMethodFieldsMock (currently set to
Mock as unknown as typeof DEPENDENCIES.AddCreditsNewPaymentMethodFields) to use
a typed mock helper or explicit typed object matching typeof
DEPENDENCIES.AddCreditsNewPaymentMethodFields (e.g., mock<typeof
DEPENDENCIES.AddCreditsNewPaymentMethodFields>(...)), and similarly replace the
(...) as unknown as ReturnType<typeof DEPENDENCIES.useSetupIntentMutation>
occurrences in buildElement / useSetupIntentMutation with a properly typed mock
or variable typed as ReturnType<typeof DEPENDENCIES.useSetupIntentMutation>,
ensuring the mock implementations conform to the real types instead of
double-casting.

In `@apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts`:
- Around line 41-43: The test step label claims an ordered snackbar sequence but
only asserts the final text; update the test.step block in
onboarding-picker-unlock-trial.spec.ts to either (A) assert the intermediate
states in sequence by using page.getByText("Processing…") and
page.getByText("Successful") with expects that wait for visibility then assert
they become hidden before the next appears (use toBeVisible and then
toBeHidden/timeouts to enforce order), or (B) if you only want to validate the
final state, rename the test.step description to "snackbar finishes with welcome
message" and keep the existing expect(page.getByText("Welcome to Akash!")).
Ensure you modify the test.step containing test.step(...) and the
page.getByText(...) assertions accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ba7d5b8d-0265-4e78-b2c4-221ada992dec

📥 Commits

Reviewing files that changed from the base of the PR and between a3d46a0 and c08d1e7.

📒 Files selected for processing (18)
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsx
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
  • apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts
  • apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts
  • apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts
  • packages/ui/components/field.tsx
  • packages/ui/components/index.tsx
  • packages/ui/components/sheet.tsx
🚧 Files skipped from review as they are similar to previous changes (15)
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx
  • apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsx
  • packages/ui/components/sheet.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsx
  • apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx
  • apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • packages/ui/components/index.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.spec.tsx
  • packages/ui/components/field.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx

Comment thread apps/deploy-web/playwright.config.ts Outdated
Comment thread apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts
@ygrishajev ygrishajev force-pushed the feat/add-credits-sheet branch from c08d1e7 to a8e79c7 Compare May 29, 2026 09:10
@baktun14
Copy link
Copy Markdown
Contributor

Is there a way we can avoid the redirect to the home page in between the signup and the 3 templates select in the video?

Comment thread apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx Outdated
@ygrishajev ygrishajev force-pushed the feat/add-credits-sheet branch from a8e79c7 to 27389cc Compare June 1, 2026 09:56
…plate

Introduce an Add Credits sheet (amount selection + Stripe payment method collection)
and wire it into the onboarding picker so
the gated LLM template prompts for a purchase before deploying.
@ygrishajev ygrishajev force-pushed the feat/add-credits-sheet branch from 27389cc to 00adf4d Compare June 1, 2026 10:11
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts (1)

41-45: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Ordering is still not actually enforced, and the re-check of the processing toast is racy.

The step claims "processing → successful → welcome", but three back-to-back toBeVisible calls only assert each text becomes visible at some point within its timeout — they do not prove sequence. Worse, "Processing payment..." was already asserted at Line 37; if that transient snackbar auto-dismisses before Line 42 runs, this assertion can flake. Either drop the redundant L42 re-check, or assert each prior toast becomes hidden before the next appears to genuinely validate order.

📝 Suggested tightening
 await test.step("snackbars appear in order: processing → successful → welcome", async () => {
-  await expect(page.getByText("Processing payment...")).toBeVisible({ timeout: 30_000 });
   await expect(page.getByText("Payment successful!")).toBeVisible({ timeout: 30_000 });
+  await expect(page.getByText("Payment successful!")).toBeHidden({ timeout: 30_000 });
   await expect(page.getByText("Welcome to Akash!")).toBeVisible({ timeout: 30_000 });
 });

As per coding guidelines: "Verify meaningful assertions, not just snapshot coverage."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts` around lines
41 - 45, The step "snackbars appear in order: processing → successful → welcome"
currently only calls three back-to-back await
expect(page.getByText(...)).toBeVisible(...) checks which do not enforce
sequence and re-checks the already-asserted "Processing payment..."
(page.getByText("Processing payment...")) risk flakiness; update the test.step
so it either removes the redundant re-check for "Processing payment..." or, to
enforce ordering, wait for each prior toast to disappear before asserting the
next (use await expect(page.getByText("Processing payment...")).toBeHidden()
before checking "Payment successful!" and similarly await
expect(page.getByText("Payment successful!")).toBeHidden() before checking
"Welcome to Akash!"), keeping the visible checks for page.getByText("Payment
successful!") and page.getByText("Welcome to Akash!") as the sequence
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Duplicate comments:
In `@apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts`:
- Around line 41-45: The step "snackbars appear in order: processing →
successful → welcome" currently only calls three back-to-back await
expect(page.getByText(...)).toBeVisible(...) checks which do not enforce
sequence and re-checks the already-asserted "Processing payment..."
(page.getByText("Processing payment...")) risk flakiness; update the test.step
so it either removes the redundant re-check for "Processing payment..." or, to
enforce ordering, wait for each prior toast to disappear before asserting the
next (use await expect(page.getByText("Processing payment...")).toBeHidden()
before checking "Payment successful!" and similarly await
expect(page.getByText("Payment successful!")).toBeHidden() before checking
"Welcome to Akash!"), keeping the visible checks for page.getByText("Payment
successful!") and page.getByText("Welcome to Akash!") as the sequence
assertions.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 08c52f4a-c59e-465a-98c3-d2869e60bda1

📥 Commits

Reviewing files that changed from the base of the PR and between 27389cc and 00adf4d.

📒 Files selected for processing (18)
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsx
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
  • apps/deploy-web/tests/ui/onboarding-picker-unlock-trial.spec.ts
  • apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts
  • apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts
  • packages/ui/components/field.tsx
  • packages/ui/components/index.tsx
  • packages/ui/components/sheet.tsx
✅ Files skipped from review due to trivial changes (1)
  • packages/ui/components/index.tsx
🚧 Files skipped from review as they are similar to previous changes (16)
  • apps/deploy-web/playwright.config.ts
  • apps/deploy-web/tests/ui/pages/AddCreditsSheetPage.ts
  • apps/deploy-web/tests/ui/pages/OnboardingPickerPage.ts
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.spec.tsx
  • apps/deploy-web/src/hooks/useEnsureTrialStarted.ts
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsAmountFields/AddCreditsAmountFields.tsx
  • apps/deploy-web/src/components/auth/AddCreditsSheet/AddCreditsSheet.spec.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.tsx
  • packages/ui/components/sheet.tsx
  • apps/deploy-web/src/components/onboarding-picker/OnboardingPickerPage.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsNewPaymentMethodFields/AddCreditsNewPaymentMethodFields.spec.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.tsx
  • packages/ui/components/field.tsx
  • apps/deploy-web/src/components/billing-usage/AddCreditsForm/AddCreditsForm.spec.tsx

@ygrishajev ygrishajev merged commit 29d661c into main Jun 1, 2026
5 checks passed
@ygrishajev ygrishajev deleted the feat/add-credits-sheet branch June 1, 2026 10:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants