From 5d42235daf3480ad5d20c10f80554cd03cfaa4f2 Mon Sep 17 00:00:00 2001 From: galargh Date: Wed, 21 Aug 2024 15:30:28 +0200 Subject: [PATCH 1/3] docs: enhance the test reporter's README --- v-next/hardhat-node-test-reporter/README.md | 90 +++++++++++++++++++- v-next/hardhat-node-test-reporter/demo.gif | Bin 0 -> 28137 bytes 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 v-next/hardhat-node-test-reporter/demo.gif diff --git a/v-next/hardhat-node-test-reporter/README.md b/v-next/hardhat-node-test-reporter/README.md index 919325d8e2..0398f7d769 100644 --- a/v-next/hardhat-node-test-reporter/README.md +++ b/v-next/hardhat-node-test-reporter/README.md @@ -2,4 +2,92 @@ This package includes Hardhat's `node:test` reporter. -This project is heavily inspired by https://github.com/voxpelli/node-test-pretty-reporter +This project is heavily inspired by https://github.com/voxpelli/node-test-pretty-reporter. + +It tries to mimic [the `Mocha`'s default `Spec` reporter](https://mochajs.org/#spec), as close as possible. + +It is designed to output information about the test runs as soon as possible and in test **defintion** order. + +Once the test run ends, it will output global information about it, based on the diagnostics emitted by `node:test`, and any custom or unrecognized diagnostics message. + +Finally, it will output the failure reasons for all the failed tests. + +It introduces a number of custom features to make it more suitable for use with Hardhat. + +![Demo](./demo.gif) + +## Installation + +`hardhat-node-test-reporter` comes built-in with Hardhat's `node:test` plugin, which itself comes bundled in by default with `hardhat-toolbox`. You don't need to install it separately. + +If you want to use the reporter in your own project, you can install it with npm (optionally, with a `--save-dev` flag): + +```bash +npm install hardhat-node-test-reporter +``` + +## Usage + +If you're using `hardhat`'s `node:test` plugin, the reporter will be used by default whenever you run the `hardhat test` task. + +If you want to use the reporter directly with `node`, you can do so by passing the `--test-reporter` flag: + +```bash +node --test --test-reporter=@ignored/hardhat-vnext-node-test-reporter +``` + +## Custom features + +### Slow Tests + +Slow threshold is configured to 75ms. If a test case takes longer than that, it will be highlighted in red. + +### Test Coverage + +Test coverage is currently not supported by this reporter. + +### GitHub Actions + +This reporter is designed to work well with GitHub Actions. By default, it will create error annotations for failed tests. You can disable this feature by setting the `NO_GITHUB_ACTIONS_ANNOTATIONS` environment variable to `true`. + +### Colour Output + +This reporter will colour the output by default in terminals that support it. You can forcefully disable this feature by setting the `FORCE_COLOR` environment variable to `0`. Similarly, you can forcefully enable this feature by setting the `FORCE_COLOR` environment variable to `1`. + +| Output Type | Colour | +| ----------- | ------------ | +| Cancelled | Gray | +| Error | Red | +| Failure | Red | +| Skipped | Cyan | +| Success | Green (tick) | +| TODO | Blue | + +### Nesting + +This reporter will indicate nesting of test suites by indenting the output at 2-space wide intervals. + +### Error Formatting + +This reporter will format errors in a human readable way. + +It will try to use the `inspect` method from the `node:util` module to print the error object together with its stack trace. + +It will replace file URLs with relative paths. This currently does not work well on Windows. + +Finally, it will attempt to show a diff of the expected and actual values of the error object, if they are available. + +### Diagnostics + +This reporter will aggregate and output diagnostics emitted by `node:test` at the end of the test run. If it doesn't recognize a diagnostic message, it will output them as-is after the well-known diagnostics. + +Well-known diagnostics are: + +- `tests` +- `suites` +- `pass` +- `fail` +- `cancelled` +- `skipped` +- `todo` +- `duration_ms` diff --git a/v-next/hardhat-node-test-reporter/demo.gif b/v-next/hardhat-node-test-reporter/demo.gif new file mode 100644 index 0000000000000000000000000000000000000000..19d3cf7023f655c12954ea8d9e8ce87bb7a93760 GIT binary patch literal 28137 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 J;z7XdKL8;Y&sP8d literal 0 HcmV?d00001 From 49fd47c9f4ddf7e7511ebc65213de52287d6b4e8 Mon Sep 17 00:00:00 2001 From: galargh Date: Thu, 22 Aug 2024 11:35:00 +0200 Subject: [PATCH 2/3] chore: small improvements to test reporter discovered while writing the readme --- .../hardhat-node-test-reporter/src/error-formatting.ts | 8 ++++++-- v-next/hardhat-node-test-reporter/src/formatting.ts | 2 +- v-next/hardhat-node-test-reporter/src/reporter.ts | 10 +++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/v-next/hardhat-node-test-reporter/src/error-formatting.ts b/v-next/hardhat-node-test-reporter/src/error-formatting.ts index de6c3db4b1..f79c1f5dce 100644 --- a/v-next/hardhat-node-test-reporter/src/error-formatting.ts +++ b/v-next/hardhat-node-test-reporter/src/error-formatting.ts @@ -5,6 +5,7 @@ import { inspect } from "node:util"; import chalk from "chalk"; import { diff } from "jest-diff"; +import { indent } from "./formatting.js"; import { cleanupTestFailError, isCancelledByParentError, @@ -18,7 +19,10 @@ export function formatError(error: Error): string { chalk.red("Test cancelled by parent error") + "\n" + chalk.gray( - " This test was cancelled due to an error in its parent suite/it or test/it, or in one of its before/beforeEach", + indent( + "This test was cancelled due to an error in its parent suite/it or test/it, or in one of its before/beforeEach", + 4, + ), ) ); } @@ -27,7 +31,7 @@ export function formatError(error: Error): string { return ( chalk.red(`Test file execution failed (exit code ${error.exitCode}).`) + "\n" + - chalk.gray(" Did you forget to await a promise?") + chalk.gray(indent("Did you forget to await a promise?", 4)) ); } diff --git a/v-next/hardhat-node-test-reporter/src/formatting.ts b/v-next/hardhat-node-test-reporter/src/formatting.ts index 9e86c2d631..caf06d05c3 100644 --- a/v-next/hardhat-node-test-reporter/src/formatting.ts +++ b/v-next/hardhat-node-test-reporter/src/formatting.ts @@ -124,7 +124,7 @@ function nestingToIndentationLength(nesting: number): number { return (nesting + 1) * 2; } -function indent(str: string, spaces: number): string { +export function indent(str: string, spaces: number): string { const padding = " ".repeat(spaces); return str.replace(/^/gm, padding); } diff --git a/v-next/hardhat-node-test-reporter/src/reporter.ts b/v-next/hardhat-node-test-reporter/src/reporter.ts index 3260cc9fc6..058f847cb9 100644 --- a/v-next/hardhat-node-test-reporter/src/reporter.ts +++ b/v-next/hardhat-node-test-reporter/src/reporter.ts @@ -53,14 +53,14 @@ export default async function* customReporter( * repeate it, we keep track of the last printed context element. We do this * by keeping track of its index in the stack. * - * We also keep track of any diagnostic message that its reported by node:test + * We also keep track of any diagnostic message that is reported by node:test * and at the end we try to parse the global diagnostics to gather information * about the test run. If during this parsing we don't recognize or can't * properly parse one of this diagnostics, we will print it at the end. * - * Whenever a test fails, we pre-format its failure reason, so that don't need - * to keep the failure event in memory, and we can still print the failure - * reason at the end. + * Whenever a test fails, we pre-format its failure reason, so that we don't + * need to keep the failure event in memory, and we can still print the + * failure reason at the end. * * This code is structed in the following way: * - We use an async generator to process the events as they come, printing @@ -74,7 +74,7 @@ export default async function* customReporter( * - The generaor drives the high-level format of the output, and only uses * the formatting functions to generate repetitive parts of it. * - * [1] As reporter by node:test, in defintion order, which may differ from + * [1] As reported by node:test, in defintion order, which may differ from * actual execution order. */ From 0c1d97de95a3516ee3b6659914c7490a0d1acb39 Mon Sep 17 00:00:00 2001 From: galargh Date: Fri, 23 Aug 2024 22:48:24 +0200 Subject: [PATCH 3/3] docs: add info on alternative ways to enable/disable colouring --- v-next/hardhat-node-test-reporter/README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/v-next/hardhat-node-test-reporter/README.md b/v-next/hardhat-node-test-reporter/README.md index 0398f7d769..518e8be0aa 100644 --- a/v-next/hardhat-node-test-reporter/README.md +++ b/v-next/hardhat-node-test-reporter/README.md @@ -52,7 +52,11 @@ This reporter is designed to work well with GitHub Actions. By default, it will ### Colour Output -This reporter will colour the output by default in terminals that support it. You can forcefully disable this feature by setting the `FORCE_COLOR` environment variable to `0`. Similarly, you can forcefully enable this feature by setting the `FORCE_COLOR` environment variable to `1`. +This reporter will colour the output by default in terminals that support it. You can forcefully disable this feature by setting the `FORCE_COLOR` environment variable to `0` (or passing a `--no-color` flag). Similarly, you can forcefully enable this feature by setting the `FORCE_COLOR` environment variable to `1` (or passing a `--color` flag). + +The behaviour is inherited from the [`chalk` package](https://github.com/chalk/chalk?tab=readme-ov-file#supportscolor). + +#### Colour Legend | Output Type | Colour | | ----------- | ------------ |