jasmine / jasmine-browser-runner

Serve and run your Jasmine specs in a browser
49 stars 23 forks source link

[question] How to get the browser logs when running jasmine-browser-runner runSpecs #9

Closed gparlakov closed 2 years ago

gparlakov commented 3 years ago

I'd like to get the logs from the browser console when running jasmine-browser-runner runSpecs for chromeHeadless.

How can I do that?

sgravrock commented 3 years ago

Sorry, but there isn't currently a way to do that.

gparlakov commented 3 years ago

Hi. Thanks for the reply.

My goal was to output the console.log-s from tests. I guess that's not possible.

On Sat, Oct 2, 2021, 21:06 Steve Gravrock @.***> wrote:

Sorry, but there isn't currently a way to do that.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jasmine/jasmine-browser-runner/issues/9#issuecomment-932795231, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2SEVY2CC5HX4ZTFG7QN4DUE5CZJANCNFSM5FANZSJQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

sgravrock commented 3 years ago

Actually, it occurs to me that you could use setSpecProperty in combination with a custom reporter to do this. First, add a helper file spec/helpers/logs.js:

(function() {
   let logs = [];

   beforeAll(function() {
      spyOn(console, 'log').and.callFake(function() {
         logs.push(arguments);
      });
   });

   afterEach(function() {
      setSpecProperty('consoleLogs', logs);
      logs = [];
   });
}());

Then add a custom reporter in reporter.js:

const {DefaultReporter} = require('jasmine-browser-runner');

function Reporter() {
}
Reporter.prototype = new DefaultReporter();
const originalSpecDone = Reporter.prototype.specDone;

Reporter.prototype.specDone = function(info) {
   originalSpecDone.call(this, info);
   doSomethingWith(info.properties.consoleLogs);
}

module.exports = Reporter;

(Yes, the reporter setup is awkward. I'm looking to improve that.)

Finally, add "reporters": ["./reporter.js"], to spec/support/jasmine.json.

The drawback is that you won't capture console.log messages that occur between specs. That can come up when an async spec signals completion before it's actually done, or when a beforeAll or afterAll causes something to be logged.

gparlakov commented 3 years ago

Thanks for the tip! I'll try that.

I'm doing a Jasmine testing course so that should come in handy.

On Mon, Oct 4, 2021, 18:38 Steve Gravrock @.***> wrote:

Actually, it occurs to me that you could use setSpecProperty in combination with a custom reporter to do this. First, add a helper file spec/helpers/logs.js:

(function() { let logs = [];

beforeAll(function() { spyOn(console, 'log').and.callFake(function() { logs.push(arguments); }); });

afterEach(function() { setSpecProperty('consoleLogs', logs); logs = []; }); }());

Then add a custom reporter in reporter.js:

const {DefaultReporter} = require('jasmine-browser-runner');

function Reporter() { } Reporter.prototype = new DefaultReporter(); const originalSpecDone = Reporter.prototype.specDone;

Reporter.prototype.specDone = function(info) { originalSpecDone.call(this, info); doSomethingWith(info.properties.consoleLogs); }

module.exports = Reporter;

(Yes, the reporter setup is awkward. I'm looking to improve that.)

Finally, add "reporters": ["./reporter.js"], to spec/support/jasmine.json.

The drawback is that you won't capture console.log messages that occur between specs. That can come up when an async spec signals completion before it's actually done, or when a beforeAll or afterAll causes something to be logged.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jasmine/jasmine-browser-runner/issues/9#issuecomment-933608524, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2SEV5ST24LVKWUZRGTXCTUFHDA5ANCNFSM5FANZSJQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

gparlakov commented 2 years ago

Hey, @sgravrock thanks a bunch. It works just like you said.

I went with :

const { DefaultReporter } = require('jasmine-browser-runner');

function Reporter() {}
Reporter.prototype = new DefaultReporter();
const originalSpecDone = Reporter.prototype.specDone;

Reporter.prototype.specDone = function (info) {
  // originalSpecDone.call(this, info) // just adds a '.' in the output for a passed test
  if (Array.isArray(info.properties.consoleLogs)) {
    info.properties.consoleLogs.forEach((a) => console.log(...a));
  }
  delete info.properties.consoleLogs;
};

module.exports = Reporter;

for reporter.js

and

(function () {
  let logs = [];

  beforeAll(function () {
    const originalLog = console.log;
    spyOn(console, 'log').and.callFake(function () {
      logs.push(arguments);
      originalLog.call(console, arguments);
    });
  });

  afterEach(function () {
    setSpecProperty('consoleLogs', logs);
    logs = [];
  });
})();
ryanb commented 8 months ago

Note DefaultReporter was renamed to ConsoleReporter so you'll need to replace it in the reporter code above if you want to use it today.

Update: I am seeing duplicate output with the reporter, so I assume custom reporters now add to the output of the console reporter. This simpler reporter.js worked for me.

class Reporter {
  specDone(info) {
    if (!info.properties) {
      return;
    }
    if (Array.isArray(info.properties.consoleLogs)) {
      info.properties.consoleLogs.forEach((a) => console.log(...a));
    }
  }
}

module.exports = Reporter;
gparlakov commented 8 months ago

Thanks for the heads up!

On Mon, Jan 22, 2024, 10:11 PM Ryan Bates @.***> wrote:

Note DefaultReporter was renamed to ConsoleReporter so you'll need to replace it in the reporter code above if you want to use it today.

— Reply to this email directly, view it on GitHub https://github.com/jasmine/jasmine-browser-runner/issues/9#issuecomment-1904729285, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2SEV7D4JUA7GUZYAUIGULYP3BYJAVCNFSM5FANZSJ2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOJQGQ3TEOJSHA2Q . You are receiving this because you modified the open/close state.Message ID: @.***>

ryanb commented 8 months ago

Another suggestion: if you also run tests in non-headless mode the console log messages will look strange with the console.log override. You can check if (navigator.webdriver) in logs.js to only override console.log when it's running in headless mode.

(function () {
  if (navigator.webdriver) {
    let logs = [];

    beforeAll(function () {
      const originalLog = console.log;
      spyOn(console, "log").and.callFake(function () {
        logs.push(arguments);
        originalLog.call(console, arguments);
      });
    });

    afterEach(function () {
      setSpecProperty("consoleLogs", logs);
      logs = [];
    });
  }
})();