|
5 | 5 | */ |
6 | 6 |
|
7 | 7 | import assert from 'node:assert'; |
8 | | -import {spawnSync} from 'node:child_process'; |
| 8 | +import {spawn} from 'node:child_process'; |
9 | 9 | import path from 'node:path'; |
10 | 10 | import {describe, it, afterEach, beforeEach} from 'node:test'; |
11 | 11 |
|
12 | 12 | const CLI_PATH = path.resolve('build/src/bin/chrome-devtools.js'); |
13 | 13 |
|
| 14 | +async function runCli( |
| 15 | + args: string[], |
| 16 | +): Promise<{status: number | null; stdout: string; stderr: string}> { |
| 17 | + return new Promise((resolve, reject) => { |
| 18 | + const child = spawn('node', [CLI_PATH, ...args]); |
| 19 | + let stdout = ''; |
| 20 | + let stderr = ''; |
| 21 | + child.stdout.on('data', chunk => { |
| 22 | + stdout += chunk; |
| 23 | + process.stdout.write(chunk); |
| 24 | + }); |
| 25 | + child.stderr.on('data', chunk => { |
| 26 | + stderr += chunk; |
| 27 | + process.stderr.write(chunk); |
| 28 | + }); |
| 29 | + child.on('close', status => resolve({status, stdout, stderr})); |
| 30 | + child.on('error', reject); |
| 31 | + }); |
| 32 | +} |
| 33 | + |
14 | 34 | describe('chrome-devtools', () => { |
15 | | - function assertDaemonIsNotRunning() { |
16 | | - const result = spawnSync('node', [CLI_PATH, 'status']); |
| 35 | + async function assertDaemonIsNotRunning() { |
| 36 | + const result = await runCli(['status']); |
17 | 37 | assert.strictEqual( |
18 | | - result.stdout.toString(), |
| 38 | + result.stdout, |
19 | 39 | 'chrome-devtools-mcp daemon is not running.\n', |
20 | 40 | ); |
21 | 41 | } |
22 | 42 |
|
23 | | - function assertDaemonIsRunning() { |
24 | | - const result = spawnSync('node', [CLI_PATH, 'status']); |
| 43 | + async function assertDaemonIsRunning() { |
| 44 | + const result = await runCli(['status']); |
25 | 45 | assert.ok( |
26 | | - result.stdout |
27 | | - .toString() |
28 | | - .startsWith('chrome-devtools-mcp daemon is running.\n'), |
| 46 | + result.stdout.startsWith('chrome-devtools-mcp daemon is running.\n'), |
29 | 47 | 'chrome-devtools-mcp daemon is not running', |
30 | 48 | ); |
31 | 49 | } |
32 | 50 |
|
33 | | - beforeEach(() => { |
34 | | - spawnSync('node', [CLI_PATH, 'stop']); |
35 | | - assertDaemonIsNotRunning(); |
| 51 | + beforeEach(async () => { |
| 52 | + await runCli(['stop']); |
| 53 | + await assertDaemonIsNotRunning(); |
36 | 54 | }); |
37 | 55 |
|
38 | | - afterEach(() => { |
39 | | - spawnSync('node', [CLI_PATH, 'stop']); |
40 | | - assertDaemonIsNotRunning(); |
| 56 | + afterEach(async () => { |
| 57 | + await runCli(['stop']); |
| 58 | + await assertDaemonIsNotRunning(); |
41 | 59 | }); |
42 | 60 |
|
43 | | - it('reports daemon status correctly', () => { |
44 | | - assertDaemonIsNotRunning(); |
| 61 | + it('reports daemon status correctly', async () => { |
| 62 | + await assertDaemonIsNotRunning(); |
45 | 63 |
|
46 | | - const startResult = spawnSync('node', [CLI_PATH, 'start']); |
| 64 | + const startResult = await runCli(['start']); |
47 | 65 | assert.strictEqual( |
48 | 66 | startResult.status, |
49 | 67 | 0, |
50 | | - `start command failed: ${startResult.stderr.toString()}`, |
| 68 | + `start command failed: ${startResult.stderr}`, |
51 | 69 | ); |
52 | 70 |
|
53 | | - assertDaemonIsRunning(); |
| 71 | + await assertDaemonIsRunning(); |
54 | 72 | }); |
55 | 73 |
|
56 | | - it('can start and stop the daemon', () => { |
57 | | - assertDaemonIsNotRunning(); |
| 74 | + it('can start and stop the daemon', async () => { |
| 75 | + await assertDaemonIsNotRunning(); |
58 | 76 |
|
59 | | - const startResult = spawnSync('node', [CLI_PATH, 'start']); |
| 77 | + const startResult = await runCli(['start']); |
60 | 78 | assert.strictEqual( |
61 | 79 | startResult.status, |
62 | 80 | 0, |
63 | | - `start command failed: ${startResult.stderr.toString()}`, |
| 81 | + `start command failed: ${startResult.stderr}`, |
64 | 82 | ); |
65 | 83 |
|
66 | | - assertDaemonIsRunning(); |
| 84 | + await assertDaemonIsRunning(); |
67 | 85 |
|
68 | | - const stopResult = spawnSync('node', [CLI_PATH, 'stop']); |
| 86 | + const stopResult = await runCli(['stop']); |
69 | 87 | assert.strictEqual( |
70 | 88 | stopResult.status, |
71 | 89 | 0, |
72 | | - `stop command failed: ${stopResult.stderr.toString()}`, |
| 90 | + `stop command failed: ${stopResult.stderr}`, |
73 | 91 | ); |
74 | 92 |
|
75 | | - assertDaemonIsNotRunning(); |
| 93 | + await assertDaemonIsNotRunning(); |
76 | 94 | }); |
77 | 95 |
|
78 | 96 | it('can invoke list_pages', async () => { |
79 | | - assertDaemonIsNotRunning(); |
| 97 | + await assertDaemonIsNotRunning(); |
80 | 98 |
|
81 | | - const startResult = spawnSync('node', [CLI_PATH, 'start']); |
| 99 | + const startResult = await runCli(['start']); |
82 | 100 | assert.strictEqual( |
83 | 101 | startResult.status, |
84 | 102 | 0, |
85 | | - `start command failed: ${startResult.stderr.toString()}`, |
| 103 | + `start command failed: ${startResult.stderr}`, |
86 | 104 | ); |
87 | 105 |
|
88 | | - const listPagesResult = spawnSync('node', [CLI_PATH, 'list_pages']); |
| 106 | + const listPagesResult = await runCli(['list_pages']); |
89 | 107 | assert.strictEqual( |
90 | 108 | listPagesResult.status, |
91 | 109 | 0, |
92 | | - `list_pages command failed: ${listPagesResult.stderr.toString()}`, |
| 110 | + `list_pages command failed: ${listPagesResult.stderr}`, |
93 | 111 | ); |
94 | 112 | assert( |
95 | | - listPagesResult.stdout.toString().includes('about:blank'), |
| 113 | + listPagesResult.stdout.includes('about:blank'), |
96 | 114 | 'list_pages output is unexpected', |
97 | 115 | ); |
98 | 116 |
|
99 | | - assertDaemonIsRunning(); |
| 117 | + await assertDaemonIsRunning(); |
100 | 118 | }); |
101 | 119 |
|
102 | 120 | it('can take screenshot', async () => { |
103 | | - const startResult = spawnSync('node', [CLI_PATH, 'start']); |
| 121 | + const startResult = await runCli(['start']); |
104 | 122 | assert.strictEqual( |
105 | 123 | startResult.status, |
106 | 124 | 0, |
107 | | - `start command failed: ${startResult.stderr.toString()}`, |
| 125 | + `start command failed: ${startResult.stderr}`, |
108 | 126 | ); |
109 | 127 |
|
110 | | - const result = spawnSync('node', [CLI_PATH, 'take_screenshot']); |
| 128 | + const result = await runCli(['take_screenshot']); |
111 | 129 | assert.strictEqual( |
112 | 130 | result.status, |
113 | 131 | 0, |
114 | | - `take_screenshot command failed: ${result.stderr.toString()}`, |
| 132 | + `take_screenshot command failed: ${result.stderr}`, |
115 | 133 | ); |
116 | 134 | assert( |
117 | | - result.stdout.toString().includes('.png'), |
| 135 | + result.stdout.includes('.png'), |
118 | 136 | 'take_screenshot output is unexpected', |
119 | 137 | ); |
120 | 138 | }); |
121 | 139 |
|
122 | | - it('forwards disclaimers to stderr on start', () => { |
123 | | - const result = spawnSync('node', [CLI_PATH, 'start']); |
| 140 | + it('forwards disclaimers to stderr on start', async () => { |
| 141 | + const result = await runCli(['start']); |
124 | 142 | assert.strictEqual( |
125 | 143 | result.status, |
126 | 144 | 0, |
127 | | - `start command failed: ${result.stderr.toString()}`, |
| 145 | + `start command failed: ${result.stderr}`, |
128 | 146 | ); |
129 | 147 | assert( |
130 | | - result.stderr.toString().includes('chrome-devtools-mcp exposes content'), |
| 148 | + result.stderr.includes('chrome-devtools-mcp exposes content'), |
131 | 149 | 'Disclaimer not found in stderr on start', |
132 | 150 | ); |
133 | 151 | }); |
|
0 commit comments