@@ -17,7 +17,8 @@ describe('Amazon Q Feature Dev', function () {
17
17
let tab : Messenger
18
18
19
19
const prompt = 'Add blank.txt file with empty content'
20
- const codegenApproachPrompt = prompt + ' and add a readme that describes the changes'
20
+ const codegenApproachPrompt = `${ prompt } and add a readme that describes the changes`
21
+ const fileLevelAcceptPrompt = `${ prompt } and add a license, and a contributing file`
21
22
const tooManyRequestsWaitTime = 100000
22
23
23
24
function waitForButtons ( buttons : FollowUpTypes [ ] ) {
@@ -50,6 +51,14 @@ describe('Amazon Q Feature Dev', function () {
50
51
)
51
52
}
52
53
54
+ async function clickActionButton ( filePath : string , actionName : string ) {
55
+ tab . clickFileActionButton ( filePath , actionName )
56
+ await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , actionName ) , {
57
+ waitIntervalInMs : 500 ,
58
+ waitTimeoutInMs : 600000 ,
59
+ } )
60
+ }
61
+
53
62
/**
54
63
* Wait for the original request to finish.
55
64
* If the response has a retry button or encountered a guardrails error, continue retrying
@@ -216,4 +225,120 @@ describe('Amazon Q Feature Dev', function () {
216
225
await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
217
226
} )
218
227
} )
228
+
229
+ describe ( 'file-level accepts' , async ( ) => {
230
+ beforeEach ( async function ( ) {
231
+ tab . addChatMessage ( { command : '/dev' , prompt : fileLevelAcceptPrompt } )
232
+ await retryIfRequired (
233
+ async ( ) => {
234
+ await tab . waitForChatFinishesLoading ( )
235
+ } ,
236
+ ( ) => {
237
+ tab . addChatMessage ( { prompt } )
238
+ }
239
+ )
240
+ await retryIfRequired ( async ( ) => {
241
+ await Promise . any ( [
242
+ waitForButtons ( [ FollowUpTypes . InsertCode , FollowUpTypes . ProvideFeedbackAndRegenerateCode ] ) ,
243
+ waitForButtons ( [ FollowUpTypes . Retry ] ) ,
244
+ ] )
245
+ } )
246
+ } )
247
+
248
+ describe ( 'fileList' , async ( ) => {
249
+ it ( 'has both accept-change and reject-change action buttons for file' , async ( ) => {
250
+ const filePath = tab . getFilePaths ( ) [ 0 ]
251
+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 2 )
252
+ assert . ok ( tab . hasAction ( filePath , 'accept-change' ) )
253
+ assert . ok ( tab . hasAction ( filePath , 'reject-change' ) )
254
+ } )
255
+
256
+ it ( 'has only revert-rejection action button for rejected file' , async ( ) => {
257
+ const filePath = tab . getFilePaths ( ) [ 0 ]
258
+ await clickActionButton ( filePath , 'reject-change' )
259
+
260
+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 1 )
261
+ assert . ok ( tab . hasAction ( filePath , 'revert-rejection' ) )
262
+ } )
263
+
264
+ it ( 'does not have any of the action buttons for accepted file' , async ( ) => {
265
+ const filePath = tab . getFilePaths ( ) [ 0 ]
266
+ await clickActionButton ( filePath , 'accept-change' )
267
+
268
+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
269
+ } )
270
+
271
+ it ( 'disables all action buttons when new task is clicked' , async ( ) => {
272
+ tab . clickButton ( FollowUpTypes . InsertCode )
273
+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
274
+ tab . clickButton ( FollowUpTypes . NewTask )
275
+ await waitForText ( 'What new task would you like to work on?' )
276
+
277
+ const filePaths = tab . getFilePaths ( )
278
+ for ( const filePath of filePaths ) {
279
+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
280
+ }
281
+ } )
282
+
283
+ it ( 'disables all action buttons when close session is clicked' , async ( ) => {
284
+ tab . clickButton ( FollowUpTypes . InsertCode )
285
+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
286
+ tab . clickButton ( FollowUpTypes . CloseSession )
287
+ await waitForText (
288
+ "Okay, I've ended this chat session. You can open a new tab to chat or start another workflow."
289
+ )
290
+
291
+ const filePaths = tab . getFilePaths ( )
292
+ for ( const filePath of filePaths ) {
293
+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
294
+ }
295
+ } )
296
+ } )
297
+
298
+ describe ( 'accept button' , async ( ) => {
299
+ describe ( 'button text' , async ( ) => {
300
+ it ( 'shows "Accept all changes" when no files are accepted or rejected, and "Accept remaining changes" otherwise' , async ( ) => {
301
+ let insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
302
+ assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
303
+
304
+ const filePath = tab . getFilePaths ( ) [ 0 ]
305
+ await clickActionButton ( filePath , 'reject-change' )
306
+
307
+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
308
+ assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
309
+
310
+ await clickActionButton ( filePath , 'revert-rejection' )
311
+
312
+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
313
+ assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
314
+
315
+ await clickActionButton ( filePath , 'accept-change' )
316
+
317
+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
318
+ assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
319
+ } )
320
+
321
+ it ( 'shows "Continue" when all files are either accepted or rejected, with at least one of them rejected' , async ( ) => {
322
+ const filePaths = tab . getFilePaths ( )
323
+ for ( const filePath of filePaths ) {
324
+ await clickActionButton ( filePath , 'reject-change' )
325
+ }
326
+
327
+ const insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
328
+ assert . ok ( insertCodeButton . pillText === 'Continue' )
329
+ } )
330
+ } )
331
+
332
+ it ( 'disappears and automatically moves on to the next step when all changes are accepted' , async ( ) => {
333
+ const filePaths = tab . getFilePaths ( )
334
+ for ( const filePath of filePaths ) {
335
+ await clickActionButton ( filePath , 'accept-change' )
336
+ }
337
+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
338
+
339
+ assert . ok ( tab . hasButton ( FollowUpTypes . InsertCode ) === false )
340
+ assert . ok ( tab . hasButton ( FollowUpTypes . ProvideFeedbackAndRegenerateCode ) === false )
341
+ } )
342
+ } )
343
+ } )
219
344
} )
0 commit comments