// Playwright-Checks Chat-Baustein: Option requestHeaders (Ticketsystem mit JWT) fuer Hochladen und Entfernen. // Nicht Teil von npm test. Aufruf: node test/ui/composer-headers.ui.mjs import http from 'node:http' import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' import { chromium } from '/root/.npm/_npx/db89d7302a373f10/node_modules/playwright-core/index.mjs' const pub = path.join(path.dirname(fileURLToPath(import.meta.url)), '../../public') // Testseite: ?mode=ok (async Header), none (ohne Option), fail (Header verworfen) const PAGE = `
` const server = http.createServer(async (req, res) => { const url = new URL(req.url, 'http://x') if (url.pathname === '/composer-test.html') { res.writeHead(200, { 'content-type': 'text/html' }) return res.end(PAGE) } try { const file = path.join(pub, url.pathname) const data = await readFile(file) res.writeHead(200, { 'content-type': file.endsWith('.js') ? 'text/javascript' : 'text/css' }) res.end(data) } catch { res.writeHead(404) res.end() } }) await new Promise((resolve) => server.listen(0, '127.0.0.1', resolve)) const base = `http://127.0.0.1:${server.address().port}` let failed = 0 const check = (name, ok, detail = '') => { console.log(`${ok ? 'OK ' : 'FAIL'} ${name}${detail ? ` (${detail})` : ''}`) if (!ok) failed += 1 } const browser = await chromium.launch() try { const run = async (mode) => { const page = await browser.newPage() page.setDefaultTimeout(30000) const calls = [] await page.route('**/upload**', (route) => { const req = route.request() calls.push({ method: req.method(), path: new URL(req.url()).pathname, auth: req.headers().authorization || null }) if (req.method() === 'DELETE') return route.fulfill({ status: 204, body: '' }) return route.fulfill({ status: 201, contentType: 'application/json', body: JSON.stringify({ attachment: { id: 'a1', name: 'notiz.txt', type: 'text/plain', size: 5, kind: 'file' } }) }) }) await page.goto(`${base}/composer-test.html?mode=${mode}`) await page.locator('#root input[type=file]:not([accept])').setInputFiles({ name: 'notiz.txt', mimeType: 'text/plain', buffer: Buffer.from('hallo') }) await page.waitForTimeout(800) return { page, calls } } const ok = await run('ok') const up = ok.calls.find((c) => c.method === 'POST') check('mit_header_upload', up?.auth === 'Bearer test', JSON.stringify(up)) await ok.page.click('.chat-tray-remove') await ok.page.waitForTimeout(500) const del = ok.calls.find((c) => c.method === 'DELETE') check('mit_header_delete', del?.path === '/upload/a1' && del?.auth === 'Bearer test', JSON.stringify(del)) const none = await run('none') const up2 = none.calls.find((c) => c.method === 'POST') check('ohne_option_kein_header', Boolean(up2) && up2.auth === null, JSON.stringify(up2)) const fail = await run('fail') const text = await fail.page.textContent('#root') check('header_fehler', fail.calls.length === 0 && text.includes('JWT weg'), `${fail.calls.length} Aufrufe, Text: ${text.slice(0, 120)}`) } finally { await browser.close() server.close() } console.log(failed ? `${failed} Check(s) fehlgeschlagen` : 'alle Checks ok') process.exit(failed ? 1 : 0)