fix: stabilize inbox confirmation retries
This commit is contained in:
@@ -48,9 +48,13 @@ let expectingInboxRefreshError = false
|
||||
let expectedInboxRefreshConsoleErrorCount = 0
|
||||
let expectingInboxConflict = false
|
||||
let expectedInboxConflictConsoleErrorCount = 0
|
||||
let expectingInboxValidationError = false
|
||||
let expectedInboxValidationConsoleErrorCount = 0
|
||||
let failNextInboxConfirm = true
|
||||
let failNextInboxWorkspaceRefresh = false
|
||||
let conflictNextInboxConfirm = false
|
||||
let validationNextInboxConfirm = false
|
||||
let invalidResponseNextInboxConfirm = false
|
||||
page.on('console', (message) => {
|
||||
if (message.type() !== 'error') return
|
||||
if (
|
||||
@@ -85,6 +89,14 @@ page.on('console', (message) => {
|
||||
expectedInboxConflictConsoleErrorCount += 1
|
||||
return
|
||||
}
|
||||
if (
|
||||
expectingInboxValidationError &&
|
||||
expectedInboxValidationConsoleErrorCount === 0 &&
|
||||
message.text() === 'Failed to load resource: the server responded with a status of 400 (Bad Request)'
|
||||
) {
|
||||
expectedInboxValidationConsoleErrorCount += 1
|
||||
return
|
||||
}
|
||||
errors.push(message.text())
|
||||
})
|
||||
|
||||
@@ -259,6 +271,23 @@ await page.route('http://localhost:9150/api/v1/**', async (route) => {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (validationNextInboxConfirm) {
|
||||
validationNextInboxConfirm = false
|
||||
await route.fulfill({
|
||||
status: 400,
|
||||
json: { error: { code: 'invalid_request', message: '建议选择无效,请重新核对' } },
|
||||
})
|
||||
return
|
||||
}
|
||||
if (invalidResponseNextInboxConfirm) {
|
||||
invalidResponseNextInboxConfirm = false
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'text/plain',
|
||||
body: 'unparseable confirmation result',
|
||||
})
|
||||
return
|
||||
}
|
||||
const confirmedItemId = url.pathname.split('/').at(-2)
|
||||
visualCheckWorkspace.inbox.find((item) => item.id === confirmedItemId).status = 'processed'
|
||||
visualCheckWorkspace.channels.find((channel) => channel.type === 'inbox').count -= 1
|
||||
@@ -719,8 +748,52 @@ if (await inboxChannelButton.count() === 0) {
|
||||
failures.push(`expected one simulated Inbox confirm console error, got ${expectedInboxConfirmConsoleErrorCount}`)
|
||||
}
|
||||
|
||||
const firstUncertainRequest = inboxConfirmRequests.at(-1)
|
||||
const analyzeRequestCountAfterUncertainFailure = inboxAnalyzeRequests.length
|
||||
const analyzeButtonAfterUncertainFailure = inboxPage.getByRole('button', { name: '分析内容', exact: true })
|
||||
if (!await analyzeButtonAfterUncertainFailure.isDisabled()) {
|
||||
failures.push('an uncertain Inbox confirmation must freeze re-analysis')
|
||||
}
|
||||
if (!await sourceSuggestionCheckbox.locator('input[type="checkbox"]').isDisabled()) {
|
||||
failures.push('an uncertain Inbox confirmation must freeze suggestion selection')
|
||||
}
|
||||
if (!await secondInboxRow.isDisabled()) {
|
||||
failures.push('an uncertain Inbox confirmation must freeze Inbox item switching')
|
||||
}
|
||||
const sourceCheckedBeforeForcedChange = await sourceSuggestionCheckbox.locator('input[type="checkbox"]').isChecked()
|
||||
await sourceSuggestionCheckbox.click({ force: true })
|
||||
if (await sourceSuggestionCheckbox.locator('input[type="checkbox"]').isChecked() !== sourceCheckedBeforeForcedChange) {
|
||||
failures.push('an uncertain Inbox confirmation must reject forced checkbox changes')
|
||||
}
|
||||
await analyzeButtonAfterUncertainFailure.click({ force: true })
|
||||
await page.waitForTimeout(50)
|
||||
if (inboxAnalyzeRequests.length !== analyzeRequestCountAfterUncertainFailure) {
|
||||
failures.push('an uncertain Inbox confirmation must not send another analyze request')
|
||||
}
|
||||
const retryConfirmButton = inboxPage.getByRole('button', { name: '重试确认', exact: true })
|
||||
if (await retryConfirmButton.count() !== 1) {
|
||||
failures.push('an uncertain Inbox confirmation must change the CTA to 重试确认')
|
||||
}
|
||||
|
||||
const workspaceRequestCount = workspaceRequests.length
|
||||
await confirmButton.click()
|
||||
const retryAction = await retryConfirmButton.count() === 1 ? retryConfirmButton : confirmButton
|
||||
invalidResponseNextInboxConfirm = true
|
||||
await retryAction.click()
|
||||
await page.waitForTimeout(350)
|
||||
if (JSON.stringify(inboxConfirmRequests.at(-1)) !== JSON.stringify(firstUncertainRequest)) {
|
||||
failures.push(`an invalid-response retry must reuse the exact uncertain request body, got ${JSON.stringify(inboxConfirmRequests.at(-1))}`)
|
||||
}
|
||||
const retryAfterInvalidResponse = inboxPage.getByRole('button', { name: '重试确认', exact: true })
|
||||
if (await retryAfterInvalidResponse.count() !== 1) {
|
||||
failures.push('an invalid confirmation response must preserve the uncertain retry state')
|
||||
}
|
||||
if (!await sourceSuggestionCheckbox.locator('input[type="checkbox"]').isDisabled()) {
|
||||
failures.push('an invalid confirmation response must keep suggestion selection frozen')
|
||||
}
|
||||
const finalRetryAction = await retryAfterInvalidResponse.count() === 1
|
||||
? retryAfterInvalidResponse
|
||||
: inboxPage.getByRole('button', { name: '确认创建', exact: true })
|
||||
await finalRetryAction.click()
|
||||
await inboxPage.getByText('已创建 2 个对象', { exact: true }).waitFor({ state: 'visible', timeout: 2000 }).catch(() => {})
|
||||
if (!await inboxPage.getByText('已创建 2 个对象', { exact: true }).isVisible()) {
|
||||
failures.push('successful Inbox confirmation must show the created object count')
|
||||
@@ -729,6 +802,12 @@ if (await inboxChannelButton.count() === 0) {
|
||||
if (JSON.stringify(submitted) !== JSON.stringify([inboxTaskSuggestionId, inboxNoteSuggestionId])) {
|
||||
failures.push(`Inbox confirm must send only checked saved suggestion identities, got ${JSON.stringify(submitted)}`)
|
||||
}
|
||||
if (JSON.stringify(inboxConfirmRequests.at(-1)) !== JSON.stringify(firstUncertainRequest)) {
|
||||
failures.push(`an uncertain Inbox retry must reuse the exact first request body, got first=${JSON.stringify(firstUncertainRequest)} retry=${JSON.stringify(inboxConfirmRequests.at(-1))}`)
|
||||
}
|
||||
if (await secondInboxRow.isDisabled()) {
|
||||
failures.push('a successful Inbox retry must clear the uncertain state for other Inbox items')
|
||||
}
|
||||
if (workspaceRequests.length <= workspaceRequestCount) {
|
||||
failures.push('successful Inbox confirmation must refresh the project workspace')
|
||||
}
|
||||
@@ -757,9 +836,26 @@ if (await inboxChannelButton.count() === 0) {
|
||||
await secondInboxRow.click()
|
||||
await inboxPage.getByRole('button', { name: '分析内容', exact: true }).click()
|
||||
await inboxPage.getByRole('checkbox').first().waitFor({ state: 'attached', timeout: 2000 }).catch(() => {})
|
||||
expectingInboxRefreshError = true
|
||||
validationNextInboxConfirm = true
|
||||
expectingInboxValidationError = true
|
||||
const secondConfirmButton = inboxPage.getByRole('button', { name: '确认创建', exact: true })
|
||||
await secondConfirmButton.click()
|
||||
await inboxPage.getByText('建议选择无效,请重新核对', { exact: true }).waitFor({ state: 'visible', timeout: 2000 }).catch(() => {})
|
||||
if (await inboxPage.getByRole('button', { name: '重试确认', exact: true }).count() !== 0) {
|
||||
failures.push('a deterministic validation failure must not enter the uncertain retry state')
|
||||
}
|
||||
if (await inboxPage.getByRole('checkbox').first().isDisabled()) {
|
||||
failures.push('a deterministic validation failure must leave suggestion selection editable')
|
||||
}
|
||||
if (await inboxPage.getByRole('button', { name: '分析内容', exact: true }).isDisabled()) {
|
||||
failures.push('a deterministic validation failure must leave re-analysis available')
|
||||
}
|
||||
expectingInboxValidationError = false
|
||||
if (expectedInboxValidationConsoleErrorCount !== 1) {
|
||||
failures.push(`expected one simulated Inbox validation console error, got ${expectedInboxValidationConsoleErrorCount}`)
|
||||
}
|
||||
expectingInboxRefreshError = true
|
||||
await secondConfirmButton.click()
|
||||
await inboxPage.getByText('已创建 3 个对象', { exact: true }).waitFor({ state: 'visible', timeout: 2000 }).catch(() => {})
|
||||
if (!await inboxPage.getByText('已创建 3 个对象', { exact: true }).isVisible()) {
|
||||
failures.push('a completed confirmation must preserve its created count when workspace refresh fails')
|
||||
|
||||
Reference in New Issue
Block a user