Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/HugoDF/alpine-test-utils
Utilities for testing Alpine.js components
https://github.com/HugoDF/alpine-test-utils
alpinejs jsdom testing
Last synced: about 1 month ago
JSON representation
Utilities for testing Alpine.js components
- Host: GitHub
- URL: https://github.com/HugoDF/alpine-test-utils
- Owner: HugoDF
- License: mit
- Archived: true
- Created: 2020-05-03T08:59:39.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2023-01-05T19:37:49.000Z (almost 2 years ago)
- Last Synced: 2024-10-30T13:06:08.433Z (about 1 month ago)
- Topics: alpinejs, jsdom, testing
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/alpine-test-utils
- Size: 624 KB
- Stars: 70
- Watchers: 3
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
- awesome - Alpine Test Utils - Utilities for testing Alpine.js components
README
![test](https://github.com/HugoDF/alpine-test-utils/workflows/test/badge.svg)
![npm version](https://img.shields.io/npm/v/alpine-test-utils)
# Alpine.js Test UtilsUtilities for testing Alpine.js components.
**This library allows you to quickly and easily write tests for Alpine.js applications via Node.js using _any testing library_.**
That means you can use AVA, Tape, Mocha, Jest or whatever other testing library you enjoy using.
This 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.
# Table of Contents
- [Installation](#installation)
- [Prerequisites](#prerequisites)
- [Install Package](#install-package)
- [Peer Dependencies](#peer-dependencies)
- [Quick Start, Write your first test](#quick-start-write-your-first-test)
- [API](#api)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Requirements](#requirements)
- [Setup](#setup)
- [npm scripts](#npm-scripts)
- [About](#about)
- [Acknowledgments](#acknowledgments)
- [LICENSE](#license)# Installation
## Prerequisites
- Node.js version 10, 12 or 14
## Install Package
The 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.
```sh
npm install --save-dev alpine-test-utils
```You may also use [yarn](https://yarnpkg.com/en/) to install.
```sh
yarn add --dev alpine-test-utils
```## Peer Dependencies
**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.
```sh
npm install --save-dev alpinejs
# or for Yarn users
yarn add --dev alpinejs
```
# Quick Start, Write your first testHere's an example to render a simple Alpine.js component using Jest/Jasmine syntax:
```js
import {render} from 'alpine-test-utils';test('test foo component', () => {
const componentHtml = ``
const component = render(componentHtml);
expect(component.querySelector('span').textContent).toEqual('bar');
});
```For more complex use cases, please see [USE_CASES.md](./USE_CASES.md) or for the full API, see the following section.
# API
| Method | Description |
| --- | --- |
| [render](#render) | Render & run Alpine.js component markup |
| [load](#loadloadsync) | Extract Alpine.js component markup from files |
| [loadSync](#loadloadsync) | Synchronous variant of `load` |
| [waitFor](#waitfor) | Wait for an assertion to pass |
| [$nextTick](#nexttick) | Wait for a re-render or async work to happen |
| [setGlobal](#setglobal) | Override globals using an object |
| [setMutationObserver](#setmutationobserver) | Set a custom MutationObserver implementation |## render
Render Alpine.js Component Markup to JSDOM & initialise Alpine.js.
Parameters:
- markup - string - the Alpine.js markup to render
- data - (Optional) object or string - data to use to override contents of x-dataReturns:
- an AlpineElement - an Element with added Alpine.js `$data` and `$el` properties and Alpine Test Utils `$nextTick` function.
Usage Example: render a component and check text is displayed as per x-data.
```js
test('component renders content of "foo" in span', () => {
const component = render(``);
expect(component.querySelector('span').textContent).toEqual('bar');
});
```For a more advanced example see [Clicking a button to toggle visibility](./USE_CASES.md#clicking-a-button-to-toggle-visibility).
## load/loadSync
Load markup from a file asynchronously using a path.
> 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.
Parameters:
- filePath - Path to the HTML/template file to load components from
Returns:
- in the async case, a `Promise` (a Promise that resolves to a string or an array of strings)
- in the sync case, a `string[]|string`.Usage Example: load a PHP template, see [the full use-case](./USE_CASES.md##loading--rendering-a-php-template-that-injects-into-x-data).
```ts
test('my test', async () => {
const markupAsync = await load(path.join(__dirname, '../fixtures/template.php'));
const markupSync = loadSync(path.join(__dirname, '../fixtures/template.php'));
});
```## waitFor
Wait until assertions pass, wrapper for [wait-for-expect](https://github.com/TheBrainFamily/wait-for-expect).
Parameters:
- callback containing the assertions. "predicate" that has to complete without throwing
- timeout - Optional, Number - Maximum wait interval, 4500ms by default
- interval - Optional, Number - Wait interval, 50ms by defaultReturns: Promise that resolves/rejects based on whether the assertions eventually pass.
Usage 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 & waiting for re-renders](./USE_CASES.md#intercepting-fetch-calls--waiting-for-re-renders)
```js
test('clicking a button to toggle visibility', async () => {
const component = render(``);
expect(component.querySelector('span').style.display).toEqual('none');
component.querySelector('button').click();
await waitFor(() => {
expect(component.querySelector('span').style.display).toEqual('');
});
});
```## $nextTick
> Note: prefer [`waitFor`](#waitfor) it's more flexible and accurate.
Function to wait until a render/async operation happens.
Parameters: none.
Returns:
- a Promise that resolves after the next async operation has completed (ie. on the next tick of the event loop)
> Note this exported as a global from the Alpine Test Utils module _and_ is attached to components during `render`, see [render](#render).
```js
test('clicking a button to toggle visibility', async () => {
const component = render(``);
expect(component.querySelector('span').style.display).toEqual('none');
component.querySelector('button').click();
await component.$nextTick();
expect(component.querySelector('span').style.display).toEqual('');
});
```## setGlobal
Override Node.js `global` using passed `override` object.
The implementation is literally `Object.assign(global, override)`.
Parameters:
- an object with keys to override on the `global` object
Returns: none.
Usage example: overring `global.fetch`, see the full use case [Intercepting `fetch` calls & waiting for re-renders](./USE_CASES.md#intercepting-fetch-calls--waiting-for-re-renders).
```js
test('intercepting fetch calls', async () => {
setGlobal({
fetch: () =>
Promise.resolve({
json: () => Promise.resolve(['data-1', 'data-2'])
})
});
});
```# Roadmap
If 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!
# Contributing
## Requirements
- Node 10
- Yarn 1.x or npm## Setup
1. Clone the repository
2. Run `yarn` or `npm install` installs all required dependencies.
3. Run `yarn test` to run all tests :D.## npm scripts
> Equivalent `npm run ` should also work
- `yarn test` run tests with [ava](https://github.com/avajs/ava).
- `yarn build` will run JSDoc -> 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.
- `yarn lint` will lint all of the files with [xo](https://github.com/xojs/xo)
- `yarn format` will run lint with `--fix` option on all the examples files (and tests).
- `yarn release`, run clean, production build and release with `np`.# About
This package is maintained by Hugo from [Code with Hugo](https://codewithhugo.com) and [Alpine.js Weekly](https://alpinejs.codewithhugo.com/newsletter).
## Acknowledgments
Special thanks to:
- The developers behind
- [Alpine.js](https://github.com/alpinejs/alpine)
- [ava](https://avajs.dev)
- [jsdoc](https://github.com/jsdoc/jsdoc)
- [tsd-jsdoc](https://github.com/englercj/tsd-jsdoc)
- [esm](https://github.com/standard-things/esm#readme)
- [np](https://github.com/sindresorhus/np#readme)
- [xo](https://github.com/xojs/xo#readme)# LICENSE
Code is licensed under the [MIT License](./LICENSE).