77 compactionFailed ,
88 compactionStarted ,
99 directory ,
10- event ,
1110 session ,
1211 sessionID ,
1312 setupTimeline ,
@@ -87,12 +86,13 @@ test("renders current protocol notices in CLI order", async ({ page }) => {
8786 expect ( ownerWarnings ) . toEqual ( [ ] )
8887} )
8988
90- test ( "renders a compaction summary while it streams and after completion " , async ( { page } ) => {
89+ test ( "renders compaction progress, summary, and outcome in order " , async ( { page } ) => {
9190 const timeline = await setupTimeline ( page , {
9291 settings : {
9392 timelineDetail : { ...timelinePresets [ 2 ] . value , notices : { placement : "separate" } } ,
9493 } ,
9594 sessionMessages : [ user , assistant ( true ) ] ,
95+ sessionStatus : { [ sessionID ] : { type : "busy" } } ,
9696 } )
9797
9898 await timeline . send (
@@ -104,7 +104,15 @@ test("renders a compaction summary while it streams and after completion", async
104104 )
105105
106106 const compaction = page . locator ( '[data-component="session-compaction-message"]' )
107- await expect ( compaction . getByText ( "Session compacted" , { exact : true } ) ) . toBeVisible ( )
107+ await expect ( compaction . getByText ( "Session compaction started" , { exact : true } ) ) . toBeVisible ( )
108+ await expect ( compaction . getByRole ( "status" ) . getByLabel ( "Compacting" , { exact : true } ) ) . toBeVisible ( )
109+ await expect ( compaction . locator ( '[data-component="text-shimmer"]' ) ) . toHaveAttribute ( "data-active" , "true" )
110+ await expect ( compaction . getByText ( "Session compacted" , { exact : true } ) ) . toHaveCount ( 0 )
111+ await expect ( page . getByRole ( "button" , { name : "Stop" , exact : true } ) ) . toBeVisible ( )
112+ await expect ( page . locator ( '[data-component="session-working"]' ) ) . toHaveCount ( 0 )
113+
114+ await page . setViewportSize ( { width : 480 , height : 900 } )
115+ await expect ( compaction . getByText ( "Session compaction started" , { exact : true } ) ) . toBeInViewport ( )
108116
109117 await timeline . send (
110118 compactionDelta ( {
@@ -114,6 +122,8 @@ test("renders a compaction summary while it streams and after completion", async
114122 )
115123 await expect ( compaction . getByRole ( "heading" , { name : "Checkpoint" } ) ) . toBeVisible ( )
116124 await expect ( compaction ) . toContainText ( "Streamed implementation details." )
125+ await expect ( compaction . getByRole ( "status" ) . getByLabel ( "Compacting" , { exact : true } ) ) . toBeVisible ( )
126+ await expect ( compaction . getByText ( "Session compacted" , { exact : true } ) ) . toHaveCount ( 0 )
117127
118128 await timeline . send (
119129 compactionEnded ( {
@@ -125,6 +135,18 @@ test("renders a compaction summary while it streams and after completion", async
125135 )
126136 await expect ( compaction ) . toContainText ( "Final implementation details." )
127137 await expect ( compaction ) . not . toContainText ( "Streamed implementation details." )
138+ await expect ( compaction . getByText ( "Session compaction started" , { exact : true } ) ) . toBeVisible ( )
139+ await expect ( compaction . getByText ( "Session compacted" , { exact : true } ) ) . toBeVisible ( )
140+ await expect
141+ . poll ( async ( ) => {
142+ const summary = await compaction . locator ( '[data-component="text-part"]' ) . boundingBox ( )
143+ const completed = await compaction . getByText ( "Session compacted" , { exact : true } ) . boundingBox ( )
144+ return ! ! summary && ! ! completed && completed . y >= summary . y + summary . height
145+ } )
146+ . toBe ( true )
147+ await expect ( compaction . getByRole ( "status" ) ) . toHaveCount ( 0 )
148+ await expect ( page . getByRole ( "button" , { name : "Stop" , exact : true } ) ) . toBeVisible ( )
149+ await expect ( page . locator ( '[data-component="session-working"]' ) ) . toBeVisible ( )
128150} )
129151
130152test ( "updates running compactions to failed and cancelled boundaries" , async ( { page } ) => {
@@ -146,7 +168,10 @@ test("updates running compactions to failed and cancelled boundaries", async ({
146168
147169 const compactions = page . locator ( '[data-component="session-compaction-message"]' )
148170 const failed = compactions . filter ( { hasText : "The provider rejected the summary." } )
149- await expect ( failed . getByText ( "Session compacted" , { exact : true } ) ) . toBeVisible ( )
171+ await expect ( failed . getByText ( "Session compaction started" , { exact : true } ) ) . toBeVisible ( )
172+ await expect ( failed . getByText ( "Session compaction failed" , { exact : true } ) ) . toBeVisible ( )
173+ await expect ( failed . getByText ( "Session compacted" , { exact : true } ) ) . toHaveCount ( 0 )
174+ await expect ( failed . getByRole ( "status" ) ) . toHaveCount ( 0 )
150175 await expect ( failed . getByText ( "ProviderError: The provider rejected the summary." , { exact : true } ) ) . toBeVisible ( )
151176 await expect ( failed ) . not . toContainText ( "Partial summary that should be discarded." )
152177
@@ -164,11 +189,48 @@ test("updates running compactions to failed and cancelled boundaries", async ({
164189
165190 await expect ( compactions ) . toHaveCount ( 2 )
166191 const cancelled = compactions . filter ( { hasNotText : "The provider rejected the summary." } )
167- await expect ( cancelled . getByText ( "Session compacted" , { exact : true } ) ) . toBeVisible ( )
192+ await expect ( cancelled . getByText ( "Session compaction started" , { exact : true } ) ) . toBeVisible ( )
193+ await expect ( cancelled . getByText ( "Session compaction cancelled" , { exact : true } ) ) . toBeVisible ( )
194+ await expect ( cancelled . getByText ( "Session compacted" , { exact : true } ) ) . toHaveCount ( 0 )
195+ await expect ( cancelled . getByRole ( "status" ) ) . toHaveCount ( 0 )
168196 await expect ( cancelled ) . not . toContainText ( "Cancellation detail should stay hidden." )
169197 await expect ( cancelled ) . not . toContainText ( "Summary before cancellation." )
170198} )
171199
200+ test ( "shows an interrupted outcome when stopping automatic compaction" , async ( { page } ) => {
201+ const timeline = await setupTimeline ( page , {
202+ sessionMessages : [ user , assistant ( true ) ] ,
203+ sessionStatus : { [ sessionID ] : { type : "busy" } } ,
204+ } )
205+ await timeline . send ( compactionStarted ( { sessionID, reason : "auto" , recent : "" } ) )
206+ await timeline . send ( compactionDelta ( { sessionID, text : "Partial automatic summary." } ) )
207+ const compaction = page . locator ( '[data-component="session-compaction-message"]' )
208+ await expect ( compaction . getByRole ( "status" ) . getByLabel ( "Compacting" , { exact : true } ) ) . toBeVisible ( )
209+ await expect ( compaction ) . toContainText ( "Partial automatic summary." )
210+
211+ const request = page . waitForRequest (
212+ ( request ) =>
213+ request . method ( ) === "POST" && new URL ( request . url ( ) ) . pathname === `/api/session/${ sessionID } /interrupt` ,
214+ )
215+ await page . getByRole ( "button" , { name : "Stop" , exact : true } ) . click ( )
216+ await request
217+ await timeline . send (
218+ compactionFailed ( {
219+ sessionID,
220+ reason : "auto" ,
221+ error : { type : "compaction.interrupted" , message : "Compaction was interrupted" } ,
222+ } ) ,
223+ )
224+
225+ await expect ( compaction . getByText ( "Session compaction started" , { exact : true } ) ) . toBeVisible ( )
226+ await expect ( compaction . getByText ( "Session compaction interrupted" , { exact : true } ) ) . toBeVisible ( )
227+ await expect ( compaction . getByText ( "Session compaction failed" , { exact : true } ) ) . toHaveCount ( 0 )
228+ await expect ( compaction . getByText ( "Session compacted" , { exact : true } ) ) . toHaveCount ( 0 )
229+ await expect ( compaction . getByRole ( "status" ) ) . toHaveCount ( 0 )
230+ await expect ( compaction ) . not . toContainText ( "Partial automatic summary." )
231+ await expect ( compaction ) . not . toContainText ( "Compaction was interrupted" )
232+ } )
233+
172234test ( "moves blocking work to the background with Ctrl+B" , async ( { page } ) => {
173235 await setupTimeline ( page , {
174236 settings : {
0 commit comments