Ctrl K
ComunidadGuías…

test/contextual-session-citation-browser.test.cjs

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
var test = require('node:test'), assert = require('node:assert/strict'), cp = require('node:child_process'), path = require('node:path'), playwright = require('playwright');
test('assistant citations render safely through stream/history and resolve exact opaque targets from pane and native workspace', async function (t) {
  var child = cp.fork(path.join(__dirname, 'fixtures/contextual-clay-server.cjs'), [], { env: Object.assign({}, process.env, { CLAY_CONTEXT_ACCESS_FIXTURE: '1' }), stdio: ['ignore', 'pipe', 'pipe', 'ipc'] });
  t.after(function () { child.kill('SIGTERM'); }); var output = '';
  child.stdout.on('data', function (value) { output += value; }); child.stderr.on('data', function (value) { output += value; });
  var info = await new Promise(function (resolve, reject) { var timer = setTimeout(function () { reject(new Error(output)); }, 15000); child.once('message', function (value) { clearTimeout(timer); resolve(value); }); });
  var browser = await playwright.chromium.launch(); t.after(async function () { await browser.close(); });
  var page = await browser.newPage({ viewport: { width: 1280, height: 800 }, reducedMotion: 'reduce' }); page.setDefaultTimeout(10000);
  var origin = 'http://127.0.0.1:' + info.port, errors = []; page.on('pageerror', function (error) { errors.push(error.message); });
  var betaRequests = [], betaSwitches = [];
  page.on('websocket', function (socket) {
    if (new URL(socket.url()).pathname !== '/p/beta/ws') return;
    socket.on('framesent', function (frame) {
      var message = JSON.parse(String(frame.payload));
      if (message.type === 'switch_session') betaRequests.push(message.id);
    });
    socket.on('framereceived', function (frame) {
      var message = JSON.parse(String(frame.payload));
      if (message.type === 'session_switched') betaSwitches.push(message.id);
    });
  });
  await page.goto(origin + '/fixture/login?to=alpha', { waitUntil: 'domcontentloaded' });
  await page.waitForFunction(function () { return !document.querySelector('.icon-strip-brand').disabled; }); await page.locator('.icon-strip-brand').click();
  var pane = page.frameLocator('#contextual-clay iframe[data-canonical="true"]'); await pane.locator('#messages').getByText('Isolated canonical integration conversation.', { exact: true }).waitFor();
  var refs = await (await page.request.get(origin + '/fixture/session-citation')).json();
  var citation = pane.locator('.clayos-session-link[data-session-ref="' + refs.alphaRef + '"]').filter({ hasText: 'Oct 16' });
  await citation.waitFor();
  assert.equal(await citation.locator('small').textContent(), 'Oct 16');
  assert.equal(await pane.locator('pre code').filter({ hasText: 'fenced example' }).count(), 1);
  assert.equal(await pane.locator('code').filter({ hasText: 'call(' }).count(), 1);
  var windowFrame = page.frames().find(function (frame) { return frame.url().includes(info.sourceSlug); });
  var literals = await windowFrame.evaluate(async function (ref) {
    var renderer = await import('./modules/chat-bubble-renderer.js');
    var row = renderer.createAssistantBubble({}); document.getElementById('messages').appendChild(row);
    renderer.renderAssistantBubbleText(row, '`[clayos/' + ref + ' — literal canonical sample]`\n\n`var citation = "[clay-landing/' + ref + ' — literal mixed code]"`\n\n```js\n[clay-landing/' + ref + ' — fenced]\n```\n\n[clayos/session:short — malformed] [clayos/' + ref + '#entry-1.5 — invalid] [clayos/' + ref + '#entry-9007199254740992 — unsafe index]\n\n[<img src=x onerror=alert(1)>](' + ref + '#entry-0)');
    var result = { literalCodes: row.querySelectorAll('code').length, pills: row.querySelectorAll('.clayos-session-link').length, imageHandlers: row.querySelectorAll('[onerror]').length, entry: row.querySelector('.clayos-session-link').dataset.sessionEntryIndex };
    row.remove(); return result;
  }, refs.alphaRef);
  assert.deepEqual(literals, { literalCodes: 3, pills: 1, imageHandlers: 0, entry: '0' });
  for (var field of ['sessionOriginId', 'mateStamp', 'mateId']) {
    await page.evaluate(async function (field) {
      var socket = (await import('./modules/ws-ref.js')).getWs(), send = socket.send;
      socket.send = function (raw) {
        var request = JSON.parse(raw);
        if (request.type === 'home_clay_session_resolve') { request.contextualSource[field] = 'spoofed'; socket.send = send; return send.call(socket, JSON.stringify(request)); }
        return send.call(socket, raw);
      };
    }, field);
    await citation.click(); await citation.locator('..').locator('.is-error').waitFor();
    assert.equal(new URL(page.url()).pathname, '/p/alpha/');
  }
  for (var deniedRef of [refs.foreignRef, refs.hiddenRef, 'session:AAAAAAAAAAAAAAAAAAAAAAAA']) {
    var denied = pane.locator('.clayos-session-link[data-session-ref="' + deniedRef + '"]'); await denied.click(); await denied.locator('..').locator('.is-error[data-session-ref="' + deniedRef + '"]').waitFor();
    assert.equal(new URL(page.url()).pathname, '/p/alpha/'); assert.equal(await page.locator('#contextual-clay').isVisible(), true);
  }
  await page.screenshot({ path: '/tmp/clay-session-citation-popover.png' });
  await citation.click(); await pane.locator('.clayos-session-link.is-loading').waitFor({ state: 'detached' });
  assert.equal(await page.locator('#contextual-clay').isVisible(), true, 'Citation navigation keeps the source window open');
  assert.equal(new URL(page.url()).pathname, '/p/alpha/');
  await page.evaluate(async function () {
    var socket = (await import('./modules/ws-ref.js')).getWs(), receive = socket.onmessage;
    socket.onmessage = function (event) { if (JSON.parse(event.data).type === 'home_clay_session_target') { window.heldCitationReply = event; return; } receive(event); };
    window.releaseCitationReply = function () { socket.onmessage = receive; receive(window.heldCitationReply); };
  });
  await citation.click(); await page.waitForFunction(function () { return !!window.heldCitationReply; });
  await page.getByRole('link', { name: 'BI', exact: true }).click(); await page.waitForURL('**/p/beta/');
  await page.evaluate(function () { window.releaseCitationReply(); }); await citation.locator('..').locator('.is-error').waitFor({ state: 'attached' });
  assert.equal(new URL(page.url()).pathname, '/p/beta/');
  await page.locator('[data-clay-expand]').click(); await page.waitForURL('**/p/' + info.sourceSlug + '/');
  var nativeLink = page.locator('#messages .clayos-session-link[data-session-ref="' + refs.betaRef + '"]'); await nativeLink.waitFor();
  assert.equal(await nativeLink.getAttribute('data-session-entry-index'), '0');
  await page.screenshot({ path: '/tmp/clay-session-citation-native.png' });
  var requestsBeforeCitation = betaRequests.length, switchesBeforeCitation = betaSwitches.length;
  await nativeLink.click(); await page.waitForURL('**/p/beta/'); await page.locator('#messages').getByText('BETA_RENDERED_DESTINATION', { exact: true }).waitFor();
  await page.locator('#messages .session-entry-target').waitFor();
  assert.deepEqual(betaRequests.slice(requestsBeforeCitation), [], 'the initial destination identity must not request a duplicate replay');
  assert.equal(betaSwitches.length - switchesBeforeCitation, 1, 'native citation receives one authoritative initial replay');
  // A same-target authoritative replay must not consume the citation feedback.
  await page.evaluate(async function () {
    var state = (await import('/p/alpha/modules/store.js')).store;
    var socket = (await import('/p/alpha/modules/ws-ref.js')).getWs();
    window.citationReplayEpoch = state.get('sessionActionEpoch');
    socket.send(JSON.stringify({ type: 'switch_session', id: state.get('activeSessionId') }));
  });
  await page.waitForFunction(async function () {
    var state = (await import('/p/alpha/modules/store.js')).store;
    return state.get('sessionActionEpoch') > window.citationReplayEpoch
      && document.querySelector('#messages').textContent.includes('BETA_RENDERED_DESTINATION')
      && !state.get('replayingHistory');
  });
  await page.locator('#messages .session-entry-target').waitFor();
  assert.deepEqual(errors, []);
});