{"id":13531603,"url":"https://github.com/HugoDF/alpine-test-utils","last_synced_at":"2025-04-01T19:32:27.286Z","repository":{"id":36968648,"uuid":"260864209","full_name":"HugoDF/alpine-test-utils","owner":"HugoDF","description":"Utilities for testing Alpine.js components","archived":true,"fork":false,"pushed_at":"2023-01-05T19:37:49.000Z","size":639,"stargazers_count":71,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T20:03:55.057Z","etag":null,"topics":["alpinejs","jsdom","testing"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/alpine-test-utils","language":"JavaScript","has_issues":false,"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/HugoDF.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"HugoDF"}},"created_at":"2020-05-03T08:59:39.000Z","updated_at":"2024-11-18T13:12:19.000Z","dependencies_parsed_at":"2023-01-17T09:45:47.133Z","dependency_job_id":null,"html_url":"https://github.com/HugoDF/alpine-test-utils","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":"HugoDF/microbundle-ts-pkg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoDF%2Falpine-test-utils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoDF%2Falpine-test-utils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoDF%2Falpine-test-utils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HugoDF%2Falpine-test-utils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HugoDF","download_url":"https://codeload.github.com/HugoDF/alpine-test-utils/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246700705,"owners_count":20819923,"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":["alpinejs","jsdom","testing"],"created_at":"2024-08-01T07:01:04.288Z","updated_at":"2025-04-01T19:32:23.213Z","avatar_url":"https://github.com/HugoDF.png","language":"JavaScript","funding_links":["https://github.com/sponsors/HugoDF"],"categories":["Extensions \u0026 Plugins"],"sub_categories":[],"readme":"![test](https://github.com/HugoDF/alpine-test-utils/workflows/test/badge.svg)\n![npm version](https://img.shields.io/npm/v/alpine-test-utils)\n# Alpine.js Test Utils\n\nUtilities for testing Alpine.js components.\n\n**This library allows you to quickly and easily write tests for Alpine.js applications via Node.js using _any testing library_.**\n\nThat means you can use AVA, Tape, Mocha, Jest or whatever other testing library you enjoy using.\n\nThis project is not officially affiliated with Alpine.js, it's maintained by community members. For any feedback, questions or issues, please create [issues](https://github.com/HugoDF/alpine-test-utils/issues) and [pull requests](https://github.com/HugoDF/alpine-test-utils/blob/master/README.md#contributing) or merely upvote or comment on existing issues or pull requests.\n\n# Table of Contents\n\n- [Installation](#installation)\n  - [Prerequisites](#prerequisites)\n  - [Install Package](#install-package)\n  - [Peer Dependencies](#peer-dependencies)\n- [Quick Start, Write your first test](#quick-start-write-your-first-test)\n- [API](#api)\n- [Roadmap](#roadmap)\n- [Contributing](#contributing)\n  - [Requirements](#requirements)\n  - [Setup](#setup)\n  - [npm scripts](#npm-scripts)\n- [About](#about)\n  - [Acknowledgments](#acknowledgments)\n- [LICENSE](#license)\n\n# Installation\n\n## Prerequisites\n\n- Node.js version 10, 12 or 14\n\n## Install Package\n\nThe following recommended installation requires [npm](https://npmjs.org/). If you are unfamiliar with npm, see the [npm docs](https://npmjs.org/doc/). Npm comes installed with Node.js since node version 0.8.x, therefore, you likely already have it.\n\n```sh\nnpm install --save-dev alpine-test-utils\n```\n\nYou may also use [yarn](https://yarnpkg.com/en/) to install.\n\n```sh\nyarn add --dev alpine-test-utils\n```\n\n## Peer Dependencies\n\n**IMPORTANT**: If you're loading Alpine.js from CDN (using a `script` tag) you'll need to install `alpinejs` in order to use `alpine-test-utils`. It should be the same version as the version of Alpine.js you are loading from CDN. using.\n\n```sh\nnpm install --save-dev alpinejs\n# or for Yarn users\nyarn add --dev alpinejs\n```\n\n\u003ca name=\"quick-start\"\u003e\u003c/a\u003e\n# Quick Start, Write your first test\n\nHere's an example to render a simple Alpine.js component using Jest/Jasmine syntax:\n\n```js\nimport {render} from 'alpine-test-utils';\n\ntest('test foo component', () =\u003e {\n  const componentHtml = `\u003cdiv x-data=\"{foo: 'bar'}\"\u003e\n    \u003cspan x-text=\"foo\"\u003e\u003c/span\u003e\n  \u003c/div\u003e`\n  const component = render(componentHtml);\n  expect(component.querySelector('span').textContent).toEqual('bar');\n});\n```\n\nFor more complex use cases, please see [USE_CASES.md](./USE_CASES.md) or for the full API, see the following section.\n\n# API\n\n| Method | Description |\n| --- | --- |\n| [render](#render) | Render \u0026 run Alpine.js component markup |\n| [load](#loadloadsync) | Extract Alpine.js component markup from files |\n| [loadSync](#loadloadsync) | Synchronous variant of `load` |\n| [waitFor](#waitfor) | Wait for an assertion to pass |\n| [$nextTick](#nexttick) | Wait for a re-render or async work to happen |\n| [setGlobal](#setglobal) | Override globals using an object |\n| [setMutationObserver](#setmutationobserver) | Set a custom MutationObserver implementation |\n\n## render\n\nRender Alpine.js Component Markup to JSDOM \u0026 initialise Alpine.js.\n\nParameters:\n\n- markup - string - the Alpine.js markup to render\n- data - (Optional) object or string - data to use to override contents of x-data\n\nReturns:\n\n- an AlpineElement - an Element with added Alpine.js `$data` and `$el` properties and Alpine Test Utils `$nextTick` function.\n\nUsage Example: render a component and check text is displayed as per x-data.\n\n```js\ntest('component renders content of \"foo\" in span', () =\u003e {\n  const component = render(`\u003cdiv x-data=\"{ foo: 'bar' }\"\u003e\n    \u003cspan x-text=\"foo\"\u003e\u003c/span\u003e\n  \u003c/div\u003e`);\n  expect(component.querySelector('span').textContent).toEqual('bar');\n});\n```\n\nFor a more advanced example see [Clicking a button to toggle visibility](./USE_CASES.md#clicking-a-button-to-toggle-visibility).\n\n## load/loadSync\n\nLoad markup from a file asynchronously using a path.\n\n\u003e Note: when a single `x-data` Alpine.js component is found in the file, it is returned. If multiple components are found, all are returned in an Array.\n\nParameters:\n\n- filePath - Path to the HTML/template file to load components from\n\nReturns:\n\n- in the async case, a `Promise\u003cstring[]|string\u003e` (a Promise that resolves to a string or an array of strings)\n- in the sync case, a `string[]|string`.\n\nUsage Example: load a PHP template, see [the full use-case](./USE_CASES.md##loading--rendering-a-php-template-that-injects-into-x-data).\n\n```ts\ntest('my test', async () =\u003e {\n  const markupAsync = await load(path.join(__dirname, '../fixtures/template.php'));\n  const markupSync = loadSync(path.join(__dirname, '../fixtures/template.php'));\n});\n```\n\n## waitFor\n\nWait until assertions pass, wrapper for [wait-for-expect](https://github.com/TheBrainFamily/wait-for-expect).\n\nParameters: \n\n- callback containing the assertions. \"predicate\" that has to complete without throwing\n- timeout - Optional, Number - Maximum wait interval, 4500ms by default\n- interval - Optional, Number - Wait interval, 50ms by default\n\nReturns: Promise that resolves/rejects based on whether the assertions eventually pass.\n\n\nUsage example: for more advanced use-cases see [Clicking a button to toggle visibility](./USE_CASES.md#clicking-a-button-to-toggle-visibility) and [Intercepting `fetch` calls \u0026 waiting for re-renders](./USE_CASES.md#intercepting-fetch-calls--waiting-for-re-renders)\n\n```js\ntest('clicking a button to toggle visibility', async () =\u003e {\n  const component = render(`\u003cdiv x-data=\"{ isOpen: false }\"\u003e\n    \u003cbutton @click=\"isOpen = !isOpen\"\u003e\u003c/button\u003e\n    \u003cspan x-show=\"isOpen\"\u003e\u003c/span\u003e\n  \u003c/div\u003e`);\n\n  expect(component.querySelector('span').style.display).toEqual('none');\n  component.querySelector('button').click();\n  await waitFor(() =\u003e {\n    expect(component.querySelector('span').style.display).toEqual('');\n  });\n});\n```\n\n\n## $nextTick\n\n\u003e Note: prefer [`waitFor`](#waitfor) it's more flexible and accurate.\n\nFunction to wait until a render/async operation happens.\n\nParameters: none.\n\nReturns: \n\n- a Promise that resolves after the next async operation has completed (ie. on the next tick of the event loop)\n\n\u003e Note this exported as a global from the Alpine Test Utils module _and_ is attached to components during `render`, see [render](#render).\n\n```js\ntest('clicking a button to toggle visibility', async () =\u003e {\n  const component = render(`\u003cdiv x-data=\"{ isOpen: false }\"\u003e\n    \u003cbutton @click=\"isOpen = !isOpen\"\u003e\u003c/button\u003e\n    \u003cspan x-show=\"isOpen\"\u003e\u003c/span\u003e\n  \u003c/div\u003e`);\n\n  expect(component.querySelector('span').style.display).toEqual('none');\n  component.querySelector('button').click();\n  await component.$nextTick();\n  expect(component.querySelector('span').style.display).toEqual('');\n});\n```\n\n\n## setGlobal\n\nOverride Node.js `global` using passed `override` object.\n\nThe implementation is literally `Object.assign(global, override)`.\n\nParameters:\n\n- an object with keys to override on the `global` object\n\nReturns: none.\n\nUsage example: overring `global.fetch`, see the full use case [Intercepting `fetch` calls \u0026 waiting for re-renders](./USE_CASES.md#intercepting-fetch-calls--waiting-for-re-renders).\n\n```js\ntest('intercepting fetch calls', async () =\u003e {\n  setGlobal({\n    fetch: () =\u003e\n      Promise.resolve({\n        json: () =\u003e Promise.resolve(['data-1', 'data-2'])\n      })\n  });\n});\n```\n\n\n# Roadmap\n\nIf you are interested in the future direction of this project, please take a look at the open [issues](https://github.com/HugoDF/alpine-test-utils/issues) and [pull requests](https://github.com/HugoDF/alpine-test-utils/pulls). I would love to hear your feedback!\n\n# Contributing\n\n## Requirements\n\n- Node 10\n- Yarn 1.x or npm\n\n## Setup\n\n1. Clone the repository\n2. Run `yarn` or `npm install` installs all required dependencies.\n3. Run `yarn test` to run all tests :D.\n\n## npm scripts\n\n\u003e Equivalent `npm run \u003cscript\u003e` should also work\n\n- `yarn test` run tests with [ava](https://github.com/avajs/ava).\n- `yarn build` will run JSDoc -\u003e TypeScript typing conversion with [jsdoc](https://github.com/jsdoc/jsdoc) and [tsd-jsdoc](https://github.com/englercj/tsd-jsdoc), changes to [./types.d.ts](./types.d.ts) shoud be committed.\n- `yarn lint` will lint all of the files with [xo](https://github.com/xojs/xo)\n- `yarn format` will run lint with `--fix` option on all the examples files (and tests).\n- `yarn release`, run clean, production build and release with `np`.\n\n# About\n\nThis package is maintained by Hugo from [Code with Hugo](https://codewithhugo.com) and [Alpine.js Weekly](https://alpinejs.codewithhugo.com/newsletter).\n\n## Acknowledgments\n\n\nSpecial thanks to:\n\n- The developers behind\n  - [Alpine.js](https://github.com/alpinejs/alpine)\n  - [ava](https://avajs.dev)\n  - [jsdoc](https://github.com/jsdoc/jsdoc)\n  - [tsd-jsdoc](https://github.com/englercj/tsd-jsdoc)\n  - [esm](https://github.com/standard-things/esm#readme)\n  - [np](https://github.com/sindresorhus/np#readme)\n  - [xo](https://github.com/xojs/xo#readme)\n\n# LICENSE\n\nCode is licensed under the [MIT License](./LICENSE).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHugoDF%2Falpine-test-utils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FHugoDF%2Falpine-test-utils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FHugoDF%2Falpine-test-utils/lists"}