070959e133
landing-page-staging / Deploy landing page to staging (push) Has been skipped
landing-page-ci / Validate landing page (push) Failing after 4s
visual-baseline / Capture visual baselines (push) Has been cancelled
bake-plugin-previews / Bake plugin previews (push) Has been cancelled
41 lines
1.6 KiB
TypeScript
41 lines
1.6 KiB
TypeScript
import { EventEmitter } from 'node:events';
|
|
import type { ChildProcess } from 'node:child_process';
|
|
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import { createBrowserOpenInvocation, openBrowser } from '../src/browser-open.js';
|
|
|
|
describe('browser open helper', () => {
|
|
it('opens URLs on Windows through cmd.exe instead of spawning the shell builtin directly', () => {
|
|
const invocation = createBrowserOpenInvocation('win32', 'http://127.0.0.1:7456/');
|
|
|
|
expect(invocation.command).toMatch(/cmd(?:\.exe)?$/i);
|
|
expect(invocation.args.slice(0, 3)).toEqual(['/d', '/s', '/c']);
|
|
expect(invocation.args[3]).toContain('start "" "http://127.0.0.1:7456/"');
|
|
expect(invocation.options).toMatchObject({ windowsVerbatimArguments: true });
|
|
});
|
|
|
|
it('escapes cmd.exe metacharacters before opening Windows URLs', () => {
|
|
const invocation = createBrowserOpenInvocation('win32', 'https://example.test/a b?q=%USERPROFILE%&name="A"');
|
|
|
|
expect(invocation.args[3]).toMatch(/^"start "" /);
|
|
expect(invocation.args[3]).toContain('"^%"USERPROFILE"^%"');
|
|
expect(invocation.args[3]).toContain('name=""A""');
|
|
});
|
|
|
|
it('handles opener spawn errors without crashing the daemon', () => {
|
|
const child = new EventEmitter() as ChildProcess;
|
|
child.unref = vi.fn() as ChildProcess['unref'];
|
|
const spawn = vi.fn(() => child);
|
|
const warn = vi.fn();
|
|
|
|
openBrowser('http://127.0.0.1:7456/', {
|
|
platform: 'linux',
|
|
spawn,
|
|
warn,
|
|
});
|
|
|
|
expect(() => child.emit('error', new Error('spawn xdg-open ENOENT'))).not.toThrow();
|
|
expect(warn).toHaveBeenCalledWith(expect.stringContaining('failed to open browser'));
|
|
});
|
|
});
|