cdp-tunnel 1.0.13 → 1.0.15
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/cli/index.js +65 -0
- package/extension-new/background.js +6 -1
- package/extension-new/cdp/handler/special.js +47 -27
- package/extension-new/core/state.js +64 -6
- package/extension-new/core/websocket.js +124 -19
- package/package.json +9 -2
- package/server/proxy-server.js +45 -34
- package/.github/workflows/publish.yml +0 -92
- package/.github/workflows/release-assets.yml +0 -50
- package/PUBLISH.md +0 -65
- package/console-test.js +0 -52
- package/docs/README_CN.md +0 -204
- package/docs/config-page-screenshot.png +0 -0
- package/final-console-test.js +0 -105
- package/simple-tab-group-test.js +0 -56
- package/test-cdp-connection.js +0 -85
- package/test-cdp-groups.js +0 -71
- package/test-check-newtab.js +0 -144
- package/test-chrome-native.js +0 -140
- package/test-client-connected.js +0 -99
- package/test-compare-formats.js +0 -88
- package/test-context-features.js +0 -113
- package/test-create-tab.js +0 -113
- package/test-debug-broadcast.js +0 -52
- package/test-debug-targets.js +0 -127
- package/test-expose-newtab.js +0 -164
- package/test-expose-shared.js +0 -189
- package/test-final-logs.js +0 -110
- package/test-fresh-chromium.js +0 -153
- package/test-init-script.js +0 -128
- package/test-keepalive.js +0 -89
- package/test-launch-chromium.js +0 -140
- package/test-launch-vs-connect.js +0 -149
- package/test-listen-events.js +0 -102
- package/test-monitor.js +0 -83
- package/test-multiple-cdp-groups.js +0 -78
- package/test-native.js +0 -96
- package/test-page-connection.js +0 -74
- package/test-playwright-connection.js +0 -45
- package/test-playwright-groups.js +0 -47
- package/test-playwright-pages.js +0 -47
- package/test-playwright-sequence.js +0 -81
- package/test-proper-context.js +0 -129
- package/test-real-final.js +0 -251
- package/test-real-scenario-v2.js +0 -166
- package/test-real-scenario-v3.js +0 -231
- package/test-real-scenario.js +0 -104
- package/test-server-logs.js +0 -98
- package/test-session-id.js +0 -91
- package/test-simple-cdp-groups.js +0 -44
- package/test-simple-context.js +0 -137
- package/test-tab-group-simple.js +0 -58
- package/test-tab-grouping.js +0 -48
- package/test-three-pages.js +0 -192
- package/test-wait-for-page.js +0 -95
- package/test-with-logs.js +0 -118
- package/test-ws-groups.js +0 -59
- package/tests/e2e-auto-test.js +0 -304
- package/tests/iframe-test-page.html +0 -89
- package/tests/playwright-demo.js +0 -45
- package/tests/playwright-interactive.js +0 -261
- package/tests/playwright-multi-demo.js +0 -60
- package/tests/playwright-multi.js +0 -85
- package/tests/playwright-single.js +0 -41
- package/tests/screenshot-config.js +0 -35
- package/tests/test-client.js +0 -89
- package/tests/test-douyin-iframe.js +0 -171
- package/tests/test-iframe-debug.js +0 -204
- package/tests/test-multi-client.js +0 -129
package/test-expose-shared.js
DELETED
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const { spawn } = require('child_process');
|
|
3
|
-
const fs = require('fs');
|
|
4
|
-
const path = require('path');
|
|
5
|
-
|
|
6
|
-
async function testExposeFunctionSharedState(port, label) {
|
|
7
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
8
|
-
console.log(`Testing ${label} (port ${port})`);
|
|
9
|
-
console.log('='.repeat(60));
|
|
10
|
-
|
|
11
|
-
try {
|
|
12
|
-
const sharedState = { counter: 0 };
|
|
13
|
-
|
|
14
|
-
const htmlContent1 = `
|
|
15
|
-
<!DOCTYPE html>
|
|
16
|
-
<html>
|
|
17
|
-
<head><title>Page 1</title></head>
|
|
18
|
-
<body>
|
|
19
|
-
<h1>Page 1 - Source</h1>
|
|
20
|
-
<button onclick="window.getAndIncrementCounter().then(r => document.getElementById('result').innerText = r)">
|
|
21
|
-
Get Counter
|
|
22
|
-
</button>
|
|
23
|
-
<div id="result">Click button to get counter</div>
|
|
24
|
-
<a href="page2.html" target="_blank">Open New Tab</a>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|
|
27
|
-
`;
|
|
28
|
-
|
|
29
|
-
const htmlContent2 = `
|
|
30
|
-
<!DOCTYPE html>
|
|
31
|
-
<html>
|
|
32
|
-
<head><title>Page 2</title></head>
|
|
33
|
-
<body>
|
|
34
|
-
<h1>Page 2 - New Tab</h1>
|
|
35
|
-
<button onclick="window.getAndIncrementCounter().then(r => document.getElementById('result').innerText = r)">
|
|
36
|
-
Get Counter
|
|
37
|
-
</button>
|
|
38
|
-
<div id="result">Click button to get counter</div>
|
|
39
|
-
</body>
|
|
40
|
-
</html>
|
|
41
|
-
`;
|
|
42
|
-
|
|
43
|
-
const serverDir = '/tmp/test-expose';
|
|
44
|
-
if (!fs.existsSync(serverDir)) {
|
|
45
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
46
|
-
}
|
|
47
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
48
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
49
|
-
|
|
50
|
-
const http = require('http');
|
|
51
|
-
const server = http.createServer((req, res) => {
|
|
52
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
53
|
-
if (fs.existsSync(filePath)) {
|
|
54
|
-
const content = fs.readFileSync(filePath);
|
|
55
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
56
|
-
res.end(content);
|
|
57
|
-
} else {
|
|
58
|
-
res.writeHead(404);
|
|
59
|
-
res.end('Not found');
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
await new Promise(resolve => server.listen(8767, resolve));
|
|
64
|
-
console.log(`[${label}] Test server started on port 8767`);
|
|
65
|
-
|
|
66
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
67
|
-
console.log(`[${label}] Connected successfully!`);
|
|
68
|
-
|
|
69
|
-
console.log(`[${label}] Creating new context...`);
|
|
70
|
-
const context = await browser.newContext();
|
|
71
|
-
|
|
72
|
-
console.log(`[${label}] Testing exposeFunction (shared counter)...`);
|
|
73
|
-
await context.exposeFunction('getAndIncrementCounter', () => {
|
|
74
|
-
sharedState.counter += 1;
|
|
75
|
-
console.log(`[${label}] getAndIncrementCounter called, counter: ${sharedState.counter}`);
|
|
76
|
-
return sharedState.counter;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
console.log(`[${label}] Creating first page...`);
|
|
80
|
-
const page1 = await context.newPage();
|
|
81
|
-
await page1.goto('http://localhost:8767/page1.html', { waitUntil: 'domcontentloaded' });
|
|
82
|
-
|
|
83
|
-
console.log(`[${label}] Calling getAndIncrementCounter in first page...`);
|
|
84
|
-
const result1 = await page1.evaluate(() => window.getAndIncrementCounter());
|
|
85
|
-
console.log(`[${label}] First page counter:`, result1);
|
|
86
|
-
|
|
87
|
-
console.log(`[${label}] Clicking link to open new tab...`);
|
|
88
|
-
try {
|
|
89
|
-
const [page2] = await Promise.all([
|
|
90
|
-
context.waitForEvent('page', { timeout: 10000 }),
|
|
91
|
-
page1.click('a:first-child')
|
|
92
|
-
]);
|
|
93
|
-
|
|
94
|
-
console.log(`[${label}] Waiting for new tab to load...`);
|
|
95
|
-
await page2.waitForLoadState('domcontentloaded');
|
|
96
|
-
console.log(`[${label}] New tab URL: ${page2.url()}`);
|
|
97
|
-
|
|
98
|
-
console.log(`[${label}] Calling getAndIncrementCounter in new tab...`);
|
|
99
|
-
const result2 = await page2.evaluate(() => window.getAndIncrementCounter());
|
|
100
|
-
console.log(`[${label}] New tab counter:`, result2);
|
|
101
|
-
|
|
102
|
-
console.log(`[${label}] Switching back to first page and calling again...`);
|
|
103
|
-
await page1.bringToFront();
|
|
104
|
-
const result1Again = await page1.evaluate(() => window.getAndIncrementCounter());
|
|
105
|
-
console.log(`[${label}] First page counter (after switch):`, result1Again);
|
|
106
|
-
|
|
107
|
-
console.log(`[${label}] Calling in new tab again...`);
|
|
108
|
-
const result2Again = await page2.evaluate(() => window.getAndIncrementCounter());
|
|
109
|
-
console.log(`[${label}] New tab counter (again):`, result2Again);
|
|
110
|
-
|
|
111
|
-
const success = result1 === 1 && result2 === 2 && result1Again === 3 && result2Again === 4;
|
|
112
|
-
|
|
113
|
-
server.close();
|
|
114
|
-
|
|
115
|
-
if (success) {
|
|
116
|
-
console.log(`[${label}] ✓ All tests passed!`);
|
|
117
|
-
console.log(`[${label}] ✓ exposeFunction shared state works across tabs!`);
|
|
118
|
-
} else {
|
|
119
|
-
console.log(`[${label}] ✗ Counter values incorrect!`);
|
|
120
|
-
console.log(`[${label}] Expected: 1, 2, 3, 4 | Got: ${result1}, ${result2}, ${result1Again}, ${result2Again}`);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
await browser.close();
|
|
124
|
-
return success;
|
|
125
|
-
|
|
126
|
-
} catch (e) {
|
|
127
|
-
console.log(`[${label}] Error: ${e.message}`);
|
|
128
|
-
server.close();
|
|
129
|
-
await browser.close();
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
} catch (error) {
|
|
134
|
-
console.error(`[${label}] ✗ Error:`, error.message);
|
|
135
|
-
console.error(`[${label}] Stack:`, error.stack);
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
async function main() {
|
|
141
|
-
console.log('Testing: exposeFunction shared state across tabs');
|
|
142
|
-
console.log('Expected: Counter increments across ALL pages (1 -> 2 -> 3 -> 4)\n');
|
|
143
|
-
|
|
144
|
-
console.log('Step 1: Starting fresh Chromium instance on port 9229...');
|
|
145
|
-
const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
|
|
146
|
-
'--remote-debugging-port=9229',
|
|
147
|
-
'--user-data-dir=/tmp/chromium-test-expose',
|
|
148
|
-
'--no-first-run',
|
|
149
|
-
'--no-default-browser-check'
|
|
150
|
-
], {
|
|
151
|
-
detached: true,
|
|
152
|
-
stdio: 'ignore'
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
console.log('Waiting for Chromium to start...');
|
|
156
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
157
|
-
|
|
158
|
-
console.log('\nStep 2: Testing Native CDP...');
|
|
159
|
-
const nativeResult = await testExposeFunctionSharedState(9229, 'Native CDP');
|
|
160
|
-
|
|
161
|
-
console.log('\nStep 3: Testing CDP Tunnel...');
|
|
162
|
-
const tunnelResult = await testExposeFunctionSharedState(9221, 'CDP Tunnel');
|
|
163
|
-
|
|
164
|
-
console.log('\nStep 4: Cleaning up...');
|
|
165
|
-
try {
|
|
166
|
-
process.kill(-chromiumProcess.pid);
|
|
167
|
-
} catch (e) {}
|
|
168
|
-
|
|
169
|
-
console.log('\n' + '='.repeat(60));
|
|
170
|
-
console.log('COMPARISON RESULTS');
|
|
171
|
-
console.log('='.repeat(60));
|
|
172
|
-
console.log(`Native CDP (port 9229): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
173
|
-
console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
174
|
-
|
|
175
|
-
if (nativeResult && tunnelResult) {
|
|
176
|
-
console.log('\n✓ Both implementations behave identically!');
|
|
177
|
-
console.log('✓ exposeFunction shared state works across tabs!');
|
|
178
|
-
} else if (nativeResult && !tunnelResult) {
|
|
179
|
-
console.log('\n✗ CDP Tunnel has issues with exposeFunction shared state!');
|
|
180
|
-
} else if (!nativeResult && tunnelResult) {
|
|
181
|
-
console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
|
|
182
|
-
} else {
|
|
183
|
-
console.log('\n✗ Both implementations have issues!');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
process.exit(0);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
main();
|
package/test-final-logs.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const http = require('http');
|
|
5
|
-
|
|
6
|
-
let serverPort = 9500;
|
|
7
|
-
|
|
8
|
-
async function testWithLogs(label, port) {
|
|
9
|
-
serverPort++;
|
|
10
|
-
const currentPort = serverPort;
|
|
11
|
-
|
|
12
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
13
|
-
console.log(`Testing ${label} (port ${port})`);
|
|
14
|
-
console.log('='.repeat(60));
|
|
15
|
-
|
|
16
|
-
const htmlContent1 = `
|
|
17
|
-
<!DOCTYPE html>
|
|
18
|
-
<html>
|
|
19
|
-
<head><title>Page 1</title></head>
|
|
20
|
-
<body>
|
|
21
|
-
<h1>Page 1 - Click the link below</h1>
|
|
22
|
-
<a href="page2.html" target="_blank" id="link1">Open New Tab</a>
|
|
23
|
-
</body>
|
|
24
|
-
</html>
|
|
25
|
-
`;
|
|
26
|
-
|
|
27
|
-
const htmlContent2 = `
|
|
28
|
-
<!DOCTYPE html>
|
|
29
|
-
<html>
|
|
30
|
-
<head><title>Page 2</title></head>
|
|
31
|
-
<body>
|
|
32
|
-
<h1>Page 2 - New Tab Opened!</h1>
|
|
33
|
-
</body>
|
|
34
|
-
</html>
|
|
35
|
-
`;
|
|
36
|
-
|
|
37
|
-
const serverDir = '/tmp/test-logs2';
|
|
38
|
-
if (!fs.existsSync(serverDir)) {
|
|
39
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
40
|
-
}
|
|
41
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
42
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
43
|
-
|
|
44
|
-
const server = http.createServer((req, res) => {
|
|
45
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
46
|
-
if (fs.existsSync(filePath)) {
|
|
47
|
-
const content = fs.readFileSync(filePath);
|
|
48
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
49
|
-
res.end(content);
|
|
50
|
-
} else {
|
|
51
|
-
res.writeHead(404);
|
|
52
|
-
res.end('Not found');
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
57
|
-
console.log(`Server: http://localhost:${currentPort}/page1.html`);
|
|
58
|
-
|
|
59
|
-
console.log('\nConnecting to CDP Tunnel...');
|
|
60
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
61
|
-
console.log('Connected!');
|
|
62
|
-
|
|
63
|
-
console.log('Creating context...');
|
|
64
|
-
const context = await browser.newContext();
|
|
65
|
-
|
|
66
|
-
console.log('Creating first page...');
|
|
67
|
-
const page1 = await context.newPage();
|
|
68
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
69
|
-
console.log(`First page loaded: ${page1.url()}`);
|
|
70
|
-
|
|
71
|
-
console.log('\n>>> CLICK THE LINK NOW - Check extension logs! <<<');
|
|
72
|
-
console.log('>>> Look for: [Tabs] Tab created or Tab not controlled <<<\n');
|
|
73
|
-
|
|
74
|
-
await page1.click('#link1');
|
|
75
|
-
|
|
76
|
-
console.log('Waiting 10 seconds for you to check logs...');
|
|
77
|
-
await new Promise(r => setTimeout(r, 10000));
|
|
78
|
-
|
|
79
|
-
console.log('\nChecking results...');
|
|
80
|
-
const allPages = context.pages();
|
|
81
|
-
console.log(`Total pages in context: ${allPages.length}`);
|
|
82
|
-
allPages.forEach((p, i) => {
|
|
83
|
-
console.log(` Page ${i}: ${p.url()}`);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
if (allPages.length >= 2) {
|
|
87
|
-
console.log('\n✓ SUCCESS!');
|
|
88
|
-
} else {
|
|
89
|
-
console.log('\n✗ FAILED - Please copy the extension logs now!');
|
|
90
|
-
console.log('Look for: [Tabs] Tab created: or Tab not controlled:');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
server.close();
|
|
94
|
-
await browser.close();
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async function main() {
|
|
98
|
-
console.log('=== Test - Check Extension Logs ===\n');
|
|
99
|
-
console.log('INSTRUCTIONS:');
|
|
100
|
-
console.log('1. Make sure extension popup DevTools is open');
|
|
101
|
-
console.log('2. When you see "CLICK THE LINK NOW", click the link in the page');
|
|
102
|
-
console.log('3. Watch the extension logs for: [Tabs] Tab created');
|
|
103
|
-
console.log('4. Copy those logs and paste them here\n');
|
|
104
|
-
|
|
105
|
-
await testWithLogs('CDP Tunnel', 9221);
|
|
106
|
-
|
|
107
|
-
process.exit(0);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
main();
|
package/test-fresh-chromium.js
DELETED
|
@@ -1,153 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const { spawn } = require('child_process');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
async function testContextFeatures(port, label) {
|
|
6
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
7
|
-
console.log(`Testing ${label} (port ${port})`);
|
|
8
|
-
console.log('='.repeat(60));
|
|
9
|
-
|
|
10
|
-
try {
|
|
11
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
12
|
-
console.log(`[${label}] Connected successfully!`);
|
|
13
|
-
|
|
14
|
-
console.log(`[${label}] Creating new context...`);
|
|
15
|
-
const context = await browser.newContext();
|
|
16
|
-
|
|
17
|
-
console.log(`[${label}] Testing exposeFunction...`);
|
|
18
|
-
await context.exposeFunction('myCustomFunction', (arg) => {
|
|
19
|
-
console.log(`[${label}] myCustomFunction called with:`, arg);
|
|
20
|
-
return `Hello from ${label}: ${arg}`;
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
console.log(`[${label}] Testing addInitScript...`);
|
|
24
|
-
await context.addInitScript(() => {
|
|
25
|
-
window.myInitScript = 'This is from addInitScript!';
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
console.log(`[${label}] Creating first page...`);
|
|
29
|
-
const page1 = await context.newPage();
|
|
30
|
-
await page1.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
31
|
-
|
|
32
|
-
console.log(`[${label}] Testing in first page...`);
|
|
33
|
-
const result1 = await page1.evaluate(async () => {
|
|
34
|
-
try {
|
|
35
|
-
const funcResult = await window.myCustomFunction('page1');
|
|
36
|
-
const initResult = window.myInitScript;
|
|
37
|
-
return { success: true, funcResult, initResult };
|
|
38
|
-
} catch (e) {
|
|
39
|
-
return { success: false, error: e.message };
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
console.log(`[${label}] First page result:`, result1);
|
|
43
|
-
|
|
44
|
-
if (!result1.success) {
|
|
45
|
-
console.log(`[${label}] ✗ First page test failed!`);
|
|
46
|
-
await browser.close();
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
console.log(`[${label}] Creating second page (simulating new tab)...`);
|
|
51
|
-
const page2 = await context.newPage();
|
|
52
|
-
await page2.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
53
|
-
|
|
54
|
-
console.log(`[${label}] Testing in second page (should persist)...`);
|
|
55
|
-
const result2 = await page2.evaluate(async () => {
|
|
56
|
-
try {
|
|
57
|
-
const funcResult = await window.myCustomFunction('page2');
|
|
58
|
-
const initResult = window.myInitScript;
|
|
59
|
-
return { success: true, funcResult, initResult };
|
|
60
|
-
} catch (e) {
|
|
61
|
-
return { success: false, error: e.message };
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
console.log(`[${label}] Second page result:`, result2);
|
|
65
|
-
|
|
66
|
-
if (!result2.success) {
|
|
67
|
-
console.log(`[${label}] ✗ Second page test failed - Context features not persisted!`);
|
|
68
|
-
await browser.close();
|
|
69
|
-
return false;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
console.log(`[${label}] Creating third page...`);
|
|
73
|
-
const page3 = await context.newPage();
|
|
74
|
-
await page3.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
75
|
-
|
|
76
|
-
console.log(`[${label}] Testing in third page...`);
|
|
77
|
-
const result3 = await page3.evaluate(async () => {
|
|
78
|
-
try {
|
|
79
|
-
const funcResult = await window.myCustomFunction('page3');
|
|
80
|
-
const initResult = window.myInitScript;
|
|
81
|
-
return { success: true, funcResult, initResult };
|
|
82
|
-
} catch (e) {
|
|
83
|
-
return { success: false, error: e.message };
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
console.log(`[${label}] Third page result:`, result3);
|
|
87
|
-
|
|
88
|
-
if (!result3.success) {
|
|
89
|
-
console.log(`[${label}] ✗ Third page test failed!`);
|
|
90
|
-
await browser.close();
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
console.log(`[${label}] ✓ All tests passed!`);
|
|
95
|
-
|
|
96
|
-
await browser.close();
|
|
97
|
-
|
|
98
|
-
return true;
|
|
99
|
-
} catch (error) {
|
|
100
|
-
console.error(`[${label}] ✗ Error:`, error.message);
|
|
101
|
-
console.error(`[${label}] Stack:`, error.stack);
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function main() {
|
|
107
|
-
console.log('Testing Context-level features persistence across tabs');
|
|
108
|
-
console.log('This tests if exposeFunction and addInitScript persist across different pages\n');
|
|
109
|
-
|
|
110
|
-
console.log('Step 1: Starting fresh Chromium instance on port 9224...');
|
|
111
|
-
const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
|
|
112
|
-
'--remote-debugging-port=9224',
|
|
113
|
-
'--user-data-dir=/tmp/chromium-test-fresh',
|
|
114
|
-
'--no-first-run',
|
|
115
|
-
'--no-default-browser-check'
|
|
116
|
-
], {
|
|
117
|
-
detached: true,
|
|
118
|
-
stdio: 'ignore'
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
console.log('Waiting for Chromium to start...');
|
|
122
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
123
|
-
|
|
124
|
-
console.log('\nStep 2: Testing Native CDP...');
|
|
125
|
-
const nativeResult = await testContextFeatures(9224, 'Native CDP');
|
|
126
|
-
|
|
127
|
-
console.log('\nStep 3: Testing CDP Tunnel...');
|
|
128
|
-
const tunnelResult = await testContextFeatures(9221, 'CDP Tunnel');
|
|
129
|
-
|
|
130
|
-
console.log('\nStep 4: Cleaning up...');
|
|
131
|
-
process.kill(-chromiumProcess.pid);
|
|
132
|
-
|
|
133
|
-
console.log('\n' + '='.repeat(60));
|
|
134
|
-
console.log('COMPARISON RESULTS');
|
|
135
|
-
console.log('='.repeat(60));
|
|
136
|
-
console.log(`Native CDP (port 9224): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
137
|
-
console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
138
|
-
|
|
139
|
-
if (nativeResult && tunnelResult) {
|
|
140
|
-
console.log('\n✓ Both implementations behave identically!');
|
|
141
|
-
console.log('✓ Context-level features (exposeFunction/addInitScript) work correctly!');
|
|
142
|
-
} else if (nativeResult && !tunnelResult) {
|
|
143
|
-
console.log('\n✗ CDP Tunnel has issues with Context-level features!');
|
|
144
|
-
} else if (!nativeResult && tunnelResult) {
|
|
145
|
-
console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
|
|
146
|
-
} else {
|
|
147
|
-
console.log('\n✗ Both implementations have issues!');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
process.exit(0);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
main();
|
package/test-init-script.js
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const { spawn } = require('child_process');
|
|
3
|
-
|
|
4
|
-
async function testAddInitScript(port, label) {
|
|
5
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
6
|
-
console.log(`Testing ${label} (port ${port})`);
|
|
7
|
-
console.log('='.repeat(60));
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
11
|
-
console.log(`[${label}] Connected successfully!`);
|
|
12
|
-
|
|
13
|
-
console.log(`[${label}] Creating new context...`);
|
|
14
|
-
const context = await browser.newContext();
|
|
15
|
-
|
|
16
|
-
console.log(`[${label}] Testing addInitScript...`);
|
|
17
|
-
await context.addInitScript(() => {
|
|
18
|
-
window.myInitScript = 'This is from addInitScript!';
|
|
19
|
-
window.myCounter = 0;
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
console.log(`[${label}] Creating first page...`);
|
|
23
|
-
const page1 = await context.newPage();
|
|
24
|
-
await page1.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
25
|
-
|
|
26
|
-
console.log(`[${label}] Testing in first page...`);
|
|
27
|
-
const result1 = await page1.evaluate(() => {
|
|
28
|
-
return {
|
|
29
|
-
initScript: window.myInitScript,
|
|
30
|
-
counter: window.myCounter
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
console.log(`[${label}] First page result:`, result1);
|
|
34
|
-
|
|
35
|
-
console.log(`[${label}] Creating second page (simulating new tab)...`);
|
|
36
|
-
const page2 = await context.newPage();
|
|
37
|
-
await page2.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
38
|
-
|
|
39
|
-
console.log(`[${label}] Testing in second page (should persist)...`);
|
|
40
|
-
const result2 = await page2.evaluate(() => {
|
|
41
|
-
return {
|
|
42
|
-
initScript: window.myInitScript,
|
|
43
|
-
counter: window.myCounter
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
console.log(`[${label}] Second page result:`, result2);
|
|
47
|
-
|
|
48
|
-
console.log(`[${label}] Creating third page...`);
|
|
49
|
-
const page3 = await context.newPage();
|
|
50
|
-
await page3.goto('about:blank', { waitUntil: 'domcontentloaded' });
|
|
51
|
-
|
|
52
|
-
console.log(`[${label}] Testing in third page...`);
|
|
53
|
-
const result3 = await page3.evaluate(() => {
|
|
54
|
-
return {
|
|
55
|
-
initScript: window.myInitScript,
|
|
56
|
-
counter: window.myCounter
|
|
57
|
-
};
|
|
58
|
-
});
|
|
59
|
-
console.log(`[${label}] Third page result:`, result3);
|
|
60
|
-
|
|
61
|
-
const success = result1.initScript && result2.initScript && result3.initScript;
|
|
62
|
-
|
|
63
|
-
if (success) {
|
|
64
|
-
console.log(`[${label}] ✓ All tests passed!`);
|
|
65
|
-
} else {
|
|
66
|
-
console.log(`[${label}] ✗ Some tests failed!`);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
await browser.close();
|
|
70
|
-
|
|
71
|
-
return success;
|
|
72
|
-
} catch (error) {
|
|
73
|
-
console.error(`[${label}] ✗ Error:`, error.message);
|
|
74
|
-
console.error(`[${label}] Stack:`, error.stack);
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
async function main() {
|
|
80
|
-
console.log('Testing addInitScript persistence across tabs');
|
|
81
|
-
console.log('This tests if addInitScript persists across different pages\n');
|
|
82
|
-
|
|
83
|
-
console.log('Step 1: Starting fresh Chromium instance on port 9225...');
|
|
84
|
-
const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
|
|
85
|
-
'--remote-debugging-port=9225',
|
|
86
|
-
'--user-data-dir=/tmp/chromium-test-init',
|
|
87
|
-
'--no-first-run',
|
|
88
|
-
'--no-default-browser-check'
|
|
89
|
-
], {
|
|
90
|
-
detached: true,
|
|
91
|
-
stdio: 'ignore'
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
console.log('Waiting for Chromium to start...');
|
|
95
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
96
|
-
|
|
97
|
-
console.log('\nStep 2: Testing Native CDP...');
|
|
98
|
-
const nativeResult = await testAddInitScript(9225, 'Native CDP');
|
|
99
|
-
|
|
100
|
-
console.log('\nStep 3: Testing CDP Tunnel...');
|
|
101
|
-
const tunnelResult = await testAddInitScript(9221, 'CDP Tunnel');
|
|
102
|
-
|
|
103
|
-
console.log('\nStep 4: Cleaning up...');
|
|
104
|
-
try {
|
|
105
|
-
process.kill(-chromiumProcess.pid);
|
|
106
|
-
} catch (e) {}
|
|
107
|
-
|
|
108
|
-
console.log('\n' + '='.repeat(60));
|
|
109
|
-
console.log('COMPARISON RESULTS');
|
|
110
|
-
console.log('='.repeat(60));
|
|
111
|
-
console.log(`Native CDP (port 9225): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
112
|
-
console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
113
|
-
|
|
114
|
-
if (nativeResult && tunnelResult) {
|
|
115
|
-
console.log('\n✓ Both implementations behave identically!');
|
|
116
|
-
console.log('✓ addInitScript works correctly and persists across tabs!');
|
|
117
|
-
} else if (nativeResult && !tunnelResult) {
|
|
118
|
-
console.log('\n✗ CDP Tunnel has issues with addInitScript!');
|
|
119
|
-
} else if (!nativeResult && tunnelResult) {
|
|
120
|
-
console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
|
|
121
|
-
} else {
|
|
122
|
-
console.log('\n✗ Both implementations have issues!');
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
process.exit(0);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
main();
|
package/test-keepalive.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const http = require('http');
|
|
5
|
-
|
|
6
|
-
let serverPort = 9900;
|
|
7
|
-
|
|
8
|
-
async function test() {
|
|
9
|
-
serverPort++;
|
|
10
|
-
const currentPort = serverPort;
|
|
11
|
-
|
|
12
|
-
const htmlContent1 = `
|
|
13
|
-
<!DOCTYPE html>
|
|
14
|
-
<html>
|
|
15
|
-
<head><title>Page 1</title></head>
|
|
16
|
-
<body>
|
|
17
|
-
<h1>Page 1</h1>
|
|
18
|
-
<a href="page2.html" target="_blank" id="link1">Open New Tab</a>
|
|
19
|
-
</body>
|
|
20
|
-
</html>
|
|
21
|
-
`;
|
|
22
|
-
|
|
23
|
-
const htmlContent2 = `
|
|
24
|
-
<!DOCTYPE html>
|
|
25
|
-
<html>
|
|
26
|
-
<head><title>Page 2</title></head>
|
|
27
|
-
<body>
|
|
28
|
-
<h1>Page 2 - New Tab</h1>
|
|
29
|
-
</body>
|
|
30
|
-
</html>
|
|
31
|
-
`;
|
|
32
|
-
|
|
33
|
-
const serverDir = '/tmp/test-keepalive';
|
|
34
|
-
if (!fs.existsSync(serverDir)) fs.mkdirSync(serverDir, { recursive: true });
|
|
35
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
36
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
37
|
-
|
|
38
|
-
const server = http.createServer((req, res) => {
|
|
39
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
40
|
-
if (fs.existsSync(filePath)) {
|
|
41
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
42
|
-
res.end(fs.readFileSync(filePath));
|
|
43
|
-
} else {
|
|
44
|
-
res.writeHead(404);
|
|
45
|
-
res.end('Not found');
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
50
|
-
console.log(`Server: http://localhost:${currentPort}`);
|
|
51
|
-
|
|
52
|
-
console.log('\n[TEST] Connecting...');
|
|
53
|
-
const browser = await chromium.connectOverCDP('http://localhost:9221');
|
|
54
|
-
console.log('[TEST] Connected!');
|
|
55
|
-
|
|
56
|
-
console.log('[TEST] Creating context...');
|
|
57
|
-
const context = await browser.newContext();
|
|
58
|
-
|
|
59
|
-
console.log('[TEST] Creating page...');
|
|
60
|
-
const page1 = await context.newPage();
|
|
61
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
62
|
-
console.log('[TEST] Page loaded');
|
|
63
|
-
|
|
64
|
-
console.log('[TEST] Clicking link...');
|
|
65
|
-
await page1.click('#link1');
|
|
66
|
-
|
|
67
|
-
console.log('[TEST] Waiting 10 seconds (keeping connection alive)...');
|
|
68
|
-
await new Promise(r => setTimeout(r, 10000));
|
|
69
|
-
|
|
70
|
-
console.log('[TEST] Checking pages...');
|
|
71
|
-
const allPages = context.pages();
|
|
72
|
-
console.log(`[TEST] Total pages: ${allPages.length}`);
|
|
73
|
-
|
|
74
|
-
if (allPages.length >= 2) {
|
|
75
|
-
console.log('[TEST] SUCCESS! New tab captured!');
|
|
76
|
-
const page2 = allPages[1];
|
|
77
|
-
console.log(`[TEST] Page 2 URL: ${page2.url()}`);
|
|
78
|
-
} else {
|
|
79
|
-
console.log('[TEST] FAILED! New tab not captured!');
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('[TEST] Closing browser...');
|
|
83
|
-
server.close();
|
|
84
|
-
await browser.close();
|
|
85
|
-
|
|
86
|
-
console.log('[TEST] Done!');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
test().then(() => process.exit(0));
|