{"id":20083644,"url":"https://github.com/marko-js/testing-library","last_synced_at":"2025-06-22T07:37:11.051Z","repository":{"id":34948119,"uuid":"192994734","full_name":"marko-js/testing-library","owner":"marko-js","description":"Simple and complete Marko testing utilities that encourage good testing practices.","archived":false,"fork":false,"pushed_at":"2024-02-14T23:11:27.000Z","size":1820,"stargazers_count":33,"open_issues_count":8,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-28T03:03:39.072Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/marko-js.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","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":"2019-06-20T22:29:47.000Z","updated_at":"2025-03-07T13:43:44.000Z","dependencies_parsed_at":"2023-12-07T16:45:18.639Z","dependency_job_id":"69dc5a33-139d-4171-9711-4c1056bb1251","html_url":"https://github.com/marko-js/testing-library","commit_stats":{"total_commits":67,"total_committers":2,"mean_commits":33.5,"dds":0.07462686567164178,"last_synced_commit":"fd20fd9d9f04a72dbd06af421790da57685730f7"},"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/marko-js/testing-library","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marko-js%2Ftesting-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marko-js%2Ftesting-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marko-js%2Ftesting-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marko-js%2Ftesting-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marko-js","download_url":"https://codeload.github.com/marko-js/testing-library/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marko-js%2Ftesting-library/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261255905,"owners_count":23131478,"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":[],"created_at":"2024-11-13T15:48:11.297Z","updated_at":"2025-06-22T07:37:06.033Z","avatar_url":"https://github.com/marko-js.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003c!-- Logo --\u003e\n  \u003ca href=\"https://www.joypixels.com/emoji/1f986\"\u003e\n    \u003cimg\n      height=\"80\"\n      width=\"80\"\n      alt=\"duck\"\n      src=\"https://raw.githubusercontent.com/marko-js/testing-library/master/assets/duck.png\"\n    /\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003ch1\u003e@marko/testing-library\u003c/h1\u003e\n  \u003cp\u003eSimple and complete Marko testing utilities that encourage good testing practices.\u003c/p\u003e\n\n  \u003c!-- CI --\u003e\n  \u003ca href=\"https://travis-ci.org/marko-js/testing-library\"\u003e\n  \u003cimg src=\"https://img.shields.io/travis/marko-js/testing-library.svg\" alt=\"Build status\"/\u003e\n  \u003c/a\u003e\n  \u003c!-- Coverage --\u003e\n  \u003ca href=\"https://codecov.io/gh/marko-js/testing-library\"\u003e\n    \u003cimg src=\"https://codecov.io/gh/marko-js/testing-library/branch/master/graph/badge.svg?token=LirxYQjltb\" alt=\"Test Coverage\"/\u003e\n  \u003c/a\u003e\n  \u003c!-- Language --\u003e\n  \u003ca href=\"http://typescriptlang.org\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/%3C%2F%3E-typescript-blue.svg\" alt=\"TypeScript\"/\u003e\n  \u003c/a\u003e\n  \u003c!-- Format --\u003e\n  \u003ca href=\"https://github.com/prettier/prettier\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/styled_with-prettier-ff69b4.svg\" alt=\"Styled with prettier\"/\u003e\n  \u003c/a\u003e\n  \u003c!-- NPM Version --\u003e\n  \u003ca href=\"https://npmjs.org/package/@marko/testing-library\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/@marko/testing-library.svg\" alt=\"NPM Version\"/\u003e\n  \u003c/a\u003e\n  \u003c!-- Downloads --\u003e\n  \u003ca href=\"https://npmjs.org/package/@marko/testing-library\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/@marko/testing-library.svg\" alt=\"Downloads\"/\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n## Table of Contents\n\n- [**Read The Docs**](https://testing-library.com/docs/marko-testing-library/intro) | [Edit the docs](https://github.com/testing-library/testing-library-docs)\n- [The problem](#the-problem)\n- [This solution](#this-solution)\n- [Installation](#installation)\n- [API](#api)\n- [Setup](#setup)\n- [Guiding Principles](#guiding-principles)\n- [Docs](#docs)\n- [Code of Conduct](#code-of-conduct)\n\n## The problem\n\nYou want to write maintainable tests for your Marko components. As a part of\nthis goal, you want your tests to avoid including implementation details of your\ncomponents and rather focus on making your tests give you the confidence for\nwhich they are intended. As part of this, you want your testbase to be\nmaintainable in the long run so refactors of your components (changes to\nimplementation but not functionality) don't break your tests and slow you and\nyour team down.\n\n## This solution\n\nThe `@marko/testing-library` is a very lightweight solution for testing Marko\ncomponents. It provides light utility functions on top of [`@testing-library/dom`](https://github.com/testing-library/dom-testing-library) in a way that encourages better testing practices. Its primary guiding principle is:\n\n\u003e [The more your tests resemble the way your software is used, the more confidence they can give you.](#guiding-principles)\n\n## Installation\n\n```console\nnpm install --save-dev @marko/testing-library\n```\n\nYou may also be interested in installing `jest-dom` so you can use\n[the custom jest matchers](https://github.com/testing-library/jest-dom#readme). Or if using another test runner like [mocha](https://mochajs.org) you could check out [`chai-dom`](https://www.chaijs.com/plugins/chai-dom/).\n\n## API\n\nMarko testing library exposes all of the same utilities for [querying the dom](https://testing-library.com/docs/dom-testing-library/api-queries), [firing events](https://testing-library.com/docs/dom-testing-library/api-events) and [testing asynchronous behavior](https://testing-library.com/docs/dom-testing-library/api-async) as [@testing-library/dom](https://github.com/testing-library/dom-testing-library). This module only exposes two additional APIs to make testing against your components easier.\n\n### `render(template, input?, { container }?)`\n\nThis funcition renders your template asynchronously and provides you with [query helpers](https://testing-library.com/docs/dom-testing-library/api-queries) that are scoped to output DOM.\n\n```javascript\nimport { render, screen } from \"@marko/testing-library\";\nimport HelloTemplate from \"./src/__test__/fixtures/hello-name.marko\";\n\ntest(\"contains the text\", async () =\u003e {\n  const { rerender } = await render(HelloTemplate, {\n    name: \"World\",\n  });\n\n  // Will find the element within the rendered result from the template.\n  expect(screen.getByText(\"Hello World\")).toBeInTheDocument();\n\n  // You can also rerender the component if needed.\n  await rerender({ name: \"Marko\" });\n\n  expect(screen.getByText(\"Hello Marko\")).toBeInTheDocument();\n});\n```\n\nThe render result will also provide you with a `container` HTMLElement. This acts as an escape hatch and allows you to test your components going against the [guiding principles](#guiding-principles). With the `container` you can grab any element using `querySelector` or other means that mean nothing to your users.\n\n```javascript\ntest(\"not a great test\", async () =\u003e {\n  const { container } = await render(HelloTemplate, { name: \"World\" });\n\n  expect(container.querySelector(\"div\")).toBeInTheDocument();\n});\n```\n\nThe problem with the above test is that your user does not care about or see that there is a `div` element, the user only see's the text content of the div. Maybe it turns out that a div wasn't the best element and we should switch to an h1? Now your tests are broken, even though there is likely no perceptable change to the user.\n\n### `cleanup()`\n\nWith client side tests your components are rendered into a placeholder HTMLElement.\nYou can call `cleanup` at any time to destroy any attached components and remove them from the DOM.\n\n```javascript\nimport { cleanup, screen } from \"@marko/testing-library\";\nimport HelloTemplate from \"./src/__test__/fixtures/hello-name.marko\";\n\ntest(\"contains the text\", async () =\u003e {\n  await render(HelloTemplate, { name: \"World\" });\n\n  expect(screen.getByText(\"Hello World\")).toBeInTheDocument();\n\n  cleanup();\n\n  expect(screen.queryByText(\"Hello Marko\")).toBeNull();\n});\n```\n\nBy default if your testing framework exposes an `afterEach` hook (such as `jest` and `mocha`) then `cleanup` will be automatically invoked after each of your tests run.\n\nIf you'd like to disable the automatic cleanup behavior described above you can import `@marko/testing-library/dont-cleanup-after-each`.\n\n```javascript\nimport \"@marko/testing-library/dont-cleanup-after-each\";\n```\n\nWith mocha you can use `mocha -r @marko/testing-library/dont-cleanup-after-each` as a shorthand.\n\nIf you are using Jest, you can include `setupFilesAfterEnv: [\"@marko/testing-library/dont-cleanup-after-each\"]` in your Jest config to avoid doing this in each file.\n\n### `normalize()`\n\nReturns a clone of the passed DOM container with Marko's internal markers removed (data-marko, etc.), id's and whitespace are also normalized.\n\n```javascript\nimport { render, normalize } from \"@marko/testing-library\";\nimport HelloTemplate from \"./src/__test__/fixtures/hello-name.marko\";\n\ntest(\"snapshot\", async () =\u003e {\n  const { container } = await render(HelloTemplate, { name: \"World\" });\n\n  expect(normalize(container)).toMatchSnapshot();\n});\n```\n\n## Setup\n\nMarko testing library is not dependent on any test runner, however it is dependent on the test environment. These utilities work for testing both server side, and client side Marko templates and provide a slightly different implementation for each. This is done using a [browser shim](https://github.com/defunctzombie/package-browser-field-spec), just like in Marko.\n\nThe [browser shim](https://github.com/defunctzombie/package-browser-field-spec) is picked up by many tools, including all bundlers and some test runners.\n\nBelow is some example configurations to test both server and browser components with some popular test runners.\n\n### [Jest](http://jestjs.io)\n\nFor Jest to understand Marko templates you must first [install the @marko/jest preset](https://github.com/marko-js/jest#installation). This allows your Marko templates to be imported into your tests.\n\nTo test components rendered in the client side, be sure to use the `@marko/jest/preset/browser` jest preset and you are good to go!\n\n**jest.config.js**\n\n```javascript\nmodule.exports = {\n  preset: \"@marko/jest/preset/browser\",\n};\n```\n\nIf you'd like to test components using server side rendering you can instead use the `@marko/jest/preset/node` jest preset.\n\n**jest.config.js**\n\n```javascript\nmodule.exports = {\n  preset: \"@marko/jest/preset/node\",\n};\n```\n\nA Jest configuration can also have multiple [projects](https://jestjs.io/docs/en/configuration#projects-array-string-projectconfig) which we can use to create a combined configuration for server side tests, and browser side tests, like so:\n\n**jest.config.js**\n\n```javascript\nmodule.exports = {\n  projects: [\n    {\n      displayName: \"server\",\n      preset: \"@marko/jest/preset/node\",\n      testRegex: \"/__tests__/[^.]+\\\\.server\\\\.js$\",\n    },\n    {\n      displayName: \"browser\",\n      preset: \"@marko/jest/preset/browser\",\n      testRegex: \"/__tests__/[^.]+\\\\.browser\\\\.js$\",\n    },\n  ],\n};\n```\n\n### [Mocha](https://mochajs.org)\n\nMocha also works great for testing Marko components. Mocha, however, has no understanding of [browser shims](https://github.com/defunctzombie/package-browser-field-spec) which means out of the box it can only work with server side Marko components.\n\nTo run server side Marko tests with `mocha` you can simply run the following command:\n\n```console\nmocha -r marko/node-require\n```\n\nThis enables the [Marko require hook](https://markojs.com/docs/installing/#require-marko-views) and allows you to require server side Marko templates directly in your tests.\n\nFor client side testing of your components with Mocha often you will use a bundler to build your tests (this will properly resolve the browser shims mentioned above) and then you can load these tests in some kind of browser context.\n\n## Guiding Principles\n\n\u003e [The more your tests resemble the way your software is used, the more\n\u003e confidence they can give you.][https://testing-library.com/docs/guiding-principles]\n\nWe try to only expose methods and utilities that encourage you to write tests\nthat closely resemble how your Marko components are used.\n\nUtilities are included in this project based on the following guiding\nprinciples:\n\n1.  If it relates to rendering components, then it should deal with DOM nodes\n    rather than component instances, and it should not encourage dealing with\n    component instances.\n2.  It should be generally useful for testing the application components in the\n    way the user would use it. We _are_ making some trade-offs here because\n    we're using a computer and often a simulated browser environment, but in\n    general, utilities should encourage tests that use the components the way\n    they're intended to be used.\n3.  Utility implementations and APIs should be simple and flexible.\n\nAt the end of the day, what we want is for this library to be pretty\nlight-weight, simple, and understandable.\n\n## Docs\n\n[**Read The Docs**](https://testing-library.com/docs/marko-testing-library/intro) |\n[Edit the docs](https://github.com/testing-library/testing-library-docs)\n\n## Code of Conduct\n\nThis project adheres to the [eBay Code of Conduct](./.github/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarko-js%2Ftesting-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarko-js%2Ftesting-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarko-js%2Ftesting-library/lists"}