Fix back navigation from filter views to cards (#2725)
* test: update sign_in_as system test helper to be more generic and support fixture users with more than one board * test: backfill a test for the card "back link" when coming from a board filter page * Fix back navigation to filter views from cards When navigating from a filter view to a card, the back link now shows the filter's label and navigates back to the filter URL instead of the card's board. The turbo-navigation Stimulus controller stores the page title alongside the referrer URL in sessionStorage. On the card show page, a referrerBackLink target rewrites the back link's href and label from the stored values. This is scoped only to the card show page to avoid navigation loops in multi-level deep pages. * Add referrer allowlist to prevent stale referrer rewrites The back link is only rewritten when the stored referrer's path matches an allowlist of paths passed via prefer_referrer. This prevents stale referrers from unrelated pages (e.g., settings) from overriding the card's back link. * Move back link navigation tests to dedicated system test file Extract back link tests from smoke_test.rb into their own file since they test specific JavaScript behavior that needs regression coverage. Move sign_in_as helper to ApplicationSystemTestCase for reuse. * Move markdown paste tests to dedicated system test file
This commit is contained in:
@@ -28,4 +28,10 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
||||
else
|
||||
driven_by :chrome_headless, screen_size: [ 1200, 1000 ]
|
||||
end
|
||||
|
||||
private
|
||||
def sign_in_as(user)
|
||||
visit session_transfer_url(user.identity.transfer_id, script_name: nil)
|
||||
assert_current_path root_path
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
require "application_system_test_case"
|
||||
|
||||
class BackLinkNavigationTest < ApplicationSystemTestCase
|
||||
test "card back link returns to board filter view when navigating from it" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
filter_url = board_url(boards(:writebook), creator_ids: [ users(:david).id ])
|
||||
visit filter_url
|
||||
click_on cards(:logo).title
|
||||
|
||||
back_link = find("a.btn--back")
|
||||
assert_selector "a.btn--back strong", text: "Back to Writebook"
|
||||
back_link.click
|
||||
assert_current_path filter_url, ignore_query: false
|
||||
end
|
||||
|
||||
test "card back link returns to global filter view when navigating from it" do
|
||||
sign_in_as(users(:kevin))
|
||||
|
||||
filter_url = cards_url(creator_ids: [ users(:kevin).id ])
|
||||
visit filter_url
|
||||
click_on cards(:text).title
|
||||
|
||||
assert_selector "a.btn--back strong", text: "Back to all boards"
|
||||
find("a.btn--back").click
|
||||
assert_current_path filter_url, ignore_query: false
|
||||
end
|
||||
|
||||
test "card back link is not rewritten when navigating from a non-filter page" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
visit account_settings_url
|
||||
click_on "Invite people"
|
||||
visit card_url(cards(:logo))
|
||||
|
||||
assert_selector "a.btn--back strong", text: "Back to Writebook"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,44 @@
|
||||
require "application_system_test_case"
|
||||
|
||||
class MarkdownPasteTest < ApplicationSystemTestCase
|
||||
test "markdown paste adds block spacing" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
visit card_url(cards(:layout))
|
||||
find("lexxy-editor").click
|
||||
paste_markdown("Hello\n\nWorld")
|
||||
|
||||
within("lexxy-editor") do
|
||||
assert_selector "p", text: "Hello"
|
||||
assert_selector "p br", visible: :all
|
||||
assert_selector "p", text: "World"
|
||||
end
|
||||
end
|
||||
|
||||
test "markdown paste preserves line breaks" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
visit card_url(cards(:layout))
|
||||
find("lexxy-editor").click
|
||||
paste_markdown("Hello\nWorld")
|
||||
|
||||
inner_html = find("lexxy-editor p", text: "Hello").native.property("innerHTML")
|
||||
children = Nokogiri::HTML5.fragment(inner_html).children
|
||||
assert_pattern do
|
||||
children => [
|
||||
{ name: "span", inner_html: "Hello" },
|
||||
{ name: "br" },
|
||||
{ name: "span", inner_html: "World" }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def paste_markdown(markdown)
|
||||
page.execute_script(<<~JS, markdown)
|
||||
const dt = new DataTransfer();
|
||||
dt.setData("text/plain", arguments[0]);
|
||||
document.activeElement.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt, bubbles: true }));
|
||||
JS
|
||||
end
|
||||
end
|
||||
@@ -76,38 +76,6 @@ class SmokeTest < ApplicationSystemTestCase
|
||||
assert_no_selector "div##{dom_id(notification)}"
|
||||
end
|
||||
|
||||
test "markdown paste adds block spacing" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
visit card_url(cards(:layout))
|
||||
find("lexxy-editor").click
|
||||
paste_markdown("Hello\n\nWorld")
|
||||
|
||||
within("lexxy-editor") do
|
||||
assert_selector "p", text: "Hello"
|
||||
assert_selector "p br", visible: :all
|
||||
assert_selector "p", text: "World"
|
||||
end
|
||||
end
|
||||
|
||||
test "markdown paste preserves line breaks" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
visit card_url(cards(:layout))
|
||||
find("lexxy-editor").click
|
||||
paste_markdown("Hello\nWorld")
|
||||
|
||||
inner_html = find("lexxy-editor p", text: "Hello").native.property("innerHTML")
|
||||
children = Nokogiri::HTML5.fragment(inner_html).children
|
||||
assert_pattern do
|
||||
children => [
|
||||
{ name: "span", inner_html: "Hello" },
|
||||
{ name: "br" },
|
||||
{ name: "span", inner_html: "World" }
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
test "dragging card to a new column" do
|
||||
sign_in_as(users(:david))
|
||||
|
||||
@@ -127,22 +95,9 @@ class SmokeTest < ApplicationSystemTestCase
|
||||
end
|
||||
|
||||
private
|
||||
def sign_in_as(user)
|
||||
visit session_transfer_url(user.identity.transfer_id, script_name: nil)
|
||||
assert_selector "h1", text: "Latest Activity"
|
||||
end
|
||||
|
||||
def fill_in_lexxy(selector = "lexxy-editor", with:)
|
||||
editor_element = find(selector)
|
||||
editor_element.set with
|
||||
page.execute_script("arguments[0].value = '#{with}'", editor_element)
|
||||
end
|
||||
|
||||
def paste_markdown(markdown)
|
||||
page.execute_script(<<~JS, markdown)
|
||||
const dt = new DataTransfer();
|
||||
dt.setData("text/plain", arguments[0]);
|
||||
document.activeElement.dispatchEvent(new ClipboardEvent("paste", { clipboardData: dt, bubbles: true }));
|
||||
JS
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user