Nightwatch: getLog and getLogTypes do not work with Firefox / geckodriver: Error while running .getLogContents()

Created on 8 Oct 2019  ยท  10Comments  ยท  Source: nightwatchjs/nightwatch

Describe the bug

When using geckodriver directly (not via Selenium), getLog() and getLogTypes() do not work:

Error while running .getSessionLogTypes() protocol action: An unknown error has occurred.

Error while running .getLogContents() protocol action: An unknown error has occurred.

Sample test

sampleTest.js:

module.exports = {
  testGetLogTypes: function(browser) {
    browser.getLogTypes(res => console.log(res));
    browser.end();
  },
  testGetLog: function(browser) {
    browser.getLog('browser', logEntries => {
      logEntries.forEach(function (log) {
        console.log('[' + log.level + '] ' + log.message);
      });
    });
    browser.end();
  }
}

Run with command

$ nightwatch test/sampleTest.js

Verbose output

debug.log


 Starting GeckoDriver on port 4444...
 GeckoDriver up and running on port 4444 with pid: 22404 (145ms).

[Sample Test] Test Suite
========================
   Request POST  /session
   { capabilities:
      { browserName: 'firefox',
        acceptSslCerts: true,
        name: 'Sample Test' },
     desiredCapabilities:
      { browserName: 'firefox',
        acceptSslCerts: true,
        platform: 'ANY',
        name: 'Sample Test' } }
   Response 200 POST /session (2077ms)
   { value:
      { sessionId: 'a6f95955-a7cc-4750-9aa2-c2f491764629',
        capabilities:
         { acceptInsecureCerts: false,
           browserName: 'firefox',
           browserVersion: '69.0.2',
           'moz:accessibilityChecks': false,
           'moz:buildID': '20191001234643',
           'moz:geckodriverVersion': '0.25.0',
           'moz:headless': false,
           'moz:processID': 14468,
           'moz:profile': 'C:\\Users\\me\\AppData\\Local\\Temp\\rust_mozprofileMcC4bQ',
           'moz:shutdownTimeout': 60000,
           'moz:useNonSpecCompliantPointerOrigin': false,
           'moz:webdriverClick': true,
           pageLoadStrategy: 'normal',
           platformName: 'windows',
           platformVersion: '10.0',
           rotatable: false,
           setWindowRect: true,
           strictFileInteractability: false,
           timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },
           unhandledPromptBehavior: 'dismiss and notify' } } }
 Received session with ID: a6f95955-a7cc-4750-9aa2-c2f491764629

 โ†’ Running [before]:
 โ†’ Completed [before].
Running:  testGetLogTypes

 โ†’ Running [beforeEach]:
 โ†’ Completed [beforeEach].

 โ†’ Running command: getLogTypes ([Function])

 โ†’ Running command: sessionLogTypes ([Function])
   Request GET  /session/a6f95955-a7cc-4750-9aa2-c2f491764629/log/types
   Response 405 GET /session/a6f95955-a7cc-4750-9aa2-c2f491764629/log/types (3ms)
   { status: -1, value: 'HTTP method not allowed' }
 Error while running .getSessionLogTypes() protocol action: An unknown error has occurred.

   Error: An unknown error has occurred.
       at process._tickCallback (internal/process/next_tick.js:68:7)
HTTP method not allowed
 โ†’ Completed command sessionLogTypes ([Function]) (10ms)
 โ†’ Completed command getLogTypes ([Function]) (15ms)

 โ†’ Running command: end ()

 โ†’ Running command: session ('delete', [Function])
   Request DELETE  /session/a6f95955-a7cc-4750-9aa2-c2f491764629
   Response 200 DELETE /session/a6f95955-a7cc-4750-9aa2-c2f491764629 (2680ms)
   { value: null }
 โ†’ Completed command end () (2692ms)
 โ†’ Completed command session ('delete', [Function]) (2683ms)
 โ†’ Running [afterEach]:
 โ†’ Completed [afterEach].
No assertions ran.
Running:  testGetLog

   Request POST  /session
   { capabilities:
      { browserName: 'firefox',
        acceptSslCerts: true,
        name: 'Sample Test' },
     desiredCapabilities:
      { browserName: 'firefox',
        acceptSslCerts: true,
        platform: 'ANY',
        name: 'Sample Test' } }
   Response 200 POST /session (2689ms)
   { value:
      { sessionId: 'fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc',
        capabilities:
         { acceptInsecureCerts: false,
           browserName: 'firefox',
           browserVersion: '69.0.2',
           'moz:accessibilityChecks': false,
           'moz:buildID': '20191001234643',
           'moz:geckodriverVersion': '0.25.0',
           'moz:headless': false,
           'moz:processID': 19384,
           'moz:profile': 'C:\\Users\\me\\AppData\\Local\\Temp\\rust_mozprofile5fzO6A',
           'moz:shutdownTimeout': 60000,
           'moz:useNonSpecCompliantPointerOrigin': false,
           'moz:webdriverClick': true,
           pageLoadStrategy: 'normal',
           platformName: 'windows',
           platformVersion: '10.0',
           rotatable: false,
           setWindowRect: true,
           strictFileInteractability: false,
           timeouts: { implicit: 0, pageLoad: 300000, script: 30000 },
           unhandledPromptBehavior: 'dismiss and notify' } } }
 Received session with ID: fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc

 โ†’ Running [beforeEach]:
 โ†’ Completed [beforeEach].

 โ†’ Running command: getLog ('browser', [Function])

 โ†’ Running command: sessionLog ('browser', [Function])
   Request POST  /session/fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc/log
   { type: 'browser' }
   Response 405 POST /session/fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc/log (4ms)
   { status: -1, value: 'HTTP method not allowed' }
 Error while running .getLogContents() protocol action: An unknown error has occurred.

   Error: An unknown error has occurred.
       at process._tickCallback (internal/process/next_tick.js:68:7)
 โ†’ Completed command sessionLog ('browser', [Function]) (9ms)
 โ†’ Completed command getLog ('browser', [Function]) (13ms)
   TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)
 โ†’ Running [afterEach]:
 โ†’ Completed [afterEach].

