Testing Applications
Weave provides a dedicated browser testing component that simplifies end-to-end testing of Weave applications. The component integrates with Etaoin for browser automation and provides convenience functions for common testing operations.
Setup
Adding the Test Component
Add the browser testing component to your project's deps.edn
:
{:aliases
{:test {:extra-deps {weave/test {:git/url "https://github.com/nakkaya/weave/"
:deps/root "components/test"}
}}}}
Prerequisites
Install ChromeDriver for browser automation:
# On macOS with Homebrew
brew install chromedriver
# On Ubuntu/Debian
sudo apt-get install chromium-chromedriver
# On other systems, download from:
# https://chromedriver.chromium.org/
Basic Usage
Import the Testing Functions
(ns my-app.test
(:require [clojure.test :refer [deftest testing is]]
[weave.test.browser :refer [with-browser visible? click]]))
Writing Your First Test
(defn my-test-view []
[:div
[:h1 {:id "title"} "Hello, Weave!"]
[:button {:id "click-me"
:data-on-click (weave/handler []
(weave/push-html!
[:h1 {:id "title"} "Clicked!"]))}
"Click Me"]])
(deftest basic-interaction-test
(with-browser my-test-view {:http-kit {:port 3333}}
(testing "button click updates title"
(visible? :title)
(is (= "Hello, Weave!" (el-text :title)))
(click :click-me)
(is (= "Clicked!" (el-text :title))))))
Testing Functions
Core Functions
with-browser
Macro that sets up a test server and browser driver for testing.
Parameters:
view-fn
- Function that returns your Hiccup viewserver-options
- Map of Weave server options (same asweave.core/run
)
Features:
- Automatically starts Weave server
- Launches headless Chrome browser
- Navigates to test URL
- Provides
*browser*
binding for test functions - Cleans up server and browser after test
visible?
Waits for an element to be visible and asserts its presence.
click
Clicks an element by ID.
fill
Fills a form field with a value.
el-text
Gets the text content of an element.
Multi-Tab Testing Functions
new-tab
Opens a new browser tab with the same test URL.
tabs
Returns all browser tab handles.
switch-tab
Switches to a specific tab.
(let [[tab1 tab2] (tabs)]
(switch-tab tab2) ; Switch to second tab
;; perform actions in tab2
(switch-tab tab1) ; Switch back to first tab
)
Examples
Testing Form Interactions
(defn contact-form-view []
[:form
[:input {:id "name" :type "text" :placeholder "Name"}]
[:input {:id "email" :type "email" :placeholder "Email"}]
[:button {:id "submit"
:data-on-click (weave/handler []
(let [{:keys [name email]} (:params weave/*request*)]
(weave/push-html! "#result"
[:div {:id "result"}
(str "Hello " name " (" email ")")])))}
"Submit"]])
(deftest form-submission-test
(with-browser contact-form-view {:http-kit {:port 3333}}
(testing "form submission displays result"
(visible? :name)
(fill :name "John Doe")
(fill :email "john@example.com")
(click :submit)
(visible? :result)
(is (= "Hello John Doe (john@example.com)" (el-text :result))))))