Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.headless

Headless Fulcro application support for testing and server-side execution.

This namespace provides utilities for running Fulcro applications in headless mode on the JVM. Key features:

  • Synchronous transaction processing (all operations complete before returning)
  • Render frame capture (inspect before/after state for assertions)
  • Raw dom-server Element tree capture (convert to hiccup or other formats as needed)
  • Controlled execution (step through transaction phases)
  • Integration with Ring handlers and Pathom parsers via loopback remotes

Example:

(require '[com.fulcrologic.fulcro.headless :as h])
(require '[com.fulcrologic.fulcro.headless.hiccup :as hic])
(require '[com.fulcrologic.fulcro.headless.loopback-remotes :as lr])

(def app (h/build-test-app
           {:root-class Root
            :remotes {:remote (lr/sync-remote my-handler)}}))

;; Transactions are synchronous
(comp/transact! app [(my-mutation)])

;; Inspect render frames
(let [frame (h/last-frame app)
      hiccup (hic/rendered-tree->hiccup (:rendered frame))]
  (is (= expected (:tree frame)))
  (hic/click! (hic/find-by-id hiccup "my-button")))
Headless Fulcro application support for testing and server-side execution.

This namespace provides utilities for running Fulcro applications in headless mode
on the JVM. Key features:

- Synchronous transaction processing (all operations complete before returning)
- Render frame capture (inspect before/after state for assertions)
- Raw dom-server Element tree capture (convert to hiccup or other formats as needed)
- Controlled execution (step through transaction phases)
- Integration with Ring handlers and Pathom parsers via loopback remotes

Example:
```clojure
(require '[com.fulcrologic.fulcro.headless :as h])
(require '[com.fulcrologic.fulcro.headless.hiccup :as hic])
(require '[com.fulcrologic.fulcro.headless.loopback-remotes :as lr])

(def app (h/build-test-app
           {:root-class Root
            :remotes {:remote (lr/sync-remote my-handler)}}))

;; Transactions are synchronous
(comp/transact! app [(my-mutation)])

;; Inspect render frames
(let [frame (h/last-frame app)
      hiccup (hic/rendered-tree->hiccup (:rendered frame))]
  (is (= expected (:tree frame)))
  (hic/click! (hic/find-by-id hiccup "my-button")))
```
raw docstring

*render-frame-max*clj

Default maximum number of render frames to keep in history.

Default maximum number of render frames to keep in history.
sourceraw docstring

attr-ofclj

(attr-of app element-id attr-key)
(attr-of app element-id attr-key frame-index)

Get an attribute value from an element by ID.

With 3 args: From the most recent frame. With 4 args: From the nth frame (0 = most recent).

Returns the attribute value, or nil if element/attr not found.

Example:

(attr-of app "email-input" :value)
;; => "user@example.com"

(attr-of app "submit-btn" :disabled)
;; => true
Get an attribute value from an element by ID.

With 3 args: From the most recent frame.
With 4 args: From the nth frame (0 = most recent).

Returns the attribute value, or nil if element/attr not found.

Example:
```clojure
(attr-of app "email-input" :value)
;; => "user@example.com"

(attr-of app "submit-btn" :disabled)
;; => true
```
sourceraw docstring

blur!clj

(blur! app element-id)

Trigger blur on an element by ID. Invokes the element's :onBlur handler.

Example:

(blur! app "username-input")
Trigger blur on an element by ID.
Invokes the element's :onBlur handler.

Example:
```clojure
(blur! app "username-input")
```
sourceraw docstring

build-test-appclj

(build-test-app {:keys [root-class remotes initial-state render-history-size
                        shared shared-fn]
                 :or {render-history-size *render-frame-max* remotes {}}})

Create a test application configured for synchronous testing.

Options:

  • :root-class - Root component class (required for render frame capture)
  • :remotes - Map of remote-name to remote implementation
  • :initial-state - Initial state map (merged with root's initial state)
  • :render-history-size - Number of frames to keep (default 10)
  • :shared - Static shared props
  • :shared-fn - Function to compute shared props from root tree

Returns a Fulcro app configured with:

  • Synchronous transaction processing
  • Frame-capturing render
  • Event capture (transactions and network events)
  • The specified remotes

Event capture is installed automatically. Use captured-transactions, captured-network-events, and clear-captured-events! to inspect what mutations were triggered and what network activity occurred.

IMPORTANT: For event capture to work, you must enable inspect notifications by setting the JVM property: -Dcom.fulcrologic.fulcro.inspect=true

Create a test application configured for synchronous testing.

Options:
- :root-class - Root component class (required for render frame capture)
- :remotes - Map of remote-name to remote implementation
- :initial-state - Initial state map (merged with root's initial state)
- :render-history-size - Number of frames to keep (default 10)
- :shared - Static shared props
- :shared-fn - Function to compute shared props from root tree

Returns a Fulcro app configured with:
- Synchronous transaction processing
- Frame-capturing render
- Event capture (transactions and network events)
- The specified remotes

Event capture is installed automatically. Use `captured-transactions`,
`captured-network-events`, and `clear-captured-events!` to inspect
what mutations were triggered and what network activity occurred.

IMPORTANT: For event capture to work, you must enable inspect notifications
by setting the JVM property: -Dcom.fulcrologic.fulcro.inspect=true
sourceraw docstring

captured-network-eventsclj

(captured-network-events app)

Get the list of captured network events.

Each entry is a map containing:

  • :event-type - One of :started, :finished, or :failed
  • :fulcro.inspect.ui.network/remote - The remote name
  • :fulcro.inspect.ui.network/request-id - Unique request identifier
  • :fulcro.inspect.ui.network/request-edn - The EQL sent (on :started)
  • :fulcro.inspect.ui.network/response-edn - The response body (on :finished)
  • :fulcro.inspect.ui.network/error - Error info (on :failed)

Example:

(df/load! app :current-user User)
(let [events (captured-network-events app)]
  (is (some #(= :finished (:event-type %)) events)))
Get the list of captured network events.

Each entry is a map containing:
- :event-type - One of :started, :finished, or :failed
- :fulcro.inspect.ui.network/remote - The remote name
- :fulcro.inspect.ui.network/request-id - Unique request identifier
- :fulcro.inspect.ui.network/request-edn - The EQL sent (on :started)
- :fulcro.inspect.ui.network/response-edn - The response body (on :finished)
- :fulcro.inspect.ui.network/error - Error info (on :failed)

Example:
```clojure
(df/load! app :current-user User)
(let [events (captured-network-events app)]
  (is (some #(= :finished (:event-type %)) events)))
```
sourceraw docstring

captured-transactionsclj

(captured-transactions app)

Get the list of captured transactions (optimistic actions).

Each entry is a map containing:

  • :fulcro.history/tx - The transaction form (mutation-sym params)
  • :fulcro.history/network-sends - Set of remotes that will be contacted
  • :component - Name of the component that initiated the transaction (if any)
  • :ident-ref - The ident of the component (if any)

Example:

(comp/transact! app [(my-mutation {:x 1})])
(let [txns (captured-transactions app)]
  (is (= 1 (count txns)))
  (is (= 'my-ns/my-mutation (-> txns first :fulcro.history/tx first))))
Get the list of captured transactions (optimistic actions).

Each entry is a map containing:
- :fulcro.history/tx - The transaction form (mutation-sym params)
- :fulcro.history/network-sends - Set of remotes that will be contacted
- :component - Name of the component that initiated the transaction (if any)
- :ident-ref - The ident of the component (if any)

Example:
```clojure
(comp/transact! app [(my-mutation {:x 1})])
(let [txns (captured-transactions app)]
  (is (= 1 (count txns)))
  (is (= 'my-ns/my-mutation (-> txns first :fulcro.history/tx first))))
```
sourceraw docstring

change!clj

(change! app element-id event)

Invoke onChange on an element with a custom event. For simple text input, prefer type-into!.

Example:

;; For a checkbox
(change! app "remember-me" {:target {:checked true}})

;; For a select
(change! app "country-select" {:target {:value "US"}})
Invoke onChange on an element with a custom event.
For simple text input, prefer `type-into!`.

Example:
```clojure
;; For a checkbox
(change! app "remember-me" {:target {:checked true}})

;; For a select
(change! app "country-select" {:target {:value "US"}})
```
sourceraw docstring

checked?clj

(checked? app element-id)
(checked? app element-id frame-index)

Check if a checkbox or radio input is checked.

With 2 args: Checks the most recent frame. With 3 args: Checks the nth frame (0 = most recent).

Example:

(is (checked? app "remember-me"))
Check if a checkbox or radio input is checked.

With 2 args: Checks the most recent frame.
With 3 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (checked? app "remember-me"))
```
sourceraw docstring

classes-ofclj

(classes-of app element-id)
(classes-of app element-id frame-index)

Get the CSS classes of an element by ID as a set.

With 2 args: From the most recent frame. With 3 args: From the nth frame (0 = most recent).

Returns a set of class names, or nil if element not found.

Example:

(classes-of app "submit-btn")
;; => #{"btn" "btn-primary" "loading"}
Get the CSS classes of an element by ID as a set.

With 2 args: From the most recent frame.
With 3 args: From the nth frame (0 = most recent).

Returns a set of class names, or nil if element not found.

Example:
```clojure
(classes-of app "submit-btn")
;; => #{"btn" "btn-primary" "loading"}
```
sourceraw docstring

clear-captured-events!clj

(clear-captured-events! app)

Clear all captured transactions and network events.

Useful for isolating assertions between test phases.

Example:

;; Phase 1
(click! app "load-btn")
(is (= 1 (count (captured-transactions app))))

;; Clear for phase 2
(clear-captured-events! app)

;; Phase 2
(click! app "save-btn")
(is (= 1 (count (captured-transactions app))))
Clear all captured transactions and network events.

Useful for isolating assertions between test phases.

Example:
```clojure
;; Phase 1
(click! app "load-btn")
(is (= 1 (count (captured-transactions app))))

;; Clear for phase 2
(clear-captured-events! app)

;; Phase 2
(click! app "save-btn")
(is (= 1 (count (captured-transactions app))))
```
sourceraw docstring

clear-render-history!clj

(clear-render-history! app)

Clear all captured render frames.

Clear all captured render frames.
sourceraw docstring

click!clj

(click! app element-id)

Click on an element by ID in the most recent render frame. Invokes the element's :onClick handler if present.

Example:

(click! app "submit-btn")
Click on an element by ID in the most recent render frame.
Invokes the element's :onClick handler if present.

Example:
```clojure
(click! app "submit-btn")
```
sourceraw docstring

click-on-text!clj

(click-on-text! app pattern)
(click-on-text! app pattern n)

Click on an element by its text content in the most recent render frame. Uses event bubbling semantics: if the matched element doesn't have an onClick handler, walks up the ancestor chain to find one.

Pattern can be:

  • A string (substring match)
  • A regex (pattern match)
  • A vector of patterns (all must match)

The optional n parameter specifies which match to click (0-indexed, default 0).

Also checks :text and :label attributes on React component elements.

Example:

(click-on-text! app "View All")
(click-on-text! app "New" 1)        ; click second 'New' link
(click-on-text! app #"Logout")
(click-on-text! app ["Account" "View"])  ; element containing both
Click on an element by its text content in the most recent render frame.
Uses event bubbling semantics: if the matched element doesn't have an onClick
handler, walks up the ancestor chain to find one.

Pattern can be:
- A string (substring match)
- A regex (pattern match)
- A vector of patterns (all must match)

The optional `n` parameter specifies which match to click (0-indexed, default 0).

Also checks :text and :label attributes on React component elements.

Example:
```clojure
(click-on-text! app "View All")
(click-on-text! app "New" 1)        ; click second 'New' link
(click-on-text! app #"Logout")
(click-on-text! app ["Account" "View"])  ; element containing both
```
sourceraw docstring

count-elementsclj

(count-elements app pred)
(count-elements app pred frame-index)

Count elements matching a predicate in the rendered hiccup.

With 2 args: Counts in the most recent frame. With 3 args: Counts in the nth frame (0 = most recent).

Example:

;; Count all list items
(is (= 5 (count-elements app #(= :li (hic/element-tag %)))))

;; Count error messages
(is (= 0 (count-elements app #(hic/has-class? % "error"))))
Count elements matching a predicate in the rendered hiccup.

With 2 args: Counts in the most recent frame.
With 3 args: Counts in the nth frame (0 = most recent).

Example:
```clojure
;; Count all list items
(is (= 5 (count-elements app #(= :li (hic/element-tag %)))))

;; Count error messages
(is (= 0 (count-elements app #(hic/has-class? % "error"))))
```
sourceraw docstring

current-hiccupclj

(current-hiccup mounted)

Get the current hiccup from a mounted component. This reflects the latest render after any state changes.

Get the current hiccup from a mounted component.
This reflects the latest render after any state changes.
sourceraw docstring

current-propsclj

(current-props app component-class ident)

Get denormalized props for a component at the given ident. Useful for inspecting component state in tests.

Get denormalized props for a component at the given ident.
Useful for inspecting component state in tests.
sourceraw docstring

disabled?clj

(disabled? app element-id)
(disabled? app element-id frame-index)

Check if an element is disabled.

With 2 args: Checks the most recent frame. With 3 args: Checks the nth frame (0 = most recent).

Example:

(is (disabled? app "submit-btn"))
Check if an element is disabled.

With 2 args: Checks the most recent frame.
With 3 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (disabled? app "submit-btn"))
```
sourceraw docstring

elementclj

(element app element-id)
(element app element-id frame-index)

Find an element by ID in the rendered hiccup.

With 2 args: Searches the most recent frame. With 3 args: Searches the nth frame (0 = most recent).

Returns the hiccup element or nil if not found.

Example:

(element app "submit-btn")
;; => [:button {:id "submit-btn" :onClick #fn} "Submit"]

;; Check element from 2 frames ago
(element app "submit-btn" 2)
Find an element by ID in the rendered hiccup.

With 2 args: Searches the most recent frame.
With 3 args: Searches the nth frame (0 = most recent).

Returns the hiccup element or nil if not found.

Example:
```clojure
(element app "submit-btn")
;; => [:button {:id "submit-btn" :onClick #fn} "Submit"]

;; Check element from 2 frames ago
(element app "submit-btn" 2)
```
sourceraw docstring

elements-by-classclj

(elements-by-class app class-name)
(elements-by-class app class-name frame-index)

Find all elements with a CSS class in the rendered hiccup.

With 2 args: Searches the most recent frame. With 3 args: Searches the nth frame (0 = most recent).

Returns a vector of matching elements.

Example:

(elements-by-class app "error-message")
;; => [[:div {:className "error-message"} "Invalid email"]]
Find all elements with a CSS class in the rendered hiccup.

With 2 args: Searches the most recent frame.
With 3 args: Searches the nth frame (0 = most recent).

Returns a vector of matching elements.

Example:
```clojure
(elements-by-class app "error-message")
;; => [[:div {:className "error-message"} "Invalid email"]]
```
sourceraw docstring

elements-by-tagclj

(elements-by-tag app tag)
(elements-by-tag app tag frame-index)

Find all elements with a specific tag in the rendered hiccup.

With 2 args: Searches the most recent frame. With 3 args: Searches the nth frame (0 = most recent).

Returns a vector of matching elements.

Example:

(elements-by-tag app :button)
;; => [[:button {...} "Save"] [:button {...} "Cancel"]]
Find all elements with a specific tag in the rendered hiccup.

With 2 args: Searches the most recent frame.
With 3 args: Searches the nth frame (0 = most recent).

Returns a vector of matching elements.

Example:
```clojure
(elements-by-tag app :button)
;; => [[:button {...} "Save"] [:button {...} "Cancel"]]
```
sourceraw docstring

exists?clj

(exists? app element-id)
(exists? app element-id frame-index)

Check if an element with the given ID exists in the rendered hiccup.

With 2 args: Checks the most recent frame. With 3 args: Checks the nth frame (0 = most recent).

Example:

(is (exists? app "welcome-message"))
(is (not (exists? app "error-message")))
Check if an element with the given ID exists in the rendered hiccup.

With 2 args: Checks the most recent frame.
With 3 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (exists? app "welcome-message"))
(is (not (exists? app "error-message")))
```
sourceraw docstring

find-by-textclj

(find-by-text app pattern)
(find-by-text app pattern frame-index)

Find all elements whose text content matches the pattern.

With 2 args: Searches the most recent frame. With 3 args: Searches the nth frame (0 = most recent).

Pattern can be:

  • A string (substring match)
  • A regex (pattern match)
  • A vector of patterns (all must match)

Returns a vector of matching hiccup elements.

Example:

(find-by-text app "Submit")
(find-by-text app #"Account.*")
Find all elements whose text content matches the pattern.

With 2 args: Searches the most recent frame.
With 3 args: Searches the nth frame (0 = most recent).

Pattern can be:
- A string (substring match)
- A regex (pattern match)
- A vector of patterns (all must match)

Returns a vector of matching hiccup elements.

Example:
```clojure
(find-by-text app "Submit")
(find-by-text app #"Account.*")
```
sourceraw docstring

frame-atclj

(frame-at app frame-index)

Get a specific render frame by index. frame-index is 0-indexed from most recent (0 = latest).

Get a specific render frame by index.
`frame-index` is 0-indexed from most recent (0 = latest).
sourceraw docstring

frames-sinceclj

(frames-since app timestamp)

Get all frames captured since the given timestamp.

Get all frames captured since the given timestamp.
sourceraw docstring

has-class?clj

(has-class? app element-id class-name)
(has-class? app element-id class-name frame-index)

Check if an element has a specific CSS class.

With 3 args: Checks the most recent frame. With 4 args: Checks the nth frame (0 = most recent).

Example:

(is (has-class? app "submit-btn" "loading"))
(is (not (has-class? app "submit-btn" "disabled")))
Check if an element has a specific CSS class.

With 3 args: Checks the most recent frame.
With 4 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (has-class? app "submit-btn" "loading"))
(is (not (has-class? app "submit-btn" "disabled")))
```
sourceraw docstring

has-pending-work?clj

(has-pending-work? app)

Returns true if there is any pending transaction work.

Returns true if there is any pending transaction work.
sourceraw docstring

hiccup-forclj

(hiccup-for app component-class)
(hiccup-for app component-class ident)

Return the hiccup for the given component based on the app current state. You MUST supply the ident unless the component has a constant ident (or is Root).

Return the hiccup for the given component based on the `app` current state. You MUST supply
the ident unless the component has a constant ident (or is Root).
sourceraw docstring

hiccup-frameclj

(hiccup-frame app)
(hiccup-frame app n-steps-ago)

Get the rendered output as hiccup from a render frame. Convenience function that converts the dom-server Element tree to hiccup.

With 1 arg: Returns hiccup from the most recent frame. With 2 args: Returns hiccup from the nth most recent frame (0 = latest).

Example:

;; Get most recent render as hiccup
(hiccup-frame app)

;; Get the render from 2 frames ago
(hiccup-frame app 2)
Get the rendered output as hiccup from a render frame.
Convenience function that converts the dom-server Element tree to hiccup.

With 1 arg: Returns hiccup from the most recent frame.
With 2 args: Returns hiccup from the nth most recent frame (0 = latest).

Example:
```clojure
;; Get most recent render as hiccup
(hiccup-frame app)

;; Get the render from 2 frames ago
(hiccup-frame app 2)
```
sourceraw docstring

input-valueclj

(input-value app element-id)
(input-value app element-id frame-index)

Get the current value of an input element by ID. Shorthand for (attr-of app id :value).

With 2 args: From the most recent frame. With 3 args: From the nth frame (0 = most recent).

Example:

(is (= "user@example.com" (input-value app "email-input")))
Get the current value of an input element by ID.
Shorthand for (attr-of app id :value).

With 2 args: From the most recent frame.
With 3 args: From the nth frame (0 = most recent).

Example:
```clojure
(is (= "user@example.com" (input-value app "email-input")))
```
sourceraw docstring

invoke-handler!clj

(invoke-handler! app element-id handler-key event)

Invoke an arbitrary handler on an element by ID. Use this for handlers not covered by the convenience functions.

Example:

(invoke-handler! app "my-element" :onMouseEnter {})
(invoke-handler! app "draggable" :onDragStart {:dataTransfer ...})
Invoke an arbitrary handler on an element by ID.
Use this for handlers not covered by the convenience functions.

Example:
```clojure
(invoke-handler! app "my-element" :onMouseEnter {})
(invoke-handler! app "draggable" :onDragStart {:dataTransfer ...})
```
sourceraw docstring

last-frameclj

(last-frame app)

Get the most recent render frame, or nil if none.

Get the most recent render frame, or nil if none.
sourceraw docstring

last-transactionclj

(last-transaction app)

Get the most recently captured transaction, or nil if none.

Convenience for the common case of checking what just happened.

Example:

(click! app "submit-btn")
(is (= 'my-ns/submit (-> (last-transaction app) :fulcro.history/tx first)))
Get the most recently captured transaction, or nil if none.

Convenience for the common case of checking what just happened.

Example:
```clojure
(click! app "submit-btn")
(is (= 'my-ns/submit (-> (last-transaction app) :fulcro.history/tx first)))
```
sourceraw docstring

mount-componentclj

(mount-component ctx factory initial-props)

Mount a component for testing with automatic re-render on state changes. Returns a MountedComponent handle that tracks the current hiccup.

Unlike render-component, this sets up a render callback so that when a state setter (from useState) is called, the component automatically re-renders. This makes tests more natural - you interact with the component and the hiccup updates automatically.

ctx - A rendering context from hooks/make-rendering-context factory - The component factory function (e.g., ui-counter) initial-props - The initial props to pass to the factory

Returns a MountedComponent record. Use current-hiccup to get the latest render.

Example:

(let [ctx (hooks/make-rendering-context)
      mounted (h/mount-component ctx ui-counter {:label "Count:"})]
  ;; Check initial render
  (is (= "0" (hic/element-text (hic/find-by-id (h/current-hiccup mounted) "count"))))

  ;; Click increment - re-renders automatically!
  (hic/click! (hic/find-by-id (h/current-hiccup mounted) "inc"))

  ;; State is updated
  (is (= "1" (hic/element-text (hic/find-by-id (h/current-hiccup mounted) "count")))))
Mount a component for testing with automatic re-render on state changes.
Returns a MountedComponent handle that tracks the current hiccup.

Unlike `render-component`, this sets up a render callback so that when
a state setter (from useState) is called, the component automatically
re-renders. This makes tests more natural - you interact with the component
and the hiccup updates automatically.

`ctx` - A rendering context from `hooks/make-rendering-context`
`factory` - The component factory function (e.g., ui-counter)
`initial-props` - The initial props to pass to the factory

Returns a MountedComponent record. Use `current-hiccup` to get the latest render.

Example:
```clojure
(let [ctx (hooks/make-rendering-context)
      mounted (h/mount-component ctx ui-counter {:label "Count:"})]
  ;; Check initial render
  (is (= "0" (hic/element-text (hic/find-by-id (h/current-hiccup mounted) "count"))))

  ;; Click increment - re-renders automatically!
  (hic/click! (hic/find-by-id (h/current-hiccup mounted) "inc"))

  ;; State is updated
  (is (= "1" (hic/element-text (hic/find-by-id (h/current-hiccup mounted) "count")))))
```
sourceraw docstring

pending-sendsclj

(pending-sends app remote-name)

Get the pending send queue for a remote. Useful for verifying what would be sent to the server.

Get the pending send queue for a remote.
Useful for verifying what would be sent to the server.
sourceraw docstring

render-componentclj

(render-component ctx component-instance)

Render a component instance (result of factory call) with hook support. Works with either a full headless app or a lightweight rendering context.

ctx - Either a headless app from build-test-app or a rendering context from hooks/make-rendering-context component-instance - The result of calling a component factory, e.g., (ui-counter {:count 0})

Returns the dom-server Element tree. Use headless.hiccup/rendered-tree->hiccup to convert to hiccup for assertions.

Example with rendering context (isolated component testing):

(let [ctx (hooks/make-rendering-context)
      result (h/render-component ctx (ui-counter {:count 0}))]
  (is (= [:div ...] (hic/rendered-tree->hiccup result))))

Example with headless app:

(let [app (h/build-test-app {:root-class Root})
      result (h/render-component app (ui-widget {:id 1}))]
  ...)
Render a component instance (result of factory call) with hook support.
Works with either a full headless app or a lightweight rendering context.

`ctx` - Either a headless app from `build-test-app` or a rendering context from
        `hooks/make-rendering-context`
`component-instance` - The result of calling a component factory, e.g., (ui-counter {:count 0})

Returns the dom-server Element tree. Use `headless.hiccup/rendered-tree->hiccup` to convert
to hiccup for assertions.

Example with rendering context (isolated component testing):
```clojure
(let [ctx (hooks/make-rendering-context)
      result (h/render-component ctx (ui-counter {:count 0}))]
  (is (= [:div ...] (hic/rendered-tree->hiccup result))))
```

Example with headless app:
```clojure
(let [app (h/build-test-app {:root-class Root})
      result (h/render-component app (ui-widget {:id 1}))]
  ...)
```
sourceraw docstring

render-component-hiccupclj

(render-component-hiccup ctx component-instance)

Convenience function: render a component instance and return hiccup directly.

ctx - Either a headless app or a rendering context from hooks/make-rendering-context component-instance - The result of calling a component factory

Example:

(let [ctx (hooks/make-rendering-context)
      hiccup (h/render-component-hiccup ctx (ui-counter {:label "Count:"}))]
  (is (= "Count:" (hic/element-text (hic/find-by-id hiccup "label")))))
Convenience function: render a component instance and return hiccup directly.

`ctx` - Either a headless app or a rendering context from `hooks/make-rendering-context`
`component-instance` - The result of calling a component factory

Example:
```clojure
(let [ctx (hooks/make-rendering-context)
      hiccup (h/render-component-hiccup ctx (ui-counter {:label "Count:"}))]
  (is (= "Count:" (hic/element-text (hic/find-by-id hiccup "label")))))
```
sourceraw docstring

render-frame!clj

(render-frame! app)

Force a render and capture the frame in history. Returns the captured frame.

Force a render and capture the frame in history.
Returns the captured frame.
sourceraw docstring

render-historyclj

(render-history app)

Get the render history (newest first). Each entry is a map with:

  • :state - The state map at render time
  • :tree - The denormalized props tree
  • :rendered - The raw dom-server Element tree
  • :timestamp - System time in milliseconds
Get the render history (newest first).
Each entry is a map with:
- :state - The state map at render time
- :tree - The denormalized props tree
- :rendered - The raw dom-server Element tree
- :timestamp - System time in milliseconds
sourceraw docstring

rendered-atclj

(rendered-at app frame-index)

Get the raw dom-server Element tree from a specific render frame. frame-index is 0-indexed from most recent (0 = latest). Use headless.hiccup/rendered-tree->hiccup to convert to hiccup.

Get the raw dom-server Element tree from a specific render frame.
`frame-index` is 0-indexed from most recent (0 = latest).
Use headless.hiccup/rendered-tree->hiccup to convert to hiccup.
sourceraw docstring

reset-app!clj

(reset-app! app)

Reset the app state to initial state from root component. Useful for test isolation.

Reset the app state to initial state from root component.
Useful for test isolation.
sourceraw docstring

set-props!clj

(set-props! mounted new-props)

Set new props on a mounted component and re-render.

Set new props on a mounted component and re-render.
sourceraw docstring

set-remote!clj

(set-remote! app remote-name remote)

Set or replace a remote on the test app. Convenience wrapper around rapp/set-remote!

Set or replace a remote on the test app.
Convenience wrapper around rapp/set-remote!
sourceraw docstring

state-at-renderclj

(state-at-render app frame-index)

Get the state map from a specific render frame. frame-index is 0-indexed from most recent (0 = latest).

Get the state map from a specific render frame.
`frame-index` is 0-indexed from most recent (0 = latest).
sourceraw docstring

text-exists?clj

(text-exists? app pattern)
(text-exists? app pattern frame-index)

Check if any element with the given text content exists in the rendered hiccup.

With 2 args: Checks the most recent frame. With 3 args: Checks the nth frame (0 = most recent).

Example:

(is (text-exists? app "Welcome, John!"))
(is (not (text-exists? app "Error")))
Check if any element with the given text content exists in the rendered hiccup.

With 2 args: Checks the most recent frame.
With 3 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (text-exists? app "Welcome, John!"))
(is (not (text-exists? app "Error")))
```
sourceraw docstring

text-ofclj

(text-of app element-id)
(text-of app element-id frame-index)

Get the text content of an element by ID.

With 2 args: From the most recent frame. With 3 args: From the nth frame (0 = most recent).

Returns the concatenated text content, or nil if element not found.

Example:

(text-of app "welcome-message")
;; => "Hello, John!"

;; Compare text before and after
(let [before (text-of app "counter" 1)
      after  (text-of app "counter" 0)]
  (is (not= before after)))
Get the text content of an element by ID.

With 2 args: From the most recent frame.
With 3 args: From the nth frame (0 = most recent).

Returns the concatenated text content, or nil if element not found.

Example:
```clojure
(text-of app "welcome-message")
;; => "Hello, John!"

;; Compare text before and after
(let [before (text-of app "counter" 1)
      after  (text-of app "counter" 0)]
  (is (not= before after)))
```
sourceraw docstring

transaction-mutationsclj

(transaction-mutations app)

Extract just the mutation symbols from captured transactions.

Example:

(click! app "btn1")
(click! app "btn2")
(is (= ['ns/action1 'ns/action2] (transaction-mutations app)))
Extract just the mutation symbols from captured transactions.

Example:
```clojure
(click! app "btn1")
(click! app "btn2")
(is (= ['ns/action1 'ns/action2] (transaction-mutations app)))
```
sourceraw docstring

tree-at-renderclj

(tree-at-render app frame-index)

Get the denormalized tree from a specific render frame. frame-index is 0-indexed from most recent (0 = latest).

Get the denormalized tree from a specific render frame.
`frame-index` is 0-indexed from most recent (0 = latest).
sourceraw docstring

type-into!clj

(type-into! app element-id new-value)

Type a value into an input element by ID. Invokes the element's :onChange handler with {:target {:value new-value}}.

Example:

(type-into! app "email-input" "user@example.com")
Type a value into an input element by ID.
Invokes the element's :onChange handler with {:target {:value new-value}}.

Example:
```clojure
(type-into! app "email-input" "user@example.com")
```
sourceraw docstring

type-into-labeled!clj

(type-into-labeled! app label-pattern value)
(type-into-labeled! app label-pattern value n)

Type a value into an input field identified by its label. Finds an input element associated with a label matching the pattern, then invokes the input's :onChange handler.

Pattern can be:

  • A string (substring match on label text)
  • A regex (pattern match)
  • A vector of patterns (all must match)

The optional n parameter specifies which matching labeled field to use (0-indexed, default 0).

Example:

(type-into-labeled! app "Username" "john.doe")
(type-into-labeled! app "Password" "secret123")
(type-into-labeled! app #"(?i)email" "user@example.com")
(type-into-labeled! app "Amount" "100.00" 1)  ; second Amount field
Type a value into an input field identified by its label.
Finds an input element associated with a label matching the pattern,
then invokes the input's :onChange handler.

Pattern can be:
- A string (substring match on label text)
- A regex (pattern match)
- A vector of patterns (all must match)

The optional `n` parameter specifies which matching labeled field to use
(0-indexed, default 0).

Example:
```clojure
(type-into-labeled! app "Username" "john.doe")
(type-into-labeled! app "Password" "secret123")
(type-into-labeled! app #"(?i)email" "user@example.com")
(type-into-labeled! app "Amount" "100.00" 1)  ; second Amount field
```
sourceraw docstring

unmount-component!clj

(unmount-component! mounted)

Unmount a component, running any cleanup effects. Clears the render callback and hook state.

Unmount a component, running any cleanup effects.
Clears the render callback and hook state.
sourceraw docstring

update-props!clj

(update-props! mounted props-fn)

Update the props of a mounted component and re-render. The props-fn receives the current props and should return the new props.

Update the props of a mounted component and re-render.
The props-fn receives the current props and should return the new props.
sourceraw docstring

visible?clj

(visible? app element-id)
(visible? app element-id frame-index)

Check if an element exists and is not hidden via inline style. Note: This only checks inline display: none or visibility: hidden. CSS classes that hide elements are not detected.

With 2 args: Checks the most recent frame. With 3 args: Checks the nth frame (0 = most recent).

Example:

(is (visible? app "modal"))
Check if an element exists and is not hidden via inline style.
Note: This only checks inline `display: none` or `visibility: hidden`.
CSS classes that hide elements are not detected.

With 2 args: Checks the most recent frame.
With 3 args: Checks the nth frame (0 = most recent).

Example:
```clojure
(is (visible? app "modal"))
```
sourceraw docstring

wait-for-idle!clj

(wait-for-idle! app)

Block until all pending work is complete. With synchronous tx processing, this is usually instant, but useful after operations that might queue follow-on work.

Block until all pending work is complete.
With synchronous tx processing, this is usually instant,
but useful after operations that might queue follow-on work.
sourceraw docstring

with-render-trackingclj

(with-render-tracking app body-fn)

Execute body and return a map with:

  • :result - The return value of body
  • :frames - All frames captured during execution
  • :frame-count - Number of frames captured

Example:

(let [{:keys [result frames]} (with-render-tracking app
                                (comp/transact! app [(my-mutation)]))]
  (is (= 1 (count frames))))
Execute body and return a map with:
- :result - The return value of body
- :frames - All frames captured during execution
- :frame-count - Number of frames captured

Example:
```clojure
(let [{:keys [result frames]} (with-render-tracking app
                                (comp/transact! app [(my-mutation)]))]
  (is (= 1 (count frames))))
```
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close