Add option for FOSS contribution payments (#730)

* First commit

* Use subscription flow for monetary contributions

* Removed only part of the SPAN

* Localize Stripe payments message

* More localization of contribution strings

* Missed two billing to payment changes

* Fix tests

* Localization of "Open Demo" strings

* Fix grammar error

* Update for consistency

* Localize CTA

* More localilzation strings
This commit is contained in:
Juan José Mata
2026-01-21 20:45:04 +01:00
committed by GitHub
parent 8e36c8e736
commit 4e425ce4e5
44 changed files with 259 additions and 98 deletions

View File

@@ -5,7 +5,7 @@ class SubscriptionsController < ApplicationController
# Upgrade page for unsubscribed users
def upgrade
if Current.family.subscription&.active?
redirect_to root_path, notice: "You are already subscribed."
redirect_to root_path, notice: "You are already contributing. Thank you!"
else
@plan = params[:plan] || "annual"
render layout: "onboardings"

View File

@@ -1,5 +1,5 @@
class Subscription < ApplicationRecord
TRIAL_DAYS = 14
TRIAL_DAYS = 45
belongs_to :family
@@ -28,11 +28,11 @@ class Subscription < ApplicationRecord
def name
case interval
when "month"
"Monthly Plan"
"Monthly Contribution"
when "year"
"Annual Plan"
"Annual Contribution"
else
"Free trial"
"Open demo"
end
end
end

View File

@@ -91,12 +91,12 @@
<div class="px-4 py-3 space-y-4 bg-container shadow-border-xs rounded-xl">
<div class="flex items-start justify-between">
<div>
<p class="text-sm font-medium text-primary">Free trial</p>
<p class="text-sm text-secondary"><%= Current.family.days_left_in_trial %> days remaining</p>
<p class="text-sm font-medium text-primary"><%= t("layouts.trial.open_demo") %></p>
<p class="text-sm text-secondary"><%= t("layouts.trial.data_deleted_in_days", days: Current.family.days_left_in_trial) %></p>
</div>
<%= render DS::Link.new(
text: "Upgrade",
text: t("layouts.trial.contribute"),
href: upgrade_subscription_path,
) %>
</div>

View File

@@ -17,21 +17,21 @@
<%= image_tag "logo-color.png", class: "w-16 mb-6" %>
<p class="text-xl lg:text-3xl text-primary font-display font-medium">
Try Sure for 14 days.
Try Sure for 45 days
</p>
<h2 class="text-xl lg:text-3xl font-display text-secondary font-medium mb-2">
No credit card required
Data will be deleted then
</h2>
<p class="text-sm text-secondary text-center mb-8">
Starting the trial activates your account for Sure. You won't need to enter payment details.
Starting today you can give the product a good look. <br/>If you like it, self-host or contribute to continue using it here.
</p>
<div class="w-full">
<% if Current.family.can_start_trial? %>
<%= render DS::Button.new(
text: "Try Sure for 14 days",
text: "Try Sure for 45 days",
href: subscription_path,
full_width: true,
data: { turbo: false }
@@ -53,7 +53,7 @@
</div>
<div class="space-y-8">
<h2 class="text-center text-lg lg:text-2xl font-medium text-primary">How your trial will work</h2>
<h2 class="text-center text-lg lg:text-2xl font-medium text-primary">How things work here</h2>
<div class="flex gap-3">
<div class="rounded-xl p-1 bg-gray-400/20 theme-dark:bg-gray-500/20 flex flex-col justify-between items-center text-secondary">
@@ -65,70 +65,19 @@
<div class="space-y-12">
<div class="space-y-1.5 text-sm">
<p class="text-primary font-medium">Today</p>
<p class="text-secondary">You'll get free access to Sure for 14 days</p>
<p class="text-secondary">You'll get free access to Sure for 45 days on our AWS.</p>
</div>
<div class="space-y-1.5 text-sm">
<p class="text-primary font-medium">In 13 days (<%= 13.days.from_now.strftime("%B %d") %>)</p>
<p class="text-secondary">We'll notify you to remind you when your trial will end.</p>
<p class="text-primary font-medium">In 40 days (<%= 40.days.from_now.strftime("%B %d") %>)</p>
<p class="text-secondary">We'll notify you to remind you to export your data.</p>
</div>
<div class="space-y-1.5 text-sm">
<p class="text-primary font-medium">In 14 days (<%= 14.days.from_now.strftime("%B %d") %>)</p>
<p class="text-secondary">Your trial ends &mdash; subscribe to continue using Sure</p>
<p class="text-primary font-medium">In 45 days (<%= 45.days.from_now.strftime("%B %d") %>)</p>
<p class="text-secondary">We delete your data &mdash; contribute to continue using Sure here!</p>
</div>
</div>
</div>
</div>
<div class="space-y-8 max-w-2xl mx-auto">
<h2 class="text-center text-lg lg:text-2xl font-medium text-primary">Here's what's included</h2>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-x-12 gap-y-6 text-secondary">
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "landmark", variant: :surface) %>
<p class="text-sm text-primary text-center">More than 10,000 institutions to connect to</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "layers", variant: :surface) %>
<p class="text-sm text-primary text-center">Connect unlimited accounts and account types</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "chart-line", variant: :surface) %>
<p class="text-sm text-primary text-center">Performance and investment returns across portfolio</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "credit-card", variant: :surface) %>
<p class="text-sm text-primary text-center">Comprehensive transaction tracking experience</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render "chats/ai_avatar" %>
<p class="text-sm text-primary text-center">Unlimited access and chats with Sure AI</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "keyboard", variant: :surface) %>
<p class="text-sm text-primary text-center">Manual account tracking that works well</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "globe-2", variant: :surface) %>
<p class="text-sm text-primary text-center">Multiple currencies and near global coverage</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "ship", variant: :surface) %>
<p class="text-sm text-primary text-center">Early access to newly released features</p>
</div>
<div class="flex flex-col gap-4 items-center">
<%= render DS::FilledIcon.new(icon: "messages-square", variant: :surface) %>
<p class="text-sm text-primary text-center">Priority human support from team</p>
</div>
</div>
</div>
</div>

