Skip to content

Commit f694b22

Browse files
test: re-enable the Cmd/Ctrl+Enter form submit hotkey spec
The example was commented out because it dispatched the keydown on `document.body`. Events bubble up, so it never reached the `form` element that carries the binding (`keydown.ctrl+enter->form#submit keydown.meta+enter->form#submit`, lib/avo/concerns/form_builder.rb). It only ever exercised the Save button's `@github/hotkey` "Mod+Enter", which is document-level but resolves to Meta on macOS and Ctrl on Linux — so it passed locally with `meta_key: true` and would have failed on CI. Dispatch from the focused field instead, which tests the real Stimulus binding and is platform-independent, and cover both modifiers. `fill_in` leaves focus on `body` under Cuprite, hence the explicit `focus_field`. Closes AVO-1117 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 2c8fdc6 commit f694b22

1 file changed

Lines changed: 24 additions & 10 deletions

File tree

spec/system/avo/group_1/hotkey_spec.rb

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,27 @@ def active_element_value
2929
page.evaluate_script("document.activeElement && document.activeElement.value")
3030
end
3131

32-
def dispatch_active_element_keydown(key)
32+
def dispatch_active_element_keydown(key, ctrl_key: false, meta_key: false)
3333
page.execute_script(<<~JS)
3434
const activeElement = document.activeElement
3535
if (activeElement) {
3636
activeElement.dispatchEvent(new KeyboardEvent("keydown", {
3737
key: #{key.to_json},
38+
ctrlKey: #{ctrl_key},
39+
metaKey: #{meta_key},
3840
bubbles: true,
3941
cancelable: true
4042
}))
4143
}
4244
JS
4345
end
4446

47+
def focus_field(field_id)
48+
page.execute_script("document.getElementById(#{field_id.to_json}).focus()")
49+
50+
expect(page.evaluate_script("document.activeElement && document.activeElement.id")).to eq(field_id)
51+
end
52+
4553
def focus_resource_table
4654
expect(page).to have_css('[data-index-row-navigator-target="table"]')
4755
expect(page).to have_css("tr[data-visit-path]", minimum: 1)
@@ -299,18 +307,24 @@ def dispatch_document_keydown(key, code: nil, shift_key: false, ctrl_key: false,
299307
expect(active_element_value).to eq("confirm")
300308
end
301309

302-
# it "submits the form with command or control enter" do
303-
# project = create(:project, name: "Original name")
310+
# The binding lives on the `form` element, so the keydown has to originate from a
311+
# field inside it and bubble up — dispatching on `body` never reaches the form.
312+
# (`fill_in` leaves focus on `body`, hence the explicit `focus_field`.)
313+
{"command" => {meta_key: true}, "control" => {ctrl_key: true}}.each do |modifier, options|
314+
it "submits the form with #{modifier} enter" do
315+
project = create(:project, name: "Original name")
304316

305-
# visit "/admin/resources/projects/#{project.id}/edit"
317+
visit "/admin/resources/projects/#{project.id}/edit"
306318

307-
# fill_in "project_name", with: "Updated from hotkey"
308-
# dispatch_keydown("Enter", meta_key: true)
319+
fill_in "project_name", with: "Updated from hotkey"
320+
focus_field("project_name")
321+
dispatch_active_element_keydown("Enter", **options)
309322

310-
# expect(page).to have_text("Project was successfully updated")
311-
# expect(page).to have_current_path("/admin/resources/projects/#{project.id}")
312-
# expect(project.reload.name).to eq("Updated from hotkey")
313-
# end
323+
expect(page).to have_text("Project was successfully updated")
324+
expect(page).to have_current_path("/admin/resources/projects/#{project.id}")
325+
expect(project.reload.name).to eq("Updated from hotkey")
326+
end
327+
end
314328

315329
describe "Shift+T focuses the screen content" do
316330
def active_element_descriptor

0 commit comments

Comments
 (0)