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.
Files changed (68) hide show
  1. package/extension-new/background.js +6 -1
  2. package/extension-new/cdp/handler/special.js +47 -27
  3. package/extension-new/core/state.js +64 -6
  4. package/extension-new/core/websocket.js +124 -19
  5. package/package.json +9 -2
  6. package/server/proxy-server.js +45 -34
  7. package/.github/workflows/publish.yml +0 -92
  8. package/.github/workflows/release-assets.yml +0 -50
  9. package/PUBLISH.md +0 -65
  10. package/console-test.js +0 -52
  11. package/docs/README_CN.md +0 -204
  12. package/docs/config-page-screenshot.png +0 -0
  13. package/final-console-test.js +0 -105
  14. package/simple-tab-group-test.js +0 -56
  15. package/test-cdp-connection.js +0 -85
  16. package/test-cdp-groups.js +0 -71
  17. package/test-check-newtab.js +0 -144
  18. package/test-chrome-native.js +0 -140
  19. package/test-client-connected.js +0 -99
  20. package/test-compare-formats.js +0 -88
  21. package/test-context-features.js +0 -113
  22. package/test-create-tab.js +0 -113
  23. package/test-debug-broadcast.js +0 -52
  24. package/test-debug-targets.js +0 -127
  25. package/test-expose-newtab.js +0 -164
  26. package/test-expose-shared.js +0 -189
  27. package/test-final-logs.js +0 -110
  28. package/test-fresh-chromium.js +0 -153
  29. package/test-init-script.js +0 -128
  30. package/test-keepalive.js +0 -89
  31. package/test-launch-chromium.js +0 -140
  32. package/test-launch-vs-connect.js +0 -149
  33. package/test-listen-events.js +0 -102
  34. package/test-monitor.js +0 -83
  35. package/test-multiple-cdp-groups.js +0 -78
  36. package/test-native.js +0 -96
  37. package/test-page-connection.js +0 -74
  38. package/test-playwright-connection.js +0 -45
  39. package/test-playwright-groups.js +0 -47
  40. package/test-playwright-pages.js +0 -47
  41. package/test-playwright-sequence.js +0 -81
  42. package/test-proper-context.js +0 -129
  43. package/test-real-final.js +0 -251
  44. package/test-real-scenario-v2.js +0 -166
  45. package/test-real-scenario-v3.js +0 -231
  46. package/test-real-scenario.js +0 -104
  47. package/test-server-logs.js +0 -98
  48. package/test-session-id.js +0 -91
  49. package/test-simple-cdp-groups.js +0 -44
  50. package/test-simple-context.js +0 -137
  51. package/test-tab-group-simple.js +0 -58
  52. package/test-tab-grouping.js +0 -48
  53. package/test-three-pages.js +0 -192
  54. package/test-wait-for-page.js +0 -95
  55. package/test-with-logs.js +0 -118
  56. package/test-ws-groups.js +0 -59
  57. package/tests/e2e-auto-test.js +0 -304
  58. package/tests/iframe-test-page.html +0 -89
  59. package/tests/playwright-demo.js +0 -45
  60. package/tests/playwright-interactive.js +0 -261
  61. package/tests/playwright-multi-demo.js +0 -60
  62. package/tests/playwright-multi.js +0 -85
  63. package/tests/playwright-single.js +0 -41
  64. package/tests/screenshot-config.js +0 -35
  65. package/tests/test-client.js +0 -89
  66. package/tests/test-douyin-iframe.js +0 -171
  67. package/tests/test-iframe-debug.js +0 -204
  68. package/tests/test-multi-client.js +0 -129
