{"id":16431824,"url":"https://github.com/coreybutler/tappedout","last_synced_at":"2025-03-23T08:31:41.031Z","repository":{"id":43360128,"uuid":"274197117","full_name":"coreybutler/tappedout","owner":"coreybutler","description":"A simple \"back to basics\" JavaScript test runner for producing TAP-formatted results. Built using ES Modules.","archived":false,"fork":false,"pushed_at":"2023-07-16T04:21:46.000Z","size":63,"stargazers_count":8,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-18T14:47:07.678Z","etag":null,"topics":["esm","esmodules","tap","test","test-runner","test-runners","testanythingprotocol","testing","testing-tools","unit"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coreybutler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-22T17:07:10.000Z","updated_at":"2024-03-14T14:02:40.000Z","dependencies_parsed_at":"2024-10-28T15:29:37.483Z","dependency_job_id":"c0f9a68d-e4e8-4775-99a3-d6ccaddb5f75","html_url":"https://github.com/coreybutler/tappedout","commit_stats":{"total_commits":46,"total_committers":2,"mean_commits":23.0,"dds":0.04347826086956519,"last_synced_commit":"735e06238e057e2b36b2497621659810e202f4ba"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreybutler%2Ftappedout","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreybutler%2Ftappedout/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreybutler%2Ftappedout/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coreybutler%2Ftappedout/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coreybutler","download_url":"https://codeload.github.com/coreybutler/tappedout/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245078067,"owners_count":20557274,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["esm","esmodules","tap","test","test-runner","test-runners","testanythingprotocol","testing","testing-tools","unit"],"created_at":"2024-10-11T08:32:51.882Z","updated_at":"2025-03-23T08:31:40.739Z","avatar_url":"https://github.com/coreybutler.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tappedout\n\nA simple \"back to basics\" JavaScript test runner for producing [TAP-formatted](https://testanything.org) results. It is runtime agnostic and built using ES Modules.\n\nIt is built using ES module syntax, drawing _inspiration_ from the [tape](https://github.com/substack/tape) library. It shares several similarities, but should not be considered \"the same\". The API has several different methods. Furthermore, tappedout is runtime-agnostic. It will work in browsers, Node, Deno, and any other ECMAScript-compliant (ES5+) runtime.\n\n**This is for library authors...**\n\nThere are many beautiful test runners. They often come at the price of requiring many dependencies, which may be fine for a single complex project. Library authors typically maintain multiple smaller repos containing smaller bits of code. The black hole of `node_modules` was way too heavy when multiplied across multiple projects. Since tappedout is written using ECMAScript standard modules, there is no need for pre-processing/transpiling just to run tests.\n\nThe name came from frustration. My patience was tapped out with one too many rollup/browserify processes.\n\n## Getting tappedout\n\n#### Node.js\n\nThis library only supports versions of Node with ES Module support. This is available in Node 12 \u0026 13 using the `--experimental-modules` flag. It is a native feature in Node 14+ (no flag needed). All versions need to specify `\"type\": \"module\"` in the `package.json` file.\n\n_Obtaining the module:_\n\n```sh\nnpm i tappedout --save-dev\n```\n\n_Implementing it in Node:_\n\n```javascript\nimport test from 'tappedout'\n```\n\n#### Browser, Deno\n\n![Version](https://img.shields.io/npm/v/tappedout?label=Latest\u0026style=for-the-badge)\n\n```javascript\nimport test from 'https://cdn.pika.dev/tappedout^1.0.0' // \u003c-- Update the version\n```\n\n## Usage\n\nHere's a basic example:\n\n```javascript\nimport test from 'tappedout'\n\ntest('My Test Suite', t =\u003e {\n  t.ok(true, 'I am OK.')\n  t.ok(false, 'I am still OK.') // Expect a failure here!\n})\n```\n\n**Output:**\n\n```sh\nTAP version 13\n# My Test Suite\nok 1 - I am OK.\nnot ok 2 - I am still OK.\n1..2\n```\n\n**_Alternative output formats:_**\n\nTAP (Test Anything Protocol) is a language-agnostic format for documenting test results. There is a companion formatting tool, [tapfmt](https://github.com/coreybutler/tapfmt), providing a language/runtime-agnostic standalone formatter. There are also [many different runtime-specific formatters](https://github.com/search?l=JavaScript\u0026q=tap+format\u0026type=Repositories) available if you search npm/github. It's relatively easy to create your own using [tap-parser](https://github.com/tapjs/tap-parser) or a similar library.\n\nTAP producers generally output to stdout/stderr (console). However, there are some circumstances where an alternative output mechanism is desired. The `tappedout` library supports overriding the default output mechanism. For example, to use a custom handler, set the logger as:\n\n```javascript\nimport test from 'tappedout'\n\ntest.logger = function () {\n  // Prefix 'TAP:' to every line\n  console.log(`TAP:`, ...arguments)\n}\n\ntest('title', t =\u003e { ... }})\n```\n\nThe most common reason for overriding the output mechanism is for writing results to a file.\n\n**Pretty Output:**\n\nThis library only outputs raw TAP results.\n\nCombine it with a post-processor for \"pretty\" output.\n\n\u003cdetails\u003e\n  \u003csummary\u003eTAP Post-Processors/Formatters\u003c/summary\u003e\n  \u003col\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/scottcorgan/tap-spec\"\u003etap-spec\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/scottcorgan/tap-dot\"\u003etap-dot\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/substack/faucet\"\u003efaucet\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/juliangruber/tap-bail\"\u003etap-bail\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/kirbysayshi/tap-browser-color\"\u003etap-browser-color\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/gummesson/tap-json\"\u003etap-json\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/derhuerst/tap-min\"\u003etap-min\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/calvinmetcalf/tap-nyan\"\u003etap-nyan\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://www.npmjs.org/package/tap-pessimist\"\u003etap-pessimist\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/toolness/tap-prettify\"\u003etap-prettify\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/shuhei/colortape\"\u003ecolortape\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/aghassemi/tap-xunit\"\u003etap-xunit\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/namuol/tap-difflet\"\u003etap-difflet\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/gritzko/tape-dom\"\u003etape-dom\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/axross/tap-diff\"\u003etap-diff\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/axross/tap-notify\"\u003etap-notify\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/zoubin/tap-summary\"\u003etap-summary\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/Hypercubed/tap-markdown\"\u003etap-markdown\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/gabrielcsapo/tap-html\"\u003etap-html\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/mcnuttandrew/tap-react-browser\"\u003etap-react-browser\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/dhershman1/tap-junit\"\u003etap-junit\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/MegaArman/tap-nyc\"\u003etap-nyc\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/Sceat/tap-spec-emoji\"\u003etap-spec (emoji patch)\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/rgruesbeck/tape-repeater\"\u003etape-repeater\u003c/a\u003e\u003c/li\u003e\n    \u003cli\u003e\u003ca href=\"https://github.com/Josenzo/tabe\"\u003etabe\u003c/a\u003e\u003c/li\u003e\n  \u003c/ol\u003e\n\n\u003c/details\u003e\n\n***Alternative startup:***\n\nBy default, tappedout automatically runs tests. This behavior can be overridden by setting `autostart` to `false`, then manually invoking the `start()` method.\n\n```javascript\nimport test from 'tappedout'\n\ntest.autostart = false\n\ntest('title 1', t =\u003e { ... }})\ntest('title 2', t =\u003e { ... }})\ntest('title 3', t =\u003e { ... }})\n\ntest.start()\n```\n\n## Overview: How to Make Simple/Awesome Tests\n\n##### Really... you should read this section if you like making things easy on yourself.\n\nThe API is very simple, yet very powerful. There are some simple design principles that can make the experience of testing great. Write less code, more naturally.\n\n1. **Directives**\n   [TAP directives](https://testanything.org/tap-version-13-specification.html#directives) are special/optional \"notes\" in the output. There are only two options: `skip` and `todo`. These directives can be added/removed throughout the development lifecycle, making it easier to focus on the tests that matter. This can be really helpful as test suites grow. Many methods in this library support a directive option, and there are some special functions for applying directives in bulk (`test.only` and `test.skip`).\u003cbr/\u003e\n2. **Detailed Output**\n   Sometimes it is valuable to have detailed information about a particular test, such as info about why a test failed. The TAP protocol allows this to be [embedded in the output, via YAML](https://testanything.org/tap-version-13-specification.html#yaml-blocks).\u003cbr/\u003e\n\n   Many of the methods in this library support key/value (JSON) arguments that will be properly embedded in the output.\n\n   - `failinfo()` and `expect()` autocreate detail objects.\n   - `info()` supports custom details.\n   - All assertion/response methods support custom detail objects, wherever you see \"`object` detail\" as a method parameter.\u003cbr/\u003e\n\n   A key usability feature of this library is the ability to add a **`DISPLAY_OUTPUT`** attribute to detail objects. By default, _passing tests do not output details_, while _non-passing tests do_. To override this behavior, make sure the detail object has an attribute called `DISPLAY_OUTPUT: true/false`.\n\n## API\n\n### comment (`string` message [, `object` detail])\n\n```javascript\ntest('suite name', t =\u003e {\n  t.comment('Comment goes here')\n})\n```\n\n```sh\n# Comment goes here\n```\n\nIf the message is `null`, `undefined`, or blank, no output will be generated.\n\n### pass (`string` message [, `string` directive, `object` detail])\n\n```javascript\ntest('suite name', t =\u003e {\n  t.pass('Looks good')\n})\n```\n\n```sh\nok 1 - Looks good\n```\n\nThe `directive` argument is optional. It accepts `todo` or `skip`.\n\n### fail (`string` message [, `string` directive, `object` detail])\n\n```javascript\ntest('suite name', t =\u003e {\n  t.fail('Uh oh')\n})\n```\n\n```sh\nnot ok 1 - Uh oh\n```\n\nThe `directive` argument is optional. It accepts `todo` or `skip`.\n\n### failinfo (`any` expected, `any` actual, `string` message [, `string` directive])\n\nThis is the same as the `fail` method, but it will output a detail message in YAML format (per the TAP spec).\n\n```javascript\ntest('suite name', t =\u003e {\n  t.failinfo(1, 2, 'Should be equal')\n})\n```\n\n```sh\nTAP version 13\n# suite name\nnot ok 1 - Should be equal\n  ---\n  message: Unmet expectation\n  severity: fail\n  expected: 1\n  actual: 2\n  ...\n1..1\n```\n\n### info (`object`)\n\nAdditional test information can be embedded in TAP results via YAML. The info method accepts a valid key/value JSON object, which will be embedded in the output in YAML format.\n\n```javascript\ntest('suite name', t =\u003e {\n  const passing = false\n\n  t.ok(passing, 'test description')\n\n  if (!passing) {\n    t.info({\n      message: 'Detail',\n      got: {\n        mytest: {\n          result: false\n        }\n      },\n      expected: {\n        mytest: {\n          result: true\n        }\n      }\n    })\n  }\n})\n```\n\n```sh\nTAP version 13\n# suite name\nnot ok 1 - test description\n  ---\n  message: Detail\n  got: {\n    \"mytest\": {\n      \"result\": false\n    }\n  }\n  expected: {\n    \"mytest\": {\n      \"result\": true\n    }\n  }\n  ...\n1..1\n```\n\n### skip (`string` msg [, `object` detail])\n\nSkip the test. This serves primarily as a placeholder for conditional tests. To skip an entire test suite, see [test.skip](#test_skip) and [test.only](#test_only).\n\n```javascript\ntest('suite name', t =\u003e {\n  t.skip('Not relevant to this runtime')\n})\n```\n\n```sh\nok 1 # skip Not relevant to this runtime\n```\n\n### todo (`string` message, [`boolean` pass = true, `object` detail])\n\nTODO items are a special directive in TAP. They always \"pass\", even if a test fails, because they're [considered to be a work in progress](https://testanything.org/tap-version-13-specification.html#todo-tests).\n\n```javascript\ntest('suite name', t =\u003e {\n  t.todo('Rule the world')\n})\n```\n\n```sh\nok # todo Rule the world\n```\n\nTo identify a \"TODO\" test that fails, specify the second optional argument:\n\n```javascript\ntest('suite name', t =\u003e {\n  t.todo('Rule the world', false)\n})\n```\n\n```sh\nnot ok # todo Rule the world\n```\n\n_Remember_, these will still be considered \"passing\" tests, under the assumption something still needs to be done before they are actually part of the test suite.\n\n### plan (`integer` count)\n\nBy specifying a plan count, it is possible to assure all of your tests run.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.plan(1)\n  t.ok(true, 'passing')\n  t.ok(true, 'I should not be here')\n})\n```\n\n```sh\nBail out! Expected 1 test, 2 ran.\n```\n\nIf the plan count does not match the number of tests that actually run, tappedout will abort (\"bail\" in TAP terms) the entire process.\n\n### ok (`boolean` condition, `string` message [, `string` directive])\n\nA simple assertion test, expecting a boolean result.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.ok(true, 'I expect to pass')\n})\n```\n\n```sh\nok 1 - I expect to pass\n```\n\nIt is also possible to supply a directive, either `todo` or `skip`:\n\n```javascript\ntest('suite name', t =\u003e {\n  t.ok(true, 'I expect to pass', 'skip')\n})\n```\n\n```sh\nok 1 # skip I expect to pass\n```\n\nSupplying a directive is a good way to rapidly skip tests or identify things to be done later.\n\n### throws (`function` fn, `string` message [, `string` directive])\n\nThis method accepts a function and expects it to throw an error.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.throws(() =\u003e {\n    throw new Error('Bad input')\n  }, 'Error thrown when user supplies bad data')\n})\n```\n\n```sh\nok 1 - Error thrown when user supplies bad data\n```\n\nIt is possible to supply an optional `todo` or `skip` directive.\n\n### doesNotThrow (`function` fn, `string` message [, `string` directive])\n\nThis method accepts a function and expects it **not** to throw an error.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.throws(() =\u003e {\n    throw new Error('Bad input')\n  }, 'No problems')\n})\n```\n\n```sh\nnot ok 1 - No problems\n```\n\n_(notice this is `not ok`)_\n\nIt is possible to supply an optional `todo` or `skip` directive.\n\n### timeoutAfter (`integer` ms) {\n\nSpecify a timeout period for the test suite.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.timeoutAfter(1000)\n\n  myAsyncFunc(() =\u003e t.end())\n})\n```\n\nIf the timeout is exceeded, the test runner will abort the entire process (bail out).\n\n### expect (`any` expected, `any` actual, `string` message [, `string` directive])\n\nThis is a special method which will compare the expected value to the actual value using a simple truthy/falsey check (i.e. `expected === actual`), just like the `ok` method. Unlike the `ok` method, this will output a YAML description of an error that occurs (uses `failinfo` internally). It is designed as a convenience method.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.expect(1, 2, 'Values should be the same')\n})\n```\n\n```sh\nTAP version 13\n# suite name\nnot ok 1 - Values should be the same\n  ---\n  message: Unmet expectation\n  severity: fail\n  expected: 1\n  actual: 2\n  ...\n1..1\n```\n\n### bail (message)\n\nAbort the process.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.bail('Everybody PANIC')\n})\n```\n\n```sh\nTAP version 13\n# suite name\nBail out! Everybody PANIC!\n```\n\n### end ()\n\nCall this method to explicitly end the test.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.ok(true, 'a-ok')\n  myAsyncFunction(t.end) // Use as a callback\n})\n```\n\n## Special Tests\n\nTAP supports two main directives, `skip` and `todo`. These test methods make it easy to define an entire test suite as being \"skipped\" or \"todo\". There is also an `only` method, which ignores all other test suites.\n\n### test.skip()\n\nThis is the same as `test()`, but with the `skip` directive applied to every test within the suite.\n\n```javascript\ntest.skip('suite name', t =\u003e {\n  t.ok(true, 'a-ok')\n})\n```\n\n```sh\nTAP version 13\n# suite name\nok 1 # skip a-ok  \u003c----- Notice \"skip\"\n1..1\n```\n\n### test.todo()\n\nThis is the same as `test()`, but with the `todo` directive applied to every test within the suite.\n\n```javascript\ntest.todo('suite name', t =\u003e {\n  t.ok(true, 'a-ok')\n})\n```\n\n```sh\nTAP version 13\n# suite name\nok 1 # todo a-ok  \u003c----- Notice \"todo\"\n1..1\n```\n\n### test.only()\n\nThis is the same as `test()`, but it tells the test runner to ignore all other tests which are not created using `test.only()`.\n\n```javascript\ntest('suite name', t =\u003e {\n  t.ok(true, 'did something')\n})\n\ntest.only('suite I care about', t =\u003e {\n  t.ok(true, 'a-ok')\n})\n```\n\nNotice only one of the test suites is actually run.\n\n```sh\nTAP version 13\n# suite I care about\nok 1 - a-ok\n1..1\n```\n\nThis method is very useful when a specific test within your suite breaks, allowing you to run just the tests you care about.\n\n### test.before()\n\nThis test will run once, before the test suite. It will not output TAP results unless one of the API functions is used (i.e. anything except `end()`). This function is used to do a one-time setup/preparation before executing tests.\n\n```javascript\nimport test from 'tappedout'\n\ntest.before(t =\u003e {\n  setupDatabase()\n  t.end()\n})\n```\n\n### test.after()\n\nThis test will run once, after all tests are complete. It will not output TAP results unless one of the API functions is used (i.e. anything except `end()`). This function is used to do a one-time cleanup/teardown after executing tests.\n\n```javascript\nimport test from 'tappedout'\n\ntest.after(t =\u003e {\n  destroyDatabase()\n  t.end()\n})\n```\n\n### test.beforeEach()\n\nThis test will run before each test. It will not output TAP results unless one of the API functions is used (i.e. anything except `end()`). This function is used to do common setup/preparation for each test.\n\n```javascript\nimport test from 'tappedout'\n\ntest.beforeEach(t =\u003e {\n  createCustomDatabaseTable()\n  t.end()\n})\n```\n\n### test.afterEach()\n\nThis test will run after each test. It will not output TAP results unless one of the API functions is used (i.e. anything except `end()`). This function is used to do common cleanup/teardown for each test.\n\n```javascript\nimport test from 'tappedout'\n\ntest.beforeEach(t =\u003e {\n  deleteCustomDatabaseTable()\n  t.end()\n})\n```\n\n## Specifying Details (Example)\n\nProviding custom detail is possible in several ways using special functions, but it is also possible to generate detailed output using any of the assertion methods. Assertion methods are those which \"assert\" whether a condition passes/fails. These methods include `pass()`, `fail()`, `ok()`, `throws()`, and `doesNotThrow()`.\n\nFor convenience, it is also possible to supply details for `skip()`, `todo()`, and `comment()` methods.\n\nHere's an example of a basic \"ok\" assertion:\n\n```javascript\ntest('suite name', t =\u003e {\n  t.ok(false, 'message', {\n    expected: 'my output',\n    actual: 'actual result',\n    hint: 'helpful information',\n    myCustomAttribute: 'my custom value'\n  })\n})\n```\n\n```sh\nTAP version 13\n# suite name\nnot ok 1 - message\n  ---\n  expected: my output\n  actual: actual result\n  hint: helpful information\n  myCustomAttribute: my custom value\n  ...\n1..1\n```\n\n## Other Features\n\nThe following features can be used to create custom test runners.\n\n### test.clear()\n\nThe clear method will remove all tests from the test runner. This is most commonly used for programmatically running multiple test suites, each with their own output.\n\n### test.start(`\u003creset\u003e`)\n\nThis can be used to run all queued tests. This is often used as an [alternative startup](#alternative-startup) strategy, or after clearing tests.\n\n`\u003creset\u003e` determines whether the test counter is reset. The test counter is used to compare the planned number of tests with the actual number of tests for a series of tests. `\u003creset\u003e` is `false` by default. Setting it to true will reset the counter as though the test runner is starting over from the beginning.\n\n### test.onEnd(`\u003ccallback\u003e`)\n\nThe `onEnd` method runs after the tests have completed. No further TAP output will be produce. This method is useful for triggering scripts that run after all testing is complete.\n\nThis is a convenience method, equivalent to `test.on('end', \u003ccallback\u003e)`.\n\n### test.on('event', `\u003chandlerFn\u003e`)\n\nThe following events may be emitted:\n\n1. `test.create` - test suite created/queued\n2. `start` - test runner starts\n3. `end` - test runner ends/completes\n4. `test.start` - a specific test suite starts\n5. `test.end` - a specific test suite ends/completes\n6. `test.abort` - abort a specific test\n7. `test.skip` - skipped a test\n\n### test.once('event', `\u003chandlerFn\u003e`)\n\nSame as `test.on()`, but the handler is removed after it is used.\n\n### test.emit('event', `\u003cargs\u003e`)\n\nEmit a standard or custom event. This is primarily used for internal operations and/or orchestrating advanced/custom test runners.\n\n### test.running\n\n`returns boolean`\n\nDetermines whether the test runner is actively running or not.\n\n---\n\nMIT license. Written by Corey Butler, Copyright 2020-2022.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreybutler%2Ftappedout","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoreybutler%2Ftappedout","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreybutler%2Ftappedout/lists"}