test/background-task-tabs-browser.test.js
Rama main · réplica de lectura del repositorio original.
var test = require('node:test'), assert = require('node:assert/strict'), cp = require('node:child_process'), path = require('node:path');
var chromium = require('playwright').chromium;
test('native task tabs open real bounded transcripts/output and retain completed tasks', { timeout: 90000 }, async function (t) {
var child = cp.fork(path.join(__dirname, 'fixtures/pane-reuse-server.cjs'), [], { env: Object.assign({}, process.env, { CLAY_BACKGROUND_TASKS: '1' }), stdio: ['ignore', 'pipe', 'pipe', 'ipc'] });
t.after(function () { child.kill('SIGTERM'); }); child.stdout.resume(); child.stderr.resume();
var info = await new Promise(function (resolve) { child.once('message', resolve); });
var browser = await chromium.launch({ headless: true }); t.after(function () { return browser.close(); });
var page = await browser.newPage({ viewport: { width: 1280, height: 850 } }), errors = [];
page.on('console', function (message) { if (message.type() === 'error') errors.push(message.text()); });
page.on('pageerror', function (error) { errors.push(error.message); });
var base = 'http://127.0.0.1:' + info.port;
if (!process.env.CLAY_TASK_COMPILED) await require('./fixtures/source-module-runtime.cjs').install(page);
await page.goto(base + '/fixture/login');
var data = await (await page.request.get(base + '/fixture/state')).json();
await page.locator('.session-item[data-session-id="' + data.standaloneId + '"]').first().click();
await page.waitForFunction(function (id) { return Array.from(document.querySelectorAll('iframe')).some(function (frame) { var live = frame.clayPane && frame.clayPane.identity(); return live && live.ready && live.sessionId === id; }); }, data.standaloneId);
await page.request.post(base + '/fixture/background-tasks?id=' + data.standaloneId);
var host = page;
// A singleton may be rendered through its authenticated pane document.
await page.waitForFunction(function () { return (document.querySelector('[data-background-task="agent-a"]') && document.querySelector('[data-background-task="agent-a"]').getClientRects().length) || Array.from(document.querySelectorAll('iframe')).some(function (frame) { try { var chip = frame.contentDocument.querySelector('[data-background-task="agent-a"]'); return chip && chip.getClientRects().length; } catch (e) { return false; } }); }).catch(function (error) { assert.fail(error.message + ' · Browser errors: ' + JSON.stringify(errors)); });
for (var frame of page.frames()) if (await frame.locator('[data-background-task="agent-a"]').isVisible()) host = frame;
await host.locator('[data-background-task="agent-a"]').click();
var viewer = host.locator('#background-task-viewer');
await viewer.getByText('Task transcript 1 row 0', { exact: true }).waitFor();
assert.equal(await host.locator('#background-tasks-bar').count(), 0);
assert.match(await viewer.innerText(), /Parent agent/); assert.match(await viewer.innerText(), /Background agent/);
await viewer.locator('.tool-header').first().click(); assert.match(await viewer.locator('.tool-item.expanded').first().innerText(), /fixture.txt/);
await page.request.post(base + '/fixture/background-tasks?id=' + data.standaloneId);
await viewer.getByText('Task transcript 2 row 0', { exact: true }).waitFor();
assert.equal(await viewer.locator('.tool-item.expanded').count(), 1);
await viewer.getByRole('button', { name: 'Next', exact: true }).click(); await viewer.getByText('Task transcript 2 row 104', { exact: true }).waitFor();
await viewer.getByRole('button', { name: 'Previous', exact: true }).click(); await viewer.getByText('Task transcript 2 row 0', { exact: true }).waitFor();
await host.locator('body').press('Escape'); await viewer.waitFor({ state: 'detached' });
assert.equal(await host.locator('[data-background-task="agent-a"]').evaluate(function (el) { return el === document.activeElement; }), true);
await host.locator('[data-background-task="shell-a"]').click(); await viewer.getByText('Native shell output 2', { exact: true }).waitFor();
assert.match(await viewer.innerText(), /Last 8 KiB/);
await host.getByRole('button', { name: 'Stop Run checks', exact: true }).click();
await host.getByRole('button', { name: 'Stop Run checks', exact: true }).waitFor({ state: 'detached' });
await host.locator('[data-background-task="shell-a"]').click(); await viewer.getByText('Native shell output 2', { exact: true }).waitFor();
await viewer.getByRole('status').filter({ hasText: 'Finished' }).waitFor();
var stopped = await (await page.request.get(base + '/fixture/background-tasks?id=' + data.standaloneId)).json(); assert.deepEqual(stopped.stopped, ['shell-a']);
await page.setViewportSize({ width: 420, height: 760 });
await host.waitForFunction(function () { var el = document.getElementById('background-task-viewer'); if (!el) return false; var rect = el.getBoundingClientRect(); return innerWidth <= 420 && rect.width <= innerWidth && rect.x >= 0; });
var box = await viewer.boundingBox(); assert.ok(box.width <= 420 && box.x >= 0, JSON.stringify(box));
await page.request.post(base + '/fixture/switch?id=' + data.otherIds[0]); await viewer.waitFor({ state: 'detached' });
assert.equal(await host.locator('[data-background-task]').count(), 0);
assert.deepEqual(errors, []);
});