const { test, expect } = require('@playwright/test'); const { buildGrpcSessionOperationPayload, buildRestAsyncJobOperationPayload, buildRestWindowOperationPayload, initializeMcpSession, login, mcpToolCall, setupPublishedAgent, uniqueName, } = require('./helpers'); test('rest window tool executes through MCP', async ({ page }) => { await login(page); const operationName = uniqueName('playwright_window_logs'); const agentSlug = uniqueName('sales_window'); const payload = buildRestWindowOperationPayload(operationName); const bundle = await setupPublishedAgent(page, { operationPayload: payload, agentSlug, toolName: operationName, toolTitle: 'Playwright Window Logs', toolDescription: 'Collects a bounded SSE log window from the local fixture.', }); const mcp = await initializeMcpSession({ workspaceSlug: bundle.workspace.slug, agentSlug, apiKey: bundle.apiKeySecret, }); const result = await mcpToolCall(mcp, operationName, {}); expect(result.window_complete).toBe(true); expect(result.has_more).toBe(false); expect(Array.isArray(result.items)).toBe(true); expect(result.items).toHaveLength(3); expect(result.items[0].message).toBe('billing started'); expect(result.items[2].message).toBe('invoice timeout'); }); test('grpc session tools create persisted stream sessions visible in UI', async ({ page }) => { await login(page); const operationName = uniqueName('playwright_echo_session'); const agentSlug = uniqueName('sales_session'); const payload = buildGrpcSessionOperationPayload(operationName); const bundle = await setupPublishedAgent(page, { operationPayload: payload, agentSlug, toolName: operationName, toolTitle: 'Playwright gRPC Session', toolDescription: 'Streams gRPC echo messages through a bounded MCP session tool family.', }); const mcp = await initializeMcpSession({ workspaceSlug: bundle.workspace.slug, agentSlug, apiKey: bundle.apiKeySecret, }); const started = await mcpToolCall(mcp, `${operationName}_start`, { message: 'hello' }); const sessionId = started.session_id; expect(started.status).toBe('running'); const polled = await mcpToolCall(mcp, `${operationName}_poll`, { session_id: sessionId }); expect(polled.session_id).toBe(sessionId); expect(Array.isArray(polled.items)).toBe(true); expect(polled.items[0].message).toContain('hello'); await page.goto('/stream-sessions'); const sessionCard = page.locator(`.resource-card[data-session-id="${sessionId}"]`); await expect(sessionCard).toBeVisible(); await sessionCard.locator('[data-action="toggle"]').click(); await expect(sessionCard.locator('.resource-detail-pre')).toBeVisible(); await sessionCard.locator('[data-action="stop"]').click(); await expect(sessionCard.locator('[data-action="stop"]')).toHaveCount(0); }); test('async job tools complete and expose results in UI', async ({ page }) => { await login(page); const operationName = uniqueName('playwright_async_lead'); const agentSlug = uniqueName('sales_async'); const payload = buildRestAsyncJobOperationPayload(operationName); const bundle = await setupPublishedAgent(page, { operationPayload: payload, agentSlug, toolName: operationName, toolTitle: 'Playwright Async Lead', toolDescription: 'Creates a lead through the async job MCP tool family.', }); const mcp = await initializeMcpSession({ workspaceSlug: bundle.workspace.slug, agentSlug, apiKey: bundle.apiKeySecret, }); const started = await mcpToolCall(mcp, `${operationName}_start`, { email: 'user@example.com' }); const jobId = started.job_id; expect(started.status).toBe('running'); let status = null; for (let attempt = 0; attempt < 20; attempt += 1) { status = await mcpToolCall(mcp, `${operationName}_status`, { job_id: jobId }); if (status.status === 'completed') { break; } await page.waitForTimeout(50); } expect(status.status).toBe('completed'); const result = await mcpToolCall(mcp, `${operationName}_result`, { job_id: jobId }); expect(result.id).toBe('lead_123'); await page.goto('/async-jobs'); const jobCard = page.locator(`.resource-card[data-job-id="${jobId}"]`); await expect(jobCard).toBeVisible(); await jobCard.locator('[data-action="toggle"]').click(); await expect(page.locator(`[data-result-for="${jobId}"]`)).toContainText('lead_123'); });