mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-10-06 15:02:20 +02:00
Integrate lab fff55a78 into PR #40 (cc25d5ba). Lab's modular email backend/frontend, modular settings, split stylesheets (static/style.css stays deleted), procfs compatibility, and request-scoped TurnContract authority win; PR #40's routing classifiers, editor/email/task features, and style.css changes are ported into lab's module and stylesheet homes. Integration fixes: - settings/api.js imports ui.js under its canonical versioned URL - browser observations keep legacy CAPTCHA/access-block evidence - artifact turns do not re-trigger broad-web research recovery - env reference documents PR test-tool variables; page regenerated PR #40 defects surfaced by lab gates and fixed here: - web_fetch generic schema drops top-level anyOf (OpenAI contract); the compact preview contract still requires url or urls - get_weather registered as a brokered network read - new lazy editor modules precached for offline use - SearXNG pin mirrored into GPU standalone compose files - image model picker again skips offline endpoints Tests updated where PR #40 changed behaviour on purpose, and PR tests moved onto lab's document_source helpers.
49 lines
2.2 KiB
JavaScript
49 lines
2.2 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { documentSource } from './helpers/document_source.mjs';
|
|
import { chromium } from 'playwright';
|
|
|
|
const source = documentSource();
|
|
const start = source.indexOf(' function clearSelection(');
|
|
const cleanup = source.slice(start, source.indexOf(' function clearSelectionAt(', start));
|
|
assert.equal((source.match(/if \(_selections.length\) clearSelection\(\{ preserveCaret: true \}\);/g) || []).length, 2);
|
|
const browser = await chromium.launch({ headless: true });
|
|
try {
|
|
const page = await browser.newPage();
|
|
await page.setContent('<div id="rich" contenteditable="true">before SELECT after</div><span id="doc-selection-badge"></span>');
|
|
await page.evaluate(cleanup => {
|
|
let _selections = [{ kind: 'rich' }];
|
|
const _richSelectionHighlightName = 'test-selection';
|
|
const rich = document.getElementById('rich');
|
|
const _emailRichbodyActive = () => rich;
|
|
const _scheduleDocumentStats = () => {};
|
|
eval(cleanup + '\nwindow.clearPinned = clearSelection;');
|
|
rich.addEventListener('input', () => {
|
|
if (_selections.length) window.clearPinned({ preserveCaret: true });
|
|
});
|
|
rich.focus();
|
|
const range = document.createRange();
|
|
range.setStart(rich.firstChild, 7);
|
|
range.setEnd(rich.firstChild, 13);
|
|
window.getSelection().removeAllRanges();
|
|
window.getSelection().addRange(range);
|
|
}, cleanup);
|
|
await page.keyboard.type('new');
|
|
const result = await page.evaluate(() => ({
|
|
text: document.getElementById('rich').textContent,
|
|
offset: window.getSelection().anchorOffset,
|
|
collapsed: window.getSelection().isCollapsed,
|
|
ranges: window.getSelection().rangeCount,
|
|
badge: document.getElementById('doc-selection-badge').style.display,
|
|
}));
|
|
assert.equal(result.text, 'before new after');
|
|
assert.equal(result.offset, 10);
|
|
assert.equal(result.collapsed, true);
|
|
assert.equal(result.ranges, 1);
|
|
assert.equal(result.badge, 'none');
|
|
await page.evaluate(() => window.clearPinned());
|
|
assert.equal(await page.evaluate(() => window.getSelection().rangeCount), 0);
|
|
console.log('PASS: replacement typing preserves caret; explicit clear still removes selection.');
|
|
} finally {
|
|
await browser.close();
|
|
}
|