fix(stealth): 修复 headed 模式下 stealth 失效并统一策略

- 修复 launch 协议未透传 stealth 导致 --headed 下补丁失效的问题\n- 在 BrowserManager 引入 StealthPolicy,统一 local/CDP/provider 能力决策\n- 增加 launch 返回 stealth 状态并在 --debug 输出连接类型与能力\n- 补充 local/CDP 回归测试与 bot.sannysoft.com 自动检查脚本\n- 同步 README、CLI help、技能文档与 CDP 文档中的 stealth 能力矩阵
This commit is contained in:
leeguooooo
2026-02-24 12:18:47 +09:00
parent 2fe7394dbe
commit 8932f28926
15 changed files with 985 additions and 89 deletions
+72
View File
@@ -53,6 +53,78 @@ describe('BrowserManager', () => {
expect(newBrowser.getBrowser()).toBeNull();
await newBrowser.close();
});
it('should report local stealth policy capabilities', async () => {
const testBrowser = new BrowserManager();
await testBrowser.launch({ headless: true, stealth: true });
const status = testBrowser.getStealthStatus('chromium');
expect(status.enabled).toBe(true);
expect(status.connectionKind).toBe('local');
expect(status.capabilities).toContain('chromium-launch-args');
expect(status.capabilities).toContain('context-init-scripts');
await testBrowser.close();
});
it('should apply init-script stealth policy for CDP connections', async () => {
const addInitScript = vi.fn().mockResolvedValue(undefined);
const mockPage = { url: () => 'http://example.com', on: vi.fn() };
const mockContext = {
pages: () => [mockPage],
on: vi.fn(),
setDefaultTimeout: vi.fn(),
addInitScript,
};
const mockBrowser = {
contexts: () => [mockContext],
close: vi.fn().mockResolvedValue(undefined),
isConnected: vi.fn(() => true),
};
const spy = vi.spyOn(chromium, 'connectOverCDP').mockResolvedValue(mockBrowser as any);
const cdpBrowser = new BrowserManager();
await cdpBrowser.launch({ cdpPort: 9222, stealth: true });
expect(addInitScript).toHaveBeenCalledTimes(1);
const status = cdpBrowser.getStealthStatus();
expect(status.enabled).toBe(true);
expect(status.connectionKind).toBe('cdp');
expect(status.capabilities).toContain('context-init-scripts');
expect(status.capabilities).not.toContain('chromium-launch-args');
await cdpBrowser.close();
spy.mockRestore();
});
it('should disable stealth capabilities when launch stealth is false in CDP mode', async () => {
const addInitScript = vi.fn().mockResolvedValue(undefined);
const mockPage = { url: () => 'http://example.com', on: vi.fn() };
const mockContext = {
pages: () => [mockPage],
on: vi.fn(),
setDefaultTimeout: vi.fn(),
addInitScript,
};
const mockBrowser = {
contexts: () => [mockContext],
close: vi.fn().mockResolvedValue(undefined),
isConnected: vi.fn(() => true),
};
const spy = vi.spyOn(chromium, 'connectOverCDP').mockResolvedValue(mockBrowser as any);
const cdpBrowser = new BrowserManager();
await cdpBrowser.launch({ cdpPort: 9222, stealth: false });
expect(addInitScript).not.toHaveBeenCalled();
const status = cdpBrowser.getStealthStatus();
expect(status.enabled).toBe(false);
expect(status.connectionKind).toBe('cdp');
expect(status.capabilities).toEqual([]);
await cdpBrowser.close();
spy.mockRestore();
});
});
describe('stale session recovery (all pages closed)', () => {