-
-
Notifications
You must be signed in to change notification settings - Fork 11.3k
🐛 Fixed upgrade button in trial banner not navigating to checkout #25674
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis PR updates the upgrade banner component to navigate to a billing plans page by replacing a button action with an anchor link. It extends E2E test infrastructure with new page object locators for the upgrade banner, updates the test configuration fixture to support billing settings with optional fields, introduces a new E2E test validating the upgrade banner navigation flow, and adds a non-null assertion to an existing test for email inbox configuration. Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
8b433e7 to
61af6e7
Compare
Ember E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 20071636694 -n playwright-report-ember -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
React E2E Tests FailedTo view the Playwright test report locally, run: REPORT_DIR=$(mktemp -d) && gh run download 20071636694 -n playwright-report-react -D "$REPORT_DIR" && npx playwright show-report "$REPORT_DIR" |
129c1ed to
080aac2
Compare
fixes https://linear.app/ghost/issue/BER-3122 The "Upgrade now" button in the React admin sidebar's trial upgrade banner had no click handler. This adds navigation to the pro checkout route, matching the behavior of the Ember implementation.
080aac2 to
4896f83
Compare
|
You have run out of free Bugbot PR reviews for this billing cycle. This will reset on January 3. To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
e2e/helpers/playwright/fixture.ts (1)
17-22: GhostConfig optional fields and billing keys look consistent; consider updating docsMaking the welcome-email fields optional and adding the two billing-related keys as optional strings fits the existing
configpattern and aligns with how tests opt-in viatest.use({config: {...}}). To keep the fixture self-documenting, you might extend the comment around lines 75–78 to also mentionhostSettings__billing__enabledandhostSettings__billing__urlas supported options.e2e/tests/admin/sidebar/upgrade-banner.test.ts (1)
1-52: Well-structured e2e covers upgrade flow; consider aligning test name with routeThe test setup looks solid: it enables billing via the shared
configfixture, mocks the external billing app withpage.route, usesSidebarPagefor interactions, and follows the AAA pattern with a single, focused scenario asserting navigation to#/pro/billing/plans. That’s all in line with the e2e ADRs.Minor nit: the test name mentions “pro checkout route” while the assertion checks the
#/pro/billing/plansURL. For clarity and future grepping, you might rename it to something likeupgrade now button - navigates to pro billing plans route.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
apps/admin/src/layout/app-sidebar/UpgradeBanner.tsx(1 hunks)e2e/helpers/pages/admin/sidebar/sidebar-page.ts(2 hunks)e2e/helpers/playwright/fixture.ts(1 hunks)e2e/tests/admin/sidebar/upgrade-banner.test.ts(1 hunks)e2e/tests/public/member-signup.test.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
e2e/**/*.{ts,tsx}
📄 CodeRabbit inference engine (e2e/AGENTS.md)
Prefer less comments and give things clear names
Files:
e2e/helpers/playwright/fixture.tse2e/helpers/pages/admin/sidebar/sidebar-page.tse2e/tests/public/member-signup.test.tse2e/tests/admin/sidebar/upgrade-banner.test.ts
e2e/**/*.{ts,js}
📄 CodeRabbit inference engine (AGENTS.md)
E2E tests should use Playwright with Docker container isolation
Files:
e2e/helpers/playwright/fixture.tse2e/helpers/pages/admin/sidebar/sidebar-page.tse2e/tests/public/member-signup.test.tse2e/tests/admin/sidebar/upgrade-banner.test.ts
e2e/helpers/pages/**/*.ts
📄 CodeRabbit inference engine (e2e/AGENTS.md)
e2e/helpers/pages/**/*.ts: Page Objects should be located inhelpers/pages/directory
Expose locators aspublic readonlyin Page Objects when used with assertions
Page Object methods should use semantic names (e.g.,login()instead ofclickLoginButton())
UsewaitFor()for guards in Page Objects, never useexpect()in page objects
Files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
e2e/**/*.test.ts
📄 CodeRabbit inference engine (e2e/AGENTS.md)
e2e/**/*.test.ts: Always follow ADRs in../adr/folder (ADR-0001: AAA pattern, ADR-0002: Page Objects)
Never use CSS/XPath selectors - only use semantic locators or data-testid
Test suite names should follow the format 'Ghost Admin - Feature' or 'Ghost Public - Feature'
Test names should be lowercase and follow the format 'what is tested - expected outcome'
Each test should represent one scenario only - never mix multiple scenarios in a single test
Follow the AAA (Arrange, Act, Assert) pattern in test structure
Prefer semantic locators (getByRole,getByLabel,getByText) over test IDs and never use CSS selectors, XPath, nth-child, or class names
UsegetByTestId()only when semantic locators are unavailable, and suggest addingdata-testidto Ghost codebase when needed
Use factory pattern for all test data creation instead of hard-coded data or direct database manipulation
Never use hard-coded waits likewaitForTimeout()
Never usenetworkidlein waits
Use Playwright's auto-waiting capabilities and run tests multiple times to ensure stability
Usetest.only()for debugging single tests
Manual login should not be used - authentication is automatic via fixture
Files:
e2e/tests/public/member-signup.test.tse2e/tests/admin/sidebar/upgrade-banner.test.ts
🧠 Learnings (14)
📚 Learning: 2025-06-10T11:07:10.800Z
Learnt from: kevinansfield
Repo: TryGhost/Ghost PR: 23770
File: apps/admin-x-settings/src/components/settings/email/newsletters/NewsletterDetailModalLabs.tsx:435-450
Timestamp: 2025-06-10T11:07:10.800Z
Learning: In Ghost's newsletter customization features, when promoting a feature from alpha to beta status, the feature flag guards are updated to make the feature available under both the `emailCustomization` (beta) and `emailCustomizationAlpha` (alpha) flags. This is done by either removing conditional guards entirely when the component is already behind both flags, or by updating conditionals to check for either flag.
Applied to files:
e2e/helpers/playwright/fixture.ts
📚 Learning: 2025-12-01T08:42:35.320Z
Learnt from: jonatansberg
Repo: TryGhost/Ghost PR: 25552
File: e2e/helpers/environment/service-managers/dev-ghost-manager.ts:210-247
Timestamp: 2025-12-01T08:42:35.320Z
Learning: In e2e/helpers/environment/service-managers/dev-ghost-manager.ts, the hardcoded volume name 'ghost-dev_shared-config' at line 231 is intentional. E2E tests run under the 'ghost-dev-e2e' project namespace but deliberately mount the shared-config volume from the main 'ghost-dev' project to access Tinybird credentials created by yarn dev:forward. This is cross-project volume sharing by design.
Applied to files:
e2e/helpers/playwright/fixture.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/helpers/pages/**/*.ts : Expose locators as `public readonly` in Page Objects when used with assertions
Applied to files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Use `getByTestId()` only when semantic locators are unavailable, and suggest adding `data-testid` to Ghost codebase when needed
Applied to files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
📚 Learning: 2025-11-25T14:28:50.351Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-25T14:28:50.351Z
Learning: Applies to ghost/i18n/locales/en/ghost.json : Add UI translations to `ghost/i18n/locales/en/ghost.json` for Admin UI features
Applied to files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Prefer semantic locators (`getByRole`, `getByLabel`, `getByText`) over test IDs and never use CSS selectors, XPath, nth-child, or class names
Applied to files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
📚 Learning: 2025-09-11T20:38:41.537Z
Learnt from: cmraible
Repo: TryGhost/Ghost PR: 24891
File: e2e/helpers/pages/portal/SignUpSuccessPage.ts:61-67
Timestamp: 2025-09-11T20:38:41.537Z
Learning: In Playwright, page.$() is deprecated and should be replaced with page.locator(). When checking element visibility with Locator.isVisible(), the method returns false both when the element doesn't exist and when it exists but isn't visible, eliminating the need for separate null checks that were required with ElementHandle.
Applied to files:
e2e/helpers/pages/admin/sidebar/sidebar-page.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Manual login should not be used - authentication is automatic via fixture
Applied to files:
e2e/tests/public/member-signup.test.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Test suite names should follow the format 'Ghost Admin - Feature' or 'Ghost Public - Feature'
Applied to files:
e2e/tests/admin/sidebar/upgrade-banner.test.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Always follow ADRs in `../adr/` folder (ADR-0001: AAA pattern, ADR-0002: Page Objects)
Applied to files:
e2e/tests/admin/sidebar/upgrade-banner.test.ts
📚 Learning: 2025-03-13T09:00:20.205Z
Learnt from: mike182uk
Repo: TryGhost/Ghost PR: 22471
File: apps/admin-x-activitypub/src/utils/pending-activity.ts:13-71
Timestamp: 2025-03-13T09:00:20.205Z
Learning: The pending activity utilities in the Ghost ActivityPub module are covered by tests in the file `apps/admin-x-activitypub/test/unit/utils/pending-activity.ts`.
Applied to files:
e2e/tests/admin/sidebar/upgrade-banner.test.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Use Playwright's auto-waiting capabilities and run tests multiple times to ensure stability
Applied to files:
e2e/tests/admin/sidebar/upgrade-banner.test.ts
📚 Learning: 2025-11-24T17:29:43.865Z
Learnt from: CR
Repo: TryGhost/Ghost PR: 0
File: e2e/AGENTS.md:0-0
Timestamp: 2025-11-24T17:29:43.865Z
Learning: Applies to e2e/**/*.test.ts : Use factory pattern for all test data creation instead of hard-coded data or direct database manipulation
Applied to files:
e2e/tests/admin/sidebar/upgrade-banner.test.ts
📚 Learning: 2025-11-06T05:35:41.162Z
Learnt from: danielraffel
Repo: TryGhost/Ghost PR: 25366
File: apps/admin/src/layout/app-sidebar/NavHeader.tsx:13-23
Timestamp: 2025-11-06T05:35:41.162Z
Learning: In apps/admin/src/layout/app-sidebar/NavHeader.tsx, the React component dispatches a synthetic KeyboardEvent to trigger the Ember keymaster.js search modal shortcut. This approach is known to have cross-browser reliability issues but was deferred for architectural refactoring in a separate PR. The recommended fix is to expose a global function or custom DOM event from the Ember app instead of relying on synthetic keyboard events with keymaster.js.
Applied to files:
apps/admin/src/layout/app-sidebar/UpgradeBanner.tsx
🧬 Code graph analysis (2)
e2e/tests/public/member-signup.test.ts (5)
ghost/core/core/server/services/member-welcome-emails/service.js (1)
config(5-5)ghost/core/test/integration/jobs/process-outbox.test.js (1)
config(10-10)ghost/core/test/integration/services/member-welcome-emails.test.js (1)
config(10-10)ghost/core/test/unit/server/services/members/members-api/repositories/MemberRepository.test.js (1)
config(7-7)ghost/core/core/server/services/members/members-api/repositories/MemberRepository.js (1)
config(11-11)
e2e/tests/admin/sidebar/upgrade-banner.test.ts (1)
e2e/helpers/pages/admin/sidebar/sidebar-page.ts (1)
SidebarPage(12-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
- GitHub Check: E2E Tests (Ember 4/4)
- GitHub Check: [Optional] E2E Tests (React 4/4)
- GitHub Check: E2E Tests (Ember 1/4)
- GitHub Check: [Optional] E2E Tests (React 2/4)
- GitHub Check: E2E Tests (Ember 2/4)
- GitHub Check: [Optional] E2E Tests (React 1/4)
- GitHub Check: [Optional] E2E Tests (React 3/4)
- GitHub Check: E2E Tests (Ember 3/4)
- GitHub Check: Unit tests (Node 22.18.0)
🔇 Additional comments (3)
e2e/tests/public/member-signup.test.ts (1)
51-56: Non‑null assertion matches updated GhostConfig optionalityUsing
config!.memberWelcomeEmailTestInbox!is consistent withGhostConfignow marking this property as optional and with the describe-leveltest.use({config: {…}})guaranteeing it for this suite. This keeps the type-checker happy while still making any missing config an explicit test setup error.If you ever refactor this suite to remove or change the
test.use({config: {...}})block, double‑check this line so it fails with a clear message rather than a cryptic runtime error.apps/admin/src/layout/app-sidebar/UpgradeBanner.tsx (1)
8-21: Anchor-based upgrade action fixes the missing navigation; confirm route paritySwitching to
<Button asChild><a href="#/pro/billing/plans">…</a></Button>gives the upgrade control a concrete navigation target while preserving button styling, and it lines up with the new e2e assertion on#/pro/billing/plans. There is a slight mismatch with the PR description mentioning#/pro?action=checkout, so it’s worth double-checking that this hash route is exactly what the Ember sidebar uses and what billing expects long-term.e2e/helpers/pages/admin/sidebar/sidebar-page.ts (1)
21-42: New sidebar locators are semantic and future-proof across Ember/ReactDefining
ghostProLinkandupgradeNowLinkaspublic readonlylocators on the page object fits the helpers guidelines, and usinggetByRolewith accessible names (plus the.or(...)composition for link/button) is a nice way to keep tests stable while both Ember and React variants exist.
| }); | ||
|
|
||
| test('upgrade now button navigates to pro checkout route', async ({page}) => { | ||
| // Arrange |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can kill these comments (arrange act..)
fixes https://linear.app/ghost/issue/BER-3122
The "Upgrade now" button in the React admin sidebar's trial upgrade banner had no click handler. Added navigation to
#/pro?action=checkoutto align with the Ember implementation.