@@ -169,6 +169,70 @@ async function overflow(page: Parameters<typeof test>[0]["page"], file: string)
169169 }
170170}
171171
172+ async function openReviewFile ( page : Parameters < typeof test > [ 0 ] [ "page" ] , file : string ) {
173+ const row = page . locator ( `[data-file="${ file } "]` ) . first ( )
174+ await expect ( row ) . toBeVisible ( )
175+ await row . hover ( )
176+
177+ const open = row . getByRole ( "button" , { name : / ^ O p e n f i l e $ / i } ) . first ( )
178+ await expect ( open ) . toBeVisible ( )
179+ await open . click ( )
180+
181+ const tab = page . getByRole ( "tab" , { name : file } ) . first ( )
182+ await expect ( tab ) . toBeVisible ( )
183+ await tab . click ( )
184+
185+ const viewer = page . locator ( '[data-component="file"][data-mode="text"]' ) . first ( )
186+ await expect ( viewer ) . toBeVisible ( )
187+ return viewer
188+ }
189+
190+ async function fileComment ( page : Parameters < typeof test > [ 0 ] [ "page" ] , note : string ) {
191+ const viewer = page . locator ( '[data-component="file"][data-mode="text"]' ) . first ( )
192+ await expect ( viewer ) . toBeVisible ( )
193+
194+ const line = viewer . locator ( 'diffs-container [data-line="2"]' ) . first ( )
195+ await expect ( line ) . toBeVisible ( )
196+ await line . hover ( )
197+
198+ const add = viewer . getByRole ( "button" , { name : / ^ C o m m e n t $ / } ) . first ( )
199+ await expect ( add ) . toBeVisible ( )
200+ await add . click ( )
201+
202+ const area = viewer . locator ( '[data-slot="line-comment-textarea"]' ) . first ( )
203+ await expect ( area ) . toBeVisible ( )
204+ await area . fill ( note )
205+
206+ const submit = viewer . locator ( '[data-slot="line-comment-action"][data-variant="primary"]' ) . first ( )
207+ await expect ( submit ) . toBeEnabled ( )
208+ await submit . click ( )
209+
210+ await expect ( viewer . locator ( '[data-slot="line-comment-content"]' ) . filter ( { hasText : note } ) . first ( ) ) . toBeVisible ( )
211+ await expect ( viewer . locator ( '[data-slot="line-comment-tools"]' ) . first ( ) ) . toBeVisible ( )
212+ }
213+
214+ async function fileOverflow ( page : Parameters < typeof test > [ 0 ] [ "page" ] ) {
215+ const viewer = page . locator ( '[data-component="file"][data-mode="text"]' ) . first ( )
216+ const view = page . locator ( '[role="tabpanel"] .scroll-view__viewport' ) . first ( )
217+ const pop = viewer . locator ( '[data-slot="line-comment-popover"][data-inline-body]' ) . first ( )
218+ const tools = viewer . locator ( '[data-slot="line-comment-tools"]' ) . first ( )
219+
220+ const [ width , viewBox , popBox , toolsBox ] = await Promise . all ( [
221+ view . evaluate ( ( el ) => el . scrollWidth - el . clientWidth ) ,
222+ view . boundingBox ( ) ,
223+ pop . boundingBox ( ) ,
224+ tools . boundingBox ( ) ,
225+ ] )
226+
227+ if ( ! viewBox || ! popBox || ! toolsBox ) return null
228+
229+ return {
230+ width,
231+ pop : popBox . x + popBox . width - ( viewBox . x + viewBox . width ) ,
232+ tools : toolsBox . x + toolsBox . width - ( viewBox . x + viewBox . width ) ,
233+ }
234+ }
235+
172236test ( "review applies inline comment clicks without horizontal overflow" , async ( { page, withProject } ) => {
173237 test . setTimeout ( 180_000 )
174238
@@ -218,6 +282,56 @@ test("review applies inline comment clicks without horizontal overflow", async (
218282 } )
219283} )
220284
285+ test ( "review file comments submit on click without clipping actions" , async ( { page, withProject } ) => {
286+ test . setTimeout ( 180_000 )
287+
288+ const tag = `review-file-comment-${ Date . now ( ) } `
289+ const file = `review-file-comment-${ tag } .txt`
290+ const note = `comment ${ tag } `
291+
292+ await page . setViewportSize ( { width : 1280 , height : 900 } )
293+
294+ await withProject ( async ( project ) => {
295+ const sdk = createSdk ( project . directory )
296+
297+ await withSession ( sdk , `e2e review file comment ${ tag } ` , async ( session ) => {
298+ await patch ( sdk , session . id , seed ( [ { file, mark : tag } ] ) )
299+
300+ await expect
301+ . poll (
302+ async ( ) => {
303+ const diff = await sdk . session . diff ( { sessionID : session . id } ) . then ( ( res ) => res . data ?? [ ] )
304+ return diff . length
305+ } ,
306+ { timeout : 60_000 } ,
307+ )
308+ . toBe ( 1 )
309+
310+ await project . gotoSession ( session . id )
311+ await show ( page )
312+
313+ const tab = page . getByRole ( "tab" , { name : / R e v i e w / i } ) . first ( )
314+ await expect ( tab ) . toBeVisible ( )
315+ await tab . click ( )
316+
317+ await expand ( page )
318+ await waitMark ( page , file , tag )
319+ await openReviewFile ( page , file )
320+ await fileComment ( page , note )
321+
322+ await expect
323+ . poll ( async ( ) => ( await fileOverflow ( page ) ) ?. width ?? Number . POSITIVE_INFINITY , { timeout : 10_000 } )
324+ . toBeLessThanOrEqual ( 1 )
325+ await expect
326+ . poll ( async ( ) => ( await fileOverflow ( page ) ) ?. pop ?? Number . POSITIVE_INFINITY , { timeout : 10_000 } )
327+ . toBeLessThanOrEqual ( 1 )
328+ await expect
329+ . poll ( async ( ) => ( await fileOverflow ( page ) ) ?. tools ?? Number . POSITIVE_INFINITY , { timeout : 10_000 } )
330+ . toBeLessThanOrEqual ( 1 )
331+ } )
332+ } )
333+ } )
334+
221335test ( "review keeps scroll position after a live diff update" , async ( { page, withProject } ) => {
222336 test . skip ( Boolean ( process . env . CI ) , "Flaky in CI for now." )
223337 test . setTimeout ( 180_000 )
0 commit comments