@@ -446,16 +446,20 @@ try {
446446 } )
447447 } , base . origin )
448448 await observeCaptureReceipts ( )
449- const capture = async ( mode : 'page' | 'selection' = 'page' ) => {
449+ const capture = async ( mode : 'page' | 'selection' | 'shortcut' = 'page' ) => {
450450 await source . bringToFront ( )
451451 const before = Number ( await shell . locator ( 'body' ) . getAttribute ( 'data-capture-receipts' ) )
452- await frame ( ) . getByRole ( 'button' , { name : 'Add resources' , exact : true } ) . press ( 'Enter' )
453- await frame ( )
454- . getByRole ( 'menuitem' , {
455- name : mode === 'page' ? 'Current page' : 'Selected text' ,
456- exact : true ,
457- } )
458- . press ( 'Enter' )
452+ if ( mode === 'shortcut' ) {
453+ await frame ( ) . getByRole ( 'button' , { name : 'Attach current page' , exact : true } ) . press ( 'Enter' )
454+ } else {
455+ await frame ( ) . getByRole ( 'button' , { name : 'Add resources' , exact : true } ) . press ( 'Enter' )
456+ await frame ( )
457+ . getByRole ( 'menuitem' , {
458+ name : mode === 'page' ? 'Current page' : 'Selected text' ,
459+ exact : true ,
460+ } )
461+ . press ( 'Enter' )
462+ }
459463 await expect ( shell . locator ( 'body' ) ) . toHaveAttribute ( 'data-capture-receipts' , String ( before + 1 ) )
460464 }
461465 const attachments = ( ) => frame ( ) . getByRole ( 'group' , { name : 'Page attached to next message' } )
@@ -772,7 +776,51 @@ try {
772776 async ( ) => {
773777 await capture ( )
774778 await attachFile ( )
779+ await shell . setViewportSize ( { width : 320 , height : 844 } )
780+ await capture ( )
781+ await capture ( )
782+ const geometry = await attachments ( )
783+ . first ( )
784+ . evaluate ( ( chip ) => {
785+ const strip = chip . parentElement ?. parentElement
786+ if ( ! strip ) throw new Error ( 'Missing attachment strip' )
787+ return { height : strip . clientHeight , contentHeight : strip . scrollHeight }
788+ } )
789+ assert ( geometry . contentHeight > 102 , 'The fixture did not exercise multiple attachment rows' )
790+ assert (
791+ geometry . contentHeight <= geometry . height + 1 ,
792+ 'Desktop attachments require nested scrolling'
793+ )
775794 await screenshot ( 'mixed-attachments' )
795+ const device = await browserContext . newCDPSession ( frame ( ) )
796+ try {
797+ await device . send ( 'Emulation.setTouchEmulationEnabled' , {
798+ enabled : true ,
799+ maxTouchPoints : 1 ,
800+ } )
801+ await expect
802+ . poll ( ( ) => frame ( ) . evaluate ( ( ) => matchMedia ( '(pointer: coarse)' ) . matches ) )
803+ . toBe ( true )
804+ const touchGeometry = await attachments ( )
805+ . first ( )
806+ . evaluate ( ( chip ) => {
807+ const strip = chip . parentElement ?. parentElement
808+ if ( ! strip ) throw new Error ( 'Missing attachment strip' )
809+ return { height : strip . clientHeight , contentHeight : strip . scrollHeight }
810+ } )
811+ assert ( touchGeometry . height <= 102 , 'Touch attachments lost their height limit' )
812+ assert (
813+ touchGeometry . contentHeight > touchGeometry . height ,
814+ 'Touch overflow fixture did not wrap'
815+ )
816+ await screenshot ( 'touch-attachments' )
817+ } finally {
818+ await device . send ( 'Emulation.setTouchEmulationEnabled' , { enabled : false } )
819+ await device . detach ( )
820+ }
821+ await attachments ( ) . last ( ) . getByRole ( 'button' , { name : 'Remove page context' } ) . click ( )
822+ await attachments ( ) . last ( ) . getByRole ( 'button' , { name : 'Remove page context' } ) . click ( )
823+ await shell . setViewportSize ( { width : 390 , height : 844 } )
776824 await attachments ( ) . first ( ) . getByRole ( 'button' , { name : 'Remove page context' } ) . click ( )
777825 await expect (
778826 frame ( ) . getByRole ( 'button' , { name : 'Remove extension-notes.txt' , exact : true } )
@@ -1223,6 +1271,25 @@ try {
12231271 await screenshot ( 'organization-first-open-capture' )
12241272 }
12251273 )
1274+ await checkNative ( 'The current-page shortcut attaches in both shared composers' , async ( ) => {
1275+ for ( const path of [ `/extension/${ alphaId } ` , `/extension/o/${ organizationId } ` ] ) {
1276+ await navigate ( `${ base . origin } ${ path } ` )
1277+ await expect ( attachments ( ) ) . toHaveCount ( 0 )
1278+ await capture ( 'shortcut' )
1279+ await expect ( attachments ( ) ) . toHaveCount ( 1 )
1280+ await attachments ( )
1281+ . first ( )
1282+ . getByRole ( 'button' , { name : / ^ R e v i e w p a g e c o n t e x t : / } )
1283+ . click ( )
1284+ const preview = frame ( ) . getByRole ( 'dialog' , { name : 'Page context' , exact : true } )
1285+ await expect ( preview . locator ( 'pre' ) ) . toContainText ( captureText )
1286+ await preview . getByRole ( 'button' , { name : 'Close' , exact : true } ) . click ( )
1287+ await frame ( ) . getByRole ( 'button' , { name : 'Attach current page' , exact : true } ) . hover ( )
1288+ await expect ( frame ( ) . getByRole ( 'tooltip' , { name : 'Attach current page' } ) ) . toBeVisible ( )
1289+ await screenshot ( path . includes ( '/o/' ) ? 'shortcut-organization-agent' : 'shortcut-workspace' )
1290+ await attachments ( ) . first ( ) . getByRole ( 'button' , { name : 'Remove page context' } ) . click ( )
1291+ }
1292+ } )
12261293 if ( liveChat ) {
12271294 await checkNative (
12281295 'Organization live admission preserves queued pages, files, and the admitted conversation mode' ,
@@ -1379,6 +1446,9 @@ try {
13791446 await screenshot ( 'organization-mode-file-recovery' )
13801447 await frame ( ) . getByRole ( 'button' , { name : 'Remove extension-notes.txt' , exact : true } ) . click ( )
13811448 await expect ( frame ( ) . getByText ( / R e m o v e u n s u p p o r t e d f i l e s / ) ) . not . toBeVisible ( )
1449+ await attachments ( ) . first ( ) . getByRole ( 'button' , { name : 'Remove page context' } ) . click ( )
1450+ await capture ( 'shortcut' )
1451+ await expect ( attachments ( ) ) . toHaveCount ( 1 )
13821452 await screenshot ( 'organization-assistant-page' )
13831453 if ( ! liveChat )
13841454 await shell . route ( '**/api/mothership/chat' , ( route ) =>
0 commit comments