Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Playwright

...

Playwright comes with several built-in reporters that help you visualize, log, and analyze test results. Here's a brief overview:

...

List Reporter (list):

  • This is the default reporter.

  • It provides a simple, human-readable output in the terminal, listing each test as it runs.

  • Shows test results (pass/fail) with clear indicators.

Dot Reporter (dot):

...

is

...

Good for situations where you want very concise feedback.

...

Line Reporter (line):

  • Similar to the dot reporter, but each test is displayed on a single line.

  • Provides more information than dot but still remains compact.

...

JSON Reporter (json):

  • Outputs test results in JSON format.

  • Useful for processing test results programmatically or for integrating with other tools.

...

JUnit Reporter (junit):

  • Generates an XML report in the JUnit format.

  • This is often used in CI/CD pipelines for integrating with test reporting tools.

...

HTML Reporter (html):

  • Generates a detailed HTML report.

  • Includes test results, screenshots, and videos (if configured).

  • Allows you to drill down into each test case and step.

...

  • Third-party reporters are community-contributed plugins that extend Playwright's reporting capabilities.

  • These reporters often integrate with popular testing and CI/CD tools, offering additional features or customizations that aren't available in Playwright's built-in reporters.

For more details: https://playwright.dev/docs/test-reporters#introduction

Custom Reporter using Playwright API

Playwright Offers API to write custom test reports. A custom reporter is a class that implements specific methods to handle events during the test run. Playwright Reporter API can be implemented and the native reporter methods of API can overridden based on needs. Below is an example:

PlaywrightCustomReporter.js

Code Block
languagejs
class MyCustomReporter {
  
   onBegin(config, suite) {
      console.log(`Starting the test run with ${suite.allTests().length} tests`);
   }

  
   onSuiteBegin(suite) {
      console.log(`Starting suite: ${suite.title}`);
   }

  
   onSuiteEnd(suite) {
      console.log(`Finished suite: ${suite.title}`);
   }

 
   onTestBegin(test) {
      console.log(`Starting test: ${test.title}`);
   }

  
   onTestEnd(test, result) {
      console.log(`Finished test: ${test.title} with status ${result.status}`);
      if (result.error) {
         console.error(`Error: ${result.error.message}`);
      }
   }

   
   onTestFailure(test, result) {
      console.error(`Test failed: ${test.title}`);
      console.error(`Error: ${result.error.message}`);
   }

  
   onTestSuccess(test, result) {
      console.log(`Test passed: ${test.title}`);
   }

   
   onTestTimeout(test) {
      console.warn(`Test timed out: ${test.title}`);
   }

   // Called when a test's retry count is exhausted
   onTestRetry(test) {
      console.warn(`Test retried: ${test.title}`);
   }

  
   onEnd(result) {
      console.log(`Test run finished with status ${result.status}`);
      console.log(`Total tests: ${result.totalTests}`);
      console.log(`Passed: ${result.passedTests}`);
      console.log(`Failed: ${result.failedTests}`);
   }

   
   onStdOut(data) {
      process.stdout.write(data);
   }

  
   onStdErr(data) {
      process.stderr.write(data);
   }

  
   onStepBegin(test, step) {
    console.log('Step Begin:');
    console.log('Test:', test);
    console.log('Step:', step);
  }
  
  onStepEnd(test, step, result) {
    console.log('Step End:');
    console.log('Test:', test);
    console.log('Step:', step);
    console.log('Result:', result);
  }
  
}

export default MyCustomReporter;

This code defines a custom reporter class MyCustomReporter that implements various methods to track and log the progress of a test run. It's designed to be used with a testing framework, likely Playwright, where it provides detailed logs at different stages of the test execution process.

Here’s a brief explanation of each method:

  1. onBegin(config, suite): Logs the start of the test run, including the number of tests in the suite.

  2. onSuiteBegin(suite): Logs the start of a test suite.

  3. onSuiteEnd(suite): Logs the end of a test suite.

  4. onTestBegin(test): Logs the start of an individual test.

  5. onTestEnd(test, result): Logs the end of an individual test, including its status and any errors if they occurred.

  6. onTestFailure(test, result): Logs detailed information about a failed test.

  7. onTestSuccess(test, result): Logs a message when a test passes.

  8. onTestTimeout(test): Logs when a test times out.

  9. onTestRetry(test): Logs when a test is retried.

  10. onEnd(result): Logs the summary of the test run, including the status and counts of total, passed, and failed tests.

  11. onStdOut(data): Writes stdout output to the console.

  12. onStdErr(data): Writes stderr output to the console.

  13. onStepBegin(test, step): Logs the start of a test step, along with the test and step details.