View File

@@ -13,22 +13,22 @@
<div class="text-sm space-y-1">
<% if @family.has_active_subscription? %>
<p class="text-primary">
<span>You are currently subscribed to the <span class="font-medium"><%= @family.subscription.name %></span>.</span>
<span>Currently on the <span class="font-medium"><%= @family.subscription.name %></span>.</span>
<% if @family.next_payment_date %>
<span>Your plan renews on <span class="font-medium"><%= @family.next_payment_date.strftime("%B %d, %Y") %></span>.</span>
<span><%= t("views.settings.payments.renewal", date: l(@family.next_payment_date, format: :long)) %></span>
<% end %>
</p>
<% elsif @family.trialing? %>
<p class="text-primary">
You are currently trialing <%= product_name %>
Currently using the open demo of <%= product_name %> <br />
<span class="text-secondary">
(<%= @family.days_left_in_trial %> days remaining)
(Data will be deleted in <%= @family.days_left_in_trial %> days)
</span>
</p>
<% else %>
<p class="text-primary">You are currently <span class="font-medium">not subscribed</span></p>
<p class="text-secondary">Once you subscribe to <%= product_name %>, you'll see your payment settings here.</p>
<p class="text-primary">You are currently <span class="font-medium">not contributing</span></p>
<p class="text-secondary">Contributions to <%= product_name %> will show here.</p>
<% end %>
</div>
</div>
@@ -44,7 +44,7 @@
) %>
<% else %>
<%= render DS::Link.new(
text: "Choose plan",
text: "Choose level",
variant: "primary",
icon: "plus",
icon_position: "right",

View File

@@ -1,6 +1,6 @@
<%# locals: (plan:, form:, checked: false) %>
<% price = plan == "annual" ? 90 : 9 %>
<% price = plan == "annual" ? 25 : 2.50 %>
<% frequency = plan == "annual" ? "/year" : "/month" %>
<div class="relative">
@@ -14,17 +14,13 @@
<div class="mt-auto flex items-end gap-1">
<p class="font-display text-xl lg:text-3xl font-medium text-primary">$<%= price %><%= frequency %></p>
<% if plan == "annual" %>
<span class="text-sm text-secondary mb-1">or <%= Money.new(price.to_f / 52).format %>/week</span>
<% end %>
</div>
<p class="text-sm text-secondary">
<% if plan == "annual" %>
Billed annually, 2 months free
Charged annually
<% else %>
Billed monthly
Charged monthly
<% end %>
</p>
<% end %>

View File

@@ -25,18 +25,18 @@
<%= image_tag "logo-color.png", class: "w-16 mb-6" %>
<% if Current.family.trialing? %>
<p class="text-xl lg:text-3xl text-primary font-display font-medium">Your trial has <%= Current.family.days_left_in_trial %> days remaining</p>
<p class="text-xl lg:text-3xl text-primary font-display font-medium"><%= t('subscriptions.upgrade.trialing', days: Current.family.days_left_in_trial) %></p>
<% else %>
<p class="text-xl lg:text-3xl text-primary font-display font-medium">Your trial is over</p>
<p class="text-xl lg:text-3xl text-primary font-display font-medium"><%= t('subscriptions.upgrade.trial_over') %></p>
<% end %>
<h2 class="text-xl lg:text-3xl font-display font-medium mb-2">
<span class="text-secondary">Unlock</span>
<span class="bg-gradient-to-r from-[#EABE7F] to-[#957049] bg-clip-text text-transparent">Sure</span>
<span class="text-secondary">today</span>
<span class="text-secondary"><%= t('subscriptions.upgrade.header.support') %></span>
<span class="bg-gradient-to-r from-[#EABE7F] to-[#957049] bg-clip-text text-transparent"><%= t('subscriptions.upgrade.header.sure') %></span>
<span class="text-secondary"><%= t('subscriptions.upgrade.header.today') %></span>
</h2>
<p class="text-sm text-secondary mb-8">To continue using Sure pick a plan below.</p>
<p class="text-sm text-secondary mb-8"><%= t('subscriptions.upgrade.cta') %></p>
<%= form_with url: new_subscription_path, method: :get, class: "max-w-xs", data: { turbo: false } do |form| %>
<div class="space-y-4 mb-6">
@@ -46,13 +46,13 @@
<div class="text-center space-y-2">
<%= render DS::Button.new(
text: "Subscribe and unlock Sure",
text: t('subscriptions.upgrade.contribute_and_support_sure'),
variant: "primary",
full_width: true
) %>
<p class="text-xs text-secondary">
In the next step, you'll be redirected to Stripe which handles our payments.
<%= t('subscriptions.upgrade.redirect_to_stripe') %>
</p>
</div>
<% end %>

View File

@@ -17,3 +17,7 @@ ca:
footer:
privacy_policy: Política de privacitat
terms_of_service: Termes del servei
trial:
open_demo: Demo oberta
data_deleted_in_days: Les dades s'eliminaran en %{days} dies
contribute: Contribuir

View File

@@ -18,3 +18,7 @@ de:
footer:
privacy_policy: Datenschutzrichtlinie
terms_of_service: Nutzungsbedingungen
trial:
open_demo: Offene Demo
data_deleted_in_days: Daten werden in %{days} Tagen gelöscht
contribute: Beitragen

View File

@@ -17,3 +17,7 @@ en:
footer:
privacy_policy: Privacy Policy
terms_of_service: Terms of Service
trial:
open_demo: Open demo
data_deleted_in_days: Data deleted in %{days} days
contribute: Contribute

View File

@@ -17,3 +17,7 @@ es:
footer:
privacy_policy: Política de privacidad
terms_of_service: Términos de servicio
trial:
open_demo: Demo pública
data_deleted_in_days: Los datos se eliminarán en %{days} días
contribute: Contribuir

View File

@@ -17,3 +17,7 @@ fr:
footer:
privacy_policy: Politique de confidentialité
terms_of_service: Conditions d'utilisation
trial:
open_demo: Démo ouverte
data_deleted_in_days: Les données seront supprimées dans %{days} jours
contribute: Contribuer

View File

@@ -17,3 +17,7 @@ nb:
footer:
privacy_policy: Personvernerklæring
terms_of_service: Vilkår for bruk
trial:
open_demo: Åpen demo
data_deleted_in_days: Data slettes om %{days} dager
contribute: Bidra

View File

@@ -17,3 +17,7 @@ nl:
footer:
privacy_policy: Privacybeleid
terms_of_service: Servicevoorwaarden
trial:
open_demo: Open demo
data_deleted_in_days: Gegevens worden over %{days} dagen verwijderd
contribute: Bijdragen

View File

@@ -17,3 +17,7 @@ pt-BR:
footer:
privacy_policy: Política de Privacidade
terms_of_service: Termos de Serviço
trial:
open_demo: Demo aberta
data_deleted_in_days: Os dados serão excluídos em %{days} dias
contribute: Contribuir

View File

@@ -18,3 +18,7 @@ ro:
footer:
privacy_policy: Politica de confidențialitate
terms_of_service: Termeni și condiții
trial:
open_demo: Demo deschis
data_deleted_in_days: Datele vor fi șterse în %{days} zile
contribute: Contribuie

View File

@@ -17,3 +17,7 @@ tr:
footer:
privacy_policy: Gizlilik Politikası
terms_of_service: Hizmet Şartları
trial:
open_demo: ık demo
data_deleted_in_days: Veriler %{days} gün içinde silinecek
contribute: Katkıda bulun

View File

@@ -18,3 +18,7 @@ zh-CN:
footer:
privacy_policy: 隐私政策
terms_of_service: 服务条款
trial:
open_demo: 开放演示
data_deleted_in_days: 数据将在 %{days} 天后删除
contribute: 贡献

View File

@@ -17,3 +17,7 @@ zh-TW:
footer:
privacy_policy: 隱私權政策
terms_of_service: 服務條款
trial:
open_demo: 開放示範
data_deleted_in_days: 資料將在 %{days} 天後刪除
contribute: 貢獻

View File

@@ -1,5 +1,9 @@
---
ca:
views:
settings:
payments:
renewal: "La teva contribució continua el %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,4 +1,8 @@
de:
views:
settings:
payments:
renewal: "Ihr Beitrag wird fortgesetzt am %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
en:
views:
settings:
payments:
renewal: "Your contribution continues on %{date}."
settings:
ai_prompts:
show:
@@ -18,9 +22,9 @@ en:
subtitle: AI identifies and enriches transaction data with merchant information
payments:
show:
page_title: Payment
subscription_subtitle: Update your subscription and payment details
subscription_title: Manage subscription
page_title: Payments
subscription_subtitle: Update your credit card details
subscription_title: Manage contributions
preferences:
show:
country: Country

View File

@@ -1,5 +1,9 @@
---
es:
views:
settings:
payments:
renewal: "Tu contribución continúa el %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
fr:
views:
settings:
payments:
renewal: "Votre contribution se poursuit le %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
nb:
views:
settings:
payments:
renewal: "Bidraget ditt fortsetter den %{date}."
settings:
payments:
show:

View File

@@ -1,5 +1,9 @@
---
nl:
views:
settings:
payments:
renewal: "Uw bijdrage wordt voortgezet op %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
pt-BR:
views:
settings:
payments:
renewal: "Sua contribuição continua em %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
ro:
views:
settings:
payments:
renewal: "Contribuția ta continuă pe %{date}."
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
tr:
views:
settings:
payments:
renewal: "Katkınız %{date} tarihinde devam edecek."
settings:
payments:
show:

View File

@@ -1,5 +1,9 @@
---
zh-CN:
views:
settings:
payments:
renewal: "您的贡献将在 %{date} 继续。"
settings:
ai_prompts:
show:

View File

@@ -1,5 +1,9 @@
---
zh-TW:
views:
settings:
payments:
renewal: "您的貢獻將於 %{date} 繼續。"
settings:
ai_prompts:
show:

View File

@@ -2,3 +2,13 @@
ca:
subscriptions:
self_hosted_alert: "%{product_name} no està disponible en mode autoallotjat."
upgrade:
contribute_and_support_sure: "Contribuir i donar suport a Sure"
cta: "Continua donant suport al desenvolupament d'aquest codi!"
header:
support: "Suport"
sure: "Sure"
today: "avui"
redirect_to_stripe: "En el proper pas, se us redirigirà a Stripe, que gestiona les targetes de crèdit per nosaltres."
trialing: "Les teves dades s'eliminaran en %{days} dies"
trial_over: "El teu període de prova ha acabat"

View File

@@ -2,3 +2,13 @@
de:
subscriptions:
self_hosted_alert: "%{product_name} ist im Self-Hosting-Modus nicht verfügbar."
upgrade:
contribute_and_support_sure: "Beitragen und Sure unterstützen"
cta: "Unterstützen Sie weiterhin die Entwicklung dieser Codebasis!"
header:
support: "Unterstützen"
sure: "Sure"
today: "heute"
redirect_to_stripe: "Im nächsten Schritt werden Sie zu Stripe weitergeleitet, das Kreditkarten für uns verwaltet."
trialing: "Ihre Daten werden in %{days} Tagen gelöscht"
trial_over: "Ihre Testversion ist abgelaufen"

View File

@@ -1,3 +1,13 @@
en:
subscriptions:
self_hosted_alert: "%{product_name} is not available in self-hosted mode."
upgrade:
contribute_and_support_sure: "Contribute and support Sure"
cta: "Continue supporting the development of this codebase!"
header:
support: "Support"
sure: "Sure"
today: "today"
redirect_to_stripe: "In the next step, you'll be redirected to Stripe which handles credit cards for us."
trialing: "Your data will be deleted in %{days} days"
trial_over: "Your trial is over"

View File

@@ -2,3 +2,13 @@
es:
subscriptions:
self_hosted_alert: "%{product_name} no está disponible en modo autoalojado."
upgrade:
contribute_and_support_sure: "Contribuir y apoyar a Sure"
cta: "¡Apoya el desarrollo de este proyecto!"
header:
support: "Apoyar"
sure: "Sure"
today: "hoy"
redirect_to_stripe: "En el siguiente paso, serás redirigido a Stripe, que gestiona las tarjetas de crédito por nosotros."
trialing: "Tus datos se eliminarán en %{days} días"
trial_over: "Tu período de prueba ha terminado"

View File

@@ -1,3 +1,13 @@
fr:
subscriptions:
self_hosted_alert: "%{product_name} n'est pas disponible en mode auto-hébergé."
upgrade:
contribute_and_support_sure: "Contribuer et soutenir Sure"
cta: "Continuez à soutenir le développement de cette base de code !"
header:
support: "Soutenir"
sure: "Sure"
today: "aujourd'hui"
redirect_to_stripe: "Dans l'étape suivante, vous serez redirigé vers Stripe, qui gère les cartes de crédit pour nous."
trialing: "Vos données seront supprimées dans %{days} jours"
trial_over: "Votre période d'essai est terminée"

View File

@@ -1,4 +1,14 @@
---
nb:
subscriptions:
self_hosted_alert: "%{product_name} er ikke tilgjengelig i selvhostet modus."
self_hosted_alert: "%{product_name} er ikke tilgjengelig i selvhostet modus."
upgrade:
contribute_and_support_sure: "Bidra og støtt Sure"
cta: "Fortsett å støtte utviklingen av denne kodebasen!"
header:
support: "Støtt"
sure: "Sure"
today: "i dag"
redirect_to_stripe: "I neste trinn vil du bli omdirigert til Stripe, som håndterer kredittkort for oss."
trialing: "Dataene dine vil bli slettet om %{days} dager"
trial_over: "Prøveperioden din er over"

View File

@@ -1,3 +1,13 @@
nl:
subscriptions:
self_hosted_alert: "%{product_name} is niet beschikbaar in zelfgehoste modus."
upgrade:
contribute_and_support_sure: "Bijdragen en Sure ondersteunen"
cta: "Blijf de ontwikkeling van deze codebase ondersteunen!"
header:
support: "Ondersteunen"
sure: "Sure"
today: "vandaag"
redirect_to_stripe: "In de volgende stap wordt u doorgestuurd naar Stripe, dat creditcards voor ons verwerkt."
trialing: "Uw gegevens worden over %{days} dagen verwijderd"
trial_over: "Uw proefperiode is voorbij"

View File

@@ -2,3 +2,13 @@
pt-BR:
subscriptions:
self_hosted_alert: "%{product_name} não está disponível no modo self-hosted."
upgrade:
contribute_and_support_sure: "Contribuir e apoiar o Sure"
cta: "Continue apoiando o desenvolvimento desta base de código!"
header:
support: "Apoiar"
sure: "Sure"
today: "hoje"
redirect_to_stripe: "Na próxima etapa, você será redirecionado para o Stripe, que processa cartões de crédito para nós."
trialing: "Seus dados serão excluídos em %{days} dias"
trial_over: "Seu período de teste terminou"

View File

@@ -1,4 +1,14 @@
---
ro:
subscriptions:
self_hosted_alert: "%{product_name} nu este disponibil în modul self-hosted."
self_hosted_alert: "%{product_name} nu este disponibil în modul self-hosted."
upgrade:
contribute_and_support_sure: "Contribuie și sprijină Sure"
cta: "Continuați să sprijiniți dezvoltarea acestei baze de cod!"
header:
support: "Sprijină"
sure: "Sure"
today: "astăzi"
redirect_to_stripe: "În pasul următor, veți fi redirecționat către Stripe, care procesează cardurile de credit pentru noi."
trialing: "Datele dvs. vor fi șterse în %{days} zile"
trial_over: "Perioada dvs. de probă s-a încheiat"

View File

@@ -1,4 +1,14 @@
---
tr:
subscriptions:
self_hosted_alert: "%{product_name} kendi sunucunda barındırılan modda kullanılamaz."
self_hosted_alert: "%{product_name} kendi sunucunda barındırılan modda kullanılamaz."
upgrade:
contribute_and_support_sure: "Katkıda bulun ve Sure'u destekle"
cta: "Bu kod tabanının geliştirilmesini desteklemeye devam edin!"
header:
support: "Destekle"
sure: "Sure"
today: "bugün"
redirect_to_stripe: "Bir sonraki adımda, kredi kartlarını bizim için işleyen Stripe'a yönlendirileceksiniz."
trialing: "Verileriniz %{days} gün içinde silinecek"
trial_over: "Deneme süreniz sona erdi"

View File

@@ -2,3 +2,13 @@
zh-CN:
subscriptions:
self_hosted_alert: "%{product_name} 在自托管模式下不可用。"
upgrade:
contribute_and_support_sure: "贡献并支持 Sure"
cta: "继续支持此代码库的开发!"
header:
support: "支持"
sure: "Sure"
today: "今天"
redirect_to_stripe: "在下一步中,您将被重定向到 Stripe它为我们处理信用卡。"
trialing: "您的数据将在 %{days} 天后删除"
trial_over: "您的试用期已结束"

View File

@@ -2,3 +2,13 @@
zh-TW:
subscriptions:
self_hosted_alert: "在自行代管模式下不支援 %{product_name}。"
upgrade:
contribute_and_support_sure: "貢獻並支持 Sure"
cta: "繼續支持此程式碼庫的開發!"
header:
support: "支持"
sure: "Sure"
today: "今天"
redirect_to_stripe: "在下一步中,您將被重新導向到 Stripe它為我們處理信用卡。"
trialing: "您的資料將在 %{days} 天後刪除"
trial_over: "您的試用期已結束"

View File

@@ -145,7 +145,7 @@ class OnboardingsTest < ApplicationSystemTestCase
test "trial page renders correctly" do
visit trial_onboarding_path
assert_text "trial" # Adjust based on actual content
assert_text "Try Sure"
end
test "navigation between onboarding steps" do