Files
ComfyUI-OpenClaw/tests/e2e/specs/approvals.spec.js
T

125 lines
4.2 KiB
JavaScript

import { expect, test } from '@playwright/test';
import { clickTab, mockComfyUiCore, waitForOpenClawReady } from '../utils/helpers.js';
const pendingApproval = {
approval_id: 'apr-001',
template_id: 'render_portrait',
status: 'pending',
requested_at: '2026-03-05T10:00:00Z',
source: 'telegram',
inputs: { prompt: 'portrait', style: 'studio' },
};
async function mockApprovalApis(page, { listStatus = 200, listData = [pendingApproval], approveStatus = 200 } = {}) {
let approvals = [...listData];
await page.route('**/openclaw/approvals**', async (route) => {
const request = route.request();
const url = new URL(request.url());
if (request.method() === 'GET' && /\/approvals\/[^/]+$/.test(url.pathname)) {
const id = decodeURIComponent(url.pathname.split('/').pop());
const match = approvals.find((item) => item.approval_id === id);
await route.fulfill({
status: match ? 200 : 404,
contentType: 'application/json',
body: JSON.stringify(match ? { approval: match } : { error: 'not_found' }),
});
return;
}
if (request.method() === 'GET') {
await route.fulfill({
status: listStatus,
contentType: 'application/json',
body: JSON.stringify(
listStatus === 200 ? { approvals } : { error: 'approval_list_failed' }
),
});
return;
}
if (request.method() === 'POST' && url.pathname.endsWith('/approve')) {
if (approveStatus === 200) {
approvals = approvals.map((item) =>
item.approval_id === pendingApproval.approval_id
? { ...item, status: 'approved' }
: item
);
}
await route.fulfill({
status: approveStatus,
contentType: 'application/json',
body: JSON.stringify(
approveStatus === 200
? { executed: true, prompt_id: 'prompt-42' }
: { error: 'approve_failed' }
),
});
return;
}
if (request.method() === 'POST' && url.pathname.endsWith('/reject')) {
approvals = approvals.map((item) =>
item.approval_id === pendingApproval.approval_id
? { ...item, status: 'rejected' }
: item
);
await route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ ok: true }),
});
return;
}
await route.fulfill({ status: 404, contentType: 'application/json', body: JSON.stringify({ error: 'not_found' }) });
});
}
test.describe('Approvals surfaces', () => {
test.beforeEach(async ({ page }) => {
await mockComfyUiCore(page);
await page.addInitScript(() => {
window.confirm = () => true;
window.alert = () => {};
});
});
test('loads pending approvals and allows approve action', async ({ page }) => {
await mockApprovalApis(page);
await page.goto('test-harness.html');
await waitForOpenClawReady(page);
await clickTab(page, 'Approvals');
await expect(page.locator('#apr-list .openclaw-list-item')).toHaveCount(1);
await expect(page.locator('#apr-list')).toContainText('render_portrait');
await page.locator('#apr-list button[data-action="approve"]').click();
await expect(page.locator('#apr-list')).toContainText('APPROVED');
});
test('shows approval list fetch failures inside the sidebar', async ({ page }) => {
await mockApprovalApis(page, { listStatus: 500, listData: [] });
await page.goto('test-harness.html');
await waitForOpenClawReady(page);
await clickTab(page, 'Approvals');
await expect(page.locator('.openclaw-error-box')).toContainText('approval_list_failed');
});
test('keeps admin console pending approvals aligned with sidebar data', async ({ page }) => {
await mockApprovalApis(page);
await page.goto('test-harness.html');
await waitForOpenClawReady(page);
await clickTab(page, 'Approvals');
await expect(page.locator('#apr-list')).toContainText('apr-001');
await page.goto('http://127.0.0.1:3000/web/admin_console.html');
await page.locator('#refreshApprovals').click();
await expect(page.locator('#approvalsList')).toContainText('apr-001');
await expect(page.locator('#approvalsList')).toContainText('render_portrait');
});
});