'use strict'; const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); const { spawn, spawnSync } = require('child_process'); const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'nuguland-ipc-')); const name = `test-${process.pid}`; const configDir = path.join(tmp, 'quickshell', name); const testEnv = { ...process.env, XDG_CONFIG_HOME: tmp, QT_NO_XDG_DESKTOP_PORTAL: '1' }; const output = []; let proc; function ipc(method) { return spawnSync('qs', ['ipc', '-c', name, 'call', 'tests', method], { encoding: 'utf8', env: testEnv, timeout: 2000 }); } try { fs.mkdirSync(configDir, { recursive: true }); for (const file of ['Notifications.qml', 'Network.qml', 'network.js']) fs.symlinkSync(path.join(__dirname, file), path.join(configDir, file)); fs.writeFileSync(path.join(configDir, 'shell.qml'), ` import QtQuick import Quickshell import Quickshell.Io ShellRoot { Notifications { id: notifications } Network { id: network; autoRefresh: false } IpcHandler { target: "tests" function notifications(): string { return JSON.stringify(notifications.selfTest()); } function network(): string { return network.selfTest(); } function ready(): string { return "ready"; } } } `); proc = spawn('dbus-run-session', ['--', 'qs', '-c', name], { detached: true, env: testEnv, stdio: ['ignore', 'pipe', 'pipe'] }); proc.stdout.on('data', chunk => output.push(String(chunk))); proc.stderr.on('data', chunk => output.push(String(chunk))); let ready = false; for (let attempt = 0; attempt < 80; attempt++) { const result = ipc('ready'); if (result.status === 0 && result.stdout.trim() === 'ready') { ready = true; break; } Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 50); } assert(ready, `isolated Quickshell IPC did not become ready: ${output.join('')}`); for (const method of ['notifications', 'network']) { const result = ipc(method); assert.strictEqual(result.status, 0, result.stderr); const report = JSON.parse(result.stdout); const passed = typeof report.pass === 'boolean' ? report.pass : report.fail === 0; assert.strictEqual(passed, true, `${method}: ${JSON.stringify(report.failures || report.cases || [])}`); } assert(!/WARN|ERROR|Error parsing|deprecated|Could not|failed/.test(output.join('')), output.join('')); console.log('notifications.test.js: ALL PASS'); } finally { if (proc) process.kill(-proc.pid, 'SIGTERM'); fs.rmSync(tmp, { recursive: true, force: true }); }