From 843db7c04c319006731bc707a22f06e1ed49cbda Mon Sep 17 00:00:00 2001 From: John Paul Ashenfelter Date: Sat, 29 Aug 2026 14:50:01 -0400 Subject: [PATCH] Cover Legacy Story and chart toggle in journey test and video Adds the Your Legacy Story page, an ongoing allocation, and the bar/pie summary toggle to the system test and the Playwright walkthrough. Scopes the allocation-section helpers to the sections with an add button, since the summary panel repeats the "Ongoing giving" heading. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Ad1F3fxrYtzxSGghZ6DV6j --- script/demo/README.md | 4 +-- script/demo/record.mjs | 35 ++++++++++++++++++++++ test/system/user_journey_test.rb | 50 +++++++++++++++++++++++++++++--- 3 files changed, 83 insertions(+), 6 deletions(-) diff --git a/script/demo/README.md b/script/demo/README.md index fba4189..7e075c4 100644 --- a/script/demo/README.md +++ b/script/demo/README.md @@ -1,7 +1,7 @@ # Journey walkthrough video -Records the member happy path (sign up → confirm email → About You → build and -share a scenario → public view) as a video using Playwright against the local +Records the member happy path (sign up → confirm email → About You → Your legacy story → +build and share a scenario → public view) as a video using Playwright against the local dev server. Same flow as `test/system/user_journey_test.rb`, slowed down for viewing. diff --git a/script/demo/record.mjs b/script/demo/record.mjs index f41e072..022bfc4 100644 --- a/script/demo/record.mjs +++ b/script/demo/record.mjs @@ -94,6 +94,21 @@ async function run() { await page.getByText("Saved.").first().waitFor(); await pause(1500); + // Your legacy story (also autosaves) + await page.getByRole("link", { name: "Dashboard" }).click(); + await pause(); + await page.getByRole("link", { name: "Your legacy story" }).click(); + await page.getByRole("heading", { name: "Your legacy" }).waitFor(); + await pause(); + await type(page, "#user_legacy_story_supported_organizations", + "The local food bank and the county library, because no one should go hungry or without books."); + await page.getByText("Saved.").first().waitFor(); + await pause(1500); + await page.locator("#user_legacy_story_core_values").scrollIntoViewIfNeeded(); + await type(page, "#user_legacy_story_core_values", "Generosity, curiosity, and community."); + await page.getByText("Saved.").first().waitFor(); + await pause(1500); + // Build a scenario await page.getByRole("link", { name: "Dashboard" }).click(); await pause(); @@ -113,7 +128,10 @@ async function run() { await page.getByText("$100,000").first().waitFor(); await pause(1500); + // Both allocation sections and the summary panel have a "... giving" heading; + // only the allocation sections carry the dialog controller. const oneTime = page.locator("[data-controller='dialog']", { hasText: /one time giving/i }).first(); + const ongoing = page.locator("[data-controller='dialog']", { hasText: /ongoing giving/i }).first(); await oneTime.getByRole("button", { name: "+ Add allocation" }).click(); await pause(); await oneTime.getByRole("button", { name: "Select a category" }).click(); @@ -125,6 +143,23 @@ async function run() { await page.getByText("$5,000").first().waitFor(); await pause(2000); + // Ongoing allocation (percentage slider defaults to 20%) + await ongoing.getByRole("button", { name: "+ Add allocation" }).click(); + await pause(); + await ongoing.getByRole("button", { name: "Select a category" }).click(); + await pause(); + await ongoing.locator("button[data-name='Education']").click(); + await pause(1500); + await ongoing.getByRole("button", { name: "Create" }).click(); + await page.getByText("20% allocated across 2 causes").waitFor(); + await pause(2000); + + // Toggle the summary chart between bar and pie + await page.getByRole("button", { name: "Pie" }).click(); + await pause(2500); + await page.getByRole("button", { name: "Bar" }).click(); + await pause(1500); + // Share → open the public link as an anonymous visitor await page.getByRole("button", { name: "Share" }).click(); await pause(); diff --git a/test/system/user_journey_test.rb b/test/system/user_journey_test.rb index 4382591..cdd8051 100644 --- a/test/system/user_journey_test.rb +++ b/test/system/user_journey_test.rb @@ -1,8 +1,8 @@ require "application_system_test_case" # Walks the happy path a brand-new member takes on a tenant: sign up, confirm -# via the emailed link, fill in About You (autosave), build a giving scenario, -# share it, and view the shared page anonymously. +# via the emailed link, fill in About You and Your Legacy Story (both autosave), +# build a giving scenario, share it, and view the shared page anonymously. class UserJourneyTest < ApplicationSystemTestCase include ActiveJob::TestHelper @@ -18,7 +18,7 @@ class UserJourneyTest < ApplicationSystemTestCase Capybara.app_host = @original_app_host end - test "a new member signs up, confirms, fills out About You, builds and shares a scenario" do + test "a new member signs up, confirms, fills out their story, builds and shares a scenario" do # Landing → sign up visit "/" assert_selector "h1", text: "Your Legacy Starts Here" @@ -54,6 +54,21 @@ class UserJourneyTest < ApplicationSystemTestCase visit "/users/biography" assert_field "user_biography_birthplace", with: "Arlington, VA" + # Legacy Story autosaves too + visit "/dashboard" + click_link "Your legacy story" + assert_selector "h1", text: "Your legacy" + fill_in "user_legacy_story_supported_organizations", with: "The local food bank, because no one should go hungry." + fill_in "user_legacy_story_core_values", with: "Generosity and community." + assert_text "Saved." + + story = user.reload.user_legacy_story + assert_equal "The local food bank, because no one should go hungry.", story.supported_organizations + assert_equal "Generosity and community.", story.core_values + + visit "/users/legacy_story" + assert_field "user_legacy_story_core_values", with: "Generosity and community." + # Build a scenario visit "/dashboard" click_link "Explore options" @@ -78,6 +93,21 @@ class UserJourneyTest < ApplicationSystemTestCase assert_text "Education" assert_text "$5,000" + within ongoing_section do + click_button "+ Add allocation" + click_button "Select a category" + find("button[data-name='Education']").click + click_button "Create" + end + assert_text "20% allocated across 2 causes" + + # Toggle the ongoing summary between bar and pie charts + click_button "Pie" + assert_selector "[data-tabs-target='panel'][data-type='pie']:not(.hidden)" + assert_selector "[data-tabs-target='panel'][data-type='bar'].hidden", visible: :all + click_button "Bar" + assert_selector "[data-tabs-target='panel'][data-type='bar']:not(.hidden)" + # Share and view the read-only page without signing in click_button "Share" click_button "Create share link" @@ -97,7 +127,19 @@ class UserJourneyTest < ApplicationSystemTestCase private def one_time_section - find("h3", text: /one time giving/i).ancestor("[data-controller='dialog']") + allocation_section(/one time giving/i) + end + + def ongoing_section + allocation_section(/ongoing giving/i) + end + + # The allocation sections and the summary panel both have a "... giving" h3; + # only the allocation sections carry the dialog controller and add button. + def allocation_section(title) + find("[data-controller='dialog']", text: title).tap do |section| + section.assert_selector "button", text: "+ Add allocation" + end end # Pull the first link containing `prefix` out of the email and return it as a