Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

A playwright test reporter (Node.js)

License

NotificationsYou must be signed in to change notification settings

cenfun/monocart-reporter

Repository files navigation

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

Install

npm i -D monocart-reporter

Playwright Config

Note: Most examples useCommonJS by default, pleasemove to ESM according to your needs.

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

Playwright Docshttps://playwright.dev/docs/test-reporters

Examples

Tutorial

Output

  • path-to/your-filename.html
    Single HTML file (data compressed), easy to transfer/deploy or open directly anywhere

Note: All attachments (screenshots images/videos) will be linked with relative path in report.

  • path-to/your-filename.json (requires optionjson is true)Separated data file which can be used for debugging or data provider (It's included in the above HTML and compressed).
  • path-to/your-filename.zip (requires optionzip is true)Zip file for merging reports
    • custom zip options
{// zip: true,// zip: `${YourOutputDir}/monocart-shard-${your-shard-number}.zip`,zip:{// custom zip `outputFile`, defaults to reporter `outputFile` but uses `.zip` extensionoutputFile:`${YourOutputDir}/monocart-shard-${your-shard-number}.zip`,// clean other report files except for zip file, defaults to falseclean:true}}

Reporter Options

View Trace Online

TheTrace Viewer requires that the trace file must be loaded over the http:// or https:// protocols withoutCORS issue.

  • Start a local web server with following CLI:
# serve and open reportnpx monocart show-report<path-to-report># serve reportnpx monocart serve-report<path-to-report>

The server add the http headerAccess-Control-Allow-Origin: * toallow requesting from any origin, it works withhttp://localhost:port/ orhttp://127.0.0.1:port/

  • To successfully work with otherIP ordomain, you can start web server withhttps:
npx monocart show-report<path-to-report> --ssl<path-to-key,path-to-cert>

For example:npx monocart show-report monocart-report/index.html --ssl ssl/key.pem,ssl/cert.pem

You can create and install local CA withmkcert

  • Using your own trace viewer url with optiontraceViewerUrl:
// reporter options{name:"My Test Report",outputFile:'./monocart-report/index.html',// defaults to 'https://trace.playwright.dev/?trace={traceUrl}'traceViewerUrl:'https://your-own-trace-viewer-url/?trace={traceUrl}'}

Custom Fields Report

You can add custom fields to the report. for example: Owner, JIRA Key etc.

Custom Columns

The report will be displayed in aTree Grid. Thecolumns function is used to customize the grid columns. The column properties following:

  • id (String) Column id (required)
  • name (String) Column name, shows in grid header
  • align (String) left (default), center, right
  • width (Number) Column width
  • minWidth,maxWidth (Number) Default to 81 ~ 300
  • styleMap (Object, String) Column style (css)
  • formatter (Function)column formatter. Arguments: value, rowItem, columnItem, cellNode
  • sortable (Boolean) Column sortable when click column header name
  • resizable (Boolean) Column width resizable
  • searchable (Boolean) Specifies whether the column is searchable
  • markdown (Boolean) Specifies whether the column needs to use markdown conversion
  • detailed (Boolean) Specifies whether the column needs to display the layout in detail (horizontal)
  • more propertiescolumnProps
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',// custom columnscolumns:(defaultColumns)=>{// insert custom column(s) before a default columnconstindex=defaultColumns.findIndex((column)=>column.id==='duration');defaultColumns.splice(index,0,{// define the column in reporterid:'owner',name:'Owner',align:'center',searchable:true,styleMap:{'font-weight':'normal'}},{// another column for JIRA linkid:'jira',name:'JIRA Key',width:100,searchable:true,styleMap:'font-weight:normal;',formatter:(v,rowItem,columnItem)=>{constkey=rowItem[columnItem.id];return`<a href="https://your-jira-url/${key}">${v}</a>`;}});}}]]};

Column Formatter

Note: Theformatter function will be serialized into string via JSON, so closures, contexts, etc. will not work!

// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',columns:(defaultColumns)=>{// duration formatterconstdurationColumn=defaultColumns.find((column)=>column.id==='duration');durationColumn.formatter=function(value,rowItem,columnItem){if(typeofvalue==='number'&&value){return`<i>${value.toLocaleString()} ms</i>`;}returnvalue;};// title formatter// Note: The title shows the tree style, it is a complicated HTML structure// it is recommended to format title base on previous.consttitleColumn=defaultColumns.find((column)=>column.id==='title');titleColumn.formatter=function(value,rowItem,columnItem,cellNode){constperviousFormatter=this.getFormatter('tree');constv=perviousFormatter(value,rowItem,columnItem,cellNode);if(rowItem.type==='step'){return`${v}<div>✅</div>`;}returnv;};}}]]};

Searchable Fields

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

Custom Fields in Comments

The code comments are good enough to provide extra information without breaking existing code, and no dependencies, clean, easy to read, etc.

  • First, enable optioncustomFieldsInComments totrue
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{// enable/disable custom fields in comments. Defaults to true.customFieldsInComments:true}]]};
  • Then, add comments for the tests

Note: Each comment item must start with@ which is similar toJSDoc.

For example, addingowner andjira to the cases, steps, and suites. or updating the value if the field exists liketitle

/** * for file (comment file in the first line) *@owner FO */const{ test, expect}=require('@playwright/test');/** * for case *@owner Kevin *@jira MCR-16888 */test('case title',()=>{});/** *@description multiple lines text descriptionmultiple lines text descriptionmultiple lines text description *@jira MCR-16888*/test('case description',()=>{});/** * for describe suite *@owner Mark *@jira MCR-16900 */test.describe('suite title',()=>{test('case title',({ browserName},testInfo)=>{/**         * rewrite assert step title "expect.toBe" to         *@title my custom assert step title         *@annotations important         */expect(testInfo).toBe(test.info());//@owner Steveawaittest.step('step title',()=>{});});});/** * rewrite "beforeAll hook" title to *@title do something before all */test.beforeAll(()=>{});/** * rewrite "beforeEach hook" title to *@title do something before each */test.beforeEach(()=>{});

Create Diagrams and Visualizations withMermaid

  • Enable Mermaid
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',mermaid:{// mermaid script url, using mermaid CDN: https://www.jsdelivr.com/package/npm/mermaidscriptSrc:'https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js',// mermaid config: https://mermaid.js.org/config/schema-docs/config.htmlconfig:{startOnLoad:false}}}]]};
  • Write Mermaid code in markdown:
/** *@description Sequence diagram for Monocart Reporter```mermaidflowchart LRA[Hard] -->|Text| B(Round)B --> C{Decision}C -->|One| D[Result 1]C -->|Two| E[Result 2]```*/test('case description',()=>{});

seeMermaid doc

Custom Fields withsetMetadata()

Usingcomments is only applicable to statically created tests, while using APIsetMetadata() can be applicable to all situations, which is including dynamically created tests.

const{ test}=require('@playwright/test');const{ setMetadata}=require('monocart-reporter');test.describe('Data Driven Tests with setMetadata(data, testInfo)',()=>{constlist=[{title:'Example Case 1 Data Driven Test',owner:'Jensen',jira:'MCR-16889',},{title:'Example Case 2 Data Driven Test',owner:'Mark',jira:'MCR-16899'}];list.forEach((item,i)=>{test(item.title,()=>{setMetadata({owner:item.owner,jira:item.jira},test.info());//expect(1).toBe(1);});});});

Custom Data Visitor

Thevisitor function will be executed for each row item (suite, case and step). Arguments:

  • data data item (suite/case/step) for reporter, you can rewrite some of its properties or add more
  • metadata original data object from Playwright test, could be one ofSuite,TestCase orTestStep

Collect Data from the Title

For example, we want to parse out the jira key from the title:

test('[MCR-123] collect data from the title',()=>{});

You can simply use regular expressions to parse and get jira key:

// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',visitor:(data,metadata)=>{// [MCR-123] collect data from the titleconstmatchResult=metadata.title.match(/\[(.+)\]/);if(matchResult&&matchResult[1]){data.jira=matchResult[1];}}}]]};

multiple matches example:collect-data

Collect Data from the Annotations

It should be easier than getting from title. seecustom annotations viatest.info().annotations

test('collect data from the annotations',()=>{test.info().annotations.push({type:"jira",description:"MCR-123"})});
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',visitor:(data,metadata)=>{// collect data from the annotationsif(metadata.annotations){constjiraItem=metadata.annotations.find((item)=>item.type==='jira');if(jiraItem&&jiraItem.description){data.jira=jiraItem.description;}}}}]]};

Remove Secrets and Sensitive Data

The report may hosted outside of the organization’s internal boundaries, security becomes a big issue. Any secrets or sensitive data, such as usernames, passwords, tokens and API keys, should be handled with extreme care. The following example is removing the password and token from the report data with the string replacement invisitor function.

// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',visitor:(data,metadata)=>{constmySecrets=[process.env.PASSWORD,process.env.TOKEN];mySecrets.forEach((secret)=>{// remove from titledata.title=data.title.replace(secret,'***');// remove from logsif(data.logs){data.logs=data.logs.map((item)=>item.replace(secret,'***'));}// remove from errorsif(data.errors){data.errors=data.errors.map((item)=>item.replace(secret,'***'));}});}}]]};

see example:remove-secrets

Style Tags

  • Add tag to test/describe title ( starts with@ )
test('test title @smoke @critical',()=>{});test.describe('describe title @smoke @critical',()=>{});// new syntax for tag in playwright v1.42.0test('test title',{tag:['@smoke','@critical']},()=>{});test.describe('describe title',{tag:['@smoke','@critical']},()=>{});
  • Custom tag style
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',tags:{smoke:{style:{background:'#6F9913'},description:'This is Smoke Test'},critical:{background:'#c00'}}}]]};
  • Put style tags in new column
module.exports={reporter:[['list'],['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',tags:{// ...},columns:(defaultColumns)=>{// disable title tagsdefaultColumns.find((column)=>column.id==='title').titleTagsDisabled=true;// add tags columnconstindex=defaultColumns.findIndex((column)=>column.id==='type');defaultColumns.splice(index,0,{id:'tags',name:'Tags',width:150,formatter:'tags'});}}]]};

seeexample

Metadata

All metadata will be listed in the report in a key/value format.

  • Global levelmetadata
// playwright.config.jsmodule.exports={globalSetup:require.resolve('./common/global-setup.js'),metadata:{product:'Monocart',env:'STG',type:'Regression',executor:'Mono',// test home page object modelurl:'https://www.npmjs.org/package/monocart-reporter'},reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html'}]]};
  • Project levelmetadata
// playwright.config.jsmodule.exports={projects:[{name:'Desktop Chromium',use:{browserName:'chromium'},metadata:{projectData:'project level metadata',owner:'PO',link:'https://github.com/cenfun/monocart-reporter'}}]}
// ./common/global-setup.jsimport{chromium}from'@playwright/test';exportdefaultasync(config)=>{constmetadata=config.metadata;// collect data and save to global metadataconstbrowser=awaitchromium.launch();constchromiumVersion=awaitbrowser.version();metadata.chromiumVersion=chromiumVersion;};
  • Collect metadata in a test

    Playwright Test runs tests inparallel with isolate test data by default, so we need to utilizeglobal state management to collect metadata in a test.

    const{ test}=require('@playwright/test');const{ useState}=require('monocart-reporter');conststate=useState({// port: 8130});test('test metadata url',async({ page})=>{consturl=awaitpage.evaluate(()=>window.location.href);awaitstate.set('url',url);});

Trend Chart

Note: The trend chart requires historical data generally stored in the server database. There is a serverless solution which is connecting and collecting historical trend data from previous report data before test every time.

  • If a report is generated in the same place every time, you can simply connect the data with the report JSON path (the data is not 100% safe if there is any runtime error, the previous output dir will be empty by Playwright but the reporter processing not finish)
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',// connect previous report data for trend charttrend:'./monocart-report/index.json'}]]};
  • Recommended: resolve the data by yourself (could be requested from the server), required data fields:
    • date (Number) the previous test date in milliseconds
    • duration (Number) the previous test duration
    • summary (Object) the previous test summary
    • trends (Array) historical data list, but except the previous self
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',// connect previous report data for trend charttrend:async()=>{constpreviousReportData=awaitreadDataFromSomeWhere("path-to/report.json");// do some data filtering to previous trendspreviousReportData.trends=previousReportData.trends.filter((item)=>{// remove data a week agoreturnitem.date>(Date.now()-7*24*60*60*1000)});returnpreviousReportData;}}]]};

Code Coverage Report

The reporter integratesmonocart-coverage-reports for coverage reports, there are two APIs:

  • addCoverageReport(data, testInfo) Add coverage to global coverage report from a test. seeGlobal Coverage Report
    • data There are two supported data inputs:Istanbul (Object) orV8 (Array)
    • testInfo seeTestInfo
  • attachCoverageReport(data, testInfo, options) Attach a coverage report to a test. Arguments:

Global Coverage Report

The global coverage report will merge all coverages into one global report after all the tests are finished.

// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',// global coverage report optionscoverage:{entryFilter:(entry)=>true,sourceFilter:(sourcePath)=>sourcePath.search(/src\/.+/)!==-1,}}]]};
// fixtures.js for v8 coverageimport{testastestBase,expect}from'@playwright/test';import{addCoverageReport}from'monocart-reporter';consttest=testBase.extend({autoTestFixture:[async({ page},use)=>{// NOTE: it depends on your project nameconstisChromium=test.info().project.name==='Desktop Chromium';// console.log('autoTestFixture setup...');// coverage API is chromium onlyif(isChromium){awaitPromise.all([page.coverage.startJSCoverage({resetOnNavigation:false}),page.coverage.startCSSCoverage({resetOnNavigation:false})]);}awaituse('autoTestFixture');// console.log('autoTestFixture teardown...');if(isChromium){const[jsCoverage,cssCoverage]=awaitPromise.all([page.coverage.stopJSCoverage(),page.coverage.stopCSSCoverage()]);constcoverageList=[...jsCoverage, ...cssCoverage];// console.log(coverageList.map((item) => item.url));awaitaddCoverageReport(coverageList,test.info());}},{scope:'test',auto:true}]});export{test,expect};
  • Adding server side coverage on global teardown

For example, a Node.js web server start at the beginning of the test with the envNODE_V8_COVERAGE=dir, the V8 coverage data will be saved todir with calling APIv8.takeCoverage() manually or terminating server gracefully. On global teardown, reading all fromdir and adding them to global coverage report. For Node.js, the V8 coverage data requires appending source manually.

// global-teardown.jsimportfsfrom'fs';importpathfrom'path';import{fileURLToPath}from'url';import{addCoverageReport}from'monocart-reporter';exportdefaultasync(config)=>{constdir="your-v8-coverage-data-dir";constfiles=fs.readdirSync(dir);for(constfilenameoffiles){constcontent=fs.readFileSync(path.resolve(dir,filename)).toString('utf-8');constjson=JSON.parse(content);letcoverageList=json.result;coverageList=coverageList.filter((entry)=>entry.url&&entry.url.startsWith('file:'));// appending sourcecoverageList.forEach((entry)=>{entry.source=fs.readFileSync(fileURLToPath(entry.url)).toString('utf8');});// there is no test info on teardown, just mock one with required configconstmockTestInfo={            config};awaitaddCoverageReport(coverageList,mockTestInfo);}}

seeCollecting V8 Coverage Data from Node.js

Coverage Options

Coverage Examples

Attach Markdown/Mermaid

test.info().attach('text/markdown:',{contentType:'text/markdown',body:`### My Markdown Title- item 1- item 2`});test.info().attach('text/mermaid:',{contentType:'text/mermaid',body:`    flowchart LR    id    `});

Attach Lighthouse Audit Report

Attach an audit report with APIattachAuditReport(runnerResult, testInfo). Arguments:

const{ test, chromium}=require('@playwright/test');const{ attachAuditReport}=require('monocart-reporter');constlighthouse=require('lighthouse/core/index.cjs');test('attach lighthouse audit report',async()=>{constport=9222;constbrowser=awaitchromium.launch({args:[`--remote-debugging-port=${port}`]});constoptions={// logLevel: 'info',// onlyCategories: ['performance', 'best-practices', 'seo'],output:'html',        port};consturl='https://github.com/cenfun/monocart-reporter';construnnerResult=awaitlighthouse(url,options);awaitbrowser.close();awaitattachAuditReport(runnerResult,test.info());});

Attach Network Report

Attach a network report with APIattachNetworkReport(har, testInfo). Arguments:

Generate HAR withrecordHar option in browser.newContext() (see example:report-network.spec.js previewreport)

constfs=require('fs');constpath=require('path');const{ test}=require('@playwright/test');const{ attachNetworkReport}=require('monocart-reporter');letcontext;test.describe('attach network report 1',()=>{constharPath=path.resolve('.temp/network-report1.har');if(fs.existsSync(harPath)){// remove previousfs.rmSync(harPath);}test('first, open page',async({ browser})=>{context=awaitbrowser.newContext({recordHar:{path:harPath}});constpage=awaitcontext.newPage();awaitpage.goto('https://github.com/cenfun/monocart-reporter');});test('next, run test cases',async()=>{});test('finally, attach HAR',async()=>{// Close context to ensure HAR is saved to disk.awaitcontext.close();awaitattachNetworkReport(harPath,test.info());});});

Generate HAR withplaywright-har

import{test}from'@playwright/test';import{attachNetworkReport}from'monocart-reporter';import{PlaywrightHar}from'playwright-har';constharPath=path.resolve('.temp/network-report2.har');if(fs.existsSync(harPath)){// remove previousfs.rmSync(harPath);}test('first, open page',async({ browser})=>{constcontext=awaitbrowser.newContext();constpage=awaitcontext.newPage();playwrightHar=newPlaywrightHar(page);awaitplaywrightHar.start();awaitpage.goto('https://github.com/cenfun/monocart-reporter');});test('next, run test cases',async()=>{});test('finally, attach HAR',async()=>{awaitplaywrightHar.stop(harPath);awaitattachNetworkReport(harPath,test.info());});

PreviewNetwork HTML Report

Global State Management

When tests are executed inisolation mode, the reporter and each test may run in a different process, they cannot share data with each other. we can start a local WebSocket server to serve the global data, and read/write the global data withuseState API from a test.

Setup Global State

module.exports={reporter:[['list'],['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',state:{data:{count:0},server:{// port: 8130},onClose:(data,config)=>{// save state data to global metadataObject.assign(config.metadata,data);}}}]]};

Get, Set, and Remove Global Data

const{ test}=require('@playwright/test');const{ useState}=require('monocart-reporter');test('state test',async({ browserName})=>{conststate=useState({// port: 8130});constcount=awaitstate.get('count');console.log('count',count);awaitstate.set('count',count+1);awaitstate.set({browser:browserName,someKey:'some value'});const[browser,someKey]=awaitstate.get('browser','someKey');console.log(browser,someKey);awaitstate.remove('someKey');constall=awaitstate.get();console.log(all);});

Send and Receive Messages between Processes

  • send message and receive response from a test (child process)
const{ test}=require('@playwright/test');const{ useState}=require('monocart-reporter');test('state test send message',async()=>{conststate=useState({// port: 8130});constresponse=awaitstate.send({testId:test.info().testId,data:'my test data'});console.log('receive response on client',response);});
  • receive message and send response from global state (main process)
module.exports={reporter:[['list'],['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',state:{onReceive:function(message){consttest=this.getTest(message.testId);if(test){// current test}console.log('receive message on server',message);return{data:'my response data'};}}}]]};

see example:Allow specified test cases to run in sequence mode with lock/unlock state

Merge Shard Reports

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

npx playwrighttest --shard=1/3npx playwrighttest --shard=2/3npx playwrighttest --shard=3/3

There are 3 reports will be generated.

Usingmerge API to merge all reports into one

Note: One more suite level "shard" will be added, its title will be the machine hostname, and the summary will be restated. All attachments will be copied to the merged output directory.

import{merge}from'monocart-reporter';// json file pathconstreportDataList=['path-to/shard1/index.json','path-to/shard2/index.json','path-to/shard3/index.json'// Or load zip file directly if the output files is zipped with option `zip` is true// 'path-to/shard1/index.zip',// 'path-to/shard2/index.zip',// 'path-to/shard3/index.zip'];awaitmerge(reportDataList,{name:'My Merged Report',outputFile:'merged-report/index.html',onEnd:async(reportData,helper)=>{// send email or third party integration}});

seeOutput forzip options

Note: The coverage reports will be merged automatically if we specify theraw report in coverage options:

// global coverage optionscoverage:{reports:[// for merging coverage reports'raw'// we can merge and zip the raw report files// ['raw', { merge: true, zip: true }]]}

see examplemerge.js

Usingmerge CLI

npx monocart merge<glob-patterns># -o --outputFilenpx monocart merge path-to/shard*/index.json -o merged-reports/index.html# -c --confignpx monocart merge path-to/shard*/my-report.zip -c mr.config.js# NOTE: The asterisk(*) is a special character which is interpreted by some operating systems# For example: Mac and Linux, please put it in quotes, but NOT for Windowsnpx monocart merge'path-to/shard*/*.zip'

The default config files (In order of priority)

  • mr.config.js
  • mr.config.cjs
  • mr.config.mjs
  • mr.config.json
  • mr.config.ts

Preload for TypeScript config file:

  • It requires node 18.19.0+
  • Installing tsx:npm i -D tsx
  • Using the--import tsx flag
  • seecomment

onEnd Hook

TheonEnd function will be executed after report generated. Arguments:

  • reportData all report data, properties:
    • name (String) report name
    • date (Number) start date in milliseconds
    • dateH (String) human-readable date withDate.toLocaleString()
    • duration (Number) test duration in milliseconds
    • durationH (String) human-readable duration
    • summary (Object) test summary, includestests,suites,steps, etc.
    • rows andcolumns (Array) all rows and columns data, both are tree structure, seedetail
    • tags (Object) tag collection
    • metadata (Object) metadata collection
    • system (Object) system information
    • trends (Array) historical trend data
    • caseTypes andsuiteTypes (Array)
    • cwd,outputDir andoutputFile (String)
    • htmlPath,jsonPath andsummaryTable (String)
    • ...
  • helper APIs:
    • helper.find(callback) Find item like arrayfind function.
    • helper.filter(callback) Filter list like arrayfilter function.
    • helper.forEach(callback) Iterate all rows of data (suites/cases/steps), returnbreak will break the iteration.
    • helper.sendEmail(emailOptions)
// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',// async hook after report data generatedonEnd:async(reportData,helper)=>{// console.log(reportData.summary);// find a test by titleconstmyCase=helper.find((item,parent)=>item.type==='case'&&item.title.includes('inline tag'));console.log(myCase&&myCase.title);// find a suite by titleconstmySuite=helper.find((item,parent)=>item.type==='suite'&&item.title.includes('new syntax'));console.log(mySuite&&mySuite.title);// filter failed casesconstfailedCases=helper.filter((item,parent)=>item.type==='case'&&item.caseType==='failed');console.log(failedCases.map((it)=>it.title));// Iterate all itemshelper.forEach((item,parent)=>{// do something});}}]]};

onData hook

TheonData function will be executed after report data generated (beforeonEnd).

// playwright.config.jsmodule.exports={reporter:[['monocart-reporter',{name:"My Test Report",outputFile:'./monocart-report/index.html',onData:(reportData)=>{// console.log('onData', reportData);reportData.name='My New Report Name';}}]]};

Integration Examples

By using theonEnd hook, we can integrate Playwright report with any other tools, such as:

Seeplaywright-reporter-integrations

Contributing

# Node.js 20+npm install starfall-cli -gnpm installnpm run buildnpm runtestnpm run dev

Dependencies


[8]ページ先頭

©2009-2025 Movatter.jp