Files
LangBot/web/tests/e2e/event-processor.spec.ts
T

116 lines
3.8 KiB
TypeScript

import { expect, test } from '@playwright/test';
import { installLangBotApiMocks } from './fixtures/langbot-api';
test('event processor shows isolated logs, paginates and scrolls expanded payloads', async ({
page,
}) => {
await installLangBotApiMocks(page, { authenticated: true });
const ref = 'event_processor:qa/welcome/default';
const processor = {
uuid: 'processor-qa',
kind: 'event_processor',
name: 'Welcome processor',
component_ref: ref,
supported_event_patterns: ['group.member_joined'],
config: { runner: { id: ref }, runner_config: { [ref]: {} } },
};
const run = {
run_id: 'run-one',
status: 'completed',
status_reason: 'stop',
created_at: 1788000000,
metadata: {
event_type: 'group.member_joined',
input_event: { member: { id: 'one' } },
delivery: {
reply_target: { target_type: 'group', target_id: 'test-group' },
},
},
};
const cursors: string[] = [];
await page.route('**/api/v1/agents**', async (route) => {
const url = new URL(route.request().url());
let data: unknown;
if (url.pathname.endsWith('/_/metadata')) {
data = {
kinds: [],
event_processors: [
{
id: ref,
label: { en_US: 'Welcome' },
supported_event_patterns: ['group.member_joined'],
config_schema: [],
plugin_author: 'qa',
plugin_name: 'welcome',
},
],
};
} else if (url.pathname.endsWith('/runs/run-one/events')) {
cursors.push(url.searchParams.get('after_sequence') ?? '');
data = {
run,
items: url.searchParams.has('after_sequence')
? [
{
sequence: 101,
type: 'processor.log',
data: { level: 'info', text: 'Final log after pagination' },
},
]
: [
{
sequence: 1,
type: 'processor.log',
data: { level: 'info', text: 'Member received' },
},
{
sequence: 100,
type: 'tool.call.completed',
data: {
result: Array.from(
{ length: 100 },
(_, i) => `Payload line ${i}`,
),
},
},
],
has_more: !url.searchParams.has('after_sequence'),
next_cursor: url.searchParams.has('after_sequence') ? null : 100,
};
} else if (url.pathname.endsWith('/runs')) {
data = { items: [run], has_more: false, next_cursor: null, total: 1 };
} else if (url.pathname.endsWith('/processor-qa')) {
data = { agent: processor };
} else {
data = { agents: [processor] };
}
await route.fulfill({ json: { code: 0, data } });
});
await page.goto('/home/agents?id=processor-qa');
await expect(
page.getByRole('heading', { name: 'Welcome processor' }),
).toBeVisible();
await expect(
page.getByRole('heading', { name: 'Logs and message flow' }),
).toBeVisible();
await expect(page.getByText('stop', { exact: true })).toHaveCount(0);
await page
.getByRole('button')
.filter({ hasText: 'group.member_joined' })
.click();
await expect(
page.getByText('Member received', { exact: true }),
).toBeVisible();
await expect(
page.getByText('Payload line 99', { exact: false }),
).toBeHidden();
await page.locator('summary').filter({ hasText: 'Action result' }).click();
await page.getByRole('button', { name: 'Load more', exact: true }).click();
await page.getByText('Final log after pagination').scrollIntoViewIfNeeded();
await expect(page.getByText('Final log after pagination')).toBeInViewport();
expect(cursors).toEqual(['', '100']);
await expect(
page.getByRole('button', { name: 'Load more', exact: true }),
).toHaveCount(0);
});