Skip to content

Commit

Permalink
display jobSummary
Browse files Browse the repository at this point in the history
fix endpoint

refactor(cw): remove unused keep-alive workaround.  (aws#6694)

This code is no longer used, and appears to have been moved to the LSP
side:
aws/aws-toolkit-vscode-staging#1214 (comment)

This fix also no longer works, and the work it was based off has
significantly changed their approach:
https://github.com/sourcegraph/cody/blob/62d73f78c432036d1f99bc9631ed534cc2ed846b/vscode/src/net/net.patch.ts

- remove it.

---

- Treat all work as PUBLIC. Private `feature/x` branches will not be
squash-merged at release time.
- Your code changes must meet the guidelines in
[CONTRIBUTING.md](https://github.com/aws/aws-toolkit-vscode/blob/master/CONTRIBUTING.md#guidelines).
- License: I confirm that my contribution is made under the terms of the
Apache 2.0 license.

test(e2e): increase file watcher count to prevent ENOSPC errors

test(amazonq): retry inline tests if no valid response was found

Merge pull request aws#6757 from jpinkney-aws/stabilize-test

test(amazonq): add retries to flaky e2e tests

telemetry(amazonq): status field tracking user actions aws#6750

- The current unit test generation telemetry event lacks a field to
distinguish between user actions: acceptance, rejection, failure, or
cancellation.

- Enhancing the amazonq_utgGenerateTests telemetry event by
incorporating a status field to capture user actions in toolkit metrics.
- Bumping telemetry version to `1.0.307`

fix(amazonq): incorrect zip entry path for file scans aws#6741

Reproduce steps:
1. Open a window with multiple workspace folders, for example
`workspaceFolders: [folder1, folder2]`
2. Open any file and run a code review on the active file, for example
`folder1/sample.py`
3. The zip entry will be created with the workspaceFolder duplicated,
for example `folder1/folder1/sample.py`

Explicitly set `includeWorkspaceFolder` to false when getting the
relative path of the file.

fix(amazonq): keyboard navigation in "Create a new prompt" overlay aws#6738

When a user selects "Create a new prompt", a mouse is required to 1)
select the prompt name input field and 2) click the Enter button. This
flow should be able to be completed with just the keyboard

Autofocus prompt input field, and allow submit on Enter key press.

fix(amazonq): duplicates in lsp getContextCommandPrompt aws#6756

There are two types of context shown in the context list:
1. the ones by explicit @
2. the ones by @workspace 1) has relativePaths with start/end line being
-1, 2) has relativePaths with non -1 start/end lines,
1) is doing dedupe with 2) but 1) also needs to dedupe itself

ci(jscpd): show hint message on detection of clones aws#6737

There appears to be cases where the fix pushed here fails:
aws#6572.
ex: aws#6735
- re-add the hint message for the case described here:
aws#6564

feat(amazonq): feedback system for internal users for /test aws#6748

- The unit test generation team lacks sufficient feedback to enhance the
quality of their produced tests.

- Implementing the feedback system for internal users to evaluate and
enhance unit test generation quality.
  • Loading branch information
chungjac committed Mar 11, 2025
1 parent 6f21d06 commit b0b8347
Show file tree
Hide file tree
Showing 26 changed files with 267 additions and 145 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/filterDuplicates.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ async function run() {
console.log('%s duplicates found', filteredDuplicates.length)
if (filteredDuplicates.length > 0) {
console.log(formatDuplicates(filteredDuplicates, commitHash, repoName))
console.log(
'* Hint: if these duplicates appear unrelated to the changes, rebase onto or merge in the latest target branch.'
)
process.exit(1)
}
}
Expand Down
2 changes: 2 additions & 0 deletions buildspec/linuxE2ETests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ phases:
# - '>/dev/null apt-get -qq install -y ca-certificates'
# - 'apt-get install --reinstall ca-certificates'
- bash buildspec/shared/linux-install.sh
# increase file watcher count (ENOSPC error)
- sysctl fs.inotify.max_user_watches=524288