Code Block
languagejson
{
  "test": {
      "title": "basic test",
      "_only": false,
      "_requireFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
      "results": [
        {
          "retry": 0,
          "parallelIndex": 0,
          "workerIndex": 0,
          "duration": 2662,
          "startTime": "2024-08-21T14:36:32.149Z",
          "stdout": [],
          "stderr": [],
          "attachments": [],
          "status": "passed",
          "steps": [
            {
              "title": "Before Hooks",
              "category": "hook",
              "startTime": "2024-08-21T14:36:32.156Z",
              "duration": 1519,
              "steps": [
                {
                  "title": "fixture: browser",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:36:32.170Z",
                  "duration": 304,
                  "steps": [
                    {
                      "title": "browserType.launch",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:36:32.176Z",
                      "duration": 298,
                      "steps": []
                    }
                  ]
                },
                {
                  "title": "fixture: context",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:36:32.476Z",
                  "duration": 20,
                  "steps": [
                    {
                      "title": "browser.newContext",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:36:32.480Z",
                      "duration": 12,
                      "steps": []
                    }
                  ]
                },
                {
                  "title": "fixture: page",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:36:32.497Z",
                  "duration": 1178,
                  "steps": [
                    {
                      "title": "browserContext.newPage",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:36:32.501Z",
                      "duration": 1174,
                      "steps": []
                    }
                  ]
                }
              ]
            },
            {
              "title": "page.goto(https://sandbox.mabl.com/)",
              "category": "pw:api",
              "startTime": "2024-08-21T14:36:33.680Z",
              "duration": 1231,
              "steps": [],
              "location": {
                "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
                "line": 5,
                "column": 15
              }
            },
            {
              "title": "locator.getByRole('button', { name: 'new window' }).click",
              "category": "pw:api",
              "startTime": "2024-08-21T14:36:34.925Z",
              "duration": 186,
              "steps": [],
              "location": {
                "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
                "line": 6,
                "column": 57
              }
            },
            {
              "title": "After Hooks",
              "category": "hook",
              "startTime": "2024-08-21T14:36:35.112Z",
              "duration": 24,
              "steps": [
                {
                  "title": "fixture: page",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:36:35.114Z",
                  "duration": 1,
                  "steps": []
                },
                {
                  "title": "fixture: context",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:36:35.116Z",
                  "duration": 1,
                  "steps": []
                }
              ]
            }
          ],
          "errors": []
        }
      ],
      "location": {
        "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
        "line": 4,
        "column": 1
      },
      "parent": {
        "title": "example.spec.js",
        "_only": false,
        "_requireFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
        "location": {
          "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
          "line": 0,
          "column": 0
        },
        "parent": {
          "title": "",
          "_only": false,
          "_requireFile": "",
          "parent": {
            "title": "",
            "_only": false,
            "_requireFile": "",
            "_use": [],
            "_entries": [
              null
            ],
            "_hooks": [],
            "_staticAnnotations": [],
            "_tags": [],
            "_modifiers": [],
            "_parallelMode": "none",
            "_type": "root"
          },
          "_use": [],
          "_entries": [
            null
          ],
          "_hooks": [],
          "_staticAnnotations": [],
          "_tags": [],
          "_modifiers": [],
          "_parallelMode": "none",
          "_fullProject": {
            "project": {
              "grep": {},
              "grepInvert": null,
              "outputDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\test-results",
              "repeatEach": 1,
              "retries": 0,
              "metadata": {},
              "name": "",
              "testDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "snapshotDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "testIgnore": [],
              "testMatch": "**/*.@(spec|test).?(c|m)[jt]s?(x)",
              "timeout": 30000,
              "use": {},
              "dependencies": [],
              "__projectId": ""
            },
            "fullConfig": {
              "config": {
                "configFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\playwright.config.js",
                "rootDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
                "forbidOnly": false,
                "fullyParallel": false,
                "globalSetup": null,
                "globalTeardown": null,
                "globalTimeout": 0,
                "grepInvert": null,
                "maxFailures": 0,
                "metadata": {
                  "actualWorkers": 1
                },
                "preserveOutput": "always",
                "reporter": [
                  [
                    "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\PlaywrightReporter.js",
                    null
                  ]
                ],
                "reportSlowTests": {
                  "max": 5,
                  "threshold": 15000
                },
                "quiet": false,
                "projects": [
                  null
                ],
                "shard": null,
                "updateSnapshots": "missing",
                "version": "1.46.1",
                "workers": 4,
                "webServer": null
              },
              "configDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "configCLIOverrides": {},
              "webServers": [],
              "plugins": [],
              "projects": [
                null
              ],
              "cliArgs": [],
              "cliListOnly": false,
              "cliPassWithNoTests": false,
              "cliFailOnFlakyTests": false,
              "defineConfigWasUsed": true
            },
            "expect": {},
            "respectGitIgnore": true,
            "snapshotPathTemplate": "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}",
            "ignoreSnapshots": false,
            "id": "",
            "deps": []
          },
          "_type": "project"
        },
        "_use": [],
        "_entries": [
          null
        ],
        "_hooks": [],
        "_staticAnnotations": [],
        "_tags": [],
        "_modifiers": [],
        "_parallelMode": "none",
        "_fileId": "dd9b2edffe9b7501040c",
        "_type": "file"
      },
      "type": "test",
      "expectedStatus": "passed",
      "timeout": 30000,
      "annotations": [],
      "retries": 0,
      "repeatEachIndex": 0,
      "_testType": {
        "fixtures": [
          {
            "fixtures": {
              "defaultBrowserType": [
                "chromium",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "browserName": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "playwright": [
                null,
                {
                  "scope": "worker",
                  "box": true
                }
              ],
              "headless": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "channel": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "launchOptions": [
                {},
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "connectOptions": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "screenshot": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "video": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "trace": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_browserOptions": [
                null,
                {
                  "scope": "worker",
                  "auto": true,
                  "box": true
                }
              ],
              "browser": [
                null,
                {
                  "scope": "worker",
                  "timeout": 0
                }
              ],
              "acceptDownloads": [
                null,
                {
                  "option": true
                }
              ],
              "bypassCSP": [
                null,
                {
                  "option": true
                }
              ],
              "colorScheme": [
                null,
                {
                  "option": true
                }
              ],
              "deviceScaleFactor": [
                null,
                {
                  "option": true
                }
              ],
              "extraHTTPHeaders": [
                null,
                {
                  "option": true
                }
              ],
              "geolocation": [
                null,
                {
                  "option": true
                }
              ],
              "hasTouch": [
                null,
                {
                  "option": true
                }
              ],
              "httpCredentials": [
                null,
                {
                  "option": true
                }
              ],
              "ignoreHTTPSErrors": [
                null,
                {
                  "option": true
                }
              ],
              "isMobile": [
                null,
                {
                  "option": true
                }
              ],
              "javaScriptEnabled": [
                null,
                {
                  "option": true
                }
              ],
              "locale": [
                null,
                {
                  "option": true
                }
              ],
              "offline": [
                null,
                {
                  "option": true
                }
              ],
              "permissions": [
                null,
                {
                  "option": true
                }
              ],
              "proxy": [
                null,
                {
                  "option": true
                }
              ],
              "storageState": [
                null,
                {
                  "option": true
                }
              ],
              "clientCertificates": [
                null,
                {
                  "option": true
                }
              ],
              "timezoneId": [
                null,
                {
                  "option": true
                }
              ],
              "userAgent": [
                null,
                {
                  "option": true
                }
              ],
              "viewport": [
                null,
                {
                  "option": true
                }
              ],
              "actionTimeout": [
                0,
                {
                  "option": true
                }
              ],
              "testIdAttribute": [
                "data-testid",
                {
                  "option": true
                }
              ],
              "navigationTimeout": [
                0,
                {
                  "option": true
                }
              ],
              "baseURL": [
                null,
                {
                  "option": true
                }
              ],
              "serviceWorkers": [
                null,
                {
                  "option": true
                }
              ],
              "contextOptions": [
                {},
                {
                  "option": true
                }
              ],
              "_combinedContextOptions": [
                null,
                {
                  "box": true
                }
              ],
              "_setupContextOptions": [
                null,
                {
                  "auto": "all-hooks-included",
                  "title": "context configuration",
                  "box": true
                }
              ],
              "_setupArtifacts": [
                null,
                {
                  "auto": "all-hooks-included",
                  "title": "trace recording",
                  "box": true
                }
              ],
              "_contextFactory": [
                null,
                {
                  "scope": "test",
                  "title": "context",
                  "box": true
                }
              ],
              "_optionContextReuseMode": [
                "none",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_optionConnectOptions": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_reuseContext": [
                null,
                {
                  "scope": "worker",
                  "title": "context",
                  "box": true
                }
              ]
            },
            "location": {
              "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\node_modules\\playwright\\lib\\index.js",
              "line": 884,
              "column": 39
            }
          }
        ]
      },
      "id": "dd9b2edffe9b7501040c-afd96d08a88ecfcf2eec",
      "_poolDigest": "37500f500367e2c2037c76158069d8d577577210",
      "_workerHash": "-37500f500367e2c2037c76158069d8d577577210-0",
      "_projectId": "",
      "_staticAnnotations": [],
      "_tags": []
    },
    "step": {
      "retry": 0,
      "parallelIndex": 0,
      "workerIndex": 0,
      "duration": 5545,
      "startTime": "2024-08-21T14:38:11.661Z",
      "stdout": [],
      "stderr": [],
      "attachments": [],
      "status": "passed",
      "steps": [
        {
          "title": "Before Hooks",
          "category": "hook",
          "startTime": "2024-08-21T14:38:11.668Z",
          "duration": 1587,
          "steps": [
            {
              "title": "fixture: browser",
              "category": "fixture",
              "startTime": "2024-08-21T14:38:11.685Z",
              "duration": 331,
              "steps": [
                {
                  "title": "browserType.launch",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:38:11.694Z",
                  "duration": 322,
                  "steps": []
                }
              ]
            },
            {
              "title": "fixture: context",
              "category": "fixture",
              "startTime": "2024-08-21T14:38:12.018Z",
              "duration": 32,
              "steps": [
                {
                  "title": "browser.newContext",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:38:12.023Z",
                  "duration": 23,
                  "steps": []
                }
              ]
            },
            {
              "title": "fixture: page",
              "category": "fixture",
              "startTime": "2024-08-21T14:38:12.051Z",
              "duration": 1204,
              "steps": [
                {
                  "title": "browserContext.newPage",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:38:12.056Z",
                  "duration": 1198,
                  "steps": []
                }
              ]
            }
          ]
        },
        {
          "title": "page.goto(https://sandbox.mabl.com/)",
          "category": "pw:api",
          "startTime": "2024-08-21T14:38:13.260Z",
          "duration": 4140,
          "steps": [],
          "location": {
            "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
            "line": 5,
            "column": 15
          }
        },
        {
          "title": "locator.getByRole('button', { name: 'new window' }).click",
          "category": "pw:api",
          "startTime": "2024-08-21T14:38:17.409Z",
          "duration": 123,
          "steps": [],
          "location": {
            "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
            "line": 6,
            "column": 57
          }
        },
        {
          "title": "After Hooks",
          "category": "hook",
          "startTime": "2024-08-21T14:38:17.534Z",
          "duration": 22,
          "steps": [
            {
              "title": "fixture: page",
              "category": "fixture",
              "startTime": "2024-08-21T14:38:17.535Z",
              "duration": 1,
              "steps": []
            },
            {
              "title": "fixture: context",
              "category": "fixture",
              "startTime": "2024-08-21T14:38:17.537Z",
              "duration": 0,
              "steps": []
            }
          ]
        }
      ],
      "errors": []
    }
}
  1. onStepEnd(test, step, result): Logs the end of a test step, including the result of the step.

Code Block
languagejson
{
  "test":{
      "title": "basic test",
      "_only": false,
      "_requireFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
      "results": [
        {
          "retry": 0,
          "parallelIndex": 0,
          "workerIndex": 0,
          "duration": 3094,
          "startTime": "2024-08-21T14:33:03.207Z",
          "stdout": [],
          "stderr": [],
          "attachments": [],
          "status": "passed",
          "steps": [
            {
              "title": "Before Hooks",
              "category": "hook",
              "startTime": "2024-08-21T14:33:03.218Z",
              "duration": 2537,
              "steps": [
                {
                  "title": "fixture: browser",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:33:03.237Z",
                  "duration": 933,
                  "steps": [
                    {
                      "title": "browserType.launch",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:33:03.245Z",
                      "duration": 925,
                      "steps": []
                    }
                  ]
                },
                {
                  "title": "fixture: context",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:33:04.172Z",
                  "duration": 21,
                  "steps": [
                    {
                      "title": "browser.newContext",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:33:04.176Z",
                      "duration": 13,
                      "steps": []
                    }
                  ]
                },
                {
                  "title": "fixture: page",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:33:04.194Z",
                  "duration": 1561,
                  "steps": [
                    {
                      "title": "browserContext.newPage",
                      "category": "pw:api",
                      "startTime": "2024-08-21T14:33:04.198Z",
                      "duration": 1557,
                      "steps": []
                    }
                  ]
                }
              ]
            },
            {
              "title": "page.goto(https://sandbox.mabl.com/)",
              "category": "pw:api",
              "startTime": "2024-08-21T14:33:05.761Z",
              "duration": 1291,
              "steps": [],
              "location": {
                "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
                "line": 5,
                "column": 15
              }
            },
            {
              "title": "locator.getByRole('button', { name: 'new window' }).click",
              "category": "pw:api",
              "startTime": "2024-08-21T14:33:07.065Z",
              "duration": 161,
              "steps": [],
              "location": {
                "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
                "line": 6,
                "column": 57
              }
            },
            {
              "title": "After Hooks",
              "category": "hook",
              "startTime": "2024-08-21T14:33:07.228Z",
              "duration": 30,
              "steps": [
                {
                  "title": "fixture: page",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:33:07.230Z",
                  "duration": 0,
                  "steps": []
                },
                {
                  "title": "fixture: context",
                  "category": "fixture",
                  "startTime": "2024-08-21T14:33:07.231Z",
                  "duration": 0,
                  "steps": []
                }
              ]
            }
          ],
          "errors": []
        }
      ],
      "location": {
        "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
        "line": 4,
        "column": 1
      },
      "parent": {
        "title": "example.spec.js",
        "_only": false,
        "_requireFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
        "location": {
          "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
          "line": 0,
          "column": 0
        },
        "parent": {
          "title": "",
          "_only": false,
          "_requireFile": "",
          "parent": {
            "title": "",
            "_only": false,
            "_requireFile": "",
            "_use": [],
            "_entries": [
              null
            ],
            "_hooks": [],
            "_staticAnnotations": [],
            "_tags": [],
            "_modifiers": [],
            "_parallelMode": "none",
            "_type": "root"
          },
          "_use": [],
          "_entries": [
            null
          ],
          "_hooks": [],
          "_staticAnnotations": [],
          "_tags": [],
          "_modifiers": [],
          "_parallelMode": "none",
          "_fullProject": {
            "project": {
              "grep": {},
              "grepInvert": null,
              "outputDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\test-results",
              "repeatEach": 1,
              "retries": 0,
              "metadata": {},
              "name": "",
              "testDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "snapshotDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "testIgnore": [],
              "testMatch": "**/*.@(spec|test).?(c|m)[jt]s?(x)",
              "timeout": 30000,
              "use": {},
              "dependencies": [],
              "__projectId": ""
            },
            "fullConfig": {
              "config": {
                "configFile": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\playwright.config.js",
                "rootDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
                "forbidOnly": false,
                "fullyParallel": false,
                "globalSetup": null,
                "globalTeardown": null,
                "globalTimeout": 0,
                "grepInvert": null,
                "maxFailures": 0,
                "metadata": {
                  "actualWorkers": 1
                },
                "preserveOutput": "always",
                "reporter": [
                  [
                    "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\PlaywrightReporter.js",
                    null
                  ]
                ],
                "reportSlowTests": {
                  "max": 5,
                  "threshold": 15000
                },
                "quiet": false,
                "projects": [
                  null
                ],
                "shard": null,
                "updateSnapshots": "missing",
                "version": "1.46.1",
                "workers": 4,
                "webServer": null
              },
              "configDir": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index",
              "configCLIOverrides": {},
              "webServers": [],
              "plugins": [],
              "projects": [
                null
              ],
              "cliArgs": [],
              "cliListOnly": false,
              "cliPassWithNoTests": false,
              "cliFailOnFlakyTests": false,
              "defineConfigWasUsed": true
            },
            "expect": {},
            "respectGitIgnore": true,
            "snapshotPathTemplate": "{snapshotDir}/{testFileDir}/{testFileName}-snapshots/{arg}{-projectName}{-snapshotSuffix}{ext}",
            "ignoreSnapshots": false,
            "id": "",
            "deps": []
          },
          "_type": "project"
        },
        "_use": [],
        "_entries": [
          null
        ],
        "_hooks": [],
        "_staticAnnotations": [],
        "_tags": [],
        "_modifiers": [],
        "_parallelMode": "none",
        "_fileId": "dd9b2edffe9b7501040c",
        "_type": "file"
      },
      "type": "test",
      "expectedStatus": "passed",
      "timeout": 30000,
      "annotations": [],
      "retries": 0,
      "repeatEachIndex": 0,
      "_testType": {
        "fixtures": [
          {
            "fixtures": {
              "defaultBrowserType": [
                "chromium",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "browserName": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "playwright": [
                null,
                {
                  "scope": "worker",
                  "box": true
                }
              ],
              "headless": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "channel": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "launchOptions": [
                {},
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "connectOptions": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "screenshot": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "video": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "trace": [
                "off",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_browserOptions": [
                null,
                {
                  "scope": "worker",
                  "auto": true,
                  "box": true
                }
              ],
              "browser": [
                null,
                {
                  "scope": "worker",
                  "timeout": 0
                }
              ],
              "acceptDownloads": [
                null,
                {
                  "option": true
                }
              ],
              "bypassCSP": [
                null,
                {
                  "option": true
                }
              ],
              "colorScheme": [
                null,
                {
                  "option": true
                }
              ],
              "deviceScaleFactor": [
                null,
                {
                  "option": true
                }
              ],
              "extraHTTPHeaders": [
                null,
                {
                  "option": true
                }
              ],
              "geolocation": [
                null,
                {
                  "option": true
                }
              ],
              "hasTouch": [
                null,
                {
                  "option": true
                }
              ],
              "httpCredentials": [
                null,
                {
                  "option": true
                }
              ],
              "ignoreHTTPSErrors": [
                null,
                {
                  "option": true
                }
              ],
              "isMobile": [
                null,
                {
                  "option": true
                }
              ],
              "javaScriptEnabled": [
                null,
                {
                  "option": true
                }
              ],
              "locale": [
                null,
                {
                  "option": true
                }
              ],
              "offline": [
                null,
                {
                  "option": true
                }
              ],
              "permissions": [
                null,
                {
                  "option": true
                }
              ],
              "proxy": [
                null,
                {
                  "option": true
                }
              ],
              "storageState": [
                null,
                {
                  "option": true
                }
              ],
              "clientCertificates": [
                null,
                {
                  "option": true
                }
              ],
              "timezoneId": [
                null,
                {
                  "option": true
                }
              ],
              "userAgent": [
                null,
                {
                  "option": true
                }
              ],
              "viewport": [
                null,
                {
                  "option": true
                }
              ],
              "actionTimeout": [
                0,
                {
                  "option": true
                }
              ],
              "testIdAttribute": [
                "data-testid",
                {
                  "option": true
                }
              ],
              "navigationTimeout": [
                0,
                {
                  "option": true
                }
              ],
              "baseURL": [
                null,
                {
                  "option": true
                }
              ],
              "serviceWorkers": [
                null,
                {
                  "option": true
                }
              ],
              "contextOptions": [
                {},
                {
                  "option": true
                }
              ],
              "_combinedContextOptions": [
                null,
                {
                  "box": true
                }
              ],
              "_setupContextOptions": [
                null,
                {
                  "auto": "all-hooks-included",
                  "title": "context configuration",
                  "box": true
                }
              ],
              "_setupArtifacts": [
                null,
                {
                  "auto": "all-hooks-included",
                  "title": "trace recording",
                  "box": true
                }
              ],
              "_contextFactory": [
                null,
                {
                  "scope": "test",
                  "title": "context",
                  "box": true
                }
              ],
              "_optionContextReuseMode": [
                "none",
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_optionConnectOptions": [
                null,
                {
                  "scope": "worker",
                  "option": true
                }
              ],
              "_reuseContext": [
                null,
                {
                  "scope": "worker",
                  "title": "context",
                  "box": true
                }
              ]
            },
            "location": {
              "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\node_modules\\playwright\\lib\\index.js",
              "line": 884,
              "column": 39
            }
          }
        ]
      },
      "id": "dd9b2edffe9b7501040c-afd96d08a88ecfcf2eec",
      "_poolDigest": "37500f500367e2c2037c76158069d8d577577210",
      "_workerHash": "-37500f500367e2c2037c76158069d8d577577210-0",
      "_projectId": "",
      "_staticAnnotations": [],
      "_tags": []
    },
  "step": {
      "retry": 0,
      "parallelIndex": 0,
      "workerIndex": 0,
      "duration": 2705,
      "startTime": "2024-08-21T14:31:07.284Z",
      "stdout": [],
      "stderr": [],
      "attachments": [],
      "status": "passed",
      "steps": [
        {
          "title": "Before Hooks",
          "category": "hook",
          "startTime": "2024-08-21T14:31:07.292Z",
          "duration": 1483,
          "steps": [
            {
              "title": "fixture: browser",
              "category": "fixture",
              "startTime": "2024-08-21T14:31:07.310Z",
              "duration": 327,
              "steps": [
                {
                  "title": "browserType.launch",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:31:07.319Z",
                  "duration": 317,
                  "steps": []
                }
              ]
            },
            {
              "title": "fixture: context",
              "category": "fixture",
              "startTime": "2024-08-21T14:31:07.639Z",
              "duration": 18,
              "steps": [
                {
                  "title": "browser.newContext",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:31:07.643Z",
                  "duration": 11,
                  "steps": []
                }
              ]
            },
            {
              "title": "fixture: page",
              "category": "fixture",
              "startTime": "2024-08-21T14:31:07.659Z",
              "duration": 1116,
              "steps": [
                {
                  "title": "browserContext.newPage",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:31:07.663Z",
                  "duration": 1112,
                  "steps": []
                }
              ]
            }
          ]
        },
        {
          "title": "page.goto(https://sandbox.mabl.com/)",
          "category": "pw:api",
          "startTime": "2024-08-21T14:31:08.781Z",
          "duration": 1333,
          "steps": [],
          "location": {
            "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
            "line": 5,
            "column": 15
          }
        },
        {
          "title": "locator.getByRole('button', { name: 'new window' }).click",
          "category": "pw:api",
          "startTime": "2024-08-21T14:31:10.127Z",
          "duration": 177,
          "steps": [],
          "location": {
            "file": "C:\\Users\\VinayChristopher\\OneDrive - Royal Cyber Inc\\Documents\\D drive\\Official\\TEAF\\playwrght\\index\\example.spec.js",
            "line": 6,
            "column": 57
          }
        },
        {
          "title": "After Hooks",
          "category": "hook",
          "startTime": "2024-08-21T14:31:10.306Z",
          "duration": 33,
          "steps": [
            {
              "title": "fixture: page",
              "category": "fixture",
              "startTime": "2024-08-21T14:31:10.309Z",
              "duration": 0,
              "steps": []
            },
            {
              "title": "fixture: context",
              "category": "fixture",
              "startTime": "2024-08-21T14:31:10.311Z",
              "duration": 0,
              "steps": []
            }
          ]
        }
      ],
      "errors": []
    },
    "result": {
      "title": "browserType.launch",
      "parent": {
        "title": "fixture: browser",
        "parent": {
          "title": "Before Hooks",
          "category": "hook",
          "startTime": "2024-08-21T14:34:58.224Z",
          "duration": 1530,
          "steps": [
            null,
            {
              "title": "fixture: context",
              "category": "fixture",
              "startTime": "2024-08-21T14:34:58.555Z",
              "duration": 22,
              "steps": [
                {
                  "title": "browser.newContext",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:34:58.560Z",
                  "duration": 13,
                  "steps": []
                }
              ]
            },
            {
              "title": "fixture: page",
              "category": "fixture",
              "startTime": "2024-08-21T14:34:58.579Z",
              "duration": 1175,
              "steps": [
                {
                  "title": "browserContext.newPage",
                  "category": "pw:api",
                  "startTime": "2024-08-21T14:34:58.584Z",
                  "duration": 1170,
                  "steps": []
                }
              ]
            }
          ]
        },
        "category": "fixture",
        "startTime": "2024-08-21T14:34:58.241Z",
        "duration": 312,
        "steps": [
          null
        ]
      },
      "category": "pw:api",
      "startTime": "2024-08-21T14:34:58.247Z",
      "duration": 305,
      "steps": []
    }
}

There are primarily two ways to use the Custom Reporter API.

  1. Define in playwright.config.js/ts

Code Block
languagejs
import { defineConfig } from '@playwright/test';

export default defineConfig({
  globalTeardown: './global-teardown',
});
  1. Passing the parameter while executing the test command

Code Block
languagejs
import {exec} from "child_process";
 
exec("npx playwright test --reporter="./myreporter/PlaywrightCustomReporter.js"")

Writing Own Custom Reporter with custom execution of Playwright Script

Custom execution of Playwright script can also be done one step at a time using async handler of express by passing one step at a time in a loop. This allows to use a completely independent custom reporter. Below is an example:

CustomReporter.js

Code Block
class CustomReporter {
   constructor() {
      this.results = [];
   }

   logStep(stepIndex, command, status, duration, errorMessage = null) {
      const stepResult = {
         stepNumber: stepIndex + 1,
         stepCommand: command,
         status,
         duration: `${duration}ms`,
         timestamp: new Date().toISOString(),
         errorMessage: errorMessage,
      };
      this.results.push(stepResult);
      console.log(`[Step ${stepIndex + 1}] ${status.toUpperCase()}: ${command} (Duration: ${duration}ms)`);
   }

   saveReport() {
      // Save or send the report as needed
      console.log("Final Test Report:", JSON.stringify(this.results, null, 2));
   }
}

export default CustomReporter;

playwrightCustomExecution.js

Code Block
import asyncHandler from "express-async-handler";
import {chromium} from "playwright";
import CustomReporter from "./customReporter.js";

// Custom Reporter

// @route   POST /api/pw/exe
// @access  Public
const execution = asyncHandler(async (req, res) => {
   const {playwright_test_steps} = req.body;
   if (playwright_test_steps) {
      const reporter = new CustomReporter(); // Initialize reporter
      let browser;

      try {
         (async () => {
            browser = await chromium.launch({
               headless: false,
            });
            const context = await browser.newContext();
            const page = await context.newPage();

            for (let i = 0; i < playwright_test_steps.length; i++) {
               const command = playwright_test_steps[i];
               const startTime = Date.now(); // Start time for execution

               try {
                  await eval(command.replace("page", "page").replace("await ", ""));
                  const duration = Date.now() - startTime; // Calculate duration
                  reporter.logStep(i, command, "passed", duration);
               } catch (error) {
                  const duration = Date.now() - startTime; // Calculate duration
                  reporter.logStep(i, command, "failed", duration, error.message);
                  await page.screenshot({path: `error-${i}.png`});
                  reporter.saveReport();
                  throw new Error(`Error executing test step ${i}: ${error.message}`);
               }
            }

            await context.close();
            await browser.close();

            // Save the final report
            reporter.saveReport();

            res.json({
               message: "Test steps executed successfully",
               report: reporter.results,
            });
         })();
      } catch (error) {
         console.log("Error executing test steps", error.message);
         if (browser) await browser.close();
         // res.status(500).json({
         //    message: "Error executing test steps",
         //    error: error.message,
         //    report: reporter.results,
         // });
      }
   } else {
      res.status(401);
      throw new Error("Invalid Script");
   }
});

export {execution};

testResults.json

...

languagejson

...

very versatile with report generation. It can be categorized in three ways:

  • In-built Reports and Third-Party Support:

    • Playwright offers built-in report generation features, including HTML and JSON reports, which provide insights into test results and performance. It also supports third-party reporters like Allure and Jest, which can be integrated to customize the reporting format and functionality.

  • Custom Report API of Playwright:

    • Playwright provides a Custom Report API that allows you to create tailored reports by hooking into test events. This API lets you capture detailed information about test execution, steps, and results, enabling you to design reports that meet specific needs or organizational standards.

  • Write Your Own Custom API:

    • For maximum flexibility, you can develop a completely custom reporting solution by directly interfacing with Playwright's test results and events. This approach involves writing your own code to collect, format, and display test data according to your unique requirements, giving you full control over the reporting process.