@@ -18,6 +18,7 @@ describe('Amazon Q Feature Dev', function () {
1818
1919 const prompt = 'Add blank.txt file with empty content'
2020 const codegenApproachPrompt = prompt + ' and add a readme that describes the changes'
21+ const fileLevelAcceptPrompt = prompt + ' and add a license, and a contributing file'
2122 const tooManyRequestsWaitTime = 100000
2223
2324 function waitForButtons ( buttons : FollowUpTypes [ ] ) {
@@ -50,6 +51,11 @@ describe('Amazon Q Feature Dev', function () {
5051 )
5152 }
5253
54+ async function clickActionButton ( filePath : string , actionName : string ) {
55+ tab . clickFileActionButton ( filePath , actionName )
56+ await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , actionName ) )
57+ }
58+
5359 /**
5460 * Wait for the original request to finish.
5561 * If the response has a retry button or encountered a guardrails error, continue retrying
@@ -215,87 +221,111 @@ describe('Amazon Q Feature Dev', function () {
215221 tab . clickButton ( FollowUpTypes . InsertCode )
216222 await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
217223 } )
224+ } )
218225
219- describe ( 'file-level accepts' , async ( ) => {
220- beforeEach ( async ( ) => {
221- await retryIfRequired ( async ( ) => {
222- await Promise . any ( [
223- waitForButtons ( [ FollowUpTypes . InsertCode , FollowUpTypes . ProvideFeedbackAndRegenerateCode ] ) ,
224- waitForButtons ( [ FollowUpTypes . Retry ] ) ,
225- ] )
226- } )
226+ describe ( 'file-level accepts' , async ( ) => {
227+ beforeEach ( async function ( ) {
228+ tab . addChatMessage ( { command : '/dev' , prompt : fileLevelAcceptPrompt } )
229+ await retryIfRequired (
230+ async ( ) => {
231+ await tab . waitForChatFinishesLoading ( )
232+ } ,
233+ ( ) => {
234+ tab . addChatMessage ( { prompt } )
235+ }
236+ )
237+ await retryIfRequired ( async ( ) => {
238+ await Promise . any ( [
239+ waitForButtons ( [ FollowUpTypes . InsertCode , FollowUpTypes . ProvideFeedbackAndRegenerateCode ] ) ,
240+ waitForButtons ( [ FollowUpTypes . Retry ] ) ,
241+ ] )
227242 } )
243+ } )
228244
229- describe ( 'fileList' , async ( ) => {
230- it ( 'has both accept-change and reject-change action buttons for file' , async ( ) => {
231- const filePath = tab . getFilePaths ( ) [ 0 ]
232- assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 2 )
233- assert . ok ( tab . hasAction ( filePath , 'accept-change' ) )
234- assert . ok ( tab . hasAction ( filePath , 'reject-change' ) )
235- } )
245+ describe ( 'fileList' , async ( ) => {
246+ it ( 'has both accept-change and reject-change action buttons for file' , async ( ) => {
247+ const filePath = tab . getFilePaths ( ) [ 0 ]
248+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 2 )
249+ assert . ok ( tab . hasAction ( filePath , 'accept-change' ) )
250+ assert . ok ( tab . hasAction ( filePath , 'reject-change' ) )
251+ } )
236252
237- it ( 'has only revert-rejection action buttons for rejected file' , async ( ) => {
238- const filePath = tab . getFilePaths ( ) [ 0 ]
239- tab . clickFileActionButton ( filePath , 'reject-change' )
240- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'reject-change' ) )
253+ it ( 'has only revert-rejection action button for rejected file' , async ( ) => {
254+ const filePath = tab . getFilePaths ( ) [ 0 ]
255+ await clickActionButton ( filePath , 'reject-change' )
241256
242- assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 1 )
243- assert . ok ( tab . hasAction ( filePath , 'revert-rejection' ) )
244- } )
257+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 1 )
258+ assert . ok ( tab . hasAction ( filePath , 'revert-rejection' ) )
259+ } )
245260
246- it ( 'does not have any action buttons for accepted file' , async ( ) => {
247- const filePath = tab . getFilePaths ( ) [ 0 ]
248- tab . clickFileActionButton ( filePath , 'accept-change' )
249- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'accept-change' ) )
261+ it ( 'does not have any of the action buttons for accepted file' , async ( ) => {
262+ const filePath = tab . getFilePaths ( ) [ 0 ]
263+ await clickActionButton ( filePath , 'accept-change' )
250264
251- assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
252- } )
265+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
253266 } )
254267
255- describe ( 'accept changes button' , async ( ) => {
256- describe ( 'button text' , async ( ) => {
257- it ( 'shows Accept all changes when all files are neither accepted nor rejected' , async ( ) => {
258- const insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
259- assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
260- } )
268+ it ( 'disables all action buttons when new task is clicked' , async ( ) => {
269+ tab . clickButton ( FollowUpTypes . InsertCode )
270+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
271+ tab . clickButton ( FollowUpTypes . NewTask )
272+ await waitForText ( 'What new task would you like to work on?' )
273+
274+ const filePaths = tab . getFilePaths ( )
275+ for ( const filePath of filePaths ) {
276+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
277+ }
278+ } )
261279
262- it ( 'shows Accept remaining changes when one or more file is rejected' , async ( ) => {
263- const filePath = tab . getFilePaths ( ) [ 0 ]
264- tab . clickFileActionButton ( filePath , 'reject-change' )
265- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'reject-change' ) )
280+ it ( 'disables all action buttons when close session is clicked' , async ( ) => {
281+ tab . clickButton ( FollowUpTypes . InsertCode )
282+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
283+ tab . clickButton ( FollowUpTypes . CloseSession )
284+ await waitForText (
285+ "Okay, I've ended this chat session. You can open a new tab to chat or start another workflow."
286+ )
266287
267- const insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
268- assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
269- } )
288+ const filePaths = tab . getFilePaths ( )
289+ for ( const filePath of filePaths ) {
290+ assert . ok ( tab . getActionsByFilePath ( filePath ) . length === 0 )
291+ }
292+ } )
293+ } )
270294
271- it ( 'shows Accept remaining changes when one or more file is accepted' , async ( ) => {
272- const filePath = tab . getFilePaths ( ) [ 0 ]
273- tab . clickFileActionButton ( filePath , 'accept-change' )
274- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'accept-change' ) )
295+ describe ( 'accept button' , async ( ) => {
296+ describe ( 'button text' , async ( ) => {
297+ it ( 'shows "Accept all changes" when no files are accepted or rejected, and "Accept remaining changes" otherwise' , async ( ) => {
298+ let insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
299+ assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
275300
276- const insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
277- assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
278- } )
301+ const filePath = tab . getFilePaths ( ) [ 0 ]
302+ await clickActionButton ( filePath , 'reject-change' )
279303
280- it ( 'shows Accept remaining changes when a file is rejected, then shows Accept all changes again when the rejection is reverted' , async ( ) => {
281- let insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
282- assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
304+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
305+ assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
283306
284- const filePath = tab . getFilePaths ( ) [ 0 ]
285- tab . clickFileActionButton ( filePath , 'reject-change' )
286- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'reject-change' ) )
307+ await clickActionButton ( filePath , 'revert-rejection' )
287308
288- insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
289- assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
309+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
310+ assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
290311
291- tab . clickFileActionButton ( filePath , 'revert-rejection' )
292- await tab . waitForEvent ( ( ) => ! tab . hasAction ( filePath , 'revert-rejection' ) )
312+ await clickActionButton ( filePath , 'accept-change' )
293313
294- insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
295- assert . ok ( insertCodeButton . pillText === 'Accept all changes' )
296- } )
314+ insertCodeButton = tab . getFollowUpButton ( FollowUpTypes . InsertCode )
315+ assert . ok ( insertCodeButton . pillText === 'Accept remaining changes' )
297316 } )
298317 } )
318+
319+ it ( 'disappears and automatically moves on to the next step when all changes are accepted' , async ( ) => {
320+ const filePaths = tab . getFilePaths ( )
321+ for ( const filePath of filePaths ) {
322+ await clickActionButton ( filePath , 'accept-change' )
323+ }
324+ await waitForButtons ( [ FollowUpTypes . NewTask , FollowUpTypes . CloseSession ] )
325+
326+ assert . ok ( tab . hasButton ( FollowUpTypes . InsertCode ) === false )
327+ assert . ok ( tab . hasButton ( FollowUpTypes . ProvideFeedbackAndRegenerateCode ) === false )
328+ } )
299329 } )
300330 } )
301331} )
0 commit comments