cdp-tunnel 1.0.13 → 1.0.14
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/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-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));
|
package/test-launch-chromium.js
DELETED
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
let serverPort = 9100;
|
|
6
|
-
|
|
7
|
-
async function testWithLaunch(label) {
|
|
8
|
-
serverPort++;
|
|
9
|
-
const currentPort = serverPort;
|
|
10
|
-
|
|
11
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
12
|
-
console.log(`Testing ${label} - chromium.launch()`);
|
|
13
|
-
console.log('='.repeat(60));
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
const sharedState = { counter: 0 };
|
|
17
|
-
|
|
18
|
-
const htmlContent1 = `
|
|
19
|
-
<!DOCTYPE html>
|
|
20
|
-
<html>
|
|
21
|
-
<head><title>Page 1</title></head>
|
|
22
|
-
<body>
|
|
23
|
-
<h1>Page 1</h1>
|
|
24
|
-
<a href="page2.html" target="_blank" id="link1">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
|
-
</body>
|
|
36
|
-
</html>
|
|
37
|
-
`;
|
|
38
|
-
|
|
39
|
-
const serverDir = '/tmp/test-launch-chromium';
|
|
40
|
-
if (!fs.existsSync(serverDir)) {
|
|
41
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
42
|
-
}
|
|
43
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
44
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
45
|
-
|
|
46
|
-
const http = require('http');
|
|
47
|
-
const server = http.createServer((req, res) => {
|
|
48
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
49
|
-
if (fs.existsSync(filePath)) {
|
|
50
|
-
const content = fs.readFileSync(filePath);
|
|
51
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
52
|
-
res.end(content);
|
|
53
|
-
} else {
|
|
54
|
-
res.writeHead(404);
|
|
55
|
-
res.end('Not found');
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
60
|
-
console.log(`[${label}] Server on port ${currentPort}`);
|
|
61
|
-
|
|
62
|
-
console.log(`[${label}] Launching Chromium...`);
|
|
63
|
-
const browser = await chromium.launch({
|
|
64
|
-
executablePath: '/Applications/Chromium.app/Contents/MacOS/Chromium',
|
|
65
|
-
headless: false
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
console.log(`[${label}] Launched!`);
|
|
69
|
-
|
|
70
|
-
console.log(`[${label}] Creating context...`);
|
|
71
|
-
const context = await browser.newContext();
|
|
72
|
-
|
|
73
|
-
console.log(`[${label}] exposeFunction getCounter...`);
|
|
74
|
-
await context.exposeFunction('getCounter', () => {
|
|
75
|
-
sharedState.counter += 1;
|
|
76
|
-
console.log(`[${label}] getCounter: ${sharedState.counter}`);
|
|
77
|
-
return sharedState.counter;
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
console.log(`[${label}] Creating first page...`);
|
|
81
|
-
const page1 = await context.newPage();
|
|
82
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
83
|
-
|
|
84
|
-
console.log(`[${label}] Testing first page...`);
|
|
85
|
-
const r1 = await page1.evaluate(() => window.getCounter());
|
|
86
|
-
console.log(`[${label}] First page: ${r1}`);
|
|
87
|
-
|
|
88
|
-
console.log(`[${label}] Clicking link...`);
|
|
89
|
-
await page1.click('#link1');
|
|
90
|
-
|
|
91
|
-
console.log(`[${label}] Waiting 3 seconds...`);
|
|
92
|
-
await new Promise(r => setTimeout(r, 3000));
|
|
93
|
-
|
|
94
|
-
console.log(`[${label}] Checking pages...`);
|
|
95
|
-
const allPages = context.pages();
|
|
96
|
-
console.log(`[${label}] Total pages: ${allPages.length}`);
|
|
97
|
-
for (let i = 0; i < allPages.length; i++) {
|
|
98
|
-
console.log(`[${label}] Page ${i}: ${allPages[i].url()}`);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (allPages.length >= 2) {
|
|
102
|
-
console.log(`[${label}] Testing new tab...`);
|
|
103
|
-
const page2 = allPages[1];
|
|
104
|
-
const r2 = await page2.evaluate(() => window.getCounter());
|
|
105
|
-
console.log(`[${label}] New tab: ${r2}`);
|
|
106
|
-
|
|
107
|
-
console.log(`[${label}] First page again...`);
|
|
108
|
-
const r1a = await page1.evaluate(() => window.getCounter());
|
|
109
|
-
console.log(`[${label}] First page again: ${r1a}`);
|
|
110
|
-
|
|
111
|
-
console.log(`[${label}] New tab again...`);
|
|
112
|
-
const r2a = await page2.evaluate(() => window.getCounter());
|
|
113
|
-
console.log(`[${label}] New tab again: ${r2a}`);
|
|
114
|
-
|
|
115
|
-
const success = r1 === 1 && r2 === 2 && r1a === 3 && r2a === 4;
|
|
116
|
-
if (success) {
|
|
117
|
-
console.log(`[${label}] ✓ PASS! Counter: 1 -> 2 -> 3 -> 4`);
|
|
118
|
-
} else {
|
|
119
|
-
console.log(`[${label}] ✗ FAIL! Expected: 1,2,3,4 Got: ${r1},${r2},${r1a},${r2a}`);
|
|
120
|
-
}
|
|
121
|
-
} else {
|
|
122
|
-
console.log(`[${label}] ✗ No new tab found!`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
server.close();
|
|
126
|
-
await browser.close();
|
|
127
|
-
|
|
128
|
-
} catch (error) {
|
|
129
|
-
console.error(`[${label}] Error:`, error.message);
|
|
130
|
-
console.error(error.stack);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async function main() {
|
|
135
|
-
console.log('Testing with chromium.launch() using system Chromium\n');
|
|
136
|
-
await testWithLaunch('Native Chromium');
|
|
137
|
-
process.exit(0);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
main();
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
let serverPort = 9000;
|
|
6
|
-
|
|
7
|
-
async function testWithLaunchBrowser(port, label, useConnect) {
|
|
8
|
-
serverPort++;
|
|
9
|
-
const currentPort = serverPort;
|
|
10
|
-
|
|
11
|
-
console.log(`\n${'='.repeat(60)}`);
|
|
12
|
-
console.log(`Testing ${label}`);
|
|
13
|
-
console.log(`Mode: ${useConnect ? 'connectOverCDP' : 'launch'}`);
|
|
14
|
-
console.log('='.repeat(60));
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const sharedState = { counter: 0 };
|
|
18
|
-
|
|
19
|
-
const htmlContent1 = `
|
|
20
|
-
<!DOCTYPE html>
|
|
21
|
-
<html>
|
|
22
|
-
<head><title>Page 1</title></head>
|
|
23
|
-
<body>
|
|
24
|
-
<h1>Page 1</h1>
|
|
25
|
-
<a href="page2.html" target="_blank" id="link1">Open New Tab</a>
|
|
26
|
-
</body>
|
|
27
|
-
</html>
|
|
28
|
-
`;
|
|
29
|
-
|
|
30
|
-
const htmlContent2 = `
|
|
31
|
-
<!DOCTYPE html>
|
|
32
|
-
<html>
|
|
33
|
-
<head><title>Page 2</title></head>
|
|
34
|
-
<body>
|
|
35
|
-
<h1>Page 2 - New Tab</h1>
|
|
36
|
-
</body>
|
|
37
|
-
</html>
|
|
38
|
-
`;
|
|
39
|
-
|
|
40
|
-
const serverDir = '/tmp/test-launch';
|
|
41
|
-
if (!fs.existsSync(serverDir)) {
|
|
42
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
43
|
-
}
|
|
44
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
45
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
46
|
-
|
|
47
|
-
const http = require('http');
|
|
48
|
-
const server = http.createServer((req, res) => {
|
|
49
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
50
|
-
if (fs.existsSync(filePath)) {
|
|
51
|
-
const content = fs.readFileSync(filePath);
|
|
52
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
53
|
-
res.end(content);
|
|
54
|
-
} else {
|
|
55
|
-
res.writeHead(404);
|
|
56
|
-
res.end('Not found');
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
61
|
-
console.log(`[${label}] Server on port ${currentPort}`);
|
|
62
|
-
|
|
63
|
-
let browser;
|
|
64
|
-
if (useConnect) {
|
|
65
|
-
console.log(`[${label}] Connecting to existing browser on port ${port}...`);
|
|
66
|
-
browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
67
|
-
} else {
|
|
68
|
-
console.log(`[${label}] Launching new browser...`);
|
|
69
|
-
browser = await chromium.launch({
|
|
70
|
-
headless: false,
|
|
71
|
-
args: [`--remote-debugging-port=${port}`]
|
|
72
|
-
});
|
|
73
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
console.log(`[${label}] Connected/Launched!`);
|
|
77
|
-
|
|
78
|
-
console.log(`[${label}] Creating context...`);
|
|
79
|
-
const context = await browser.newContext();
|
|
80
|
-
|
|
81
|
-
console.log(`[${label}] exposeFunction getCounter...`);
|
|
82
|
-
await context.exposeFunction('getCounter', () => {
|
|
83
|
-
sharedState.counter += 1;
|
|
84
|
-
console.log(`[${label}] getCounter: ${sharedState.counter}`);
|
|
85
|
-
return sharedState.counter;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
console.log(`[${label}] Creating first page...`);
|
|
89
|
-
const page1 = await context.newPage();
|
|
90
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
91
|
-
|
|
92
|
-
console.log(`[${label}] Testing first page...`);
|
|
93
|
-
try {
|
|
94
|
-
const r1 = await page1.evaluate(() => window.getCounter());
|
|
95
|
-
console.log(`[${label}] First page: ${r1}`);
|
|
96
|
-
} catch (e) {
|
|
97
|
-
console.log(`[${label}] First page ERROR: ${e.message}`);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
console.log(`[${label}] Clicking link...`);
|
|
101
|
-
await page1.click('#link1');
|
|
102
|
-
|
|
103
|
-
console.log(`[${label}] Waiting 3 seconds...`);
|
|
104
|
-
await new Promise(r => setTimeout(r, 3000));
|
|
105
|
-
|
|
106
|
-
console.log(`[${label}] Checking pages...`);
|
|
107
|
-
const allPages = context.pages();
|
|
108
|
-
console.log(`[${label}] Total pages: ${allPages.length}`);
|
|
109
|
-
for (let i = 0; i < allPages.length; i++) {
|
|
110
|
-
console.log(`[${label}] Page ${i}: ${allPages[i].url()}`);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
server.close();
|
|
114
|
-
await browser.close();
|
|
115
|
-
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error(`[${label}] Error:`, error.message);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
async function main() {
|
|
122
|
-
console.log('='.repeat(60));
|
|
123
|
-
console.log('Test 1: Playwright launch() - should work perfectly');
|
|
124
|
-
console.log('Test 2: connectOverCDP() - for comparison');
|
|
125
|
-
console.log('='.repeat(60));
|
|
126
|
-
|
|
127
|
-
console.log('\n### Test 1: chromium.launch() ###');
|
|
128
|
-
await testWithLaunchBrowser(0, 'Launch', false);
|
|
129
|
-
|
|
130
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
131
|
-
|
|
132
|
-
console.log('\n### Test 2: chromium.connectOverCDP() to fresh browser ###');
|
|
133
|
-
const p = require('child_process').spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
|
|
134
|
-
'--remote-debugging-port=9240',
|
|
135
|
-
'--user-data-dir=/tmp/chromium-connect-test',
|
|
136
|
-
'--no-first-run',
|
|
137
|
-
'--no-default-browser-check'
|
|
138
|
-
], { detached: true, stdio: 'ignore' });
|
|
139
|
-
|
|
140
|
-
await new Promise(r => setTimeout(r, 3000));
|
|
141
|
-
|
|
142
|
-
await testWithLaunchBrowser(9240, 'Connect', true);
|
|
143
|
-
|
|
144
|
-
try { process.kill(-p.pid); } catch(e) {}
|
|
145
|
-
|
|
146
|
-
process.exit(0);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
main();
|