@@ -112,8 +112,61 @@ def test_fetch_made_without_turbo
112112 assert_equal "*/*" , Primer ::ViewComponents ::ToggleSwitchController . last_request . headers [ "HTTP_ACCEPT" ]
113113 end
114114
115+ def test_switch_does_not_move_when_loading_spinner_is_shown
116+ visit_preview ( :small )
117+
118+ before_top = track_top
119+
120+ # Show the spinner the same way setLoadingState() does, without racing the request.
121+ unhide ( find ( "[data-target='toggle-switch.loadingSpinner']" , visible : :hidden ) )
122+ assert_selector ( "[data-target='toggle-switch.loadingSpinner']" )
123+
124+ assert_in_delta before_top , track_top , 0.5
125+ end
126+
127+ def test_switch_does_not_move_when_error_icon_is_shown
128+ visit_preview ( :small )
129+
130+ before_top = track_top
131+
132+ # Show the error icon the same way setErrorState() does.
133+ unhide ( find ( "[data-target='toggle-switch.errorIcon']" , visible : :hidden ) )
134+ assert_selector ( "[data-target='toggle-switch.errorIcon']" )
135+
136+ assert_in_delta before_top , track_top , 0.5
137+ end
138+
139+ def test_loading_spinner_is_centered_in_the_status_icon_slot
140+ visit_preview ( :small )
141+
142+ unhide ( find ( "[data-target='toggle-switch.loadingSpinner']" , visible : :hidden ) )
143+ assert_selector ( "[data-target='toggle-switch.loadingSpinner']" )
144+
145+ assert_in_delta vertical_center ( find ( "[data-target='toggle-switch.loadingSpinner'] svg" ) ) ,
146+ vertical_center ( find ( ".ToggleSwitch-statusIcon" ) ) ,
147+ 0.5
148+ end
149+
115150 private
116151
152+ # The status icons are hidden with the `hidden` attribute. `hidden` is an HTMLElement IDL
153+ # property, so `el.hidden = false` silently does nothing on the error icon's <svg>. The
154+ # component removes the attribute, so do the same here.
155+ def unhide ( element )
156+ execute_script ( "arguments[0].removeAttribute('hidden');" , element )
157+ end
158+
159+ def track_top
160+ evaluate_script ( "arguments[0].getBoundingClientRect().top;" , find ( ".ToggleSwitch-track" ) )
161+ end
162+
163+ def vertical_center ( element )
164+ evaluate_script (
165+ "(function (r) { return r.top + r.height / 2; })(arguments[0].getBoundingClientRect());" ,
166+ element
167+ )
168+ end
169+
117170 def wait_for_spinner
118171 refute_selector ( "[data-target='toggle-switch.loadingSpinner']" )
119172 end
0 commit comments