0
votes

I'm trying to write to console the network log after a test failure as part of my protractor suite. The code works fine when in an afterEach() block but fails to execute the promise when inside of a custom jasmine reporter. As far as I can tell the promise never executes, but there are no known/shown errors.

protractor config (simplified):

exports.config = {
  specs: ['./e2e/**/*.spec.ts'],
  capabilities: {
    browserName: 'chrome',
    chromeOptions: {
      perfLoggingPrefs: {
        enableNetwork: true,
        enablePage: false,
      }
    },
    loggingPrefs: {
      performance: 'ALL',
      browser: 'ALL'
    },
  },
  onPrepare() {
    jasmine.getEnv().addReporter({
      specDone: result => {
        new ErrorReporter(browser).logNetworkError(result);
      }
    });
  },
};

ErrorReporter:

class ErrorReporter {
  constructor(browser) {
    this.browser = browser;
  }

  logNetworkError(result) {
    if(result.status === 'failed') {
// execution makes it in here
      this.browser.manage().logs().get('performance').then(function(browserLogs) {
// execution DOES NOT make it here
        browserLogs.forEach(function(log) {
          const message = JSON.parse(log.message).message;

          if(message.method === 'Network.responseReceived') {
            const status = message.params.response.status;
            const url = message.params.response.url;

            if(status !== 200 && status !== 304) {
              console.log(`----E2E NETWORK ERROR----`);
              console.log(`STATUS: [${status}]`);
              console.log(`URL: [${url}]`);
              console.log(`RESPONSE: [${log.message}]`);
            }
          }
        });
      });
    }
  }
}

module.exports = ErrorReporter;

The code inside the logNetworkError() method works completely fine when executed in an afterEach() block but never writes out any logs when executed as a custom reporter. I would expect that this would work as a jasmine reporter as well.

If it's not possible to execute this as a jasmine reporter is there some way to access the executed test's results in the afterEach() block? I do not want to log on successful test execution.

1

1 Answers

0
votes

I figured out the solution. There was 2 main problems. The first was that I needed to use async and await inside of the function that was creating the log:

  async logNetworkError(result) {
      if(result.status === 'failed') {

        const logs = await this.browser.manage().logs().get('performance');

        logs.forEach((log) => {
          const message = JSON.parse(log.message).message;

          if(message.method === 'Network.responseReceived') {
            const status = message.params.response.status;
            const url = message.params.response.url;

            if(status !== 200 && status !== 304) {
              console.log(`-----E2E NETWORK ERROR-----`);
              console.log(`TEST NAME: ${result.fullName}`);
              console.log(`STATUS: [${status}]`);
              console.log(`URL: [${url}]`);
              console.log(`RESPONSE: [${log.message}]`);
            }
          }
        });
      }
  }

the second part of the problem was that another reporter which was saving screenshots did not have async and await which was stopping other reporters from completing. Adding async/await to both reporters solved this issue.