Available since v0.1.0
fs-assert-updated
StableResolves when the matched element's text, attributes, or children mutate in place. Mutation-observed — the element identity is preserved; only its content changes.
Syntax
fs-assert-updated="<selector>"
fs-assert-updated="<selector>[modifier=value]..."
When to use it
Use when the target element already exists and the triggered action will modify it. The canonical choice for:
- Class toggles on an existing element (
.active,.completed,.expanded) - Text content changes on counters, status indicators, labels
- Attribute changes (
aria-expanded,data-state,src) - Idiomorph or morphdom in-place patches
If a new element is going to be created, use added instead.
Example
<button
fs-assert="counter/increment"
fs-trigger="click"
fs-assert-updated='#counter[text-matches=\d+]'>
Increment
</button>
<div id="counter">0</div>
Passes when #counter's text changes to match the regex after the click.
Mutation record shape
updated resolves from mutation records whose target matches the selector — either attributes / characterData records directly on the element, or childList records where the element is the parent. The resolver walks text-node mutations up to their parent element via parentElement, so a text-only change satisfies updated with text-matches without having to target the text node directly.
Pairs well with
fs-trigger="click"— clicks that mutate an existing counter, label, or statusfs-trigger="change"— form controls flipping state[text-matches=...]— verify new text[classlist=...]— verify class changes[data-state=...]— verify data-attr changes- Dynamic assertion values — compute the expected next state in the template
Gotchas
- Using
updatedon HTMXhx-swap="outerHTML". outerHTML replaces the element wholesale. The new node lands inaddedElements, notupdatedElements, andupdatedwill never resolve. Useadded. See the HTMX swap strategy table. - Using
updatedwith OOB or invariant. Both need a witnessed mutation. OOB assertions are created when a parent resolves — the mutation already happened. Invariants evaluate perpetually — they don't wait for a new mutation. Usevisible,hidden,added, orremovedfor those cases. - Broad selectors.
updatedwaits for a mutation on the first matching element. In lists with many similar items, prefer specific ids or data attributes to avoid matching the wrong element.
See also
added— for new elementsstable— the temporal inverse (passes when NOT updated)- Assertions index