@@ -1,231 +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 - Baidu Like</title></head>
16
- <body>
17
- <h1>Baidu Search</h1>
18
- <input type="text" id="kw" placeholder="Search..." />
19
- <button id="su">Search</button>
20
- <div id="results">
21
- <a href="page2.html" target="_blank">Result 1</a>
22
- <a href="page3.html" target="_blank">Result 2</a>
23
- </div>
24
- <script>
25
- console.log('Page 1 loaded');
26
- </script>
27
- </body>
28
- </html>
29
- `;
30
-
31
- const htmlContent2 = `
32
- <!DOCTYPE html>
33
- <html>
34
- <head><title>Page 2 - Result</title></head>
35
- <body>
36
- <h1>Result Page 2</h1>
37
- <p>This is the result page.</p>
38
- <a href="page3.html" target="_blank">Go to Page 3</a>
39
- </body>
40
- </html>
41
- `;
42
-
43
- const htmlContent3 = `
44
- <!DOCTYPE html>
45
- <html>
46
- <head><title>Page 3 - Final</title></head>
47
- <body>
48
- <h1>Final Page 3</h1>
49
- <p>This is the final page.</p>
50
- </body>
51
- </html>
52
- `;
53
-
54
- const serverDir = '/tmp/test-pages';
55
- if (!fs.existsSync(serverDir)) {
56
- fs.mkdirSync(serverDir, { recursive: true });
57
- }
58
- fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
59
- fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
60
- fs.writeFileSync(path.join(serverDir, 'page3.html'), htmlContent3);
61
-
62
- const http = require('http');
63
- const server = http.createServer((req, res) => {
64
- let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
65
- if (fs.existsSync(filePath)) {
66
- const content = fs.readFileSync(filePath);
67
- res.writeHead(200, { 'Content-Type': 'text/html' });
68
- res.end(content);
69
- } else {
70
- res.writeHead(404);
71
- res.end('Not found');
72
- }
73
- });
74
-
75
- await new Promise(resolve => server.listen(8765, resolve));
76
- console.log(`[${label}] Test server started on port 8765`);
77
-
78
- const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
79
- console.log(`[${label}] Connected successfully!`);
80
-
81
- console.log(`[${label}] Creating new context...`);
82
- const context = await browser.newContext();
83
-
84
- console.log(`[${label}] Testing addInitScript with counter...`);
85
- await context.addInitScript(() => {
86
- window.myInitScript = 'This is from addInitScript!';
87
- window.myCounter = (window.myCounter || 0) + 1;
88
- console.log('[InitScript] myCounter:', window.myCounter);
89
- });
90
-
91
- console.log(`[${label}] Creating first page...`);
92
- const page1 = await context.newPage();
93
- await page1.goto('http://localhost:8765/page1.html', { waitUntil: 'domcontentloaded' });
94
-
95
- console.log(`[${label}] Testing in first page (counter should be 1)...`);
96
- const result1 = await page1.evaluate(() => {
97
- return {
98
- url: window.location.href,
99
- initScript: window.myInitScript,
100
- counter: window.myCounter
101
- };
102
- });
103
- console.log(`[${label}] First page result:`, result1);
104
-
105
- console.log(`[${label}] Clicking first link (opens new tab)...`);
106
- const [page2] = await Promise.all([
107
- context.waitForEvent('page'),
108
- page1.click('a:first-child')
109
- ]);
110
-
111
- console.log(`[${label}] Waiting for new tab to load...`);
112
- await page2.waitForLoadState('domcontentloaded');
113
- console.log(`[${label}] New tab URL: ${page2.url()}`);
114
-
115
- console.log(`[${label}] Testing in new tab (counter should be 2)...`);
116
- const result2 = await page2.evaluate(() => {
117
- return {
118
- url: window.location.href,
119
- initScript: window.myInitScript,
120
- counter: window.myCounter
121
- };
122
- });
123
- console.log(`[${label}] Second page result:`, result2);
124
-
125
- console.log(`[${label}] Clicking another link in new tab...`);
126
- try {
127
- const [page3] = await Promise.all([
128
- context.waitForEvent('page'),
129
- page2.click('a:first-child')
130
- ]);
131
-
132
- console.log(`[${label}] Waiting for second new tab...`);
133
- await page3.waitForLoadState('domcontentloaded');
134
- console.log(`[${label}] Second new tab URL: ${page3.url()}`);
135
-
136
- console.log(`[${label}] Testing in second new tab (counter should be 3)...`);
137
- const result3 = await page3.evaluate(() => {
138
- return {
139
- url: window.location.href,
140
- initScript: window.myInitScript,
141
- counter: window.myCounter
142
- };
143
- });
144
- console.log(`[${label}] Third page result:`, result3);
145
- } catch (e) {
146
- console.log(`[${label}] No more links to click`);
147
- }
148
-
149
- console.log(`[${label}] Switching back to first page...`);
150
- await page1.bringToFront();
151
-
152
- console.log(`[${label}] Testing in first page again (counter should still be 1)...`);
153
- const result1Again = await page1.evaluate(() => {
154
- return {
155
- url: window.location.href,
156
- initScript: window.myInitScript,
157
- counter: window.myCounter
158
- };
159
- });
160
- console.log(`[${label}] First page (after switch) result:`, result1Again);
161
-
162
- const success = result1.counter === 1 && result2.counter === 2;
163
-
164
- server.close();
165
-
166
- if (success) {
167
- console.log(`[${label}] ✓ All tests passed!`);
168
- } else {
169
- console.log(`[${label}] ✗ Counter not incrementing correctly!`);
170
- }
171
-
172
- await browser.close();
173
-
174
- return success;
175
- } catch (error) {
176
- console.error(`[${label}] ✗ Error:`, error.message);
177
- console.error(`[${label}] Stack:`, error.stack);
178
- return false;
179
- }
180
- }
181
-
182
- async function main() {
183
- console.log('Testing real scenario: Page1 -> Click link -> New tab -> Click link -> Another new tab');
184
- console.log('Expected: Counter increments with each new page (1 -> 2 -> 3)\n');
185
-
186
- console.log('Step 1: Starting fresh Chromium instance on port 9227...');
187
- const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
188
- '--remote-debugging-port=9227',
189
- '--user-data-dir=/tmp/chromium-test-real',
190
- '--no-first-run',
191
- '--no-default-browser-check'
192
- ], {
193
- detached: true,
194
- stdio: 'ignore'
195
- });
196
-
197
- console.log('Waiting for Chromium to start...');
198
- await new Promise(resolve => setTimeout(resolve, 3000));
199
-
200
- console.log('\nStep 2: Testing Native CDP...');
201
- const nativeResult = await testRealScenario(9227, 'Native CDP');
202
-
203
- console.log('\nStep 3: Testing CDP Tunnel...');
204
- const tunnelResult = await testRealScenario(9221, 'CDP Tunnel');
205
-
206
- console.log('\nStep 4: Cleaning up...');
207
- try {
208
- process.kill(-chromiumProcess.pid);
209
- } catch (e) {}
210
-
211
- console.log('\n' + '='.repeat(60));
212
- console.log('COMPARISON RESULTS');
213
- console.log('='.repeat(60));
214
- console.log(`Native CDP (port 9227): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
215
- console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
216
-
217
- if (nativeResult && tunnelResult) {
218
- console.log('\n✓ Both implementations behave identically!');
219
- console.log('✓ addInitScript works correctly and counter increments across tabs!');
220
- } else if (nativeResult && !tunnelResult) {
221
- console.log('\n✗ CDP Tunnel has issues with addInitScript counter!');
222
- } else if (!nativeResult && tunnelResult) {
223
- console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
224
- } else {
225
- console.log('\n✗ Both implementations have issues!');
226
- }
227
-
228
- process.exit(0);
229
- }
230
-
231
- main();
@@ -1,104 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testContextFeaturesWithRealScenario(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
- const contexts = browser.contexts();
13
- console.log(`[${label}] Found ${contexts.length} context(s)`);
14
-
15
- let context;
16
- if (contexts.length === 0) {
17
- console.log(`[${label}] Creating new context...`);
18
- context = await browser.newContext();
19
- } else {
20
- context = contexts[0];
21
- }
22
-
23
- console.log(`[${label}] Testing exposeFunction...`);
24
- await context.exposeFunction('myCustomFunction', (arg) => {
25
- console.log(`[${label}] myCustomFunction called with:`, arg);
26
- return `Hello from ${label}: ${arg}`;
27
- });
28
-
29
- console.log(`[${label}] Testing addInitScript...`);
30
- await context.addInitScript(() => {
31
- window.myInitScript = 'This is from addInitScript!';
32
- console.log('Init script executed!');
33
- });
34
-
35
- console.log(`[${label}] Opening Baidu...`);
36
- const page = await context.newPage();
37
- await page.goto('https://www.baidu.com');
38
-
39
- console.log(`[${label}] Testing in Baidu page...`);
40
- const result1 = await page.evaluate(async () => {
41
- const funcResult = await window.myCustomFunction('baidu-test');
42
- const initResult = window.myInitScript;
43
- return { funcResult, initResult };
44
- });
45
- console.log(`[${label}] Baidu page result:`, result1);
46
-
47
- console.log(`[${label}] Searching for "example"...`);
48
- await page.fill('#kw', 'example');
49
- await page.click('#su');
50
- await page.waitForSelector('#content_left', { timeout: 10000 });
51
-
52
- console.log(`[${label}] Clicking first search result...`);
53
- const [newPage] = await Promise.all([
54
- context.waitForEvent('page'),
55
- page.click('#content_left a:first-child')
56
- ]);
57
-
58
- console.log(`[${label}] New tab opened: ${newPage.url()}`);
59
-
60
- await newPage.waitForLoadState('domcontentloaded');
61
-
62
- console.log(`[${label}] Testing in new tab (should persist)...`);
63
- const result2 = await newPage.evaluate(async () => {
64
- const funcResult = await window.myCustomFunction('new-tab-test');
65
- const initResult = window.myInitScript;
66
- return { funcResult, initResult };
67
- });
68
- console.log(`[${label}] New tab result:`, result2);
69
-
70
- console.log(`[${label}] ✓ All tests passed!`);
71
-
72
- await browser.close();
73
-
74
- return true;
75
- } catch (error) {
76
- console.error(`[${label}] ✗ Error:`, error.message);
77
- console.error(`[${label}] Stack:`, error.stack);
78
- return false;
79
- }
80
- }
81
-
82
- async function main() {
83
- console.log('Testing Context-level features persistence across tabs');
84
- console.log('Scenario: Open Baidu -> Search -> Click result (opens new tab) -> Check persistence\n');
85
-
86
- const nativeResult = await testContextFeaturesWithRealScenario(9333, 'Native CDP');
87
- const tunnelResult = await testContextFeaturesWithRealScenario(9221, 'CDP Tunnel');
88
-
89
- console.log('\n' + '='.repeat(60));
90
- console.log('COMPARISON RESULTS');
91
- console.log('='.repeat(60));
92
- console.log(`Native CDP (port 9333): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
93
- console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
94
-
95
- if (nativeResult && tunnelResult) {
96
- console.log('\n✓ Both implementations behave identically!');
97
- } else if (nativeResult && !tunnelResult) {
98
- console.log('\n✗ CDP Tunnel has issues with Context-level features!');
99
- } else {
100
- console.log('\n✗ Native CDP has issues (unexpected)!');
101
- }
102
- }
103
-
104
- main();
@@ -1,98 +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 = 9700;
7
-
8
- async function testWithLogs(label, port) {
9
- serverPort++;
10
- const currentPort = serverPort;
11
-
12
- console.log(`Testing ${label} (port ${port})`);
13
-
14
- const htmlContent1 = `
15
- <!DOCTYPE html>
16
- <html>
17
- <head><title>Page 1</title></head>
18
- <body>
19
- <h1>Page 1 - Click the link below</h1>
20
- <a href="page2.html" target="_blank" id="link1">Open New Tab</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 - New Tab Opened!</h1>
31
- </body>
32
- </html>
33
- `;
34
-
35
- const serverDir = '/tmp/test-server-logs';
36
- if (!fs.existsSync(serverDir)) {
37
- fs.mkdirSync(serverDir, { recursive: true });
38
- }
39
- fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
40
- fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
41
-
42
- const server = http.createServer((req, res) => {
43
- let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
44
- if (fs.existsSync(filePath)) {
45
- const content = fs.readFileSync(filePath);
46
- res.writeHead(200, { 'Content-Type': 'text/html' });
47
- res.end(content);
48
- } else {
49
- res.writeHead(404);
50
- res.end('Not found');
51
- }
52
- });
53
-
54
- await new Promise(resolve => server.listen(currentPort, resolve));
55
-
56
- console.log('\n=== Connecting to CDP Tunnel ===');
57
- console.log('>>> Check proxy server console for "[CLIENT CONNECTED]" <<<\n');
58
-
59
- const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
60
- console.log('Connected!');
61
-
62
- console.log('\n=== Creating context and page ===');
63
- const context = await browser.newContext();
64
- const page1 = await context.newPage();
65
- await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
66
- console.log(`Page loaded: ${page1.url()}`);
67
-
68
- console.log('\n=== Waiting 5 seconds - check if client disconnects ===');
69
- console.log('>>> Check proxy server console for "[CLIENT DISCONNECTED]" <<<\n');
70
- await new Promise(r => setTimeout(r, 5000));
71
-
72
- console.log('\n=== Clicking link ===');
73
- await page1.click('#link1');
74
-
75
- console.log('\n=== Waiting 5 more seconds ===');
76
- await new Promise(r => setTimeout(r, 5000));
77
-
78
- console.log('\n=== Checking pages ===');
79
- const allPages = context.pages();
80
- console.log(`Pages: ${allPages.length}`);
81
-
82
- server.close();
83
- await browser.close();
84
- }
85
-
86
- async function main() {
87
- console.log('=== Test - Check Proxy Server Logs ===\n');
88
- console.log('INSTRUCTIONS:');
89
- console.log('1. Check proxy server console (where you ran npm start)');
90
- console.log('2. Look for: [CLIENT CONNECTED] and [CLIENT DISCONNECTED]');
91
- console.log('3. Tell me when the client disconnects!\n');
92
-
93
- await testWithLogs('CDP Tunnel', 9221);
94
-
95
- process.exit(0);
96
- }
97
-
98
- main();
@@ -1,91 +0,0 @@
1
- const WebSocket = require('ws');
2
-
3
- async function testWithSessionId() {
4
- console.log('[Session Test] Testing with proper sessionId handling...\n');
5
-
6
- const ws = new WebSocket('ws://localhost:9221/client');
7
-
8
- let requestId = 1;
9
- let currentSessionId = null;
10
-
11
- const sendRequest = (method, params = {}, sessionId = null) => {
12
- const id = requestId++;
13
- const msg = { id, method, params };
14
- if (sessionId) {
15
- msg.sessionId = sessionId;
16
- }
17
- console.log(`[SEND] #${id}: ${method}${sessionId ? ` (session: ${sessionId.substring(0, 8)})` : ''}`);
18
- ws.send(JSON.stringify(msg));
19
- return id;
20
- };
21
-
22
- ws.on('open', async () => {
23
- console.log('[Session Test] Connected!\n');
24
-
25
- console.log('Step 1: Enable Target domain');
26
- sendRequest('Target.setDiscoverTargets', { discover: true });
27
-
28
- await sleep(500);
29
-
30
- console.log('\nStep 2: Get all targets');
31
- sendRequest('Target.getTargets');
32
-
33
- await sleep(1000);
34
-
35
- console.log('\nStep 3: Attach to first page target');
36
- sendRequest('Target.attachToTarget', {
37
- targetId: '4724AF3A60A419ECDEC2002A153733A2', // 百度首页
38
- flatten: true
39
- });
40
-
41
- await sleep(1000);
42
- });
43
-
44
- ws.on('message', (data) => {
45
- try {
46
- const msg = JSON.parse(data.toString());
47
-
48
- if (msg.id) {
49
- console.log(`[RECV] #${msg.id}:`, JSON.stringify(msg, null, 2).substring(0, 400));
50
-
51
- if (msg.result && msg.result.sessionId) {
52
- currentSessionId = msg.result.sessionId;
53
- console.log(`\n*** Got sessionId: ${currentSessionId.substring(0, 8)} ***\n`);
54
-
55
- setTimeout(async () => {
56
- console.log('Step 4: Enable Page domain on attached target (with sessionId)');
57
- sendRequest('Page.enable', {}, currentSessionId);
58
-
59
- await sleep(500);
60
-
61
- console.log('\nStep 5: Navigate the page (with sessionId)');
62
- sendRequest('Page.navigate', { url: 'https://www.example.com' }, currentSessionId);
63
-
64
- await sleep(2000);
65
-
66
- console.log('\n[Session Test] Test completed');
67
- ws.close();
68
- process.exit(0);
69
- }, 500);
70
- }
71
- } else if (msg.method) {
72
- console.log(`[EVENT] ${msg.method}:`, {
73
- sessionId: msg.sessionId?.substring(0, 8) || 'none',
74
- params: JSON.stringify(msg.params).substring(0, 100)
75
- });
76
- }
77
- } catch (e) {
78
- console.log('[RECV] Raw:', data.toString().substring(0, 100));
79
- }
80
- });
81
-
82
- ws.on('error', (err) => {
83
- console.error('[ERROR]', err.message);
84
- });
85
- }
86
-
87
- function sleep(ms) {
88
- return new Promise(resolve => setTimeout(resolve, ms));
89
- }
90
-
91
- testWithSessionId();
@@ -1,44 +0,0 @@
1
- const { chromium } = require('playwright');
2
-
3
- async function testSimpleCDPGroups() {
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
- // 等待一段时间
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
- // 等待一段时间
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. 应该创建了一个名为"CDP-{客户端ID}"的标签组');
33
- console.log('2. 两个标签页应该被添加到该组中');
34
-
35
- // 不关闭浏览器,让用户手动检查
36
- console.log('\n测试脚本完成,浏览器连接保持打开状态,请手动检查标签组。');
37
- console.log('按Ctrl+C退出脚本...');
38
-
39
- } catch (error) {
40
- console.error('测试过程中出现错误:', error);
41
- }
42
- }
43
-
44
- testSimpleCDPGroups();