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-simple-context.js
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
|
|
3
|
-
async function testContextFeaturesSimple(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
|
-
});
|
|
33
|
-
|
|
34
|
-
console.log(`[${label}] Creating first page...`);
|
|
35
|
-
const page1 = await context.newPage();
|
|
36
|
-
await page1.goto('data:text/html,<html><body><h1>Page 1</h1></body></html>');
|
|
37
|
-
|
|
38
|
-
console.log(`[${label}] Testing in first page...`);
|
|
39
|
-
const result1 = await page1.evaluate(async () => {
|
|
40
|
-
try {
|
|
41
|
-
const funcResult = await window.myCustomFunction('page1');
|
|
42
|
-
const initResult = window.myInitScript;
|
|
43
|
-
return { success: true, funcResult, initResult };
|
|
44
|
-
} catch (e) {
|
|
45
|
-
return { success: false, error: e.message };
|
|
46
|
-
}
|
|
47
|
-
});
|
|
48
|
-
console.log(`[${label}] First page result:`, result1);
|
|
49
|
-
|
|
50
|
-
if (!result1.success) {
|
|
51
|
-
console.log(`[${label}] ✗ First page test failed!`);
|
|
52
|
-
await browser.close();
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
console.log(`[${label}] Creating second page (simulating new tab)...`);
|
|
57
|
-
const page2 = await context.newPage();
|
|
58
|
-
await page2.goto('data:text/html,<html><body><h1>Page 2</h1></body></html>');
|
|
59
|
-
|
|
60
|
-
console.log(`[${label}] Testing in second page (should persist)...`);
|
|
61
|
-
const result2 = await page2.evaluate(async () => {
|
|
62
|
-
try {
|
|
63
|
-
const funcResult = await window.myCustomFunction('page2');
|
|
64
|
-
const initResult = window.myInitScript;
|
|
65
|
-
return { success: true, funcResult, initResult };
|
|
66
|
-
} catch (e) {
|
|
67
|
-
return { success: false, error: e.message };
|
|
68
|
-
}
|
|
69
|
-
});
|
|
70
|
-
console.log(`[${label}] Second page result:`, result2);
|
|
71
|
-
|
|
72
|
-
if (!result2.success) {
|
|
73
|
-
console.log(`[${label}] ✗ Second page test failed - Context features not persisted!`);
|
|
74
|
-
await browser.close();
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
console.log(`[${label}] Creating third page...`);
|
|
79
|
-
const page3 = await context.newPage();
|
|
80
|
-
await page3.goto('data:text/html,<html><body><h1>Page 3</h1></body></html>');
|
|
81
|
-
|
|
82
|
-
console.log(`[${label}] Testing in third page...`);
|
|
83
|
-
const result3 = await page3.evaluate(async () => {
|
|
84
|
-
try {
|
|
85
|
-
const funcResult = await window.myCustomFunction('page3');
|
|
86
|
-
const initResult = window.myInitScript;
|
|
87
|
-
return { success: true, funcResult, initResult };
|
|
88
|
-
} catch (e) {
|
|
89
|
-
return { success: false, error: e.message };
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
console.log(`[${label}] Third page result:`, result3);
|
|
93
|
-
|
|
94
|
-
if (!result3.success) {
|
|
95
|
-
console.log(`[${label}] ✗ Third page test failed!`);
|
|
96
|
-
await browser.close();
|
|
97
|
-
return false;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
console.log(`[${label}] ✓ All tests passed!`);
|
|
101
|
-
|
|
102
|
-
await browser.close();
|
|
103
|
-
|
|
104
|
-
return true;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.error(`[${label}] ✗ Error:`, error.message);
|
|
107
|
-
console.error(`[${label}] Stack:`, error.stack);
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
async function main() {
|
|
113
|
-
console.log('Testing Context-level features persistence across tabs');
|
|
114
|
-
console.log('This tests if exposeFunction and addInitScript persist across different pages\n');
|
|
115
|
-
|
|
116
|
-
const nativeResult = await testContextFeaturesSimple(9333, 'Native CDP');
|
|
117
|
-
const tunnelResult = await testContextFeaturesSimple(9221, 'CDP Tunnel');
|
|
118
|
-
|
|
119
|
-
console.log('\n' + '='.repeat(60));
|
|
120
|
-
console.log('COMPARISON RESULTS');
|
|
121
|
-
console.log('='.repeat(60));
|
|
122
|
-
console.log(`Native CDP (port 9333): ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
123
|
-
console.log(`CDP Tunnel (port 9221): ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
124
|
-
|
|
125
|
-
if (nativeResult && tunnelResult) {
|
|
126
|
-
console.log('\n✓ Both implementations behave identically!');
|
|
127
|
-
console.log('✓ Context-level features (exposeFunction/addInitScript) work correctly!');
|
|
128
|
-
} else if (nativeResult && !tunnelResult) {
|
|
129
|
-
console.log('\n✗ CDP Tunnel has issues with Context-level features!');
|
|
130
|
-
} else if (!nativeResult && tunnelResult) {
|
|
131
|
-
console.log('\n? CDP Tunnel works but Native CDP has issues (unexpected)!');
|
|
132
|
-
} else {
|
|
133
|
-
console.log('\n✗ Both implementations have issues!');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
main();
|
package/test-tab-group-simple.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// 简单测试标签分组功能
|
|
2
|
-
// 复制到Chrome扩展的控制台中运行
|
|
3
|
-
|
|
4
|
-
console.log('=== 测试标签分组功能 ===');
|
|
5
|
-
|
|
6
|
-
// 创建第一个标签页
|
|
7
|
-
chrome.tabs.create({ url: 'https://www.baidu.com/', active: false }, function(tab1) {
|
|
8
|
-
console.log('创建第一个标签页:', tab1.id);
|
|
9
|
-
|
|
10
|
-
// 等待2秒后创建组
|
|
11
|
-
setTimeout(function() {
|
|
12
|
-
console.log('尝试创建标签组...');
|
|
13
|
-
|
|
14
|
-
// 创建新组
|
|
15
|
-
chrome.tabs.group({ tabIds: tab1.id }, function(groupId) {
|
|
16
|
-
if (chrome.runtime.lastError) {
|
|
17
|
-
console.error('创建组失败:', chrome.runtime.lastError.message);
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
console.log('创建的组ID:', groupId);
|
|
22
|
-
|
|
23
|
-
// 更新组的标题和颜色
|
|
24
|
-
chrome.tabGroups.update(groupId, {
|
|
25
|
-
title: 'CDP-Test',
|
|
26
|
-
color: 'blue'
|
|
27
|
-
}, function(group) {
|
|
28
|
-
if (chrome.runtime.lastError) {
|
|
29
|
-
console.error('更新组失败:', chrome.runtime.lastError.message);
|
|
30
|
-
} else {
|
|
31
|
-
console.log('组创建并更新成功:', group);
|
|
32
|
-
|
|
33
|
-
// 创建第二个标签页
|
|
34
|
-
chrome.tabs.create({ url: 'https://www.google.com/', active: false }, function(tab2) {
|
|
35
|
-
console.log('创建第二个标签页:', tab2.id);
|
|
36
|
-
|
|
37
|
-
// 等待2秒后添加到组
|
|
38
|
-
setTimeout(function() {
|
|
39
|
-
console.log('将第二个标签页添加到组...');
|
|
40
|
-
chrome.tabs.group({ tabIds: tab2.id, groupId: groupId }, function(resultGroupId) {
|
|
41
|
-
if (chrome.runtime.lastError) {
|
|
42
|
-
console.error('添加标签页到组失败:', chrome.runtime.lastError.message);
|
|
43
|
-
} else {
|
|
44
|
-
console.log('标签页已添加到组:', resultGroupId);
|
|
45
|
-
|
|
46
|
-
// 查询所有标签组
|
|
47
|
-
chrome.tabGroups.query({}, function(groups) {
|
|
48
|
-
console.log('所有标签组:', groups);
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}, 2000);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
}, 2000);
|
|
58
|
-
});
|
package/test-tab-grouping.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const { chromium } = require('playwright');
|
|
2
|
-
|
|
3
|
-
async function testTabGrouping() {
|
|
4
|
-
console.log('Testing tab grouping functionality...');
|
|
5
|
-
|
|
6
|
-
// Connect to CDP tunnel
|
|
7
|
-
const browser = await chromium.connectOverCDP('http://localhost:9221');
|
|
8
|
-
|
|
9
|
-
try {
|
|
10
|
-
// Create a new page
|
|
11
|
-
console.log('Creating new page...');
|
|
12
|
-
const page = await browser.newPage();
|
|
13
|
-
|
|
14
|
-
// Navigate to Baidu
|
|
15
|
-
console.log('Navigating to Baidu...');
|
|
16
|
-
await page.goto('https://www.baidu.com/');
|
|
17
|
-
|
|
18
|
-
// Wait for a moment to ensure the page is loaded
|
|
19
|
-
await page.waitForTimeout(2000);
|
|
20
|
-
|
|
21
|
-
console.log('Page created successfully. Check if it is in the "lo" group.');
|
|
22
|
-
|
|
23
|
-
// Create another page to test multiple pages
|
|
24
|
-
console.log('Creating second page...');
|
|
25
|
-
const page2 = await browser.newPage();
|
|
26
|
-
await page2.goto('https://www.google.com/');
|
|
27
|
-
await page2.waitForTimeout(2000);
|
|
28
|
-
|
|
29
|
-
console.log('Second page created. Check if both pages are in the "lo" group.');
|
|
30
|
-
|
|
31
|
-
// Keep the browser open for inspection
|
|
32
|
-
console.log('Test completed. Check the Chrome browser for tab groups.');
|
|
33
|
-
|
|
34
|
-
// Wait for user input to close
|
|
35
|
-
console.log('Press Enter to close...');
|
|
36
|
-
process.stdin.resume();
|
|
37
|
-
process.stdin.on('data', async () => {
|
|
38
|
-
await browser.close();
|
|
39
|
-
process.exit(0);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
} catch (error) {
|
|
43
|
-
console.error('Error during test:', error);
|
|
44
|
-
await browser.close();
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
testTabGrouping();
|
package/test-three-pages.js
DELETED
|
@@ -1,192 +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
|
-
let serverPort = 9050;
|
|
7
|
-
|
|
8
|
-
async function testThreePages(port, label) {
|
|
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
|
-
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" id="link1">Go to Page 2 (same tab)</a>
|
|
26
|
-
<button id="btn" onclick="window.getCounter().then(r => document.getElementById('result').innerText = r)">Get Counter</button>
|
|
27
|
-
<div id="result">-</div>
|
|
28
|
-
</body>
|
|
29
|
-
</html>
|
|
30
|
-
`;
|
|
31
|
-
|
|
32
|
-
const htmlContent2 = `
|
|
33
|
-
<!DOCTYPE html>
|
|
34
|
-
<html>
|
|
35
|
-
<head><title>Page 2</title></head>
|
|
36
|
-
<body>
|
|
37
|
-
<h1>Page 2</h1>
|
|
38
|
-
<a href="page3.html" target="_blank" id="link2">Open Page 3 (new tab)</a>
|
|
39
|
-
<button id="btn" onclick="window.getCounter().then(r => document.getElementById('result').innerText = r)">Get Counter</button>
|
|
40
|
-
<div id="result">-</div>
|
|
41
|
-
</body>
|
|
42
|
-
</html>
|
|
43
|
-
`;
|
|
44
|
-
|
|
45
|
-
const htmlContent3 = `
|
|
46
|
-
<!DOCTYPE html>
|
|
47
|
-
<html>
|
|
48
|
-
<head><title>Page 3</title></head>
|
|
49
|
-
<body>
|
|
50
|
-
<h1>Page 3 - New Tab</h1>
|
|
51
|
-
<button id="btn" onclick="window.getCounter().then(r => document.getElementById('result').innerText = r)">Get Counter</button>
|
|
52
|
-
<div id="result">-</div>
|
|
53
|
-
</body>
|
|
54
|
-
</html>
|
|
55
|
-
`;
|
|
56
|
-
|
|
57
|
-
const serverDir = '/tmp/test-three-pages';
|
|
58
|
-
if (!fs.existsSync(serverDir)) {
|
|
59
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
60
|
-
}
|
|
61
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
62
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
63
|
-
fs.writeFileSync(path.join(serverDir, 'page3.html'), htmlContent3);
|
|
64
|
-
|
|
65
|
-
const http = require('http');
|
|
66
|
-
const server = http.createServer((req, res) => {
|
|
67
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
68
|
-
if (fs.existsSync(filePath)) {
|
|
69
|
-
const content = fs.readFileSync(filePath);
|
|
70
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
71
|
-
res.end(content);
|
|
72
|
-
} else {
|
|
73
|
-
res.writeHead(404);
|
|
74
|
-
res.end('Not found');
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
79
|
-
console.log(`[${label}] Test server on port ${currentPort}`);
|
|
80
|
-
|
|
81
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
82
|
-
console.log(`[${label}] Connected!`);
|
|
83
|
-
|
|
84
|
-
const context = await browser.newContext();
|
|
85
|
-
console.log(`[${label}] Context created`);
|
|
86
|
-
|
|
87
|
-
await context.exposeFunction('getCounter', () => {
|
|
88
|
-
sharedState.counter += 1;
|
|
89
|
-
console.log(`[${label}] getCounter called -> counter: ${sharedState.counter}`);
|
|
90
|
-
return sharedState.counter;
|
|
91
|
-
});
|
|
92
|
-
console.log(`[${label}] exposeFunction registered`);
|
|
93
|
-
|
|
94
|
-
const page1 = await context.newPage();
|
|
95
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
96
|
-
console.log(`[${label}] Page 1 loaded: ${page1.url()}`);
|
|
97
|
-
|
|
98
|
-
const r1 = await page1.evaluate(() => window.getCounter());
|
|
99
|
-
console.log(`[${label}] Page 1 counter: ${r1} (expect 1)`);
|
|
100
|
-
|
|
101
|
-
console.log(`[${label}] --- Step 1: Click link in Page 1 -> navigate to Page 2 (same tab) ---`);
|
|
102
|
-
await Promise.all([
|
|
103
|
-
page1.waitForURL('**/page2.html'),
|
|
104
|
-
page1.click('#link1')
|
|
105
|
-
]);
|
|
106
|
-
console.log(`[${label}] Page 1 navigated to Page 2: ${page1.url()}`);
|
|
107
|
-
|
|
108
|
-
const r2 = await page1.evaluate(() => window.getCounter());
|
|
109
|
-
console.log(`[${label}] Page 2 counter: ${r2} (expect 2)`);
|
|
110
|
-
|
|
111
|
-
console.log(`[${label}] --- Step 2: Click link in Page 2 -> open Page 3 (new tab) ---`);
|
|
112
|
-
const [page3] = await Promise.all([
|
|
113
|
-
context.waitForEvent('page', { timeout: 10000 }),
|
|
114
|
-
page1.click('#link2')
|
|
115
|
-
]);
|
|
116
|
-
await page3.waitForLoadState('domcontentloaded');
|
|
117
|
-
console.log(`[${label}] Page 3 opened in new tab: ${page3.url()}`);
|
|
118
|
-
|
|
119
|
-
const r3 = await page3.evaluate(() => window.getCounter());
|
|
120
|
-
console.log(`[${label}] Page 3 counter: ${r3} (expect 3)`);
|
|
121
|
-
|
|
122
|
-
console.log(`[${label}] --- Step 3: Verify all pages ---`);
|
|
123
|
-
const allPages = context.pages();
|
|
124
|
-
console.log(`[${label}] Total pages in context: ${allPages.length} (expect 2)`);
|
|
125
|
-
|
|
126
|
-
const r2again = await page1.evaluate(() => window.getCounter());
|
|
127
|
-
console.log(`[${label}] Page 2 counter again: ${r2again} (expect 4)`);
|
|
128
|
-
|
|
129
|
-
const r3again = await page3.evaluate(() => window.getCounter());
|
|
130
|
-
console.log(`[${label}] Page 3 counter again: ${r3again} (expect 5)`);
|
|
131
|
-
|
|
132
|
-
const success = r1 === 1 && r2 === 2 && r3 === 3 && r2again === 4 && r3again === 5;
|
|
133
|
-
|
|
134
|
-
server.close();
|
|
135
|
-
|
|
136
|
-
if (success) {
|
|
137
|
-
console.log(`[${label}] ✓ PASS! Counter: ${r1} -> ${r2} -> ${r3} -> ${r2again} -> ${r3again}`);
|
|
138
|
-
} else {
|
|
139
|
-
console.log(`[${label}] ✗ FAIL! Expected: 1,2,3,4,5 Got: ${r1},${r2},${r3},${r2again},${r3again}`);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
await browser.close();
|
|
143
|
-
return success;
|
|
144
|
-
|
|
145
|
-
} catch (error) {
|
|
146
|
-
console.error(`[${label}] ✗ Error:`, error.message);
|
|
147
|
-
return false;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
async function main() {
|
|
152
|
-
console.log('Testing: Page1 -> navigate to Page2 (same tab) -> open Page3 (new tab)');
|
|
153
|
-
console.log('Counter: 1 -> 2 -> 3 -> 4 -> 5 (shared state via exposeFunction)\n');
|
|
154
|
-
|
|
155
|
-
console.log('Step 1: Starting Chromium on port 9230...');
|
|
156
|
-
const chromiumProcess = spawn('/Applications/Chromium.app/Contents/MacOS/Chromium', [
|
|
157
|
-
'--remote-debugging-port=9230',
|
|
158
|
-
'--user-data-dir=/tmp/chromium-test-three',
|
|
159
|
-
'--no-first-run',
|
|
160
|
-
'--no-default-browser-check'
|
|
161
|
-
], { detached: true, stdio: 'ignore' });
|
|
162
|
-
|
|
163
|
-
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
164
|
-
|
|
165
|
-
console.log('\nStep 2: Testing Native CDP...');
|
|
166
|
-
const nativeResult = await testThreePages(9230, 'Native CDP');
|
|
167
|
-
|
|
168
|
-
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
169
|
-
|
|
170
|
-
console.log('\nStep 3: Testing CDP Tunnel...');
|
|
171
|
-
const tunnelResult = await testThreePages(9221, 'CDP Tunnel');
|
|
172
|
-
|
|
173
|
-
try { process.kill(-chromiumProcess.pid); } catch (e) {}
|
|
174
|
-
|
|
175
|
-
console.log('\n' + '='.repeat(60));
|
|
176
|
-
console.log(`Native CDP: ${nativeResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
177
|
-
console.log(`CDP Tunnel: ${tunnelResult ? '✓ PASS' : '✗ FAIL'}`);
|
|
178
|
-
|
|
179
|
-
if (nativeResult && tunnelResult) {
|
|
180
|
-
console.log('\n✓ Both work identically!');
|
|
181
|
-
} else if (!nativeResult && tunnelResult) {
|
|
182
|
-
console.log('\n✓ CDP Tunnel works! Native CDP has limitations.');
|
|
183
|
-
} else if (nativeResult && !tunnelResult) {
|
|
184
|
-
console.log('\n✗ CDP Tunnel has issues!');
|
|
185
|
-
} else {
|
|
186
|
-
console.log('\n✗ Both have issues!');
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
process.exit(0);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
main();
|
package/test-wait-for-page.js
DELETED
|
@@ -1,95 +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 = 10100;
|
|
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-wait';
|
|
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] Setting up page event listener...');
|
|
65
|
-
let newPageReceived = false;
|
|
66
|
-
context.on('page', (page) => {
|
|
67
|
-
newPageReceived = true;
|
|
68
|
-
console.log('[EVENT] New page created:', page.url());
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
console.log('[TEST] Clicking link and waiting for new page...');
|
|
72
|
-
try {
|
|
73
|
-
const [newPage] = await Promise.all([
|
|
74
|
-
context.waitForEvent('page', { timeout: 5000 }),
|
|
75
|
-
page1.click('#link1')
|
|
76
|
-
]);
|
|
77
|
-
console.log('[TEST] New page captured:', newPage.url());
|
|
78
|
-
} catch (e) {
|
|
79
|
-
console.log('[TEST] Timeout waiting for new page:', e.message);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
console.log('\n[TEST] Checking pages...');
|
|
83
|
-
const allPages = context.pages();
|
|
84
|
-
console.log(`[TEST] Total pages: ${allPages.length}`);
|
|
85
|
-
allPages.forEach((p, i) => {
|
|
86
|
-
console.log(` Page ${i}: ${p.url()}`);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
console.log(`\n[TEST] New page event received: ${newPageReceived}`);
|
|
90
|
-
|
|
91
|
-
server.close();
|
|
92
|
-
await browser.close();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
test().then(() => process.exit(0));
|
package/test-with-logs.js
DELETED
|
@@ -1,118 +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 = 9400;
|
|
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('Please check Chrome extension popup for logs');
|
|
15
|
-
console.log('='.repeat(60));
|
|
16
|
-
|
|
17
|
-
const htmlContent1 = `
|
|
18
|
-
<!DOCTYPE html>
|
|
19
|
-
<html>
|
|
20
|
-
<head><title>Page 1</title></head>
|
|
21
|
-
<body>
|
|
22
|
-
<h1>Page 1 - Click the link below</h1>
|
|
23
|
-
<a href="page2.html" target="_blank" id="link1">Open New Tab</a>
|
|
24
|
-
</body>
|
|
25
|
-
</html>
|
|
26
|
-
`;
|
|
27
|
-
|
|
28
|
-
const htmlContent2 = `
|
|
29
|
-
<!DOCTYPE html>
|
|
30
|
-
<html>
|
|
31
|
-
<head><title>Page 2</title></head>
|
|
32
|
-
<body>
|
|
33
|
-
<h1>Page 2 - New Tab Opened!</h1>
|
|
34
|
-
</body>
|
|
35
|
-
</html>
|
|
36
|
-
`;
|
|
37
|
-
|
|
38
|
-
const serverDir = '/tmp/test-logs';
|
|
39
|
-
if (!fs.existsSync(serverDir)) {
|
|
40
|
-
fs.mkdirSync(serverDir, { recursive: true });
|
|
41
|
-
}
|
|
42
|
-
fs.writeFileSync(path.join(serverDir, 'page1.html'), htmlContent1);
|
|
43
|
-
fs.writeFileSync(path.join(serverDir, 'page2.html'), htmlContent2);
|
|
44
|
-
|
|
45
|
-
const server = http.createServer((req, res) => {
|
|
46
|
-
let filePath = path.join(serverDir, req.url === '/' ? 'page1.html' : req.url);
|
|
47
|
-
if (fs.existsSync(filePath)) {
|
|
48
|
-
const content = fs.readFileSync(filePath);
|
|
49
|
-
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
50
|
-
res.end(content);
|
|
51
|
-
} else {
|
|
52
|
-
res.writeHead(404);
|
|
53
|
-
res.end('Not found');
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
await new Promise(resolve => server.listen(currentPort, resolve));
|
|
58
|
-
console.log(`[${label}] Server: http://localhost:${currentPort}`);
|
|
59
|
-
|
|
60
|
-
console.log(`\n[${label}] Step 1: Connecting to CDP Tunnel...`);
|
|
61
|
-
const browser = await chromium.connectOverCDP(`http://localhost:${port}`);
|
|
62
|
-
console.log(`[${label}] Connected!`);
|
|
63
|
-
|
|
64
|
-
console.log(`\n[${label}] Step 2: Creating context...`);
|
|
65
|
-
const context = await browser.newContext();
|
|
66
|
-
|
|
67
|
-
console.log(`\n[${label}] Step 3: Creating first page...`);
|
|
68
|
-
const page1 = await context.newPage();
|
|
69
|
-
await page1.goto(`http://localhost:${currentPort}/page1.html`, { waitUntil: 'domcontentloaded' });
|
|
70
|
-
console.log(`[${label}] First page loaded: ${page1.url()}`);
|
|
71
|
-
|
|
72
|
-
console.log(`\n[${label}] Step 4: Waiting 2 seconds...`);
|
|
73
|
-
await new Promise(r => setTimeout(r, 2000));
|
|
74
|
-
|
|
75
|
-
console.log(`\n[${label}] Step 5: Clicking link to open new tab...`);
|
|
76
|
-
console.log(`[${label}] >>> PLEASE CHECK EXTENSION LOGS NOW <<<`);
|
|
77
|
-
await page1.click('#link1');
|
|
78
|
-
|
|
79
|
-
console.log(`\n[${label}] Step 6: Waiting 5 seconds for new tab...`);
|
|
80
|
-
await new Promise(r => setTimeout(r, 5000));
|
|
81
|
-
|
|
82
|
-
console.log(`\n[${label}] Step 7: Checking results...`);
|
|
83
|
-
const allPages = context.pages();
|
|
84
|
-
console.log(`[${label}] Total pages in context: ${allPages.length}`);
|
|
85
|
-
allPages.forEach((p, i) => {
|
|
86
|
-
console.log(` Page ${i}: ${p.url()}`);
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
if (allPages.length >= 2) {
|
|
90
|
-
console.log(`\n[${label}] ✓ SUCCESS! New tab was captured!`);
|
|
91
|
-
} else {
|
|
92
|
-
console.log(`\n[${label}] ✗ FAILED! New tab was NOT captured!`);
|
|
93
|
-
console.log(`[${label}] Please check extension logs and copy them here.`);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
server.close();
|
|
97
|
-
await browser.close();
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
async function main() {
|
|
101
|
-
console.log('=== Test with Log Monitoring ===');
|
|
102
|
-
console.log('Instructions:');
|
|
103
|
-
console.log('1. Open Chrome extension popup');
|
|
104
|
-
console.log('2. Click "Inspect" or open DevTools for the popup');
|
|
105
|
-
console.log('3. Watch the console logs');
|
|
106
|
-
console.log('4. When the test runs, copy the logs here\n');
|
|
107
|
-
|
|
108
|
-
await testWithLogs('CDP Tunnel', 9221);
|
|
109
|
-
|
|
110
|
-
console.log('\n' + '='.repeat(60));
|
|
111
|
-
console.log('Test completed!');
|
|
112
|
-
console.log('Please share the extension logs if the test failed.');
|
|
113
|
-
console.log('='.repeat(60));
|
|
114
|
-
|
|
115
|
-
process.exit(0);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
main();
|