https://github.com/luontola/html-utils
Utilities for writing and testing HTML on Node.js
https://github.com/luontola/html-utils
html html-templating htmx javascript javascript-library nodejs react testing-tools typescript
Last synced: over 1 year ago
JSON representation
Utilities for writing and testing HTML on Node.js
- Host: GitHub
- URL: https://github.com/luontola/html-utils
- Owner: luontola
- License: apache-2.0
- Created: 2025-02-25T21:37:49.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-03-20T18:37:37.000Z (over 1 year ago)
- Last Synced: 2025-03-20T20:04:17.223Z (over 1 year ago)
- Topics: html, html-templating, htmx, javascript, javascript-library, nodejs, react, testing-tools, typescript
- Language: TypeScript
- Homepage:
- Size: 42 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# Esko's HTML Utils
This project contains a couple utilities for writing and testing HTML in JavaScript/Node.js.
These utilities are not available on npm, but they are meant to be copy-pasted into your project. They come complete
with unit tests, so they can be evolved to fit your project's needs.
## HTML Templating
There is a tag function for writing tagged templates, to produce HTML without a heavy framework like React.
The placeholders are automatically escaped to avoid XSS vulnerabilities.
```js
const input = "alert(1)"
const output = html`
Hello ${input}
`
expect(output.html).toBe("Hello <script>alert(1)</script>
")
```
You can create components using plain old functions. Works great with [htmx](https://htmx.org/).
```js
function homePage() {
return html`
Welcome
${clickerButton()}
`
}
function clickerButton(counter: number = 0) {
return html`
Clicked ${counter} times
`
}
```
See [html-templates.ts](src/html-templates.ts) and [html-templates.test.ts](test/html-templates.test.ts)
## Unit Testing the UI
There is a helper function for extracting the visible text from HTML, to easily unit test HTML templates.
The components mentioned in the previous section could be unit tested like this:
```js
expect(visualizeHtml(homePage())).toBe(normalizeWhitespace(`
Welcome
Clicked 0 times`))
const button = clickerButton(5)
expect(visualizeHtml(button)).toBe("Clicked 5 times")
expect(button.html).toContain(`hx-get="/clicker?counter=6"`)
```
By default `visualizeHtml` strips all HTML tags.
But if you add a `data-test-icon` attribute to an element, the element will be replaced with its value.
This enables [stringly asserted](https://martinfowler.com/articles/tdd-html-templates.html#BonusLevelStringlyAsserted)
testing to assert non-textual information.
```js
expect(visualizeHtml("
one
two
")).toBe("one two")
expect(visualizeHtml(``)).toBe("☑️")
```
In addition to raw HTML and [our HTML templates](#html-templating), `visualizeHtml` works also for React elements.
If you use only one of them, you can delete a few lines from `visualizeHtml` to remove the unnecessary dependency.
See [html-testing.ts](src/html-testing.ts) and [html-testing.test.ts](test/html-testing.test.ts)
## Installing
To use this library, download it to be part of your project:
```
wget https://raw.githubusercontent.com/luontola/html-utils/refs/heads/main/src/html-templates.ts
wget https://raw.githubusercontent.com/luontola/html-utils/refs/heads/main/test/html-templates.test.ts
wget https://raw.githubusercontent.com/luontola/html-utils/refs/heads/main/src/html-testing.ts
wget https://raw.githubusercontent.com/luontola/html-utils/refs/heads/main/test/html-testing.test.ts
```
In particular, the testing library often benefits from project-specific customizations.
This library is [finished software](https://josem.co/the-beauty-of-finished-software/), so there is no need to get
constant updates to it.
No new features is a feature in itself.
You wouldn't want to be [left-padded](https://en.wikipedia.org/wiki/Npm_left-pad_incident) because of just 50 lines of
code, would you?