Repository: nightwatchjs/nightwatch (js)

Issue:
setGeolocation not functional in headless mode
### Description of the bug/issue

When I run the setGeolocation example test in headless Chrome then it seems that the geolocation services are not enabled in the browser whilst when I do the same thing without the headless tag everything works as it should with the command

### Steps to reproduce

Run example here https://nightwatchjs.org/api/setGeolocation.html#apimethod-container
using headless Chrome

### Sample test

```node
describe('mock geolocation', function () {
  it('sets the geolocation to Tokyo, Japan and then resets it', () => {
    browser
      .setGeolocation({
        latitude: 35.689487,
        longitude: 139.691706,
        accuracy: 100
      })  // sets the geolocation to Tokyo, Japan
      .navigateTo('https://www.gps-coordinates.net/my-location')
      .pause(3000)
      .verify.textContains('span#addr', 'Tokyo Metropolitan Government Main Building 1, Midori-no-hashi, Nishi-Shinjuku 2-chome, Shinjuku, 163-8001, Japan')
      .setGeolocation()  // resets the geolocation
      .navigateTo('https://www.gps-coordinates.net/my-location')
      .pause(3000);
  });
});
```


### Command to run

```bash
node nightwatch test.js --headless
```


### Verbose Output

```fundamental
[mock geolocation] Test Suite
──────────────────────────────────────────────────────────
⠋ Starting ChromeDriver on auto-generated port...
 Starting ChromeDriver with server_path=C:\Users\*****\e2e_tests_upgrade - new marketplace\node_modules\chromedriver\lib\chromedriver\chromedriver.exe...
   Request POST /session  
   {
     desiredCapabilities: {
       browserName: 'chrome',
       javascriptEnabled: true,
       acceptSslCerts: true,
       browserTag: 'mttestcr',
       loggingPrefs: { browser: 'ALL' },
       'goog:chromeOptions': {
         w3c: false,
         args: [
           '--no-sandbox',
           '--ignore-certificate-errors',
           '--allow-insecure-localhost',
           '--headless',
           '--disable-gpu',
           '--disable-software-rasterizer',
           '--window-size=1920,925',
           '--log-level=3',
           '--disable-logging'
         ],
         prefs: { 'profile.default_content_setting_values.cookies': 1 }
       },
       name: 'mock geolocation'
     },
     capabilities: {
       alwaysMatch: {
         browserName: 'chrome',
         'goog:chromeOptions': {
           w3c: false,
           args: [
             '--no-sandbox',
             '--ignore-certificate-errors',
             '--allow-insecure-localhost',
             '--headless',
             '--disable-gpu',
             '--disable-software-rasterizer',
             '--window-size=1920,925',
             '--log-level=3',
             '--disable-logging'
           ],
           prefs: { 'profile.default_content_setting_values.cookies': 1 }
         }
       }
     }
⠹ Starting ChromeDriver on auto-generated port...

⠸ Starting ChromeDriver on auto-generated port...
⠦ Starting ChromeDriver on auto-generated port...
   Response 200 POST /session (500ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: {
       acceptInsecureCerts: false,
       acceptSslCerts: false,
       browserConnectionEnabled: false,
       browserName: 'chrome',
       chrome: {
         chromedriverVersion: '106.0.5249.61 (511755355844955cd3e264779baf0dd38212a4d0-refs/branch-heads/5249@{#569})',
         userDataDir: 'C:\\Users\\CHRISK~1\\AppData\\Local\\Temp\\scoped_dir3508_2130984217'
       },
       cssSelectorsEnabled: true,
       databaseEnabled: false,
       'goog:chromeOptions': { debuggerAddress: 'localhost:60939' },
       handlesAlerts: true,
       hasTouchScreen: false,
       javascriptEnabled: true,
       locationContextEnabled: true,
       mobileEmulationEnabled: false,
       nativeEvents: true,
       networkConnectionEnabled: false,
       pageLoadStrategy: 'normal',
       platform: 'Windows',
       proxy: {},
       rotatable: false,
       setWindowRect: true,
       strictFileInteractability: false,
       takesHeapSnapshot: true,
       takesScreenshot: true,
       timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },
       unexpectedAlertBehaviour: 'ignore',
       version: '106.0.5249.119',
       webStorageEnabled: true,
       'webauthn:extension:credBlob': true,
       'webauthn:extension:largeBlob': true,
       'webauthn:virtualAuthenticators': true
     }
ℹ Connected to ChromeDriver on port undefined (592ms).
  Using: chrome (106.0.5249.119) on WINDOWS.

 Received session with ID: 505d7b2a2f501f84bb84ab25521d9896

 → Running [before]:
 → Completed [before].



  Running sets the geolocation to Tokyo, Japan and then resets it:
───────────────────────────────────────────────────────────────────────────────────────────────────
 → Running [beforeEach]:
 → Completed [beforeEach].
 
 → Running command: setGeolocation ({latitude, longitude, accuracy})
   Request GET /json
   Response 200 GET /json (3ms)
[
  {
    description: '',
    devtoolsFrontendUrl: '/devtools/inspector.html?ws=localhost:60939/devtools/page/0E6BD7249BAA8DC4EF70CE80FB65079D',
    id: '0E6BD7249BAA8DC4EF70CE80FB65079D',
    title: 'data:,',
    type: 'page',
    url: 'data:,',
    webSocketDebuggerUrl: 'ws://localhost:60939/devtools/page/0E6BD7249BAA8DC4EF70CE80FB65079D'
  }
]
  → Completed command: setGeolocation ({latitude, longitude, accuracy}) (21ms)

 → Running command: navigateTo ('https://www.gps-coordinates.net/my-location')
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/url
   { url: 'https://www.gps-coordinates.net/my-location' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/url (4905ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: null
  }
  → Completed command: navigateTo ('https://www.gps-coordinates.net/my-location') (4907ms)

 → Running command: pause (3000)
  → Completed command: pause (3000) (3008ms)

 → Running command: verify.textContains ('span#addr', 'Tokyo Metropolitan Government Main Building 1, Midori-no-hashi, Nishi-Shinjuku 2-chome, Shinjuku, 163-8001, Japan')

 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements          
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (13ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (14ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (37ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (11ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (10ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (25ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (8ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (8ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (25ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (11ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (8ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (22ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (9ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (11ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (24ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (6ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (10ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (20ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (11ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (7ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (21ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (8ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (10ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (21ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (7ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (7ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (17ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (6ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (11ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → Completed command: getText ({selector, suppressNotFoundErrors}, [Function]) (20ms)
 
 → Running command: getText ({selector, suppressNotFoundErrors}, [Function])
   Request POST /session/505d7b2a2f501f84bb84ab25521d9896/elements  
   { using: 'css selector', value: 'span#addr' }
   Response 200 POST /session/505d7b2a2f501f84bb84ab25521d9896/elements (10ms)
   {
     sessionId: '505d7b2a2f501f84bb84ab25521d9896',
     status: 0,
     value: [ { ELEMENT: '0.40845738720576685-1' } ]
  }
   Request GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text  

   Response 200 GET /session/505d7b2a2f501f84bb84ab25521d9896/element/0.40845738720576685-1/text (8ms)
   { sessionId: '505d7b2a2f501f84bb84ab25521d9896', status: 0, value: '' }
  → NightwatchAssertError

    Testing if element <span#addr> contains text 'Tokyo Metropolitan Government Main Building 1, Midori-no-hashi, Nishi-Shinjuku 2-chome, Shinjuku, 163-8001, Japan' in 5000ms - expected "contains text 'Tokyo Metropolitan Government Main Building 1, Midori-no-hashi, Nishi-Shinjuku 2-chome, Shinjuku, 163-8001, Japan'" but got: "does not contain 'Tokyo Metropolitan Government Main Building 1, Midori-no-hashi, Nishi-Shinjuku 2-chome, Shinjuku, 163-8001, Japan'" (5498ms)
```


