Add 7 new init scripts to cover WebGL fingerprinting, missing Chrome APIs, permissions behavior, CDP artifacts, and HeadlessChrome UA string. Enable Chromium's new headless mode (Channel: "chromium") when stealth is active to use the full UI layer that is harder to detect. Closes #58 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
171 lines
4.7 KiB
Go
171 lines
4.7 KiB
Go
package extractor
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestMergeOptions_StealthDefault(t *testing.T) {
|
|
base := BrowserOptions{Stealth: Bool(true)}
|
|
got := mergeOptions(base, nil)
|
|
if got.Stealth == nil || !*got.Stealth {
|
|
t.Fatal("expected stealth to default to true")
|
|
}
|
|
}
|
|
|
|
func TestMergeOptions_StealthOverrideFalse(t *testing.T) {
|
|
base := BrowserOptions{Stealth: Bool(true)}
|
|
got := mergeOptions(base, []BrowserOptions{{Stealth: Bool(false)}})
|
|
if got.Stealth == nil || *got.Stealth {
|
|
t.Fatal("expected stealth to be overridden to false")
|
|
}
|
|
}
|
|
|
|
func TestMergeOptions_LaunchArgsAppend(t *testing.T) {
|
|
base := BrowserOptions{LaunchArgs: []string{"--arg1"}}
|
|
got := mergeOptions(base, []BrowserOptions{{LaunchArgs: []string{"--arg2", "--arg3"}}})
|
|
if len(got.LaunchArgs) != 3 {
|
|
t.Fatalf("expected 3 launch args, got %d", len(got.LaunchArgs))
|
|
}
|
|
if got.LaunchArgs[0] != "--arg1" || got.LaunchArgs[1] != "--arg2" || got.LaunchArgs[2] != "--arg3" {
|
|
t.Fatalf("unexpected launch args: %v", got.LaunchArgs)
|
|
}
|
|
}
|
|
|
|
func TestMergeOptions_InitScriptsAppend(t *testing.T) {
|
|
base := BrowserOptions{InitScripts: []string{"script1"}}
|
|
got := mergeOptions(base, []BrowserOptions{{InitScripts: []string{"script2"}}})
|
|
if len(got.InitScripts) != 2 {
|
|
t.Fatalf("expected 2 init scripts, got %d", len(got.InitScripts))
|
|
}
|
|
if got.InitScripts[0] != "script1" || got.InitScripts[1] != "script2" {
|
|
t.Fatalf("unexpected init scripts: %v", got.InitScripts)
|
|
}
|
|
}
|
|
|
|
func TestMergeOptions_StealthNilDoesNotOverride(t *testing.T) {
|
|
base := BrowserOptions{Stealth: Bool(true)}
|
|
got := mergeOptions(base, []BrowserOptions{{Stealth: nil}})
|
|
if got.Stealth == nil || !*got.Stealth {
|
|
t.Fatal("expected stealth to remain true when override is nil")
|
|
}
|
|
}
|
|
|
|
func TestStealthChromiumArgs(t *testing.T) {
|
|
if len(stealthChromiumArgs) == 0 {
|
|
t.Fatal("expected at least one chromium stealth arg")
|
|
}
|
|
found := false
|
|
for _, arg := range stealthChromiumArgs {
|
|
if arg == "--disable-blink-features=AutomationControlled" {
|
|
found = true
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected --disable-blink-features=AutomationControlled in stealth chromium args")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts(t *testing.T) {
|
|
if len(stealthInitScripts) == 0 {
|
|
t.Fatal("expected at least one stealth init script")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_Count(t *testing.T) {
|
|
if len(stealthInitScripts) != 12 {
|
|
t.Fatalf("expected 12 stealth init scripts, got %d", len(stealthInitScripts))
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_WebGLSpoof(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "SwiftShader") || strings.Contains(s, "UNMASKED_RENDERER") || strings.Contains(s, "37446") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that spoofs WebGL renderer")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_ChromeApp(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "chrome.app") && strings.Contains(s, "chrome.csi") && strings.Contains(s, "chrome.loadTimes") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that stubs chrome.app, chrome.csi, and chrome.loadTimes")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_PermissionsQuery(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "permissions.query") && strings.Contains(s, "notifications") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that overrides permissions.query for notifications")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_Notification(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "Notification") && strings.Contains(s, "requestPermission") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that stubs Notification constructor")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_NavigatorConnection(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "connection") && strings.Contains(s, "effectiveType") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that stubs navigator.connection")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_CDPCleanup(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "cdc_") && strings.Contains(s, "delete") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that cleans up CDP artifacts")
|
|
}
|
|
}
|
|
|
|
func TestStealthInitScripts_UserAgentStrip(t *testing.T) {
|
|
found := false
|
|
for _, s := range stealthInitScripts {
|
|
if strings.Contains(s, "HeadlessChrome") && strings.Contains(s, "userAgent") {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
if !found {
|
|
t.Fatal("expected a stealth script that strips HeadlessChrome from user agent")
|
|
}
|
|
}
|