'Selenium 4.x execute "Page.addScriptToEvaluateOnNewDocument" properly

I'm having a strange issue where I really cannot find a solution. My production website needs some testing and of course bot checking is enabled (not naming it).

Under my tests after using "Page.addScriptToEvaluateOnNewDocument", the result is not what I would expect.

  • If I visit the website directly in the current tab of Chromium, it won't pass the bot checks.
  • If I manually open a new tab and visit the website, it passes the bot checks.

At first I thought the scripts are not being executed in the current tab, however checking things that I overwrite shows that they are.

Using this little script I've taken from puppeteer is a PASS in both tabs:

async function test() {
  const results = {}

  async function test(name, fn) {
    const detectionPassed = await fn()
    if (detectionPassed) {
      console.log(`WARNING: Chrome headless detected via ${name}`)
    } else {
      console.log(`PASS: Chrome headless NOT detected via ${name}`)
    }
    results[name] = detectionPassed
  }

  await test('userAgent', _ => {
    return /HeadlessChrome/.test(window.navigator.userAgent)
  })

  // Detects the --enable-automation || --headless flags
  // Will return true in headful if --enable-automation is provided
  await test('navigator.webdriver present', _ => {
    return 'webdriver' in navigator
  })

  await test('window.chrome missing', _ => {
    return /Chrome/.test(window.navigator.userAgent) && !window.chrome
  })

  await test('permissions API', async _ => {
    const permissionStatus = await navigator.permissions.query({
      name: 'notifications'
    })
    // eslint-disable-next-line
    return (
      Notification.permission === 'denied' && // eslint-disable-line no-undef
      permissionStatus.state === 'prompt'
    )
  })

  await test('permissions API overriden', _ => {
    const permissions = window.navigator.permissions
    if (permissions.query.toString() !== 'function query() { [native code] }')
      return true
    if (
      permissions.query.toString.toString() !==
      'function toString() { [native code] }'
    )
      return true
    if (
      permissions.query.toString.hasOwnProperty('[[Handler]]') && // eslint-disable-line no-prototype-builtins
      permissions.query.toString.hasOwnProperty('[[Target]]') && // eslint-disable-line no-prototype-builtins
      permissions.query.toString.hasOwnProperty('[[IsRevoked]]') // eslint-disable-line no-prototype-builtins
    )
      return true
    if (permissions.hasOwnProperty('query')) return true // eslint-disable-line no-prototype-builtins
  })

  await test('navigator.plugins empty', _ => {
    return navigator.plugins.length === 0
  })

  await test('navigator.languages blank', _ => {
    return navigator.languages === ''
  })

  await test('iFrame for fresh window object', _ => {
    // evaluateOnNewDocument scripts don't apply within [srcdoc] (or [sandbox]) iframes
    // https://github.com/GoogleChrome/puppeteer/issues/1106#issuecomment-359313898
    const iframe = document.createElement('iframe')
    iframe.srcdoc = 'page intentionally left blank'
    document.body.appendChild(iframe)

    // Here we would need to rerun all tests with `iframe.contentWindow` as `window`
    // Example:
    return iframe.contentWindow.navigator.plugins.length === 0
  })

  // This detects that a devtools protocol agent is attached.
  // So it will also pass true in headful Chrome if the devtools window is attached
  await test('toString', _ => {
    let gotYou = 0
    const spooky = /./
    spooky.toString = function() {
      gotYou++
      return 'spooky'
    }
    console.debug(spooky)
    return gotYou > 1
  })

  return results
};
test();

My question would be, does "Page.addScriptToEvaluateOnNewDocument" really executes properly only in a new tab?

It really makes no sense to me why this is working in a new tab rather than in the current one.

Current setup and usage:

  • Chrome + Chrome Driver: v85.0.4183.83
  • Selenium Standalone: 4.1.1

Arguments:

  • --no-first-run --no-service-autorun --no-default-browser-check --disable-blink-features=AutomationControlled --window-size=1280,1024

excludeSwitches:

  • allow-pre-commit-input disable-background-networking disable-backgrounding-occluded-windows disable-client-side-phishing-detection disable-default-apps disable-hang-monitor disable-popup-blocking disable-prompt-on-repost disable-sync enable-automation enable-blink-features enable-logging password-store test-type use-mock-keychain

Preferences:

  • profile.default_content_setting_values.popups 1
  • profile.default_content_setting_values.cookies 1
  • profile.cookie_controls_mode 0

UseAutomationExtension: false

Please advise, I would upmost appreciate it.



Solution 1:[1]

I have found out the solution. It's just how it works. Hurray.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mecanik