@@ -191,6 +191,73 @@ describe('preview-bar-manager', () => {
191191 } ) ;
192192 } ) ;
193193
194+ describe ( 'element picker button disabled state' , ( ) => {
195+ function getSelectBtn ( ) : HTMLButtonElement {
196+ return document . querySelector < HTMLButtonElement > (
197+ '#gist-preview-bar .gist-pb-select-elem-btn'
198+ ) ! ;
199+ }
200+
201+ function getPickerOverlay ( ) : HTMLElement | null {
202+ return document . querySelector < HTMLElement > ( '.gist-pb-picker-overlay' ) ;
203+ }
204+
205+ it ( 'select element button is not disabled initially' , ( ) => {
206+ initBarWithMessage ( [ ] , 'inline' ) ;
207+ expect ( getSelectBtn ( ) . disabled ) . toBe ( false ) ;
208+ } ) ;
209+
210+ it ( 'disables the button when element picker is activated' , ( ) => {
211+ initBarWithMessage ( [ ] , 'inline' ) ;
212+ const btn = getSelectBtn ( ) ;
213+ btn . click ( ) ;
214+ expect ( btn . disabled ) . toBe ( true ) ;
215+ expect ( getPickerOverlay ( ) ) . not . toBeNull ( ) ;
216+ } ) ;
217+
218+ it ( 're-enables the button after picker is cancelled with Escape' , ( ) => {
219+ initBarWithMessage ( [ ] , 'inline' ) ;
220+ getSelectBtn ( ) . click ( ) ;
221+ expect ( getSelectBtn ( ) . disabled ) . toBe ( true ) ;
222+
223+ document . dispatchEvent ( new KeyboardEvent ( 'keydown' , { key : 'Escape' } ) ) ;
224+
225+ expect ( getPickerOverlay ( ) ) . toBeNull ( ) ;
226+ expect ( getSelectBtn ( ) . disabled ) . toBe ( false ) ;
227+ } ) ;
228+
229+ it ( 're-enables the button after an element is picked' , ( ) => {
230+ // Add a target element for the picker to find
231+ const target = document . createElement ( 'div' ) ;
232+ target . id = 'pick-target' ;
233+ document . body . appendChild ( target ) ;
234+
235+ // Stub CSS.escape since jsdom doesn't support it
236+ const globalCSS = globalThis as unknown as Record < string , unknown > ;
237+ const origCSS = globalCSS . CSS ;
238+ globalCSS . CSS = { escape : ( v : string ) => v } ;
239+
240+ initBarWithMessage ( [ ] , 'inline' ) ;
241+ getSelectBtn ( ) . click ( ) ;
242+ expect ( getSelectBtn ( ) . disabled ) . toBe ( true ) ;
243+
244+ const overlay = getPickerOverlay ( ) ! ;
245+ // Simulate clicking on the overlay — elementFromPoint will return the target
246+ const origElementFromPoint = document . elementFromPoint ;
247+ document . elementFromPoint = vi . fn (
248+ ( ) => target
249+ ) as unknown as typeof document . elementFromPoint ;
250+
251+ overlay . dispatchEvent ( new MouseEvent ( 'click' , { bubbles : true } ) ) ;
252+
253+ document . elementFromPoint = origElementFromPoint ;
254+ globalCSS . CSS = origCSS ;
255+
256+ expect ( getPickerOverlay ( ) ) . toBeNull ( ) ;
257+ expect ( getSelectBtn ( ) . disabled ) . toBe ( false ) ;
258+ } ) ;
259+ } ) ;
260+
194261 describe ( 'updatePreviewBarStep' , ( ) => {
195262 it ( 'updates the bar when step changes' , ( ) => {
196263 const steps : StepDisplayConfig [ ] = [
0 commit comments