firefox-devtools-mcp 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +17035 -7132
- package/package.json +3 -2
- package/scripts/run-integration-tests-windows.mjs +188 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firefox-devtools-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server for Firefox DevTools automation",
|
|
5
5
|
"author": "freema",
|
|
6
6
|
"license": "MIT",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"test:tools": "node scripts/test-bidi-devtools.js",
|
|
36
36
|
"test:input": "node scripts/test-input-tools.js",
|
|
37
37
|
"test:screenshot": "node scripts/test-screenshot.js",
|
|
38
|
-
"test:dialog": "node scripts/test-dialog.js"
|
|
38
|
+
"test:dialog": "node scripts/test-dialog.js",
|
|
39
|
+
"test:integration:win": "node scripts/run-integration-tests-windows.mjs"
|
|
39
40
|
},
|
|
40
41
|
"keywords": [
|
|
41
42
|
"mcp",
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Windows Integration Tests Runner
|
|
4
|
+
*
|
|
5
|
+
* Runs integration tests directly via node to avoid vitest fork issues on Windows.
|
|
6
|
+
* See: https://github.com/freema/firefox-devtools-mcp/issues/33
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { FirefoxDevTools } from '../dist/index.js';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { dirname, resolve } from 'node:path';
|
|
12
|
+
import assert from 'node:assert';
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const fixturesPath = resolve(__dirname, '../tests/fixtures');
|
|
16
|
+
|
|
17
|
+
let firefox = null;
|
|
18
|
+
let passed = 0;
|
|
19
|
+
let failed = 0;
|
|
20
|
+
|
|
21
|
+
async function test(name, fn) {
|
|
22
|
+
process.stdout.write(` ${name}... `);
|
|
23
|
+
try {
|
|
24
|
+
await fn();
|
|
25
|
+
console.log('\x1b[32m✓\x1b[0m');
|
|
26
|
+
passed++;
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.log('\x1b[31m✗\x1b[0m');
|
|
29
|
+
console.error(` Error: ${error.message}`);
|
|
30
|
+
failed++;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function setup() {
|
|
35
|
+
console.log('\n🚀 Starting Firefox...');
|
|
36
|
+
firefox = new FirefoxDevTools({
|
|
37
|
+
headless: true,
|
|
38
|
+
enableBidiLogging: false,
|
|
39
|
+
width: 1280,
|
|
40
|
+
height: 720,
|
|
41
|
+
});
|
|
42
|
+
await firefox.connect();
|
|
43
|
+
console.log('✅ Firefox connected\n');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function teardown() {
|
|
47
|
+
if (firefox) {
|
|
48
|
+
await firefox.close();
|
|
49
|
+
console.log('\n✅ Firefox closed');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Tab Management Tests
|
|
55
|
+
// ============================================================================
|
|
56
|
+
async function tabTests() {
|
|
57
|
+
console.log('📋 Tab Management Tests:');
|
|
58
|
+
|
|
59
|
+
await test('should list tabs', async () => {
|
|
60
|
+
const fixturePath = `file://${fixturesPath}/simple.html`;
|
|
61
|
+
await firefox.navigate(fixturePath);
|
|
62
|
+
await firefox.refreshTabs();
|
|
63
|
+
const tabs = firefox.getTabs();
|
|
64
|
+
assert(Array.isArray(tabs), 'tabs should be an array');
|
|
65
|
+
assert(tabs.length > 0, 'should have at least one tab');
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
await test('should create new tab', async () => {
|
|
69
|
+
await firefox.refreshTabs();
|
|
70
|
+
const initialTabs = firefox.getTabs();
|
|
71
|
+
const initialCount = initialTabs.length;
|
|
72
|
+
|
|
73
|
+
const fixturePath = `file://${fixturesPath}/simple.html`;
|
|
74
|
+
await firefox.createNewPage(fixturePath);
|
|
75
|
+
|
|
76
|
+
await firefox.refreshTabs();
|
|
77
|
+
const updatedTabs = firefox.getTabs();
|
|
78
|
+
assert(updatedTabs.length === initialCount + 1, 'should have one more tab');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
await test('should get selected tab index', async () => {
|
|
82
|
+
const idx = firefox.getSelectedTabIdx();
|
|
83
|
+
assert(typeof idx === 'number', 'index should be a number');
|
|
84
|
+
assert(idx >= 0, 'index should be non-negative');
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// ============================================================================
|
|
89
|
+
// Snapshot Tests
|
|
90
|
+
// ============================================================================
|
|
91
|
+
async function snapshotTests() {
|
|
92
|
+
console.log('\n📸 Snapshot Tests:');
|
|
93
|
+
|
|
94
|
+
await test('should take snapshot', async () => {
|
|
95
|
+
const fixturePath = `file://${fixturesPath}/simple.html`;
|
|
96
|
+
await firefox.navigate(fixturePath);
|
|
97
|
+
await new Promise(r => setTimeout(r, 500));
|
|
98
|
+
|
|
99
|
+
const snapshot = await firefox.takeSnapshot();
|
|
100
|
+
assert(snapshot, 'snapshot should exist');
|
|
101
|
+
assert(snapshot.text || snapshot.markdown, 'snapshot should have text or markdown');
|
|
102
|
+
assert(snapshot.json, 'snapshot should have json');
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
await test('should have uidMap in snapshot', async () => {
|
|
106
|
+
const snapshot = await firefox.takeSnapshot();
|
|
107
|
+
assert(Array.isArray(snapshot.json.uidMap), 'uidMap should be an array');
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// ============================================================================
|
|
112
|
+
// Console Tests
|
|
113
|
+
// ============================================================================
|
|
114
|
+
async function consoleTests() {
|
|
115
|
+
console.log('\n💬 Console Tests:');
|
|
116
|
+
|
|
117
|
+
await test('should get console messages', async () => {
|
|
118
|
+
const messages = await firefox.getConsoleMessages();
|
|
119
|
+
assert(Array.isArray(messages), 'messages should be an array');
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
await test('should clear console messages', async () => {
|
|
123
|
+
firefox.clearConsoleMessages();
|
|
124
|
+
const messages = await firefox.getConsoleMessages();
|
|
125
|
+
assert(messages.length === 0, 'messages should be empty after clear');
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// ============================================================================
|
|
130
|
+
// Network Tests
|
|
131
|
+
// ============================================================================
|
|
132
|
+
async function networkTests() {
|
|
133
|
+
console.log('\n🌐 Network Tests:');
|
|
134
|
+
|
|
135
|
+
await test('should start network monitoring', async () => {
|
|
136
|
+
await firefox.startNetworkMonitoring();
|
|
137
|
+
// No error means success
|
|
138
|
+
assert(true);
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
await test('should get network requests', async () => {
|
|
142
|
+
const requests = await firefox.getNetworkRequests();
|
|
143
|
+
assert(Array.isArray(requests), 'requests should be an array');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
await test('should clear network requests', async () => {
|
|
147
|
+
firefox.clearNetworkRequests();
|
|
148
|
+
const requests = await firefox.getNetworkRequests();
|
|
149
|
+
assert(requests.length === 0, 'requests should be empty after clear');
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await test('should stop network monitoring', async () => {
|
|
153
|
+
await firefox.stopNetworkMonitoring();
|
|
154
|
+
assert(true);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// ============================================================================
|
|
159
|
+
// Main
|
|
160
|
+
// ============================================================================
|
|
161
|
+
async function main() {
|
|
162
|
+
console.log('═══════════════════════════════════════════════════════════');
|
|
163
|
+
console.log(' Windows Integration Tests (direct node runner)');
|
|
164
|
+
console.log('═══════════════════════════════════════════════════════════');
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
await setup();
|
|
168
|
+
|
|
169
|
+
await tabTests();
|
|
170
|
+
await snapshotTests();
|
|
171
|
+
await consoleTests();
|
|
172
|
+
await networkTests();
|
|
173
|
+
|
|
174
|
+
await teardown();
|
|
175
|
+
|
|
176
|
+
console.log('\n═══════════════════════════════════════════════════════════');
|
|
177
|
+
console.log(` Results: \x1b[32m${passed} passed\x1b[0m, \x1b[31m${failed} failed\x1b[0m`);
|
|
178
|
+
console.log('═══════════════════════════════════════════════════════════\n');
|
|
179
|
+
|
|
180
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
181
|
+
} catch (error) {
|
|
182
|
+
console.error('\n❌ Fatal error:', error.message);
|
|
183
|
+
await teardown();
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
main();
|