Ctrl K
ComunidadGuías…

test/home-mate-settings.test.js

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

Archivo original ↗Preguntar a KiBot
var test = require('node:test');
var assert = require('node:assert/strict');
var child = require('node:child_process');
var path = require('node:path');
var pw = require('playwright');

test('production Mate settings preserve drafts and acknowledge prompt/model saves', async function (t) {
  var port = 35000 + process.pid % 10000;
  var server = child.spawn(process.execPath, [path.join(__dirname,'fixtures/session-folders-dom/serve.js'), String(port)], {stdio:['ignore','pipe','pipe']});
  var browser; t.after(async function () { if (browser) await browser.close(); server.kill(); });
  await new Promise(function (resolve, reject) { server.stdout.once('data',resolve); server.once('error',reject); });
  browser = await pw.chromium.launch();
  var page = await browser.newPage({viewport:{width:1280,height:900}, reducedMotion:'reduce'});
  var errors = []; page.on('pageerror',function (e) { errors.push(e.stack || e.message); });
  await page.goto('http://127.0.0.1:' + port + '/mate-settings.html');
  await page.waitForFunction(function () { return window.__ready; }).catch(function (error) {
    throw new Error(error.message + "\nPage errors: " + errors.join("\n"));
  });
  var dialog = page.getByRole('dialog', {name:'Mate settings'});
  var prompt = page.getByRole('textbox', {name:'Mate prompt'});
  assert.equal(await prompt.count(), 0);
  await page.waitForFunction(function () { return Array.from(document.querySelectorAll('.mate-settings-profile-avatar img')).every(function (img) { return img.complete && img.naturalWidth > 0; }); });
  assert.equal(await page.getByRole('button',{name:'Model: Luna',exact:true}).count(), 0);
  assert.equal(await page.getByRole('button',{name:'Upload image',exact:true}).count(), 0);
  await t.test('identity is readable until Edit, with cancel, retained drafts and acknowledged save', async function () {
    assert.equal(await page.getByRole('textbox',{name:'Name',exact:true}).count(),0);
    assert.equal(await page.getByText('A thoughtful partner for product design.',{exact:true}).isVisible(),true);
    await page.getByRole('button',{name:'Edit Mate identity'}).click();
    await page.getByRole('textbox',{name:'Name',exact:true}).fill('Ari revised');
    await page.getByRole('textbox',{name:'Introduction',exact:true}).fill('A concise design partner.');
    await dialog.getByRole('button',{name:'Prompt',exact:true}).click();
    await dialog.getByRole('button',{name:'General',exact:true}).click();
    assert.equal(await page.getByRole('textbox',{name:'Name',exact:true}).inputValue(),'Ari revised');
    await dialog.getByRole('button',{name:'Close Mate settings'}).click();
    await page.locator('#confirm-cancel').click();
    await page.evaluate(function () { window.__fail = 'Identity save failed.'; });
    await page.getByRole('button',{name:'Save identity'}).click();
    await page.getByRole('alert').filter({hasText:'Identity save failed.'}).waitFor();
    assert.equal(await page.getByRole('textbox',{name:'Name',exact:true}).inputValue(),'Ari revised');
    await page.evaluate(function () { window.__fail = ''; });
    await page.getByRole('button',{name:'Cancel',exact:true}).click();
    assert.equal(await page.getByRole('textbox',{name:'Name',exact:true}).count(),0);
    await page.getByRole('button',{name:'Edit Mate identity'}).click();
    await page.getByRole('textbox',{name:'Introduction',exact:true}).fill('A concise design partner.');
    await page.getByRole('button',{name:'Save identity'}).click();
    await page.getByText('A concise design partner.',{exact:true}).waitFor();
    assert.equal(await page.getByRole('textbox',{name:'Name',exact:true}).count(),0);
    var saved = await page.evaluate(function () { return window.__sent.filter(function (m) { return m.type === 'mate_update'; }).pop(); });
    assert.equal(saved.updates.profile.avatarStyle,'bottts');
    assert.equal(saved.updates.profile.displayName,'Ari');
    assert.equal(saved.updates.bio,'A concise design partner.');
  });
  await dialog.getByRole('button',{name:'Prompt',exact:true}).click();
  await prompt.waitFor();
  var original = await prompt.inputValue();
  await t.test('Prompt shows actual instructions and retains a draft across pages', async function () {
    assert.match(original, /thoughtful design partner/);
    await prompt.fill(original + '\nAsk before changing direction.');
    await dialog.getByRole('button',{name:'Model',exact:true}).click();
    await page.getByRole('button',{name:'Model: Luna',exact:true}).waitFor();
    await dialog.getByRole('button',{name:'Prompt',exact:true}).click();
    assert.match(await prompt.inputValue(), /Ask before changing direction/);
    await dialog.getByRole('button',{name:'Close Mate settings'}).click();
    assert.equal(await page.locator('#confirm-modal').isVisible(), true);
    await page.locator('#confirm-cancel').click();
    assert.equal(await dialog.isVisible(), true);
    await page.getByRole('button',{name:'Save prompt',exact:true}).click();
    await page.getByText('Prompt saved. New conversations use these instructions.').waitFor();
    assert.equal(await page.getByRole('button',{name:'Save prompt',exact:true}).count(), 0);
  });
  await t.test('prompt save failure, conflict, offline and stale response retain intent', async function () {
    await prompt.fill(original + '\nA revised draft remains visible until acknowledged.');
    await page.evaluate(function () { window.__fail = 'Disk is read-only.'; });
    await page.getByRole('button',{name:'Save prompt',exact:true}).click();
    await page.getByRole('alert').filter({hasText:'Disk is read-only.'}).waitFor();
    assert.match(await prompt.inputValue(), /revised draft/);
    await page.evaluate(function () { window.__fail = 'Changed elsewhere.'; });
    await page.getByRole('button',{name:'Save prompt',exact:true}).click();
    await page.getByRole('button',{name:'Reload saved prompt'}).waitFor();
    assert.match(await prompt.inputValue(), /revised draft/);
    await page.evaluate(function () { window.__fail = ''; });
    await page.getByRole('button',{name:'Reload saved prompt'}).click();
    await page.waitForFunction(function () { return !document.querySelector('.mate-instructions-input').disabled; });
    assert.match(await prompt.inputValue(), /Ask before changing direction/);
    await page.evaluate(function () { window.__instructions({mateId:'mate_preview',requestId:'stale',ok:true,content:'wrong'}); window.__offline(true); });
    await prompt.fill(original + '\nOffline changes remain in the editor.');
    await page.getByRole('button',{name:'Save prompt',exact:true}).click();
    await page.getByText('Clay is offline. Reconnect and try again.',{exact:true}).waitFor();
    assert.match(await prompt.inputValue(), /Offline changes/);
    await page.evaluate(function () { window.__offline(false); });
    await page.getByRole('button',{name:'Cancel',exact:true}).click();
  });
  await t.test('compact model draft, keyboard picker, failure retry and acknowledged save', async function () {
    await dialog.getByRole('button',{name:'Model',exact:true}).click();
    await page.getByRole('button',{name:'Provider: Codex',exact:true}).click();
    await page.keyboard.press('Escape');
    assert.equal(await dialog.isVisible(), true);
    await page.getByRole('button',{name:'Provider: Codex',exact:true}).click();
    await page.getByRole('option',{name:'Claude Code',exact:true}).click();
    await page.getByRole('button',{name:'Model: Choose a model',exact:true}).waitFor();
    await page.getByRole('button',{name:'Model: Choose a model',exact:true}).click();
    await page.getByRole('option',{name:'Sol',exact:true}).click();
    assert.equal(await page.evaluate(function () { return window.__sent.filter(function (m) { return m.type === 'home_mate_model_set'; }).length; }), 0);
    await dialog.getByRole('button',{name:'Prompt',exact:true}).click();
    await dialog.getByRole('button',{name:'Model',exact:true}).click();
    assert.equal(await page.locator('#mate-settings-model').inputValue(), 'sol');
    await page.evaluate(function () { window.__fail = 'Model save failed.'; });
    await page.getByRole('button',{name:'Save model',exact:true}).click();
    await page.getByText('Model save failed.',{exact:true}).waitFor();
    assert.equal(await page.locator('#mate-settings-model').inputValue(), 'sol');
    await page.evaluate(function () { window.__fail = ''; });
    await page.getByRole('button',{name:'Save model',exact:true}).click();
    await page.getByText('Model saved.',{exact:true}).waitFor();
    var saved = await page.evaluate(function () { return window.__sent.filter(function (m) { return m.type === 'home_mate_model_set'; }).pop(); });
    assert.equal(saved.vendor,'claude'); assert.equal(saved.model,'sol'); assert.equal(saved.sessionId,1);
  });
  await t.test('appearance controls and focus return remain available', async function () {
    await dialog.getByRole('button',{name:'General',exact:true}).click();
    await page.getByRole('button',{name:'Change Mate avatar'}).click();
    assert.equal(await page.getByRole('button',{name:'Upload image',exact:true}).isVisible(), true);
    assert.equal(await page.locator('.home-mate-avatar-choice').count(),96);
    await page.getByRole('button',{name:'Teal Diamond avatar',exact:true}).click();
    await page.getByRole('button',{name:'Save avatar',exact:true}).click();
    await page.getByText('Avatar saved.',{exact:true}).waitFor();
    await page.getByRole('button',{name:'Cancel',exact:true}).click();
    assert.equal(await page.getByRole('button',{name:'Upload image',exact:true}).count(),0);
    await dialog.getByRole('button',{name:'Close Mate settings'}).click();
    assert.equal(await page.getByRole('button',{name:'Actions for Ari'}).evaluate(function (el) { return el === document.activeElement; }), true);
    await page.getByRole('button',{name:'Actions for Ari'}).click();
    await page.getByRole('menuitem',{name:'Mate settings'}).click();
    await dialog.getByRole('button',{name:'Model',exact:true}).click();
    await page.getByRole('button',{name:'Model: Sol',exact:true}).waitFor();
  });
  await t.test('light/dark and narrow settings fit, with reachable model controls', async function () {
    for (var theme of ['light','dark']) {
      for (var width of [1280,390]) {
        await page.setViewportSize({width:width,height:width === 1280 ? 720 : 900});
        await page.evaluate(function (theme) { document.documentElement.classList.toggle('light-theme',theme === 'light'); }, theme);
        for (var section of ['General','Model','Prompt']) {
          await dialog.getByRole('button',{name:section,exact:true}).click();
          var fits = await dialog.evaluate(function (el) { var r=el.getBoundingClientRect(); return r.left >= 0 && r.right <= innerWidth + 1 && r.bottom <= innerHeight + 1 && el.scrollWidth <= el.clientWidth + 1; });
          assert.equal(fits,true);
          if (section === 'Prompt') {
            var geometry = await prompt.evaluate(function (el) {
              var r = el.getBoundingClientRect(); var body = el.closest('.home-mate-settings-body').getBoundingClientRect();
              return {height:r.height, available:body.height, bottomGap:body.bottom-r.bottom};
            });
            assert.ok(geometry.height > geometry.available * .7);
            assert.ok(geometry.bottomGap <= 28);
          }
          if (section === 'Model') {
            if (width === 1280) assert.equal(await dialog.locator('.home-mate-settings-content').evaluate(function (el) { return el.scrollHeight <= el.clientHeight + 1; }),true);
            await page.getByRole('button',{name:/^Model: /}).scrollIntoViewIfNeeded();
            assert.equal(await page.getByRole('button',{name:/^Model: /}).isVisible(), true);
            await dialog.locator('.home-mate-settings-content').evaluate(function (el) { el.scrollTop = 0; });
          }
          await page.screenshot({path:'/tmp/mate-settings-' + section.toLowerCase() + '-' + theme + '-' + width + '.png'});
        }
      }
    }
  });
  await t.test('permanent deletion requires exact typed acknowledgement and cancels safely', async function () {
    await dialog.getByRole('button',{name:'General',exact:true}).click();
    var remove = page.getByRole('button',{name:'Delete Mate',exact:true});
    await remove.click();
    var confirmation = page.getByRole('alertdialog');
    var input = page.getByRole('textbox',{name:'Type understand to confirm permanent deletion'});
    var confirm = page.getByRole('button',{name:'Delete permanently',exact:true});
    assert.equal(await confirm.isDisabled(),true);
    assert.match(await confirmation.innerText(),/cannot be undone/);
    await input.fill('UNDERSTAND'); assert.equal(await confirm.isDisabled(),true);
    await input.fill('understand '); assert.equal(await confirm.isDisabled(),true);
    await page.keyboard.press('Escape');
    assert.equal(await confirmation.count(),0);
    assert.equal(await remove.evaluate(function (el) { return el === document.activeElement; }),true);
    assert.equal(await page.evaluate(function () { return window.__sent.filter(function (m) { return m.type === 'mate_delete'; }).length; }),0);
    await remove.click(); await input.fill('understand');
    assert.equal(await confirm.isEnabled(),true);
    await page.locator('#confirm-cancel').click();
    await remove.click(); assert.equal(await input.inputValue(),''); assert.equal(await confirm.isDisabled(),true);
    await input.fill('understand');
    await page.screenshot({path:'/tmp/mate-delete-confirm-narrow-dark.png'});
    await confirm.click();
    assert.equal(await page.evaluate(function () { return window.__sent.filter(function (m) { return m.type === 'mate_delete'; }).length; }),1);
    assert.equal(await dialog.count(),0);
    assert.equal(await page.locator('.mate-delete-challenge').count(),0);
    assert.equal(await page.locator('#confirm-ok').isDisabled(),false);
  });
  assert.deepEqual(errors,[]);
});