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.
Files changed (69) hide show
  1. package/cli/index.js +65 -0
  2. package/extension-new/background.js +6 -1
  3. package/extension-new/cdp/handler/special.js +47 -27
  4. package/extension-new/core/state.js +64 -6
  5. package/extension-new/core/websocket.js +124 -19
  6. package/package.json +9 -2
  7. package/server/proxy-server.js +45 -34
  8. package/.github/workflows/publish.yml +0 -92
  9. package/.github/workflows/release-assets.yml +0 -50
  10. package/PUBLISH.md +0 -65
  11. package/console-test.js +0 -52
  12. package/docs/README_CN.md +0 -204
  13. package/docs/config-page-screenshot.png +0 -0
  14. package/final-console-test.js +0 -105
  15. package/simple-tab-group-test.js +0 -56
  16. package/test-cdp-connection.js +0 -85
  17. package/test-cdp-groups.js +0 -71
  18. package/test-check-newtab.js +0 -144
  19. package/test-chrome-native.js +0 -140
  20. package/test-client-connected.js +0 -99
  21. package/test-compare-formats.js +0 -88
  22. package/test-context-features.js +0 -113
  23. package/test-create-tab.js +0 -113
  24. package/test-debug-broadcast.js +0 -52
  25. package/test-debug-targets.js +0 -127
  26. package/test-expose-newtab.js +0 -164
  27. package/test-expose-shared.js +0 -189
  28. package/test-final-logs.js +0 -110
  29. package/test-fresh-chromium.js +0 -153
  30. package/test-init-script.js +0 -128
  31. package/test-keepalive.js +0 -89
  32. package/test-launch-chromium.js +0 -140
  33. package/test-launch-vs-connect.js +0 -149
  34. package/test-listen-events.js +0 -102
  35. package/test-monitor.js +0 -83
  36. package/test-multiple-cdp-groups.js +0 -78
  37. package/test-native.js +0 -96
  38. package/test-page-connection.js +0 -74
  39. package/test-playwright-connection.js +0 -45
  40. package/test-playwright-groups.js +0 -47
  41. package/test-playwright-pages.js +0 -47
  42. package/test-playwright-sequence.js +0 -81
  43. package/test-proper-context.js +0 -129
  44. package/test-real-final.js +0 -251
  45. package/test-real-scenario-v2.js +0 -166
  46. package/test-real-scenario-v3.js +0 -231
  47. package/test-real-scenario.js +0 -104
  48. package/test-server-logs.js +0 -98
  49. package/test-session-id.js +0 -91
  50. package/test-simple-cdp-groups.js +0 -44
  51. package/test-simple-context.js +0 -137
  52. package/test-tab-group-simple.js +0 -58
  53. package/test-tab-grouping.js +0 -48
  54. package/test-three-pages.js +0 -192
  55. package/test-wait-for-page.js +0 -95
  56. package/test-with-logs.js +0 -118
  57. package/test-ws-groups.js +0 -59
  58. package/tests/e2e-auto-test.js +0 -304
  59. package/tests/iframe-test-page.html +0 -89
  60. package/tests/playwright-demo.js +0 -45
  61. package/tests/playwright-interactive.js +0 -261
  62. package/tests/playwright-multi-demo.js +0 -60
  63. package/tests/playwright-multi.js +0 -85
  64. package/tests/playwright-single.js +0 -41
  65. package/tests/screenshot-config.js +0 -35
  66. package/tests/test-client.js +0 -89
  67. package/tests/test-douyin-iframe.js +0 -171
  68. package/tests/test-iframe-debug.js +0 -204
  69. package/tests/test-multi-client.js +0 -129