FAILED: 1 errors (2.733s)
   TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)
 โ†’ Running [after]:
 โ†’ Completed [after].

 โ†’ Running command: end ([Function])

 โ†’ Running command: session ('delete', [Function])
   Request DELETE  /session/fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc
   Response 200 DELETE /session/fc3bc0aa-eb61-4d3a-9ff1-b8757a2732cc (748ms)
   { value: null }
 โ†’ Completed command end ([Function]) (754ms)
 โ†’ Completed command session ('delete', [Function]) (750ms)
_________________________________________________

TEST FAILURE: 1 error during execution 0 tests failed, 2 passed. 8.571s

 ร— sampleTest
 โ€“ testGetLog (2.733s)
   TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)

  TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)


 Wrote report file to: tests_output\FIREFOX_69.0.2_10.0_sampleTest.xml.
 Wrote log file to: C:\test\geckodriver.log.
 GeckoDriver process closed.

Configuration

nightwatch.conf.js:

module.exports = {
    test_settings: {
        default: {
            "webdriver": {
                start_process: true,
                port: 4444,
                server_path: require("geckodriver").path
            }
        }
    }
};

package.json:

{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "geckodriver": "^1.18.0",
    "nightwatch": "^1.2.4"
  }
}

Your Environment

| Executable | Version |
| ---: | :--- |
| nightwatch --version | v1.2.4 |

| Browser driver | Version |
| --- | --- |
| geckodriver | 1.18.0,
0.25.0 (bdb64cf16b68 2019-09-10 00:45 +0300),
FIREFOX_69.0.2_10.0 |

| OS | Version |
| --- | --- |
| Windows 10 | 1903 |

bug stale

All 10 comments

Thanks for the neat bug report, we appreciate you taking the time. Does it work when using Selenium?

I could never get Selenium to work with the current geckodriver. So no I do not know if it works there (to be honest, I'm glad I'm off Selenium).

It does work, however the log endpoints are not available in geckodriver as they don't seem to be part of the W3C Webdriver spec.

It does work fine via Chrome (with the w3c: false flag).

Here's a working nightwatch.conf.js in case you want to give it a try with Selenium or if you want to use chromedriver:

Install selenium-server from npm:

$ npm i selenium-server --save-dev

__nightwatch.conf.js__:

const geckodriver = require('geckodriver');
const chromedriver = require('chromedriver');

module.exports = {
  // Run gecko standalone
  webdriver: {
    start_process: true,
    port: 4444,
    server_path: geckodriver.path
  },

  test_settings: {
    default: {
        desiredCapabilities : {
           browserName : 'firefox',
           alwaysMatch: {
             acceptInsecureCerts: true,
           }
         }
      },

   // Chrome in headless mode
    chrome: {
      desiredCapabilities : {
        browserName : 'chrome',
        chromeOptions : {
          w3c: false,
          args: [
            '--no-sandbox',
            '--ignore-certificate-errors',
            '--allow-insecure-localhost',
            '--headless'
          ]
        }
      },

      webdriver: {
        port: 9515,
        server_path: chromedriver.path
      }
    },

   selenium: {
      webdriver: {
        start_process: false,
      },
      selenium: {
        start_process: true,
        host: '127.0.0.1',
        port: 4444,
        server_path: require('selenium-server').path,
        cli_args: {
          'webdriver.gecko.driver': geckodriver.path
        }
      }
    }
  }
};

You can run with:

$ nightwatch --env selenium

Cool, thanks!
Yes, it seems to also fail in the same way with Selenium.

