1- import { expect , test } from "@playwright/test"
1+ import { expect , test , type Page } from "@playwright/test"
22import { mockOpenCodeServer } from "../utils/mock-server"
33import { expectSessionTitle } from "../utils/waits"
44
@@ -14,6 +14,7 @@ const branchDiffs = [
1414]
1515
1616test ( "keeps the review tree and terminal sized when both panels are open" , async ( { page } ) => {
17+ test . setTimeout ( 120_000 )
1718 await page . setViewportSize ( { width : 1400 , height : 900 } )
1819 await mockOpenCodeServer ( page , {
1920 directory,
@@ -91,17 +92,73 @@ test("keeps the review tree and terminal sized when both panels are open", async
9192 await expect ( page . locator ( "#terminal-panel" ) ) . toBeVisible ( )
9293 // Terminal activation retries focus through 240ms; let that settle before opening the mode select.
9394 await page . waitForTimeout ( 300 )
94- await page . getByRole ( "button" , { name : "Git changes" } ) . click ( )
95- await page . getByRole ( "option" , { name : "Branch changes" } ) . click ( )
95+ await selectMode ( page , "Git changes" , "Branch changes" )
9696 await expect ( page . getByRole ( "tab" , { name : "Review 2740" } ) ) . toBeVisible ( )
97- await expect ( page . getByRole ( "button" , { name : "action.yml" } ) ) . toBeVisible ( )
97+ await expectTree ( page , 2_745 , "action.yml" )
98+ await expectStackGeometry ( page )
9899
100+ await page . locator ( '#review-panel [data-component="file-tree-v2"]' ) . evaluate ( ( element ) => {
101+ const viewport = element . closest < HTMLElement > ( ".scroll-view__viewport" ) !
102+ viewport . scrollTop = viewport . scrollHeight
103+ } )
104+ await selectMode ( page , "Branch changes" , "Git changes" )
105+ await expectTree ( page , 2 , "git.ts" )
106+ await selectMode ( page , "Git changes" , "Branch changes" )
107+ await expectTree ( page , 2_745 , "action.yml" )
108+
109+ const filter = page . getByRole ( "searchbox" , { name : "Filter files" } )
110+ await filter . fill ( "generated-2738" )
111+ await expectTree ( page , 1 , "generated-2738.ts" )
112+ await filter . fill ( "" )
113+ await expectTree ( page , 2_745 , "action.yml" )
114+
115+ await page . getByRole ( "button" , { name : "Toggle file tree" } ) . click ( )
116+ await expect ( page . locator ( '[data-slot="session-review-v2-sidebar"]' ) ) . toHaveAttribute ( "aria-hidden" , "true" )
117+ await expect ( page . locator ( '#review-panel [data-component="file-tree-v2"]' ) ) . toHaveCount ( 1 )
118+ await page . getByRole ( "button" , { name : "Toggle file tree" } ) . click ( )
119+ await expectTree ( page , 2_745 , "action.yml" )
120+
121+ await page . keyboard . press ( "Control+Backquote" )
122+ await expect ( page . locator ( "#terminal-panel" ) ) . toHaveCount ( 0 )
123+ await expectTree ( page , 2_745 , "action.yml" )
124+ await page . keyboard . press ( "Control+Backquote" )
125+ await expect ( page . locator ( "#terminal-panel" ) ) . toBeVisible ( )
126+ await expectTree ( page , 2_745 , "action.yml" )
127+
128+ await page . getByRole ( "button" , { name : "Toggle review" } ) . click ( )
129+ await expect ( page . locator ( "#review-panel" ) ) . toHaveAttribute ( "aria-hidden" , "true" )
130+ await expect ( page . locator ( '#review-panel [data-component="file-tree-v2"]' ) ) . toHaveCount ( 1 )
131+ await page . getByRole ( "button" , { name : "Toggle review" } ) . click ( )
132+ await expectTree ( page , 2_745 , "action.yml" )
133+ await page . setViewportSize ( { width : 1_000 , height : 700 } )
134+ await expectTree ( page , 2_745 , "action.yml" )
135+ await expectStackGeometry ( page )
136+ } )
137+
138+ async function selectMode ( page : Page , current : string , next : string ) {
139+ await page . getByRole ( "button" , { name : current } ) . click ( )
140+ await page . getByRole ( "option" , { name : next } ) . click ( )
141+ }
142+
143+ async function expectTree ( page : Page , total : number , file : string ) {
99144 const tree = page . locator ( '#review-panel [data-component="file-tree-v2"]' )
100- await expect ( tree ) . toHaveAttribute ( "data-total-rows" , "2745" )
101- const renderedRows = await tree . locator ( '[data-slot="file-tree-v2-row"]' ) . count ( )
102- expect ( renderedRows ) . toBeGreaterThan ( 0 )
103- expect ( renderedRows ) . toBeLessThanOrEqual ( 60 )
145+ await expect ( tree ) . toHaveAttribute ( "data-total-rows" , String ( total ) )
146+ await expect
147+ . poll ( ( ) => tree . evaluate ( ( element ) => element . querySelectorAll ( '[data-slot="file-tree-v2-row"]' ) . length ) )
148+ . toBeGreaterThan ( 0 )
149+ const state = await tree . evaluate ( ( element ) => ( {
150+ root : element . getBoundingClientRect ( ) . height ,
151+ viewport : element . closest < HTMLElement > ( ".scroll-view__viewport" ) ! . getBoundingClientRect ( ) . height ,
152+ rows : element . querySelectorAll ( '[data-slot="file-tree-v2-row"]' ) . length ,
153+ } ) )
154+ expect ( state . viewport ) . toBeGreaterThan ( 0 )
155+ expect ( state . root ) . toBeGreaterThan ( 0 )
156+ expect ( state . rows ) . toBeGreaterThan ( 0 )
157+ expect ( state . rows ) . toBeLessThanOrEqual ( 60 )
158+ await expect ( page . getByRole ( "button" , { name : file } ) ) . toBeVisible ( )
159+ }
104160
161+ async function expectStackGeometry ( page : Page ) {
105162 const geometry = await page . evaluate ( ( ) => {
106163 const review = document . querySelector < HTMLElement > ( "#review-panel" ) !
107164 const terminal = document . querySelector < HTMLElement > ( "#terminal-panel" ) !
@@ -116,7 +173,7 @@ test("keeps the review tree and terminal sized when both panels are open", async
116173 } )
117174 expect ( Math . abs ( geometry . review - geometry . reviewParent ) ) . toBeLessThanOrEqual ( 1 )
118175 expect ( Math . abs ( geometry . terminal - geometry . terminalParent ) ) . toBeLessThanOrEqual ( 1 )
119- } )
176+ }
120177
121178function base64Encode ( value : string ) {
122179 return Buffer . from ( value , "utf8" ) . toString ( "base64" ) . replace ( / \+ / g, "-" ) . replace ( / \/ / g, "_" ) . replace ( / = / g, "" )
0 commit comments