@@ -1,74 +0,0 @@
1
- const WebSocket = require('ws');
2
-
3
- const TARGET_ID = '4724AF3A60A419ECDEC2002A153733A2'; // 百度首页
4
-
5
- console.log('[Page Test] Connecting to specific page...');
6
-
7
- const ws = new WebSocket(`ws://localhost:9221/devtools/page/${TARGET_ID}`);
8
-
9
- ws.on('open', () => {
10
- console.log('[Page Test] Connected to page!');
11
-
12
- ws.send(JSON.stringify({
13
- id: 1,
14
- method: 'Page.enable',
15
- params: {}
16
- }));
17
-
18
- console.log('[Page Test] Enabled Page domain');
19
-
20
- setTimeout(() => {
21
- ws.send(JSON.stringify({
22
- id: 2,
23
- method: 'Runtime.evaluate',
24
- params: {
25
- expression: 'document.title'
26
- }
27
- }));
28
- console.log('[Page Test] Getting page title...');
29
- }, 500);
30
-
31
- setTimeout(() => {
32
- ws.send(JSON.stringify({
33
- id: 3,
34
- method: 'Page.captureScreenshot',
35
- params: {}
36
- }));
37
- console.log('[Page Test] Taking screenshot...');
38
- }, 1000);
39
- });
40
-
41
- ws.on('message', (data) => {
42
- try {
43
- const msg = JSON.parse(data.toString());
44
-
45
- if (msg.id) {
46
- console.log('[Page Test] Response #' + msg.id + ':', {
47
- success: !!msg.result,
48
- error: msg.error,
49
- result: msg.result?.result?.value ||
50
- (msg.result?.data ? `screenshot (${msg.result.data.length} chars)` : undefined)
51
- });
52
- } else if (msg.method) {
53
- console.log('[Page Test] Event:', msg.method);
54
- } else {
55
- console.log('[Page Test] Other message:', msg);
56
- }
57
- } catch (e) {
58
- console.log('[Page Test] Raw message:', data.toString().substring(0, 100));
59
- }
60
- });
61
-
62
- ws.on('close', (code, reason) => {
63
- console.log('[Page Test] Connection closed:', code, reason.toString());
64
- });
65
-
66
- ws.on('error', (err) => {
67
- console.error('[Page Test] Error:', err.message);
68
- });
69
-
70
- setTimeout(() => {
71
- console.log('\n[Page Test] Test completed, closing connection...');
72
- ws.close();
73
- process.exit(0);
74
- }, 3000);
@@ -1,45 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testPlaywright() {
4
- console.log('[Playwright Test] Connecting to CDP proxy...');
5
-
6
- try {
7
- const browser = await chromium.connectOverCDP('http://localhost:9221');
8
- console.log('[Playwright Test] Connected successfully!');
9
-
10
- const contexts = browser.contexts();
11
- console.log(`[Playwright Test] Found ${contexts.length} context(s)`);
12
-
13
- if (contexts.length > 0) {
14
- const context = contexts[0];
15
- const pages = context.pages();
16
- console.log(`[Playwright Test] Found ${pages.length} page(s) in first context`);
17
-
18
- if (pages.length > 0) {
19
- const page = pages[0];
20
- console.log(`[Playwright Test] First page URL: ${page.url()}`);
21
-
22
- console.log('[Playwright Test] Trying to navigate to a new page...');
23
- const newPage = await context.newPage();
24
- await newPage.goto('https://www.example.com');
25
- console.log(`[Playwright Test] New page URL: ${newPage.url()}`);
26
-
27
- await newPage.waitForTimeout(2000);
28
-
29
- console.log('[Playwright Test] Taking screenshot...');
30
- await newPage.screenshot({ path: 'test-screenshot.png' });
31
- console.log('[Playwright Test] Screenshot saved to test-screenshot.png');
32
-
33
- await newPage.close();
34
- }
35
- }
36
-
37
- console.log('[Playwright Test] Test completed successfully!');
38
- await browser.close();
39
- } catch (error) {
40
- console.error('[Playwright Test] Error:', error.message);
41
- console.error('[Playwright Test] Stack:', error.stack);
42
- }
43
- }
44
-
45
- testPlaywright();
@@ -1,47 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testCDPGroups() {
4
- console.log('=== 测试CDP连接的标签分组功能 ===\n');
5
-
6
- try {
7
- // 连接到CDP服务器
8
- console.log('连接到CDP服务器...');
9
- const browser = await chromium.connectOverCDP('http://localhost:9221');
10
- console.log('CDP连接成功');
11
-
12
- // 创建第一个标签页
13
- console.log('创建第一个标签页...');
14
- const page1 = await browser.newPage();
15
- console.log('第一个标签页创建完成');
16
-
17
- // 等待5秒
18
- console.log('等待5秒...');
19
- await new Promise(resolve => setTimeout(resolve, 5000));
20
-
21
- // 创建第二个标签页
22
- console.log('创建第二个标签页...');
23
- const page2 = await browser.newPage();
24
- console.log('第二个标签页创建完成');
25
-
26
- // 等待5秒
27
- console.log('等待5秒...');
28
- await new Promise(resolve => setTimeout(resolve, 5000));
29
-
30
- console.log('\n=== 测试完成 ===');
31
- console.log('请检查Chrome浏览器中的标签组:');
32
- console.log('1. 应该创建了两个新的标签页');
33
- console.log('2. 这两个标签页应该被添加到一个名为"CDP-{客户端ID}"的标签组中');
34
-
35
- // 不关闭浏览器,让用户手动检查
36
- console.log('\n测试脚本完成,浏览器连接保持打开状态,请手动检查标签组。');
37
- console.log('按Ctrl+C退出脚本...');
38
-
39
- // 保持脚本运行
40
- await new Promise(() => {});
41
-
42
- } catch (error) {
43
- console.error('测试过程中出现错误:', error);
44
- }
45
- }
46
-
47
- testCDPGroups();
@@ -1,47 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testPlaywrightPages() {
4
- console.log('[Playwright Pages Test] Connecting to CDP proxy...');
5
-
6
- try {
7
- const browser = await chromium.connectOverCDP('http://localhost:9221');
8
- console.log('[Playwright Pages Test] Connected successfully!');
9
-
10
- const contexts = browser.contexts();
11
- console.log(`[Playwright Pages Test] Found ${contexts.length} context(s)`);
12
-
13
- for (let i = 0; i < contexts.length; i++) {
14
- const context = contexts[i];
15
- console.log(`\n[Playwright Pages Test] Context ${i}:`);
16
-
17
- const pages = context.pages();
18
- console.log(` Pages: ${pages.length}`);
19
-
20
- for (let j = 0; j < pages.length; j++) {
21
- const page = pages[j];
22
- console.log(` Page ${j}: ${page.url()}`);
23
- }
24
- }
25
-
26
- console.log('\n[Playwright Pages Test] Trying to get all pages via CDP...');
27
- const client = await browser.newBrowserCDPSession();
28
-
29
- const result = await client.send('Target.getTargets');
30
- console.log(`[Playwright Pages Test] Found ${result.targetInfos.length} targets via CDP`);
31
-
32
- const pageTargets = result.targetInfos.filter(t => t.type === 'page');
33
- console.log(`[Playwright Pages Test] Found ${pageTargets.length} page targets`);
34
-
35
- pageTargets.slice(0, 5).forEach((t, i) => {
36
- console.log(` ${i + 1}. ${t.url}`);
37
- });
38
-
39
- console.log('[Playwright Pages Test] Test completed!');
40
- await browser.close();
41
- } catch (error) {
42
- console.error('[Playwright Pages Test] Error:', error.message);
43
- console.error('[Playwright Pages Test] Stack:', error.stack);
44
- }
45
- }
46
-
47
- testPlaywrightPages();
@@ -1,81 +0,0 @@
1
- const WebSocket = require('ws');
2
-
3
- async function testPlaywrightConnectionSequence() {
4
- console.log('[Sequence Test] Simulating Playwright connection sequence...\n');
5
-
6
- const ws = new WebSocket('ws://localhost:9221/client');
7
-
8
- let requestId = 1;
9
-
10
- const sendRequest = (method, params = {}) => {
11
- const id = requestId++;
12
- const msg = { id, method, params };
13
- console.log(`[SEND] #${id}: ${method}`, params);
14
- ws.send(JSON.stringify(msg));
15
- return id;
16
- };
17
-
18
- ws.on('open', async () => {
19
- console.log('[Sequence Test] Connected!\n');
20
-
21
- console.log('Step 1: Enable Target domain');
22
- sendRequest('Target.setDiscoverTargets', { discover: true });
23
-
24
- await sleep(500);
25
-
26
- console.log('\nStep 2: Get all targets');
27
- sendRequest('Target.getTargets');
28
-
29
- await sleep(1000);
30
-
31
- console.log('\nStep 3: Attach to first page target');
32
- sendRequest('Target.attachToTarget', {
33
- targetId: '4724AF3A60A419ECDEC2002A153733A2', // 百度首页
34
- flatten: true
35
- });
36
-
37
- await sleep(1000);
38
-
39
- console.log('\nStep 4: Enable Page domain on attached target');
40
- sendRequest('Page.enable');
41
-
42
- await sleep(500);
43
-
44
- console.log('\nStep 5: Navigate the page');
45
- sendRequest('Page.navigate', { url: 'https://www.example.com' });
46
-
47
- await sleep(2000);
48
-
49
- console.log('\n[Sequence Test] Test completed');
50
- ws.close();
51
- process.exit(0);
52
- });
53
-
54
- ws.on('message', (data) => {
55
- try {
56
- const msg = JSON.parse(data.toString());
57
-
58
- if (msg.id) {
59
- console.log(`[RECV] #${msg.id}:`, JSON.stringify(msg, null, 2).substring(0, 300));
60
- } else if (msg.method) {
61
- console.log(`[EVENT] ${msg.method}:`, {
62
- targetId: msg.params?.targetInfo?.targetId?.substring(0, 8),
63
- sessionId: msg.params?.sessionId?.substring(0, 8),
64
- url: msg.params?.targetInfo?.url?.substring(0, 50)
65
- });
66
- }
67
- } catch (e) {
68
- console.log('[RECV] Raw:', data.toString().substring(0, 100));
69
- }
70
- });
71
-
72
- ws.on('error', (err) => {
73
- console.error('[ERROR]', err.message);
74
- });
75
- }
76
-
77
- function sleep(ms) {
78
- return new Promise(resolve => setTimeout(resolve, ms));
79
- }
80
-
81
- testPlaywrightConnectionSequence();
@@ -1,129 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testContextFeaturesProper(port, label) {
4
- console.log(`\n${'='.repeat(60)}`);
5
- console.log(`Testing ${label} (port ${port})`);
6
- console.log('='.repeat(60));
7
-
8
- try {
9
- const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
10
- console.log(`[${label}] Connected successfully!`);
11
-
12
- console.log(`[${label}] Creating new context...`);
13
- const context = await browser.newContext();
14
-
15
- console.log(`[${label}] Testing exposeFunction...`);
16
- await context.exposeFunction('myCustomFunction', (arg) => {
17
- console.log(`[${label}] myCustomFunction called with:`, arg);
18
- return `Hello from ${label}: ${arg}`;
19
- });
20
-
21
- console.log(`[${label}] Testing addInitScript...`);
22
- await context.addInitScript(() => {
23
- window.myInitScript = 'This is from addInitScript!';
24
- });
25
-
26
- console.log(`[${label}] Creating first page...`);
27
- const page1 = await context.newPage();
28
- await page1.goto('about:blank');
29
-
30
- console.log(`[${label}] Testing in first page...`);
31
- const result1 = await page1.evaluate(async () => {
32
- try {
33
- const funcResult = await window.myCustomFunction('page1');
34
- const initResult = window.myInitScript;
35
- return { success: true, funcResult, initResult };
36
- } catch (e) {
37
- return { success: false, error: e.message };
38
- }
39
- });
40
- console.log(`[${label}] First page result:`, result1);
41
-
42
- if (!result1.success) {
43
- console.log(`[${label}] ✗ First page test failed!`);
44
- await browser.close();
45
- return false;
46
- }
47
-
48
- console.log(`[${label}] Creating second page (simulating new tab)...`);
49
- const page2 = await context.newPage();
50
- await page2.goto('about:blank');
51
-
52
- console.log(`[${label}] Testing in second page (should persist)...`);
53
- const result2 = await page2.evaluate(async () => {
54
- try {
55
- const funcResult = await window.myCustomFunction('page2');
56
- const initResult = window.myInitScript;
57
- return { success: true, funcResult, initResult };
58
- } catch (e) {
59
- return { success: false, error: e.message };
60
- }
61
- });
62
- console.log(`[${label}] Second page result:`, result2);
63
-
64
- if (!result2.success) {
65
- console.log(`[${label}] ✗ Second page test failed - Context features not persisted!`);
66
- await browser.close();
67
- return false;
68
- }
69
-
70
- console.log(`[${label}] Creating third page...`);
71
- const page3 = await context.newPage();
72
- await page3.goto('about:blank');
73
-
74
- console.log(`[${label}] Testing in third page...`);
75
- const result3 = await page3.evaluate(async () => {
76
- try {
77
- const funcResult = await window.myCustomFunction('page3');
78
- const initResult = window.myInitScript;
79
- return { success: true, funcResult, initResult };
80
- } catch (e) {
81
- return { success: false, error: e.message };
82
- }
83
- });
84
- console.log(`[${label}] Third page result:`, result3);
85
-
86
- if (!result3.success) {
87
- console.log(`[${label}] ✗ Third page test failed!`);
88
- await browser.close();
89
- return false;
90
- }
91
-
92
- console.log(`[${label}] ✓ All tests passed!`);
93
-
94
- await browser.close();
95
-
96
- return true;
97
- } catch (error) {
98
- console.error(`[${label}] ✗ Error:`, error.message);
99
- console.error(`[${label}] Stack:`, error.stack);
100
- return false;
101
- }
102
- }
103
-
104
- async function main() {
105
- console.log('Testing Context-level features persistence across tabs');
106
- console.log('This tests if exposeFunction and addInitScript persist across different pages\n');
107
-
108
- const nativeResult = await testContextFeaturesProper(9333, 'Native CDP');
109
- const tunnelResult = await testContextFeaturesProper(9221, 'CDP Tunnel');
110
-
111
- console.log('\n' + '='.repeat(60));
112
- console.log('COMPARISON RESULTS');
113
- console.log('='.repeat(60));
114
- console.log(`Native CDP (port 9333): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
115
- console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
116
-
117
- if (nativeResult && tunnelResult) {
118
- console.log('\n✓ Both implementations behave identically!');
119
- console.log('✓ Context-level features (exposeFunction/addInitScript) work correctly!');
120
- } else if (nativeResult && !tunnelResult) {
121
- console.log('\n✗ CDP Tunnel has issues with Context-level features!');
122
- } else if (!nativeResult && tunnelResult) {
123
- console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
124
- } else {
125
- console.log('\n✗ Both implementations have issues!');
126
- }
127
- }
128
-
129
- main();
@@ -1,251 +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 testRealScenario(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 htmlContent1 = `
13
- <!DOCTYPE html>
14
- <html>
15
- <head><title>Page 1</title></head>
16
- <body>
17
- <h1>Page 1 - Source</h1>
18
- <p>This is the source page.</p>
19
- <a href="page2.html" target="_blank">Open Result 1</a>
20
- <a href="page3.html" target="_blank">Open Result 2</a>
21
- </body>
22
- </html>
23
- `;
24
-
25
- const htmlContent2 = `
26
- <!DOCTYPE html>
27
- <html>
28
- <head><title>Page 2</title></head>
29
- <body>
30
- <h1>Page 2 - Result 1</h1>
31
- <p>This is result page 1.</p>
32
- <a href="page3.html" target="_blank">Open Result 2</a>
33
- </body>
34
- </html>
35
- `;
36
-
37
- const htmlContent3 = `
38
- <!DOCTYPE html>
39
- <html>
40
- <head><title>Page 3</title></head>
41
- <body>
42
- <h1>Page 3 - Result 2</h1>
43
- <p>This is result page 2.</p>
44
- </body>
45
- </html>
46
- `;
47
-
48
- const serverDir = '/tmp/test-pages-v2';
49
- if (!fs.existsSync(serverDir)) {
50
- fs.mkdirSync(serverDir, { recursive: true });
51
- }
52
- fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
53
- fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
54
- fs.writeFileSync(path.join(serverDir, 'page3.html'), htmlContent3);
55
-
56
- const http = require('http');
57
- const server = http.createServer((req, res) => {
58
- let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
59
- if (fs.existsSync(filePath)) {
60
- const content = fs.readFileSync(filePath);
61
- res.writeHead(200, { 'Content-Type': 'text/html' });
62
- res.end(content);
63
- } else {
64
- res.writeHead(404);
65
- res.end('Not found');
66
- }
67
- });
68
-
69
- await new Promise(resolve => server.listen(8766, resolve));
70
- console.log(`[${label}] Test server started on port 8766`);
71
-
72
- const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
73
- console.log(`[${label}] Connected successfully!`);
74
-
75
- console.log(`[${label}] Creating new context...`);
76
- const context = await browser.newContext();
77
-
78
- console.log(`[${label}] Testing addInitScript - set unique value per page...`);
79
- await context.addInitScript(() => {
80
- window.pageLoadedAt = Date.now();
81
- window.testValue = 'init-script-executed';
82
- console.log('[InitScript] Executed at:', window.pageLoadedAt);
83
- });
84
-
85
- console.log(`[${label}] Creating first page...`);
86
- const page1 = await context.newPage();
87
- await page1.goto('http://localhost:8766/page1.html', { waitUntil: 'domcontentloaded' });
88
- await page1.waitForTimeout(500);
89
-
90
- console.log(`[${label}] Testing in first page...`);
91
- const result1 = await page1.evaluate(() => {
92
- return {
93
- url: window.location.href,
94
- testValue: window.testValue,
95
- pageLoadedAt: window.pageLoadedAt
96
- };
97
- });
98
- console.log(`[${label}] First page:`, {
99
- url: result1.url,
100
- testValue: result1.testValue,
101
- pageLoadedAt: new Date(result1.pageLoadedAt).toLocaleTimeString()
102
- });
103
-
104
- console.log(`[${label}] Clicking first link (opens new tab)...`);
105
- try {
106
- const [page2] = await Promise.all([
107
- context.waitForEvent('page', { timeout: 10000 }),
108
- page1.click('a:first-child')
109
- ]);
110
-
111
- console.log(`[${label}] Waiting for new tab to load...`);
112
- await page2.waitForLoadState('domcontentloaded');
113
- await page2.waitForTimeout(500);
114
- console.log(`[${label}] New tab URL: ${page2.url()}`);
115
-
116
- console.log(`[${label}] Testing in second page (should have init script)...`);
117
- const result2 = await page2.evaluate(() => {
118
- return {
119
- url: window.location.href,
120
- testValue: window.testValue,
121
- pageLoadedAt: window.pageLoadedAt
122
- };
123
- });
124
- console.log(`[${label}] Second page:`, {
125
- url: result2.url,
126
- testValue: result2.testValue,
127
- pageLoadedAt: new Date(result2.pageLoadedAt).toLocaleTimeString()
128
- });
129
-
130
- console.log(`[${label}] Clicking another link...`);
131
- try {
132
- const [page3] = await Promise.all([
133
- context.waitForEvent('page', { timeout: 10000 }),
134
- page2.click('a:first-child')
135
- ]);
136
-
137
- console.log(`[${label}] Waiting for third tab...`);
138
- await page3.waitForLoadState('domcontentloaded');
139
- await page3.waitForTimeout(500);
140
-
141
- console.log(`[${label}] Testing in third page...`);
142
- const result3 = await page3.evaluate(() => {
143
- return {
144
- url: window.location.href,
145
- testValue: window.testValue,
146
- pageLoadedAt: window.pageLoadedAt
147
- };
148
- });
149
- console.log(`[${label}] Third page:`, {
150
- url: result3.url,
151
- testValue: result3.testValue,
152
- pageLoadedAt: new Date(result3.pageLoadedAt).toLocaleTimeString()
153
- });
154
- } catch (e) {
155
- console.log(`[${label}] No more links to click`);
156
- }
157
- } catch (e) {
158
- console.log(`[${label}] Error waiting for new tab: ${e.message}`);
159
- }
160
-
161
- console.log(`[${label}] Switching back to first page...`);
162
- await page1.bringToFront();
163
- await page1.waitForTimeout(500);
164
-
165
- console.log(`[${label}] Testing in first page again...`);
166
- const result1Again = await page1.evaluate(() => {
167
- return {
168
- url: window.location.href,
169
- testValue: window.testValue,
170
- pageLoadedAt: window.pageLoadedAt
171
- };
172
- });
173
- console.log(`[${label}] First page (after switch):`, {
174
- url: result1Again.url,
175
- testValue: result1Again.testValue,
176
- pageLoadedAt: new Date(result1Again.pageLoadedAt).toLocaleTimeString()
177
- });
178
-
179
- const success = result1.testValue === 'init-script-executed' &&
180
- result2?.testValue === 'init-script-executed' &&
181
- result1.pageLoadedAt !== result2?.pageLoadedAt;
182
-
183
- server.close();
184
-
185
- if (success) {
186
- console.log(`[${label}] ✓ All tests passed!`);
187
- console.log(`[${label}] ✓ addInitScript executed in ALL new pages!`);
188
- } else {
189
- console.log(`[${label}] ✗ Some tests failed!`);
190
- }
191
-
192
- await browser.close();
193
-
194
- return success;
195
- } catch (error) {
196
- console.error(`[${label}] ✗ Error:`, error.message);
197
- console.error(`[${label}] Stack:`, error.stack);
198
- return false;
199
- }
200
- }
201
-
202
- async function main() {
203
- console.log('Testing: Page1 -> Click link (new tab) -> Click link (another new tab)');
204
- console.log('Expected: addInitScript executes in EVERY new page (different timestamps)\n');
205
-
206
- console.log('Step 1: Starting fresh Chromium instance on port 9228...');
207
- const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
208
- '--remote-debugging-port=9228',
209
- '--user-data-dir=/tmp/chromium-test-final',
210
- '--no-first-run',
211
- '--no-default-browser-check'
212
- ], {
213
- detached: true,
214
- stdio: 'ignore'
215
- });
216
-
217
- console.log('Waiting for Chromium to start...');
218
- await new Promise(resolve => setTimeout(resolve, 3000));
219
-
220
- console.log('\nStep 2: Testing Native CDP...');
221
- const nativeResult = await testRealScenario(9228, 'Native CDP');
222
-
223
- console.log('\nStep 3: Testing CDP Tunnel...');
224
- const tunnelResult = await testRealScenario(9221, 'CDP Tunnel');
225
-
226
- console.log('\nStep 4: Cleaning up...');
227
- try {
228
- process.kill(-chromiumProcess.pid);
229
- } catch (e) {}
230
-
231
- console.log('\n' + '='.repeat(60));
232
- console.log('COMPARISON RESULTS');
233
- console.log('='.repeat(60));
234
- console.log(`Native CDP (port 9228): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
235
- console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
236
-
237
- if (nativeResult && tunnelResult) {
238
- console.log('\n✓ Both implementations behave identically!');
239
- console.log('✓ addInitScript executes in EVERY new page!');
240
- } else if (nativeResult && !tunnelResult) {
241
- console.log('\n✗ CDP Tunnel has issues with addInitScript!');
242
- } else if (!nativeResult && tunnelResult) {
243
- console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
244
- } else {
245
- console.log('\n✗ Both implementations have issues!');
246
- }
247
-
248
- process.exit(0);
249
- }
250
-
251
- main();