[Sample Test] Test Suite
========================
Running:  testGetLogTypes

   Response 500 GET /wd/hub/session/f50fad6e-85c3-4723-bc45-a89c30840a3e/log/types (24ms)
   { value:
      { error:
         [ 'Build info: version: \'3.141.59\', revision: \'e82be7d358\', time: \'2018-11-14T08:25:53\'',
           'System info: host: \'VM1\', ip: \'10.0.75.1\', os.name: \'Windows 10\', os.arch: \'amd64\', os.version: \'10.0\', java.version: \'1.8.0_201-1-ojdkbuild\'',
           'Driver info: driver.version: unknown' ],
        message:
         'Unable to determine type from: H. Last 1 characters read: H' },
     status: 13 }
 Error while running .getSessionLogTypes() protocol action: Unable to determine type from: H. Last 1 characters read: H

   Error: Unable to determine type from: H. Last 1 characters read: H
       at process._tickCallback (internal/process/next_tick.js:68:7)
{ error:
   [ 'Build info: version: \'3.141.59\', revision: \'e82be7d358\', time: \'2018-11-14T08:25:53\'',
     'System info: host: \'VM1\', ip: \'10.0.75.1\', os.name: \'Windows 10\', os.arch: \'amd64\', os.version: \'10.0\', java.version: \'1.8.0_201-1-ojdkbuild\'',
     'Driver info: driver.version: unknown' ],
  message:
   'Unable to determine type from: H. Last 1 characters read: H' }
No assertions ran.
Running:  testGetLog

   Response 500 POST /wd/hub/session/5e0409cc-8795-4bb5-8012-cc03a792aabb/log (16ms)
   { value:
      { error:
         [ 'Build info: version: \'3.141.59\', revision: \'e82be7d358\', time: \'2018-11-14T08:25:53\'',
           'System info: host: \'VM1\', ip: \'10.0.75.1\', os.name: \'Windows 10\', os.arch: \'amd64\', os.version: \'10.0\', java.version: \'1.8.0_201-1-ojdkbuild\'',
           'Driver info: driver.version: unknown' ],
        message:
         'Unable to determine type from: H. Last 1 characters read: H' },
     status: 13 }
 Error while running .getLogContents() protocol action: Unable to determine type from: H. Last 1 characters read: H

   Error: Unable to determine type from: H. Last 1 characters read: H
       at process._tickCallback (internal/process/next_tick.js:68:7)
   TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)

FAILED: 1 errors (2.809s)
   TypeError: Error while running "getLog" command: logEntries.forEach is not a function
       at NightwatchAPI.browser.getLog.logEntries (C:\test\sampleTest.js:8:18)
       at process._tickCallback (internal/process/next_tick.js:68:7)
_________________________________________________

TEST FAILURE: 1 error during execution 0 tests failed, 2 passed. 11.051s

Does it mean I can never fetch the logs from Firefox until W3C specifies it, or is there another, geckodriver-specific API?

what kind of logs do you need? you can also run geckodriver in verbose mode and you will get more logs that way. To do that, add -v or -vvtocli_args`:

webdriver: {
    start_process: true,
    port: 4444,
    server_path: geckodriver.path,
    cli_args: [
      '-vv' // for trace level
    ]
  },

The webdriver's verbose mode writes too much output, and into a separate file.
I instead want to include anything written to the _browser console_ into the _e2e test console_.
I currently achieve it like this

  before(browser) {
    this.logtimer = setInterval(() => browser.getLog('browser', logEntries => {
      logEntries.forEach(log => console.log('[' + log.level + '] ' + log.message));
    }), 1000);
  },
  after(browser) {
    if (this.logtimer) clearInterval(this.logtimer);
    browser.end();
  }

This helps a lot by showing any errors from the browser console _before_ the e2e test times out.
In my case that directly points to the error in half of the cases of e2e test failures, so it is immensely useful.
That's why I would like the getLog() API to function with geckodriver as well.

I see. This could also be achieved using execute(). I don't think getLog will work for geckodriver anytime soon.

@rustyx I achieved logging Firefox console errors by doing this:

1) Enabled option in firefox:

    "desiredCapabilities": {
        "alwaysMatch": {
            "moz:firefoxOptions": {
                "prefs": {
                    "devtools.console.stdout.content": true, // Used to capture console output.
                 }
            }
        },

2) Injected a function into geckodriver streams in globals before hook. A bit hacky, but works for now, until @beatfactor decides to change the implementation of webdriver-server:

const WebDriver = require('nightwatch/lib/runner/webdriver-server.js');
...
    before: (done) => {
        if (WebDriver.instances.firefox) {
            let geckodriverProcess = WebDriver.instances.firefox.instance.process;
            geckodriverProcess.stdout.on('data', browserLog); // This works for geckodriver.
            geckodriverProcess.stderr.on('data', browserLog); // This works for selenium.
        }
        done();
    }

3) The required browserLog function:

let browserLog = function (data) {
    let message = data.toString().trimRight();
    if (/^console.error:/.test(message)) {
          // do whatever you want with the "message" here...
    }
};

This issue has been automatically marked as stale because it has not had any recent activity.
If possible, please retry using the latest Nightwatch version and update the issue with any relevant details. If no further activity occurs, it will be closed. Thank you for your contribution.

@Pieras2 Please take a moment and review our code of conduct.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

maxgalbu picture maxgalbu  ยท  3Comments

betweenbrain picture betweenbrain  ยท  4Comments

bushev picture bushev  ยท  4Comments

danielbentov picture danielbentov  ยท  4Comments

antogyn picture antogyn  ยท  4Comments