Files
crank/apps/ui/tests/e2e/approvals.spec.js
T

91 lines
3.6 KiB
JavaScript

const { test, expect } = require('@playwright/test');
const { login, localized } = require('./helpers');
test('logs approval panel renders safe pending approval metadata', async ({ page }) => {
await login(page);
let approveCalled = false;
await page.route(/\/api\/admin\/workspaces\/[^/]+\/approvals(?:\?.*)?$/, async (route) => {
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
items: [
{
approval: {
id: 'approval_ui_safe_summary',
agent_id: 'agent_sales',
operation_id: 'op_charge_customer',
operation_version: 3,
status: 'pending',
risk_level: 'dangerous',
request_id: 'req_approval_ui',
trace_id: '0af7651916cd43dd8448eb211c80319c',
request_payload: {
email: 'customer@example.com',
api_key: '[REDACTED]',
},
response_payload: null,
created_at: '2026-08-22T10:00:00Z',
expires_at: '2026-08-22T10:05:00Z',
decided_at: null,
decision_note: null,
},
},
],
}),
});
});
await page.route(/\/api\/admin\/workspaces\/[^/]+\/approvals\/approval_ui_safe_summary\/approve$/, async (route) => {
approveCalled = true;
const body = JSON.parse(route.request().postData() || '{}');
expect(body).toEqual({ approve: 'yes' });
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({
approval: {
id: 'approval_ui_safe_summary',
agent_id: 'agent_sales',
operation_id: 'op_charge_customer',
operation_version: 3,
status: 'approved',
risk_level: 'dangerous',
request_id: 'req_approval_ui',
trace_id: '0af7651916cd43dd8448eb211c80319c',
request_payload: { email: 'customer@example.com', api_key: '[REDACTED]' },
response_payload: { approve: 'yes' },
created_at: '2026-08-22T10:00:00Z',
expires_at: '2026-08-22T10:05:00Z',
decided_at: '2026-08-22T10:01:00Z',
decision_note: null,
},
}),
});
});
page.on('dialog', async (dialog) => {
expect(dialog.message()).toMatch(localized(
'Approve this pending confirmation request?',
'Подтвердить эту заявку?',
));
await dialog.accept();
});
await page.goto('/logs');
await expect(page.locator('.approval-panel-title')).toHaveText(
localized('Human confirmations', 'Подтверждения человеком'),
);
await expect(page.locator('#approval-list')).toContainText('approval_ui_safe_summary');
await expect(page.locator('#approval-list')).toContainText('op_charge_customer v3');
await expect(page.locator('#approval-list')).toContainText('agent_sales');
await expect(page.locator('#approval-list')).toContainText('customer@example.com');
await expect(page.locator('#approval-list')).toContainText('[REDACTED]');
await expect(page.locator('#approval-list')).toContainText('req_approval_ui');
await expect(page.locator('#approval-list')).toContainText('0af7651916cd43dd8448eb211c80319c');
await expect(page.locator('.approval-approve')).toHaveText(localized('Approve', 'Подтвердить'));
await expect(page.locator('.approval-deny')).toHaveText(localized('Deny', 'Отклонить'));
await expect(page.locator('#approval-list')).not.toContainText('SECRET_APPROVAL_CANARY');
await page.locator('.approval-approve').click();
await expect.poll(() => approveCalled).toBe(true);
});