microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
65.8k stars 3.58k forks source link

[Question] How to use log4js with Playwright runner? #9366

Closed ghost closed 2 years ago

ghost commented 2 years ago

Hello! We're migrating from the Jest to the Playwright runner. We were using log4js and now I wondering whether we can use it with Playwright? I know about Playwright Logger... but is it possible to make migration less painful? Thanks for any help in advance.

Our log4js config:

import log4js from 'log4js';

log4js.configure({
  appenders: {
    console: {
      type: 'stdout', layout:
        {
          type: 'pattern',
          pattern: '%[[%d] [%5p] %c %]- %m'
        }
    },
    console_restricted: {
      type: 'logLevelFilter',
      appender: 'console',
      level: process.env.LOG_LEVEL?.toLowerCase() === 'all' ? 'debug' : process.env.LOG_LEVEL
    },
    fileWithTestId: {
      type: 'multiFile',
      base: 'test-output/logs/',
      property: 'testId',
      extension: '.txt'
    },
    fileByCategory: {
      type: 'multiFile',
      base: 'test-output/logs/',
      property: 'categoryName',
      extension: '.txt'
    }
  },
  categories: {
    default: {
      appenders: [
        'console_restricted',
        'fileWithTestId',
        'fileByCategory'
      ],
      level: 'all'
    }
  }
});

export const createLogger = (name: string, testId: string): log4js.Logger => {
  const logger = log4js.getLogger(`[${name.padStart(10, '-')}]`);
  logger.addContext('testId', testId);
  return logger;
};
aslushnikov commented 2 years ago

@StanislavKhvalinskyiDevPro I assume that you use log4js for some of your logging inside tests. This should just work straight away.

So what exactly doesn't work with Playwright Test?

ghost commented 2 years ago

@aslushnikov thanks for your quick response. Logger configuration above is exporting in the index.ts export * from './logging'; I initialize logger in the tests/helpers like this this.logger = createLogger(`${id}: ${new.target.name}`, id) Playwright complains on this line TypeError: (0 , _config.createLogger) is not a function

If I change index.ts like this export { createLogger } from './logging'; I get different error TypeError: Cannot read property 'createLogger' of undefined.

ghost commented 2 years ago

Sorry, closed by mistake.

JoelEinbinder commented 2 years ago

Is your ./logging file a .js file or a .ts file? Are you compiling your own typescript or using the built in playwright test typescript support?

ghost commented 2 years ago

Yep, we're using TypeScript. If I understood the manual right we have to compile TS before running tests in case of any problems. I'll try it.

ghost commented 2 years ago

OK, looks like I made step forward. Before I rewrote all import aliases to the regular imports. BTW does Playwright OK with workspaces? TS compilation failed with quite not clear description:

tsc --incremental -p ./tsconfig.json

/node_modules/typescript/lib/tsc.js:87003
                throw e;
                ^

TypeError: Cannot read property 'length' of undefined
    at computeLineStarts (/node_modules/typescript/lib/tsc.js:6526:27)
    at Object.getLineStarts (/node_modules/typescript/lib/tsc.js:6579:60)
    at getCurrentLineMap (/node_modules/typescript/lib/tsc.js:81807:59)
    at emitDetachedCommentsAndUpdateCommentsInfo (/node_modules/typescript/lib/tsc.js:85141:94)
    at emitBodyWithDetachedComments (/node_modules/typescript/lib/tsc.js:85004:17)
    at emitSourceFile (/node_modules/typescript/lib/tsc.js:83870:21)
    at pipelineEmitWithHint (/node_modules/typescript/lib/tsc.js:81884:24)
    at pipelineEmit (/node_modules/typescript/lib/tsc.js:81840:13)
    at print (/node_modules/typescript/lib/tsc.js:81774:13)
    at Object.writeFile (/node_modules/typescript/lib/tsc.js:81758:13)

Process finished with exit code 1

Without compilation test also failed but with better description. But I anyway cannot get how to make it work:

 TypeError: Cannot read property 'level' of undefined

        at Level.isGreaterThanOrEqualTo (/node_modules/log4js/lib/levels.js:78:37)
        at /node_modules/log4js/lib/appenders/logLevelFilter.js:6:20
        at /node_modules/log4js/lib/log4js.js:42:5
        at Array.forEach (<anonymous>)
        at sendLogEventToAppender (/node_modules/log4js/lib/log4js.js:41:21)
        at /node_modules/log4js/lib/clustering.js:23:26
        at Array.forEach (<anonymous>)
        at sendToListeners (/node_modules/log4js/lib/clustering.js:23:13)
        at Object.send (/node_modules/log4js/lib/clustering.js:89:7)
        at Logger._log (/node_modules/log4js/lib/logger.js:90:16)
        at Logger.log (/node_modules/log4js/lib/logger.js:73:12)
        at Logger.<computed> [as info] (/node_modules/log4js/lib/logger.js:124:10)
        at LoginPage.pageObject.<computed> [as navigateTo] (/src/config/page.conditions.ts:50:14)
        at /src/tests/login.test.ts:29:21
        at WorkerRunner._runTestWithBeforeHooks (/node_modules/@playwright/test/lib/test/workerRunner.js:450:7)
ghost commented 2 years ago

The issue was resolved. I found that configuration of log4js was invalid ¯_(ツ)_/¯ For some reason we should explicitly declare, that .env file is using: require('dotenv').config();.