From 67ae2e72f31f50ebf94e48d904a72e5b746e88d9 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 28 Jan 2022 16:18:14 +0000 Subject: [PATCH 1/4] Replace inline JS for toggling order cycle advanced settings with StimulusJs controller Partially addresses #8699. This adjusts the Stimulus toggle controller so you can toggle content in both directions via a single element. This is in addition to the previous behaviour for toggling via multiple elements like radio buttons when each element always toggles in one direction only. If a toggle element contains a chevron icon this will automatically toggle the direction of that icon too. Note, in order to not have to re-implement the animation provided by the slideToggle() function in standard JavaScript, this just switches the style :display between 'none' and 'block' so it is not as smooth. Perhaps it could be made more smooth later with a CSS transition. --- .../_order_cycle_top_buttons.html.haml | 16 +--- app/views/spree/layouts/_admin_body.html.haml | 2 +- .../controllers/toggle_controller.js | 15 +++- .../stimulus/toggle_controller_test.js | 83 +++++++++++++++++-- 4 files changed, 93 insertions(+), 23 deletions(-) diff --git a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml index 86ca6b2ae4..08bbb2c70d 100644 --- a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml +++ b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml @@ -1,19 +1,9 @@ +- content_for :wrapper_data_controllers, "toggle" - content_for :page_actions do - :javascript - function toggleSettings(){ - if( $('#advanced_settings').is(":visible") ){ - $('button#toggle_settings i').switchClass("icon-chevron-up","icon-chevron-down") - } - else { - $('button#toggle_settings i').switchClass("icon-chevron-down","icon-chevron-up") - } - $("#advanced_settings").slideToggle() - } - %li - %button#toggle_settings{ onClick: 'toggleSettings()' } + %button#toggle_settings{ "data-action": "toggle#toggle" } = t('.advanced_settings') %i.icon-chevron-down -#advanced_settings{ hidden: true } +#advanced_settings{ "data-toggle-target": "content", style: "display: none" } = render partial: "/admin/order_cycles/advanced_settings" diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index bc380b803c..68b02110ce 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -2,7 +2,7 @@ = render "layouts/i18n_script" = yield :stripe_js -#wrapper{ data: { hook: '' } } +#wrapper{ data: { hook: '', controller: (yield :wrapper_data_controllers) } } .flash-container - if flash[:error] .flash.error= flash[:error] diff --git a/app/webpacker/controllers/toggle_controller.js b/app/webpacker/controllers/toggle_controller.js index de87ad095d..0084e10d76 100644 --- a/app/webpacker/controllers/toggle_controller.js +++ b/app/webpacker/controllers/toggle_controller.js @@ -4,9 +4,22 @@ export default class extends Controller { static targets = ["content"]; toggle(event) { + event.stopImmediatePropagation() const input = event.currentTarget; + const chevron = input.querySelector(".icon-chevron-down, .icon-chevron-up") + const toggleViaSingleElement = !input.dataset.toggleShow; + + if(chevron) { + chevron.classList.toggle("icon-chevron-down"); + chevron.classList.toggle("icon-chevron-up"); + } + this.contentTargets.forEach((t) => { - t.style.display = input.dataset.toggleShow === "true" ? "block" : "none"; + if(toggleViaSingleElement) { + t.style.display = t.style.display === "none" ? "block" : "none"; + } else { + t.style.display = input.dataset.toggleShow === "true" ? "block" : "none"; + } }); } } diff --git a/spec/javascripts/stimulus/toggle_controller_test.js b/spec/javascripts/stimulus/toggle_controller_test.js index 7dcd527e16..94f2727fc1 100644 --- a/spec/javascripts/stimulus/toggle_controller_test.js +++ b/spec/javascripts/stimulus/toggle_controller_test.js @@ -9,9 +9,17 @@ describe("ToggleController", () => { describe("#toggle", () => { beforeEach(() => { document.body.innerHTML = `
- -
- content + + + + +
+ visible content +
+
`; @@ -19,14 +27,73 @@ describe("ToggleController", () => { application.register("toggle", toggle_controller); }); - it("toggle the content", () => { - const button = document.getElementById("button"); - const content = document.getElementById("content"); - expect(content.style.display).toBe(""); + it("toggling a button which shows and hides content switches the visibility of content", () => { + const button = document.getElementById("toggle"); + const invisibleContent = document.getElementById("invisible-content"); + const visibleContent = document.getElementById("visible-content"); + expect(invisibleContent.style.display).toBe("none"); + expect(visibleContent.style.display).toBe("block"); button.click(); - expect(content.style.display).toBe("block"); + expect(invisibleContent.style.display).toBe("block"); + expect(visibleContent.style.display).toBe("none"); + }); + + it("toggling a button with 'data-toggle-show=true' shows invisible content", () => { + const button = document.getElementById("toggle-show"); + const invisibleContent = document.getElementById("invisible-content"); + expect(invisibleContent.style.display).toBe("none"); + + button.click(); + + expect(invisibleContent.style.display).toBe("block"); + }); + + it("toggling a button with 'data-toggle-show=true' doesn't hide visible content", () => { + const button = document.getElementById("toggle-show"); + const visibleContent = document.getElementById("visible-content"); + expect(visibleContent.style.display).toBe("block"); + + button.click(); + + expect(visibleContent.style.display).toBe("block"); + }); + + it("toggling a button with 'data-toggle-show=false' hides visible content", () => { + const button = document.getElementById("toggle-hide"); + const visibleContent = document.getElementById("visible-content"); + expect(visibleContent.style.display).toBe("block"); + + button.click(); + + expect(visibleContent.style.display).toBe("none"); + }); + + it("toggling a button with 'data-toggle-show=false' doesn't show invisible content", () => { + const button = document.getElementById("toggle-hide"); + const invisibleContent = document.getElementById("invisible-content"); + expect(invisibleContent.style.display).toBe("none"); + + button.click(); + + expect(invisibleContent.style.display).toBe("none"); + }); + + it("toggling a button with a chevron icon switches the visibility of content and the direction of the icon", () => { + const buttonA = document.getElementById("toggle-with-chevron"); + const chevron = buttonA.querySelector("i"); + const invisibleContent = document.getElementById("invisible-content"); + const visibleContent = document.getElementById("visible-content"); + expect(invisibleContent.style.display).toBe("none"); + expect(visibleContent.style.display).toBe("block"); + expect(chevron.className).toBe("icon-chevron-down"); + + buttonA.click(); + + expect(invisibleContent.style.display).toBe("block"); + expect(visibleContent.style.display).toBe("none"); + expect(chevron.className).toBe("icon-chevron-up"); }); }); }); From d03b52a163302a32b6417947c9b49131dd681b84 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 4 Feb 2022 11:47:38 +0000 Subject: [PATCH 2/4] Revert "Replace inline JS for toggling order cycle advanced settings with StimulusJs controller" This reverts commit 67ae2e72f31f50ebf94e48d904a72e5b746e88d9. --- .../_order_cycle_top_buttons.html.haml | 16 +++- app/views/spree/layouts/_admin_body.html.haml | 2 +- .../controllers/toggle_controller.js | 15 +--- .../stimulus/toggle_controller_test.js | 83 ++----------------- 4 files changed, 23 insertions(+), 93 deletions(-) diff --git a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml index 08bbb2c70d..86ca6b2ae4 100644 --- a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml +++ b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml @@ -1,9 +1,19 @@ -- content_for :wrapper_data_controllers, "toggle" - content_for :page_actions do + :javascript + function toggleSettings(){ + if( $('#advanced_settings').is(":visible") ){ + $('button#toggle_settings i').switchClass("icon-chevron-up","icon-chevron-down") + } + else { + $('button#toggle_settings i').switchClass("icon-chevron-down","icon-chevron-up") + } + $("#advanced_settings").slideToggle() + } + %li - %button#toggle_settings{ "data-action": "toggle#toggle" } + %button#toggle_settings{ onClick: 'toggleSettings()' } = t('.advanced_settings') %i.icon-chevron-down -#advanced_settings{ "data-toggle-target": "content", style: "display: none" } +#advanced_settings{ hidden: true } = render partial: "/admin/order_cycles/advanced_settings" diff --git a/app/views/spree/layouts/_admin_body.html.haml b/app/views/spree/layouts/_admin_body.html.haml index 68b02110ce..bc380b803c 100644 --- a/app/views/spree/layouts/_admin_body.html.haml +++ b/app/views/spree/layouts/_admin_body.html.haml @@ -2,7 +2,7 @@ = render "layouts/i18n_script" = yield :stripe_js -#wrapper{ data: { hook: '', controller: (yield :wrapper_data_controllers) } } +#wrapper{ data: { hook: '' } } .flash-container - if flash[:error] .flash.error= flash[:error] diff --git a/app/webpacker/controllers/toggle_controller.js b/app/webpacker/controllers/toggle_controller.js index 0084e10d76..de87ad095d 100644 --- a/app/webpacker/controllers/toggle_controller.js +++ b/app/webpacker/controllers/toggle_controller.js @@ -4,22 +4,9 @@ export default class extends Controller { static targets = ["content"]; toggle(event) { - event.stopImmediatePropagation() const input = event.currentTarget; - const chevron = input.querySelector(".icon-chevron-down, .icon-chevron-up") - const toggleViaSingleElement = !input.dataset.toggleShow; - - if(chevron) { - chevron.classList.toggle("icon-chevron-down"); - chevron.classList.toggle("icon-chevron-up"); - } - this.contentTargets.forEach((t) => { - if(toggleViaSingleElement) { - t.style.display = t.style.display === "none" ? "block" : "none"; - } else { - t.style.display = input.dataset.toggleShow === "true" ? "block" : "none"; - } + t.style.display = input.dataset.toggleShow === "true" ? "block" : "none"; }); } } diff --git a/spec/javascripts/stimulus/toggle_controller_test.js b/spec/javascripts/stimulus/toggle_controller_test.js index 94f2727fc1..7dcd527e16 100644 --- a/spec/javascripts/stimulus/toggle_controller_test.js +++ b/spec/javascripts/stimulus/toggle_controller_test.js @@ -9,17 +9,9 @@ describe("ToggleController", () => { describe("#toggle", () => { beforeEach(() => { document.body.innerHTML = `
- - - - -
- visible content -
- `; @@ -27,73 +19,14 @@ describe("ToggleController", () => { application.register("toggle", toggle_controller); }); - it("toggling a button which shows and hides content switches the visibility of content", () => { - const button = document.getElementById("toggle"); - const invisibleContent = document.getElementById("invisible-content"); - const visibleContent = document.getElementById("visible-content"); - expect(invisibleContent.style.display).toBe("none"); - expect(visibleContent.style.display).toBe("block"); + it("toggle the content", () => { + const button = document.getElementById("button"); + const content = document.getElementById("content"); + expect(content.style.display).toBe(""); button.click(); - expect(invisibleContent.style.display).toBe("block"); - expect(visibleContent.style.display).toBe("none"); - }); - - it("toggling a button with 'data-toggle-show=true' shows invisible content", () => { - const button = document.getElementById("toggle-show"); - const invisibleContent = document.getElementById("invisible-content"); - expect(invisibleContent.style.display).toBe("none"); - - button.click(); - - expect(invisibleContent.style.display).toBe("block"); - }); - - it("toggling a button with 'data-toggle-show=true' doesn't hide visible content", () => { - const button = document.getElementById("toggle-show"); - const visibleContent = document.getElementById("visible-content"); - expect(visibleContent.style.display).toBe("block"); - - button.click(); - - expect(visibleContent.style.display).toBe("block"); - }); - - it("toggling a button with 'data-toggle-show=false' hides visible content", () => { - const button = document.getElementById("toggle-hide"); - const visibleContent = document.getElementById("visible-content"); - expect(visibleContent.style.display).toBe("block"); - - button.click(); - - expect(visibleContent.style.display).toBe("none"); - }); - - it("toggling a button with 'data-toggle-show=false' doesn't show invisible content", () => { - const button = document.getElementById("toggle-hide"); - const invisibleContent = document.getElementById("invisible-content"); - expect(invisibleContent.style.display).toBe("none"); - - button.click(); - - expect(invisibleContent.style.display).toBe("none"); - }); - - it("toggling a button with a chevron icon switches the visibility of content and the direction of the icon", () => { - const buttonA = document.getElementById("toggle-with-chevron"); - const chevron = buttonA.querySelector("i"); - const invisibleContent = document.getElementById("invisible-content"); - const visibleContent = document.getElementById("visible-content"); - expect(invisibleContent.style.display).toBe("none"); - expect(visibleContent.style.display).toBe("block"); - expect(chevron.className).toBe("icon-chevron-down"); - - buttonA.click(); - - expect(invisibleContent.style.display).toBe("block"); - expect(visibleContent.style.display).toBe("none"); - expect(chevron.className).toBe("icon-chevron-up"); + expect(content.style.display).toBe("block"); }); }); }); From 05756616dd8d514640aabacf7fb298ee6f516115 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 4 Feb 2022 12:23:24 +0000 Subject: [PATCH 3/4] Add a remote-toggle controller that can toggle elements outside of its scope This is instead of adding the :data-controller attribute to the div#wrapper because that will wrap pretty much all content on the admin pages. Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> --- .../_order_cycle_top_buttons.html.haml | 19 ++---- .../controllers/remote_toggle_controller.js | 17 ++++++ .../stimulus/remote_toggle_controller_test.js | 58 +++++++++++++++++++ 3 files changed, 79 insertions(+), 15 deletions(-) create mode 100644 app/webpacker/controllers/remote_toggle_controller.js create mode 100644 spec/javascripts/stimulus/remote_toggle_controller_test.js diff --git a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml index 86ca6b2ae4..2cc89117b0 100644 --- a/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml +++ b/app/views/admin/order_cycles/_order_cycle_top_buttons.html.haml @@ -1,19 +1,8 @@ - content_for :page_actions do - :javascript - function toggleSettings(){ - if( $('#advanced_settings').is(":visible") ){ - $('button#toggle_settings i').switchClass("icon-chevron-up","icon-chevron-down") - } - else { - $('button#toggle_settings i').switchClass("icon-chevron-down","icon-chevron-up") - } - $("#advanced_settings").slideToggle() - } - - %li - %button#toggle_settings{ onClick: 'toggleSettings()' } + %li{ "data-controller": "remote-toggle", "data-remote-toggle-selector-value": "#advanced_settings" } + %button#toggle_settings{ "data-action": "click->remote-toggle#toggle" } = t('.advanced_settings') - %i.icon-chevron-down + %i.icon-chevron-down{ "data-remote-toggle-target": "chevron" } -#advanced_settings{ hidden: true } +#advanced_settings{ style: "display: none" } = render partial: "/admin/order_cycles/advanced_settings" diff --git a/app/webpacker/controllers/remote_toggle_controller.js b/app/webpacker/controllers/remote_toggle_controller.js new file mode 100644 index 0000000000..25006d8651 --- /dev/null +++ b/app/webpacker/controllers/remote_toggle_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "stimulus"; + +export default class extends Controller { + static targets = ["chevron"]; + static values = { selector: String } + + toggle(event) { + if (this.hasChevronTarget) { + this.chevronTarget.classList.toggle("icon-chevron-down") + this.chevronTarget.classList.toggle("icon-chevron-up") + } + + const element = document.querySelector(this.selectorValue) + element.style.display = element.style.display === "none" ? "block" : "none" + } +} + diff --git a/spec/javascripts/stimulus/remote_toggle_controller_test.js b/spec/javascripts/stimulus/remote_toggle_controller_test.js new file mode 100644 index 0000000000..e46a0b61fe --- /dev/null +++ b/spec/javascripts/stimulus/remote_toggle_controller_test.js @@ -0,0 +1,58 @@ +/** + * @jest-environment jsdom + */ + +import { Application } from "stimulus"; +import remote_toggle_controller from "../../../app/webpacker/controllers/remote_toggle_controller"; + +describe("RemoteToggleController", () => { + describe("#toggle", () => { + beforeEach(() => { + document.body.innerHTML = ` +
+ + +
+
...
+ `; + + const application = Application.start(); + application.register("remote-toggle", remote_toggle_controller); + }); + + it("clicking a toggle switches the visibility of the :data-remote-toggle-selector element", () => { + const button = document.getElementById("remote-toggle"); + const content = document.getElementById("content"); + expect(content.style.display).toBe(""); + + button.click(); + + expect(content.style.display).toBe("none"); + + button.click(); + + expect(content.style.display).toBe("block"); + }); + + /* skipping, this test passes when it's the only test in this file but not otherwise? */ + it.skip("clicking a toggle with a chevron icon switches the visibility of content and the direction of the icon", () => { + const button = document.getElementById("remote-toggle-with-chevron"); + const chevron = button.querySelector("i"); + const content = document.getElementById("content"); + expect(content.style.display).toBe(""); + expect(chevron.className).toBe("icon-chevron-down"); + + button.click(); + + expect(content.style.display).toBe("none"); + expect(chevron.className).toBe("icon-chevron-up"); + + button.click(); + + expect(content.style.display).toBe("block"); + expect(chevron.className).toBe("icon-chevron-down"); + }); + }); +}); From 1b8c1bd27a3816473a6c78c0a33f086eee75374d Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 11 Feb 2022 10:21:26 +0000 Subject: [PATCH 4/4] Only initialise Stimulus app once in Jest tests in :beforeAll rather than :beforeEach Before there was an issue with the remote_toggle_controller tests, which contains two tests. If you commented out one test and ran the other it would pass and vice versa but if both tests were uncommented only the first test would ever pass, the second one would fail. See https://github.com/openfoodfoundation/openfoodnetwork/pull/8805#discussion_r801464322 Co-authored-by: Matt-Yorkley <9029026+Matt-Yorkley@users.noreply.github.com> --- .../stimulus/paymentmethod_controller_test.js | 10 ++++++---- .../stimulus/remote_toggle_controller_test.js | 11 ++++++----- .../stimulus/stripe_cards_controller_test.js | 8 +++++--- spec/javascripts/stimulus/tabs_controller_test.js | 10 ++++++---- spec/javascripts/stimulus/toggle_controller_test.js | 8 +++++--- spec/javascripts/stimulus/update_controller_test.js | 8 +++++--- 6 files changed, 33 insertions(+), 22 deletions(-) diff --git a/spec/javascripts/stimulus/paymentmethod_controller_test.js b/spec/javascripts/stimulus/paymentmethod_controller_test.js index 09180ac066..b81dbbf605 100644 --- a/spec/javascripts/stimulus/paymentmethod_controller_test.js +++ b/spec/javascripts/stimulus/paymentmethod_controller_test.js @@ -6,13 +6,18 @@ import { Application } from "stimulus"; import paymentmethod_controller from "../../../app/webpacker/controllers/paymentmethod_controller"; describe("PaymentmethodController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("paymentmethod", paymentmethod_controller); + }); + describe("#selectPaymentMethod", () => { beforeEach(() => { document.body.innerHTML = `
- +
`; - - const application = Application.start(); - application.register("paymentmethod", paymentmethod_controller); }); it("fill the right payment container", () => { diff --git a/spec/javascripts/stimulus/remote_toggle_controller_test.js b/spec/javascripts/stimulus/remote_toggle_controller_test.js index e46a0b61fe..507ce3827d 100644 --- a/spec/javascripts/stimulus/remote_toggle_controller_test.js +++ b/spec/javascripts/stimulus/remote_toggle_controller_test.js @@ -6,6 +6,11 @@ import { Application } from "stimulus"; import remote_toggle_controller from "../../../app/webpacker/controllers/remote_toggle_controller"; describe("RemoteToggleController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("remote-toggle", remote_toggle_controller); + }); + describe("#toggle", () => { beforeEach(() => { document.body.innerHTML = ` @@ -17,9 +22,6 @@ describe("RemoteToggleController", () => {
...
`; - - const application = Application.start(); - application.register("remote-toggle", remote_toggle_controller); }); it("clicking a toggle switches the visibility of the :data-remote-toggle-selector element", () => { @@ -36,8 +38,7 @@ describe("RemoteToggleController", () => { expect(content.style.display).toBe("block"); }); - /* skipping, this test passes when it's the only test in this file but not otherwise? */ - it.skip("clicking a toggle with a chevron icon switches the visibility of content and the direction of the icon", () => { + it("clicking a toggle with a chevron icon switches the visibility of content and the direction of the icon", () => { const button = document.getElementById("remote-toggle-with-chevron"); const chevron = button.querySelector("i"); const content = document.getElementById("content"); diff --git a/spec/javascripts/stimulus/stripe_cards_controller_test.js b/spec/javascripts/stimulus/stripe_cards_controller_test.js index 44679a1e81..36d74ea314 100644 --- a/spec/javascripts/stimulus/stripe_cards_controller_test.js +++ b/spec/javascripts/stimulus/stripe_cards_controller_test.js @@ -6,6 +6,11 @@ import { Application } from "stimulus"; import stripe_cards_controller from "../../../app/webpacker/controllers/stripe_cards_controller"; describe("StripeCardsController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("stripe-cards", stripe_cards_controller); + }); + beforeEach(() => { document.body.innerHTML = `
`; - - const application = Application.start(); - application.register("stripe-cards", stripe_cards_controller); }); describe("#connect", () => { it("initialize with the right display state", () => { diff --git a/spec/javascripts/stimulus/tabs_controller_test.js b/spec/javascripts/stimulus/tabs_controller_test.js index a67296bd0b..fa4ab5d737 100644 --- a/spec/javascripts/stimulus/tabs_controller_test.js +++ b/spec/javascripts/stimulus/tabs_controller_test.js @@ -6,6 +6,11 @@ import { Application } from "stimulus"; import tabs_controller from "../../../app/webpacker/controllers/tabs_controller"; describe("TabsController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("tabs", tabs_controller); + }); + describe("#select", () => { beforeEach(() => { document.body.innerHTML = ` @@ -13,7 +18,7 @@ describe("TabsController", () => { - +
Dogs content
@@ -25,9 +30,6 @@ describe("TabsController", () => { `; - - const application = Application.start(); - application.register("tabs", tabs_controller); }); it("shows the corresponding content when a tab button is clicked", () => { diff --git a/spec/javascripts/stimulus/toggle_controller_test.js b/spec/javascripts/stimulus/toggle_controller_test.js index 7dcd527e16..c60669d1b8 100644 --- a/spec/javascripts/stimulus/toggle_controller_test.js +++ b/spec/javascripts/stimulus/toggle_controller_test.js @@ -6,6 +6,11 @@ import { Application } from "stimulus"; import toggle_controller from "../../../app/webpacker/controllers/toggle_controller"; describe("ToggleController", () => { + beforeAll(() => { + const application = Application.start(); + application.register("toggle", toggle_controller); + }); + describe("#toggle", () => { beforeEach(() => { document.body.innerHTML = `
@@ -14,9 +19,6 @@ describe("ToggleController", () => { content
`; - - const application = Application.start(); - application.register("toggle", toggle_controller); }); it("toggle the content", () => { diff --git a/spec/javascripts/stimulus/update_controller_test.js b/spec/javascripts/stimulus/update_controller_test.js index 33c85645c7..a6c4463944 100644 --- a/spec/javascripts/stimulus/update_controller_test.js +++ b/spec/javascripts/stimulus/update_controller_test.js @@ -6,15 +6,17 @@ import { Application } from "stimulus"; import updateinput_controller from "../../../app/webpacker/controllers/updateinput_controller"; describe("updateInput controller", () => { + beforeAll(() => { + const application = Application.start(); + application.register("updateinput", updateinput_controller); + }); + describe("#update", () => { beforeEach(() => { document.body.innerHTML = `
`; - - const application = Application.start(); - application.register("updateinput", updateinput_controller); }); it("update the input value", () => {