@@ -474,6 +474,121 @@ describe('vwc-dial-pad', () => {
474474 } ) ;
475475 } ) ;
476476
477+ describe ( 'long press on 0' , ( ) => {
478+ function getZeroButton ( component : HTMLElement ) {
479+ return getDigitButtons ( component ) [ 10 ] as Button ;
480+ }
481+
482+ function createPointerEvent (
483+ type : string ,
484+ options : EventInit = { }
485+ ) : PointerEvent {
486+ // Create a mock PointerEvent for test environment
487+ const event = new Event ( type , options ) as PointerEvent ;
488+ Object . defineProperty ( event , 'pointerType' , {
489+ value : 'mouse' ,
490+ writable : true ,
491+ } ) ;
492+ Object . defineProperty ( event , 'pointerId' , {
493+ value : 1 ,
494+ writable : true ,
495+ } ) ;
496+ return event ;
497+ }
498+
499+ it ( 'should add "0" when tapping 0' , async ( ) => {
500+ getZeroButton ( element ) . click ( ) ;
501+ await Updates . next ( ) ;
502+ expect ( getTextField ( element ) . value ) . toEqual ( '0' ) ;
503+ } ) ;
504+
505+ it ( 'should add "+" when long pressing 0 and suppress subsequent click' , async ( ) => {
506+ element . pattern = '^\\+?[0-9#*]*$' ;
507+ await Updates . next ( ) ;
508+ const btn = getZeroButton ( element ) ;
509+ vi . useFakeTimers ( ) ;
510+ try {
511+ const pointerDown = createPointerEvent ( 'pointerdown' , {
512+ bubbles : true ,
513+ } ) ;
514+ Object . defineProperty ( pointerDown , 'currentTarget' , {
515+ value : btn ,
516+ writable : true ,
517+ } ) ;
518+ btn . dispatchEvent ( pointerDown ) ;
519+ vi . advanceTimersByTime ( 600 ) ;
520+ btn . dispatchEvent (
521+ createPointerEvent ( 'pointerup' , {
522+ bubbles : true ,
523+ } )
524+ ) ;
525+ vi . runAllTimers ( ) ;
526+ } finally {
527+ vi . useRealTimers ( ) ;
528+ }
529+ await Updates . next ( ) ;
530+
531+ // Simulate potential click following pointerup; should be suppressed
532+ btn . dispatchEvent ( new MouseEvent ( 'click' , { bubbles : true } ) ) ;
533+ await Updates . next ( ) ;
534+ expect ( getTextField ( element ) . value ) . toEqual ( '+' ) ;
535+ } ) ;
536+
537+ it ( 'should not trigger long press on 0 when disabled' , async ( ) => {
538+ element . pattern = '^\\+?[0-9#*]*$' ;
539+ element . disabled = true ;
540+ await Updates . next ( ) ;
541+ const btn = getZeroButton ( element ) ;
542+ vi . useFakeTimers ( ) ;
543+ try {
544+ const pointerDown = createPointerEvent ( 'pointerdown' , {
545+ bubbles : true ,
546+ } ) ;
547+ Object . defineProperty ( pointerDown , 'currentTarget' , {
548+ value : btn ,
549+ writable : true ,
550+ } ) ;
551+ btn . dispatchEvent ( pointerDown ) ;
552+ vi . advanceTimersByTime ( 600 ) ;
553+ vi . runAllTimers ( ) ;
554+ } finally {
555+ vi . useRealTimers ( ) ;
556+ }
557+ await Updates . next ( ) ;
558+ expect ( getTextField ( element ) . value ) . toEqual ( '' ) ;
559+ } ) ;
560+
561+ it ( 'should not add "+" when pointer leaves 0 button before long press completes' , async ( ) => {
562+ element . pattern = '^\\+?[0-9#*]*$' ;
563+ await Updates . next ( ) ;
564+ const btn = getZeroButton ( element ) ;
565+ vi . useFakeTimers ( ) ;
566+ try {
567+ const pointerDown = createPointerEvent ( 'pointerdown' , {
568+ bubbles : true ,
569+ } ) ;
570+ Object . defineProperty ( pointerDown , 'currentTarget' , {
571+ value : btn ,
572+ writable : true ,
573+ } ) ;
574+ btn . dispatchEvent ( pointerDown ) ;
575+ vi . advanceTimersByTime ( 300 ) ;
576+ // Leave before long press completes
577+ btn . dispatchEvent (
578+ createPointerEvent ( 'pointerleave' , {
579+ bubbles : true ,
580+ } )
581+ ) ;
582+ vi . advanceTimersByTime ( 300 ) ;
583+ vi . runAllTimers ( ) ;
584+ } finally {
585+ vi . useRealTimers ( ) ;
586+ }
587+ await Updates . next ( ) ;
588+ expect ( getTextField ( element ) . value ) . toEqual ( '' ) ;
589+ } ) ;
590+ } ) ;
591+
477592 describe ( 'Methods' , ( ) => {
478593 describe ( 'focus' , function ( ) {
479594 it ( 'should set the focus on the text field' , async function ( ) {
0 commit comments