Files
VisionL/packages/daemon/src/__tests__/stealth-navigator.test.ts
T

137 lines
4.8 KiB
TypeScript

// Integration tests for injectNavigatorStealth / 隐身导航注入集成测试
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { chromium } from 'playwright-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import type { Browser, BrowserContext } from 'playwright';
import type { FingerprintProfile } from '@visionl/core';
import { injectNavigatorStealth } from '../stealth/navigator.js';
chromium.use(StealthPlugin());
const integration = process.env.VISIONL_INTEGRATION === '1' ? describe : describe.skip;
const testProfile: FingerprintProfile = {
id: 'fp_stealth_nav',
name: 'Stealth Navigator Test',
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
platform: 'Win32',
languages: ['en-US', 'en'],
acceptLanguage: 'en-US,en;q=0.9',
screen: { width: 1920, height: 1080, colorDepth: 24, pixelRatio: 1 },
viewport: { width: 1280, height: 720 },
webgl: { vendor: 'Google Inc.', renderer: 'ANGLE (NVIDIA GeForce RTX 3060)' },
timezone: 'America/New_York',
permissions: {
notifications: 'denied',
geolocation: 'granted',
camera: 'denied',
microphone: 'denied',
},
behavior: {
mouseMoveDelay: { min: 50, max: 150 },
keyPressDelay: { min: 80, max: 200 },
scrollStepDelay: { min: 30, max: 100 },
},
canvasNoise: { enabled: true, strength: 0.5 },
};
integration('injectNavigatorStealth', () => {
let browser: Browser;
let context: BrowserContext;
beforeAll(async () => {
browser = await chromium.launch({
headless: true,
args: ['--no-sandbox', '--disable-setuid-sandbox'],
});
});
afterAll(async () => {
if (context) await context.close();
if (browser) await browser.close();
});
it('should set navigator.webdriver to false', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const webdriver = await page.evaluate(() => navigator.webdriver);
expect(webdriver).toBe(false);
});
it('should override navigator.languages from profile', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const langs = await page.evaluate(() => navigator.languages);
expect(langs).toEqual(testProfile.languages);
});
it('should override navigator.platform from profile', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const platform = await page.evaluate(() => navigator.platform);
expect(platform).toBe(testProfile.platform);
});
it('should set navigator.vendor to "Google Inc."', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const vendor = await page.evaluate(() => navigator.vendor);
expect(vendor).toBe('Google Inc.');
});
it('should set navigator.productSub to "20030107"', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const productSub = await page.evaluate(() => navigator.productSub);
expect(productSub).toBe('20030107');
});
it('should inject navigator.connection if missing', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const connection = await page.evaluate(() => {
const c = (navigator as any).connection;
if (!c) return null;
return { downlink: c.downlink, effectiveType: c.effectiveType, rtt: c.rtt, saveData: c.saveData };
});
expect(connection).not.toBeNull();
expect(connection!.downlink).toBe(10);
expect(connection!.effectiveType).toBe('4g');
expect(connection!.rtt).toBe(50);
expect(connection!.saveData).toBe(false);
});
it('should keep navigator.plugins accessible', async () => {
context = await browser.newContext();
await injectNavigatorStealth(context, testProfile);
const page = await context.newPage();
await page.goto('about:blank');
const plugins = await page.evaluate(() => {
const p = navigator.plugins;
return { length: p.length, hasItem: typeof p.item === 'function', hasNamedItem: typeof p.namedItem === 'function' };
});
expect(typeof plugins.length).toBe('number');
expect(plugins.hasItem).toBe(true);
expect(plugins.hasNamedItem).toBe(true);
});
});