### Nightwatch Configuration

```node
// Autogenerated by Nightwatch
// Refer to the online docs for more details: https://nightwatchjs.org/gettingstarted/configuration/
const Services = {}; loadServices();

require('dotenv').config();

const FAILURES_ERRORS_PATH = "./failures"; // Location of the screenshots taken on failures/errors
const REPORTS = "./reports"; // The location where the JUnit XML report files will be saved.

module.exports = {
  // An array of folders (excluding subfolders) where your tests are located;
  // if this is not specified, the test source must be passed as the second argument to the test runner.
  src_folders: ["Scenarios"],

  // See https://nightwatchjs.org/guide/working-with-page-objects/
  page_objects_path: "pages",

  // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-commands
  custom_commands_path: ["./custom_commands", "./node_modules/nightwatch-xhr/es5/commands", "./node_modules/nightwatch-mixpanel/es5/commands", "./node_modules/nightwatch-vrt/commands"],

  // See https://nightwatchjs.org/guide/extending-nightwatch/#writing-custom-assertions
  custom_assertions_path: ["./custom_assertions", "./node_modules/nightwatch-xhr/es5/assertions", "./node_modules/nightwatch-mixpanel/es5/assertions", "node_modules/nightwatch-vrt/assertions"],

  // See https://nightwatchjs.org/guide/#external-globals
  globals_path: "./globals.js",

  data_path: "data",
  output_folder: REPORTS, // The location where the JUnit XML report files will be saved.
  live_output: false, // Whether or not to buffer the output in case of parallel running
  detailed_output: true, // By default detailed assertion output is displayed while the test is running. Set this to `false` if you'd like to only see the test case name displayed and pass/fail status. Detailed output is disabled by default when running tests in parallel.
  //parallel_process_delay: 1000, // Specifies the delay (in milliseconds) between starting the child processes when running in parallel mode.

  webdriver: {

    "keep_alive": true // Enable HTTP Keep-Alive. If set to true the keepAlive option is enabled with default settings (keepAliveMsecs = 3000). If set to an object, can specify specify the keepAliveMsecs value.

  },

  // This object contains all the test related options.

  test_settings: {
    default: {
      disable_error_log: false, // Set this to true if you'd like to not display errors during the execution of the test (they are shown at the end always).
      launch_url: "http://localhost", // A url which can be used later in the tests as the main url to load. Can be useful if your tests will run on different environments, each one with a different url.
      silent: true, // Whether to show the extended HTTP traffic command logs from the WebDriver or Selenium server.
      use_xpath: false, // 	Use xpath as the default locator strategy
      test_workers: { "enabled": true, "workers": 24 }, // Whether or not to run individual test files in parallel. If set to `true`, runs the tests in parallel and determines the number of workers automatically. If set to an object, can specify specify the number of workers as `"auto"` or a `number`. 
      globals: require('./globals'), // An object which will be made available within the test and can be overwritten per environment
      screenshots: {
        enabled: true,
        path: FAILURES_ERRORS_PATH,
        on_failure: true
      },

      desiredCapabilities: { // An object which will be passed to the Selenium WebDriver when a new session will be created. You can specify browser name for instance along with other capabilities. 
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        browserTag: "mttestcr"
      },
      end_session_on_fail: true, // End the session automatically when the test is being terminated, usually after a failed assertion.
      skip_testcases_on_fail: true, // Skip the remaining testcases (or test steps) from the same test suite (i.e. test file), when one testcase fails.
      detailed_output: true, // By default detailed assertion output is displayed while the test is running. Set this to `false` if you'd like to only see the test case name displayed and pass/fail status. This is especially useful when running tests in parallel.

      webdriver: {
        start_process: true, // When this is enabled, the Webdriver server is run in background in a child process and started/stopped automatically. Nightwatch includes support for managing Chromedriver, Geckodriver (Firefox), Safaridriver, and Selenium Server. Please refer to the Install Webdriver section for details.
        server_path: (Services.chromedriver ? Services.chromedriver.path : '') // Only useful if start_process is enabled.
      },

    },

    firefox: {
      desiredCapabilities: {
        browserName: 'firefox',
        alwaysMatch: {
          acceptInsecureCerts: true,
          'moz:firefoxOptions': {
            args: [
              // '-verbose'
              '--window-size=1920,925',
              '--no-sandbox',
            ]
          }
        },
      },
      browserTag: "mttestff",
      webdriver: {
        start_process: true,
        port: 4444,
        server_path: (Services.geckodriver ? Services.geckodriver.path : ''),
        cli_args: [
          // very verbose geckodriver logs
          // '-vv'

        ]
      },

    },

    h_firefox: {
      desiredCapabilities: {
        browserName: 'firefox',
        alwaysMatch: {
          acceptInsecureCerts: true,
          'moz:firefoxOptions': {
            args: [
              '--headless',
              // '-verbose'
              '--window-size=1920,925',
              '--no-sandbox',
            ]
          }
        },
      },
      browserTag: "mttestff",
      webdriver: {
        start_process: true,
        port: 4444,
        server_path: (Services.geckodriver ? Services.geckodriver.path : ''),
        cli_args: [
          // very verbose geckodriver logs
          // '-vv'

        ]
      },

    },

    chrome: {
      desiredCapabilities: {
        browserName: 'chrome',
        loggingPrefs: {
          browser: "ALL"
        },
        javascriptEnabled: true,
        acceptSslCerts: true,
        'goog:chromeOptions': {
          // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
          //
          // This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
          w3c: false,
          args: [
            '--no-sandbox',
            //'--ignore-certificate-errors',
            //'--allow-insecure-localhost',
            '--disable-software-rasterizer',
            '--disable-gpu',
            '--window-size=1920,925',
            '--log-level=3',
            '--disable-logging'

          ],
          prefs: {
            "profile.default_content_setting_values.cookies": 1, // Allow sites to save and read cookie data (recommended): 2=Blocked, 1=Allow
          },
        }
      },

      webdriver: {
        start_process: true,
        port: 9515,
        server_path: (Services.chromedriver ? Services.chromedriver.path : ''),
        cli_args: [
          // --verbose
        ]
      },

    },

    h_chrome: {
      desiredCapabilities: {
        browserName: 'chrome',
        loggingPrefs: {
          browser: "ALL"
        },
        javascriptEnabled: true,
        acceptSslCerts: true,
        'goog:chromeOptions': {
          // More info on Chromedriver: https://sites.google.com/a/chromium.org/chromedriver/
          //
          // This tells Chromedriver to run using the legacy JSONWire protocol (not required in Chrome 78)
          w3c: false,
          args: [
            '--no-sandbox',
            '--ignore-certificate-errors',
            '--allow-insecure-localhost',
            '--headless',
            '--disable-gpu',
            '--disable-software-rasterizer',
            //'--verbose',
            '--window-size=1920,925',
            '--log-level=3',
            '--disable-logging'

          ],
          prefs: {
            "profile.default_content_setting_values.cookies": 1, // Allow sites to save and read cookie data (recommended): 2=Blocked, 1=Allow
          },
        },

      },

      webdriver: {
        start_process: true,
        port: 9515,
        server_path: (Services.chromedriver ? Services.chromedriver.path : ''),
        cli_args: [
          // --verbose
        ]
      },

    },

    edge: {
      desiredCapabilities: {
        browserName: 'MicrosoftEdge',
        acceptSslCerts: true,
        'ms:edgeOptions': {
          w3c: false,
          // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
          args: [
          ]
        },
        browserTag: "mtteste"
      },

      webdriver: {
        start_process: true,
        // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
        //  and set the location below:
        server_path: "C:\\Windows\\System32\\msedgedriver.exe",
        cli_args: [
          // --verbose

        ]
      },

    },

    h_edge: {
      desiredCapabilities: {
        browserName: 'MicrosoftEdge',
        'ms:edgeOptions': {
          w3c: false,
          // More info on EdgeDriver: https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/capabilities-edge-options
          args: [
            '--no-sandbox',
            //'--ignore-certificate-errors',
            //'--allow-insecure-localhost',
            '--headless',
            '--window-size=1920,925',
            '--log-level=3',
            '--disable-gpu',
            '--disable-software-rasterizer',
          ]
        },
        browserTag: "mtteste"
      },

      webdriver: {
        start_process: true,
        // Download msedgedriver from https://docs.microsoft.com/en-us/microsoft-edge/webdriver-chromium/
        //  and set the location below:
        server_path: "C:\\Windows\\System32\\msedgedriver.exe",
        cli_args: [
          // --verbose
        ]
      },

    },

    safari: {
      test_workers: { "enabled": false },
      desiredCapabilities: {
        acceptInsecureCerts: false,
        browserName: 'safari',
        browserTag: "mttests",
      },
      webdriver: {
        port: 4445,
        start_process: true,
        server_path: '/usr/bin/safaridriver'
      }
    },

    //////////////////////////////////////////////////////////////////////////////////
    // Configuration for when using the Selenium service, either locally or remote,  |
    //  like Selenium Grid                                                           |
    //////////////////////////////////////////////////////////////////////////////////
    selenium_server: {
      // Selenium Server is running locally and is managed by Nightwatch
      selenium: {
        start_process: false,
        host: '127.0.0.1',
        port: 4444,
        launch_url: 'http://localhost',
        server_path: (Services.seleniumServer ? Services.seleniumServer.path : ''),
        screenshots: {
          enabled: true,
          path: FAILURES_ERRORS_PATH,
          on_failure: true
        },
        cli_args: {
          'webdriver.gecko.driver': (Services.geckodriver ? Services.geckodriver.path : ''),
          'webdriver.chrome.driver': (Services.chromedriver ? Services.chromedriver.path : '')
        }
      }
    },

    'selenium.chrome': {
      extends: 'selenium_server',
      desiredCapabilities: {
        browserName: 'chrome',
        javascriptEnabled: true,
        acceptSslCerts: true,
        acceptInsecureCerts: true,
        chromeOptions: {
          w3c: false,
          args: [
            '--no-sandbox',
            '--ignore-certificate-errors',
            '--allow-insecure-localhost',
            '--headless',
            '--disable-gpu',
            '--disable-software-rasterizer',
            //'--verbose',
            '--window-size=1920,925',
            '--log-level=3',
            '--disable-logging'

          ]
        }
      },
      webdriver: {
        start_process: false,
      }

    },

    'selenium.firefox': {
      extends: 'selenium_server',
      desiredCapabilities: {
        browserName: 'firefox',
        'moz:firefoxOptions': {
          args: [
            '-headless',
            // '-verbose'
          ]
        }
      }
    }
  }
};

function loadServices() {
  try {
    Services.seleniumServer = require('selenium-server');
  } catch (err) { }

  try {
    Services.chromedriver = require('chromedriver');
  } catch (err) { }

  try {
    Services.geckodriver = require('geckodriver');
  } catch (err) { }
}
```


