@@ -448,18 +448,42 @@ export function collectSnapshot(startingElementId = 0): unknown {
448448 // like any other. Redaction above is realm-safe and runs first, so
449449 // widening this cannot expose a credential field.
450450 const value = ( el as HTMLInputElement ) . value
451- if ( tag === 'INPUT' && ( el as HTMLInputElement ) . type === 'file' ) {
451+ const inputType = tag === 'INPUT' ? ( el as HTMLInputElement ) . type : ''
452+ if ( inputType === 'file' ) {
452453 parts . push ( 'upload-unsupported' )
453- } else if ( value && isSensitiveValueField ( el ) ) parts . push ( 'value-withheld' )
454- else if ( value ) parts . push ( `value=${ quote ( cut ( String ( value ) , 120 ) ) } ` )
454+ } else if ( inputType !== 'checkbox' && inputType !== 'radio' ) {
455+ if ( value && isSensitiveValueField ( el ) ) parts . push ( 'value-withheld' )
456+ else if ( value ) parts . push ( `value=${ quote ( cut ( String ( value ) , 120 ) ) } ` )
457+ }
455458 }
456459 if ( tag === 'A' ) {
457460 const href = el . getAttribute ( 'href' )
458461 if ( href ) parts . push ( `href=${ quote ( cut ( href , 200 ) ) } ` )
459462 }
460463 if ( ( el as HTMLInputElement ) . disabled === true ) parts . push ( 'disabled' )
461464 if ( el . getAttribute ( 'aria-disabled' ) === 'true' ) parts . push ( 'aria-disabled' )
462- if ( ( el as HTMLInputElement ) . checked === true ) parts . push ( 'checked' )
465+ if ( el . getAttribute ( 'aria-readonly' ) === 'true' ) parts . push ( 'aria-readonly' )
466+ if ( el . getAttribute ( 'aria-required' ) === 'true' ) parts . push ( 'aria-required' )
467+ if ( tag === 'INPUT' ) {
468+ const input = el as HTMLInputElement
469+ if ( input . type === 'checkbox' || input . type === 'radio' ) {
470+ parts . push ( input . checked ? 'checked' : 'unchecked' )
471+ }
472+ if ( input . readOnly ) parts . push ( 'readonly' )
473+ if ( input . required ) parts . push ( 'required' )
474+ } else if ( tag === 'TEXTAREA' ) {
475+ const textarea = el as HTMLTextAreaElement
476+ if ( textarea . readOnly ) parts . push ( 'readonly' )
477+ if ( textarea . required ) parts . push ( 'required' )
478+ } else if ( tag === 'SELECT' && ( el as HTMLSelectElement ) . required ) {
479+ parts . push ( 'required' )
480+ }
481+ for ( const attribute of [ 'aria-checked' , 'aria-expanded' , 'aria-pressed' , 'aria-selected' ] ) {
482+ const value = el . getAttribute ( attribute )
483+ if ( value === 'true' || value === 'false' || value === 'mixed' ) {
484+ parts . push ( `${ attribute } =${ value } ` )
485+ }
486+ }
463487 const suffix = parts . length > 0 ? ` ${ parts . join ( ' ' ) } ` : ''
464488 const lineIndex = lines . length
465489 if ( push ( `${ indent } - ${ role } ${ quote ( name ) } [ref=${ id } ]${ suffix } ` ) ) {
0 commit comments