Skip to content

clundstedt-m/monocart-reporter

This branch is 1122 commits behind cenfun/monocart-reporter:main.

Repository files navigation

Monocart Reporter

Preview

https://cenfun.github.io/monocart-reporter

More Test Reports

Install

npm i monocart-reporter

Playwright Config

// playwright.config.js
module.exports = {
    reporter: [
        ['list'],
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html'
        }]
    ]
};

Playwright Docs https://playwright.dev/docs/test-reporters

Examples

Output Assets

  • path-to/your-filename.html
    Single HTML file (data compressed), easy to transfer/deploy or open directly anywhere
    Note that test attachments (screenshots images/videos) are not included but linked with relative path in report. All attachments will be found in playwrightConfig.outputDir
// playwright.config.js
// attachments outputDir and report outputFile used same folder
const date = new Date().toISOString().slice(0, 10); //2022-10-10
const outputDir = `./test-results/${date}`;
module.exports = {
    outputDir: outputDir,
    reporter: [
        ['monocart-reporter', {  
            name: `My Test Report ${date}`,
            outputFile: `${outputDir}/index.html`
        }]
    ]
};
// deploy the folder to your report site and easy checking online
// http://your.report.site/test-results/2022-10-10
  • path-to/your-filename.json
    Separated metadata file (Already included in the above HTML and compressed, it can be deleted). Can be used for debugging or custom data collection.

Default Options

{
    // the report name
    name: '',

    // the output file path (relative process.cwd)
    outputFile: './test-results/report.html',

    // custom attachment path. default is relative to output file
    attachmentPath: null,
    // attachmentPath: (currentPath, extras) => `https://cenfun.github.io/monocart-reporter/${currentPath}`,

    // custom tags style
    tags: null,
    // tags: {
    //     smoke: {
    //         'background': '#6F9913'
    //     },
    //     sanity: {
    //         'background': '#178F43'
    //     }
    // },

    // custom columns
    columns: null,
    // columns: (defaultColumns) => {},

    // additional custom visitor for columns
    visitor: null,
    // visitor: (data, metadata, collect) => {},

    // async hook after report data generated
    onEnd: null
    // onEnd: async (reportData, capability) => {}
}

See options.js

Columns and Formatter

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',

            // custom columns
            columns: (defaultColumns) => {

                // insert custom column(s) before a default column
                const durationColumnIndex = defaultColumns.findIndex((column) => column.id === 'duration');
                defaultColumns.splice(durationColumnIndex, 0, {
                    // define the column in reporter
                    id: 'owner',
                    name: 'Owner',
                    align: 'center',
                    searchable: true,
                    styleMap: {
                        'font-weight': 'normal'
                    }
                }, {
                    // another column for JIRA link
                    id: 'jira',
                    name: 'JIRA Key',
                    width: 100,
                    searchable: true,
                    styleMap: 'font-weight:normal;',
                    formatter: (valueFormatted, rowItem, columnItem) => {
                        const key = rowItem[columnItem.id];
                        return `<a href="https://your-jira-key-link.com/${key}" target="_blank">${valueFormatted}</a>`;
                    }
                });

            }
        }]
    ]
};

Data Collection Visitor

Collect Data from Comments (similar to JsDoc)

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            // additional custom visitor for columns
            visitor: (data, metadata, collect) => {
                // auto collect data from comments
                const comments = collect.comments();
                if (comments) {
                    Object.assign(data, comments);
                }
            }
        }]
    ]
};

Adding Comments to Your Tests

Compared to importing external libraries and calling its interface, Comments is a better way, no dependence, cleaner, easy to read, and never break the existing code.

  • Case
/**
 * add extra information for case
 * @owner Kevin
 * @jira MCR-16888
 */
test('case title', () => { 

});

/**
 * @description multiple lines text description
multiple lines text description
multiple lines text description
 * @jira MCR-16888
*/
test('case description', () => {

});
  • Describe
/**
 * add extra information for describe
 * @owner Mark
 * @jira MCR-16900
 */
test.describe('suite title', () => {

});
  • Step
test('case title', ({ browserName }, testInfo) => {

    /**
     * override assert step title "expect.toBe" to
     * @title my custom assert step title
     * @annotations important
     */
    expect(testInfo).toBe(test.info());

    // @owner Steve
    await test.step('step title', () => {
       
    });

});
  • Hooks
/**
 * override "beforeAll hook" title to
 * @title do something before all
 */
test.beforeAll(() => { 

});

/**
 * override "beforeEach hook" title to
 * @title do something before each
 */
test.beforeEach(() => { 
    
});
  • File
/**
 * add extra information for file in the first line 
 * @owner FO
 */
const { test, expect } = require('@playwright/test');
  • Project (Can't use comments)
// playwright.config.js
module.exports = {
    projects: [
        {
            name: 'Desktop Chromium',
            // add extra information for project with metadata
            metadata: {
                owner: 'PO'
            }
        }
    ]
};  

Removing Secrets and Sensitive Data from Report

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            visitor: (data, metadata, collect) => {
                // remove secrets and sensitive data from reporter
                if (data.type === 'step') {

                    // step title before:
                    // locator.type(input[type=password], mysecretpassword)
                    // apiRequestContext.get(https://api.npmjs.org/?token=myapitoken)

                    const mySecrets = [process.env.LOGIN_PASSWORD, process.env.API_TOKEN];
                    mySecrets.forEach((secret) => {
                        data.title = data.title.replace(secret, '***');
                    });

                    // step title after:
                    // locator.type(input[type=password], ***)
                    // apiRequestContext.get(https://api.npmjs.org/?token=***)
                }
            }
        }]
    ]
};