### Nightwatch.js Version

2.3.9

### Node Version

v14.17.1

### Browser

Version 106.0.5249.119 (Official Build) (64-bit)

### Operating System

Windows 10 Pro

### Additional Information

![geolocbug](https://user-images.githubusercontent.com/34232960/197546980-83473aa9-5412-4b64-8387-6ada3b34e4ab.png)


Pull request description:
Fixes/3451 cdp command fix
## Changes
- added a fix to run CDP commands on Node v17 and above
- changed the logic to run the test in headless mode for the chrome browser.

## Impact
- fixes #3451 

Patch:
diff --git a/lib/core/client.js b/lib/core/client.js
index 505678a4..8e336272 100644
--- a/lib/core/client.js
+++ b/lib/core/client.js
@@ -471,7 +471,7 @@ class NightwatchClient extends EventEmitter {
     let value = this.settings.baseUrl || this.settings.launchUrl || this.settings.launch_url || null;
 
     // For e2e and component testing on android emulator
-    if (!this.settings.desiredCapabilities.real_mobile && this.settings.desiredCapabilities.avd) {         
+    if (value && !this.settings.desiredCapabilities.real_mobile && this.settings.desiredCapabilities.avd) {         
       value = value.replace('localhost', '10.0.2.2').replace('127.0.0.1', '10.0.2.2');
     }
 
diff --git a/lib/http/request.js b/lib/http/request.js
index 1c0543ec..7207d3a6 100644
--- a/lib/http/request.js
+++ b/lib/http/request.js
@@ -1,6 +1,7 @@
 const EventEmitter = require('events');
 const http   = require('http');
 const https  = require('https');
+const dns = require('dns');
 const HttpUtil = require('./http.js');
 const HttpOptions = require('./options.js');
 const Auth = require('./auth.js');
@@ -9,6 +10,11 @@ const HttpResponse = require('./response.js');
 const Utils = require('./../utils');
 const {Logger, isString} = Utils;
 
+// To handle Node v17 issue. Refer https://github.com/nodejs/node/issues/40702 for details.
+if (dns.setDefaultResultOrder && (typeof dns.setDefaultResultOrder === 'function')) {
+  dns.setDefaultResultOrder('ipv4first');
+}
+
 const __defaultSettings__ = {
   credentials: null,
   use_ssl: false,
diff --git a/lib/transport/selenium-webdriver/options.js b/lib/transport/selenium-webdriver/options.js
index f5eb9e5b..246a0ad0 100644
--- a/lib/transport/selenium-webdriver/options.js
+++ b/lib/transport/selenium-webdriver/options.js
@@ -317,8 +317,8 @@ module.exports = class SeleniumCapabilities {
   }
 
   addHeadlessOption({options}) {
-    if (this.argv.headless && (options instanceof Capabilities) && options.headless) {
-      options.headless();
+    if (this.argv.headless && (options instanceof Capabilities) && (this.isChrome || options.headless)) {
+      this.isChrome ? options.addArguments('headless=chrome') : options.headless();
     }
 
     return this;
diff --git a/package-lock.json b/package-lock.json
index b39758a2..c2d29d56 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
 {
   "name": "nightwatch",
-  "version": "2.5.3",
+  "version": "2.5.4",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "nightwatch",
-      "version": "2.5.3",
+      "version": "2.5.4",
       "license": "MIT",
       "dependencies": {
         "@nightwatch/chai": "5.0.2",
diff --git a/package.json b/package.json
index 5b58accb..4d3e9b7f 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "nightwatch",
   "description": "Easy to use Node.js based end-to-end testing solution for web applications using the W3C WebDriver API.",
-  "version": "2.5.3",
+  "version": "2.5.4",
   "author": "Andrei Rusu",
   "homepage": "https://nightwatchjs.org",
   "main": "./lib/index.js",


Test patch:
diff --git a/test/lib/command-mocks.js b/test/lib/command-mocks.js
index 236f64b7..2bb21d9b 100644
--- a/test/lib/command-mocks.js
+++ b/test/lib/command-mocks.js
@@ -385,7 +385,7 @@ module.exports = {
     url = '/wd/hub/session'
   }) {
     const browserName = 'chrome';
-    const headlessOpt = headless ? 'headless' : '';
+    const headlessOpt = headless ? 'headless=chrome' : '';
     const options = {
       ['goog:chromeOptions']: {}
     };
diff --git a/test/src/core/testCreateSession.js b/test/src/core/testCreateSession.js
index 951ba9f6..654e1097 100644
--- a/test/src/core/testCreateSession.js
+++ b/test/src/core/testCreateSession.js
@@ -198,7 +198,7 @@ describe('test Request With Credentials', function () {
       sessionId: '1352110219202',
       capabilities: {browserName: 'chrome', version: 'TEST', platform: 'TEST'}
     });
-    assert.deepStrictEqual(sessionOptions.get('goog:chromeOptions'), {args: ['headless']});
+    assert.deepStrictEqual(sessionOptions.get('goog:chromeOptions'), {args: ['headless=chrome']});
   });
 
   it('Test create session with headless mode in Edge', async function () {
@@ -287,7 +287,7 @@ describe('test Request With Credentials', function () {
     assert.deepStrictEqual(sessionOptions.get('goog:chromeOptions'), {
       args: [
         '--no-sandbox',
-        'headless'
+        'headless=chrome'
       ]
     });
   });
diff --git a/test/src/index/testMobileComponent.js b/test/src/index/testMobileComponent.js
index 8fa284fe..cfd1618c 100644
--- a/test/src/index/testMobileComponent.js
+++ b/test/src/index/testMobileComponent.js
@@ -33,4 +33,62 @@ describe('Mobile Component Testing in Android Emulator', function () {
 
     assert.strictEqual(client.api.baseUrl, 'http://10.0.2.2:3000');
   });
-});
\ No newline at end of file
+
+  it('test baseUrl - not defined',  function(){
+    const client = NightwatchClient.client({
+      webdriver: {
+        start_process: true
+      },
+      desiredCapabilities: {
+        avd: 'nightwatch-android-11',
+        real_mobile: false
+      }
+    });
+
+    assert.strictEqual(client.api.baseUrl, null);
+  });
+
+  it('test baseUrl - non local',  function(){
+    const client = NightwatchClient.client({
+      baseUrl: 'https://www.google.com/',
+      webdriver: {
+        start_process: true
+      },
+      desiredCapabilities: {
+        avd: 'nightwatch-android-11',
+        real_mobile: false
+      }
+    });
+
+    assert.strictEqual(client.api.baseUrl, 'https://www.google.com/');
+  });
+
+  it('test baseUrl - real mobile',  function(){
+    const client = NightwatchClient.client({
+      baseUrl: 'http://127.0.0.1:3000',
+      webdriver: {
+        start_process: true
+      },
+      desiredCapabilities: {
+        avd: 'nightwatch-android-11',
+        real_mobile: true
+      }
+    });
+
+    assert.strictEqual(client.api.baseUrl, 'http://127.0.0.1:3000');
+  });
+
+  it('test baseUrl - no mobile',  function(){
+    const client = NightwatchClient.client({
+      baseUrl: 'http://127.0.0.1:3000',
+      webdriver: {
+        start_process: true
+      },
+      desiredCapabilities: {
+        real_mobile: false
+      }
+    });
+
+    assert.strictEqual(client.api.baseUrl, 'http://127.0.0.1:3000');
+  });
+});
diff --git a/test/src/index/transport/testChromeOptions.js b/test/src/index/transport/testChromeOptions.js
index afe90c23..b1a82695 100644
--- a/test/src/index/transport/testChromeOptions.js
+++ b/test/src/index/transport/testChromeOptions.js
@@ -108,7 +108,7 @@ describe('Test chrome options', function () {
     const options = client.transport.createSessionOptions({headless: true});
 
     assert.strictEqual(options instanceof ChromeOptions, true);
-    assert.deepStrictEqual(options.options_.args, ['headless']);
+    assert.deepStrictEqual(options.options_.args, ['headless=chrome']);
   });
 
   it('devtools cli arg', function(){