pre_build:
commands:
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"skippedTestReport": "ts-node ./scripts/skippedTestReport.ts ./packages/amazonq/test/e2e/"
},
"devDependencies": {
"@aws-toolkits/telemetry": "^1.0.305",
"@aws-toolkits/telemetry": "^1.0.307",
"@playwright/browser-chromium": "^1.43.1",
"@stylistic/eslint-plugin": "^2.11.0",
"@types/he": "^1.2.3",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "Amazon Q chat: Create a new prompt form does not autofocus or submit with Enter press"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"type": "Bug Fix",
"description": "/review: Zip files are created with the wrong file path for file scans in multifolder workspaces."
}
1 change: 1 addition & 0 deletions packages/amazonq/test/e2e/amazonq/chat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { loginToIdC } from './utils/setup'
import { webviewConstants, webviewTabConstants } from 'aws-core-vscode/amazonq'

describe('Amazon Q Chat', function () {
this.retries(3)
let framework: qTestingFramework
let tab: Messenger
let store: MynahUIDataModel
Expand Down
83 changes: 70 additions & 13 deletions packages/amazonq/test/e2e/inline/inline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import {
using,
} from 'aws-core-vscode/test'
import { RecommendationHandler, RecommendationService, session } from 'aws-core-vscode/codewhisperer'
import { Commands, globals, sleep, waitUntil } from 'aws-core-vscode/shared'
import { Commands, globals, sleep, waitUntil, collectionUtil } from 'aws-core-vscode/shared'
import { loginToIdC } from '../amazonq/utils/setup'

describe('Amazon Q Inline', async function () {
const retries = 3
this.retries(retries)

let tempFolder: string
const waitOptions = {
interval: 500,
Expand All @@ -37,13 +40,24 @@ describe('Amazon Q Inline', async function () {
const folder = await TestFolder.create()
tempFolder = folder.path
await closeAllEditors()
await resetCodeWhispererGlobalVariables(false)
await resetCodeWhispererGlobalVariables()
})

afterEach(async function () {
await closeAllEditors()
if (this.currentTest?.state === undefined || this.currentTest?.isFailed() || this.currentTest?.isPending()) {
logUserDecisionStatus()
}
})

function logUserDecisionStatus() {
const events = getUserTriggerDecision()
console.table({
'telemetry events': JSON.stringify(events),
'recommendation service status': RecommendationService.instance.isRunning,
})
}

async function setupEditor({ name, contents }: { name?: string; contents?: string } = {}) {
const fileName = name ?? 'test.ts'
const textContents =
Expand All @@ -58,16 +72,28 @@ describe('Amazon Q Inline', async function () {
}

async function waitForRecommendations() {
const ok = await waitUntil(
async () =>
RecommendationHandler.instance.isSuggestionVisible() || session.getSuggestionState(0) === 'Showed',
const suggestionShown = await waitUntil(async () => session.getSuggestionState(0) === 'Showed', waitOptions)
if (!suggestionShown) {
throw new Error(`Suggestion did not show. Suggestion States: ${JSON.stringify(session.suggestionStates)}`)
}
const suggestionVisible = await waitUntil(
async () => RecommendationHandler.instance.isSuggestionVisible(),
waitOptions
)
if (!ok) {
assert.fail(
if (!suggestionVisible) {
throw new Error(
`Suggestions failed to become visible. Suggestion States: ${JSON.stringify(session.suggestionStates)}`
)
}
console.table({
'suggestions states': JSON.stringify(session.suggestionStates),
'valid recommendation': RecommendationHandler.instance.isValidResponse(),
'recommendation service status': RecommendationService.instance.isRunning,
recommendations: session.recommendations,
})
if (!RecommendationHandler.instance.isValidResponse()) {
throw new Error('Did not find a valid response')
}
}

/**
Expand All @@ -82,17 +108,23 @@ describe('Amazon Q Inline', async function () {
})
return events.some((event) => event.codewhispererSuggestionState === suggestionState)
}, waitOptions)
const events = globals.telemetry.logger.query({
metricName,
})
if (!ok) {
assert.fail(`Telemetry failed to be emitted. Current events: ${JSON.stringify(events)}`)
assert.fail(`Telemetry for ${metricName} with suggestionState ${suggestionState} was not emitted`)
}
const events = getUserTriggerDecision()
if (events.length > 1 && events[events.length - 1].codewhispererSuggestionState !== suggestionState) {
assert.fail(`Telemetry events were emitted in the wrong order. Current events: ${JSON.stringify(events)}`)
assert.fail(`Telemetry events were emitted in the wrong order`)
}
}

function getUserTriggerDecision() {
return globals.telemetry.logger
.query({
metricName: 'codewhisperer_userTriggerDecision',
})
.map((e) => collectionUtil.partialClone(e, 3, ['credentialStartUrl'], '[omitted]'))
}

for (const [name, invokeCompletion] of [
['automatic', async () => await vscode.commands.executeCommand('type', { text: '\n' })],
['manual', async () => Commands.tryExecute('aws.amazonq.invokeInlineCompletion')],
Expand All @@ -101,7 +133,7 @@ describe('Amazon Q Inline', async function () {
let originalEditorContents: string | undefined

describe('supported filetypes', () => {
beforeEach(async () => {
async function setup() {
await setupEditor()

/**
Expand All @@ -119,6 +151,31 @@ describe('Amazon Q Inline', async function () {

// wait until the ghost text appears
await waitForRecommendations()
}

beforeEach(async () => {
/**
* Every once and a while the backend won't respond with any recommendations.
* In those cases, re-try the setup up-to ${retries} times
*/
let attempt = 0
while (attempt < retries) {
try {
await setup()
console.log(`test run ${attempt} succeeded`)
logUserDecisionStatus()
break
} catch (e) {
console.log(`test run ${attempt} failed`)
console.log(e)
logUserDecisionStatus()
attempt++
await resetCodeWhispererGlobalVariables()
}
}
if (attempt === retries) {
assert.fail(`Failed to invoke ${name} tests after ${attempt} attempts`)
}
})

it(`${name} invoke accept`, async function () {
Expand Down
23 changes: 23 additions & 0 deletions packages/core/src/amazonq/webview/ui/apps/cwChatConnector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,29 @@ export class Connector extends BaseConnector {
)
}

onFormTextualItemKeyPress = (
tabId: string,
event: KeyboardEvent,
formData: Record<string, string>,
itemId: string,
eventId?: string
) => {
if (itemId === 'prompt-name' && event.key === 'Enter') {
event.preventDefault()
this.sendMessageToExtension({
command: 'form-action-click',
action: {
id: 'submit-create-prompt',
formItemValues: formData,
},
tabType: this.getTabType(),
tabID: tabId,
})
return true
}
return false
}

handleMessageReceive = async (messageData: any): Promise<void> => {
if (messageData.type === 'chatMessage') {
await this.processChatMessage(messageData)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ export class Connector extends BaseConnector {
body: messageData.message,
canBeVoted: false,
informationCard: messageData.informationCard,
buttons: messageData.buttons ?? [],
}
this.onChatAnswerReceived(messageData.tabID, answer, messageData)
}
Expand Down
14 changes: 14 additions & 0 deletions packages/core/src/amazonq/webview/ui/connector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,6 +670,20 @@ export class Connector {
}
}

onFormTextualItemKeyPress = (
event: KeyboardEvent,
formData: Record<string, string>,
itemId: string,
tabId: string,
eventId?: string
) => {
switch (this.tabsStorage.getTab(tabId)?.type) {
case 'cwc':
return this.cwChatConnector.onFormTextualItemKeyPress(tabId, event, formData, itemId, eventId)
}
return false
}

onCustomFormAction = (
tabId: string,
messageId: string | undefined,
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/amazonq/webview/ui/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,15 @@ export const createMynahUI = (
onCustomFormAction: (tabId, action, eventId) => {
connector.onCustomFormAction(tabId, undefined, action, eventId)
},
onFormTextualItemKeyPress: (
event: KeyboardEvent,
formData: Record<string, string>,
itemId: string,
tabId: string,
eventId?: string
) => {
return connector.onFormTextualItemKeyPress(event, formData, itemId, tabId, eventId)
},
onChatPromptProgressActionButtonClicked: (tabID, action) => {
connector.onCustomFormAction(tabID, undefined, action)
},
Expand Down
Loading

0 comments on commit b0b8347

Please sign in to comment.