Metadata

  • add metadata to config
// playwright.config.js
module.exports = {
    globalSetup: require.resolve('./common/global-setup.js'),
    metadata: {
        // test home page object model
        url: 'https://www.npmjs.org/package/monocart-reporter',
        // test addInitScript
        clientPath: 'tests/common/client.js'
    },
     reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html'
        }]
    ]
  • collect metadata in global setup
// ./common/global-setup.js
import { chromium } from '@playwright/test';
export default async (config) => {
    const metadata = config.metadata;
    // collect data and save to metadata
    const browser = await chromium.launch();
    const chromiumVersion = await browser.version();
    metadata.chromiumVersion = chromiumVersion;
};

Searchable Fields

// playwright.config.js
module.exports = {
     reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            columns: (defaultColumns) => {
                const locationColumn = defaultColumns.find((column) => column.id === 'location');
                locationColumn.searchable = true;
            }
        }]
    ]

Style Tags

  • Add tag to test title (starts with @)
test('test title @smoke @critical', () => { ... });
  • Custom tag style
// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            tags: {
                smoke: {
                    style: {
                        background: '#6F9913'
                    },
                    description: 'This is Smoke Test'
                },
                critical: {
                    background: '#c00'
                }
            }
        }]
    ]
};

Merge Shard Reports

There will be multiple reports to be generated if Playwright test executes in sharding mode. for example:

npx playwright test --shard=1/3
npx playwright test --shard=2/3
npx playwright test --shard=3/3

There are 3 reports will be generated. Using MonocartReporter.merge() API to merge all reports into one.

import MonocartReporter from 'monocart-reporter';

const reportDataList = [
    // json file path
    'path-to/shard1/index.json',
    'path-to/shard2/index.json',
    // or JSON data
    JSON.parse(fs.readFileSync(path.resolve('path-to/shard3/index.json')))
];

await MonocartReporter.merge(reportDataList, {
    name: 'My Merged Report',
    outputFile: 'merged-report/index.html',
    attachmentPath: (currentPath, extras) => {
       // return `https://cenfun.github.io/monocart-reporter/${currentPath}`;
    },
    onEnd: async (reportData, capability) => {
        
    }
});

example: merged report

onEnd callback

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            // async hook after report data generated
            onEnd: async (reportData, capability) => {
                //await myAsyncFunction();
            }
        }]
    ]
};

Send Email

Check example: send-email.js

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            onEnd: async (reportData, capability) => {
                const sendEmail = require('./common/send-email.js');
                await sendEmail(reportData, capability);
            }
        }]
    ]
};

Preview in Gmail

Testrail Integration

Check example: testrail.js

// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            onEnd: async (reportData, capability) => {
                const testrail = require('./common/testrail.js');
                await testrail(reportData, capability);
            }
        }]
    ]
};

Preview Testrail Run/Results

Slack Integration

  1. Simply send message with @slack/webhook, example: slack-webhook.js
// playwright.config.js
module.exports = {
    reporter: [
        ['monocart-reporter', {  
            name: "My Test Report",
            outputFile: './test-results/report.html',
            onEnd: async (reportData, capability) => {
                const slackWebhook = require('./common/slack-webhook.js');
                await slackWebhook(reportData, capability);
            }
        }]
    ]
};
  1. Post chat message or upload report file with @slack/web-api, example: slack-web-api.js

Preview in Slack

Report UI packages/app

Dependencies

nmls -p
┌────────────────────────────┬─────────┬──────────┬──────┬───────────┬────────┐
│  Name                      │ Version │     Size │ Deps │ Deps Size │ Nested │
├────────────────────────────┼─────────┼──────────┼──────┼───────────┼────────┤
│ └ monocart-reporter        │ 1.6.3   │ 598.5 KB │   18 │   2.50 MB │      1 │
│   ├ dependencies           │         │          │      │           │        │
│   │ ├ @babel/code-frame    │ 7.18.6  │  6.82 KB │   10 │  153.0 KB │      0 │
│   │ ├ @babel/parser        │ 7.21.3  │  1.79 MB │    0 │       0 B │      0 │
│   │ ├ console-grid         │ 2.0.1   │  36.9 KB │    0 │       0 B │      0 │
│   │ ├ eight-colors         │ 1.0.3   │  14.9 KB │    0 │       0 B │      0 │
│   │ ├ lz-utils             │ 1.0.6   │  26.5 KB │    0 │       0 B │      0 │
│   │ ├ nodemailer           │ 6.9.1   │ 476.0 KB │    0 │       0 B │      0 │
│   │ └ stack-utils          │ 2.0.6   │  14.3 KB │    1 │   3.18 KB │      1 │
├────────────────────────────┼─────────┼──────────┼──────┼───────────┼────────┤
│   └ packages in workspaces │         │          │      │           │        │
│     └ monocart-reporter    │ 1.6.3   │ 534.4 KB │    0 │       0 B │      0 │
└────────────────────────────┴─────────┴──────────┴──────┴───────────┴────────┘

CHANGELOG

About

A playwright test reporter (Node.js)

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • JavaScript 66.0%
  • Vue 33.7%
  • HTML 0.3%