$ show clj-commons/etaoin
Etaoin is a pure Clojure library that implements the W3C WebDriver protocol for automating major browsers (Chrome, Firefox, Safari, Edge). It provides a comprehensive, idiomatic Clojure API for browser controlβnavigation, element interaction, JavaScript execution, screenshots, shadow DOM, and moreβwithout requiring Selenium or Java interop. The library also includes a Selenium IDE (.side) file executor, Chrome DevTools performance log parsing, and a rich macro DSL for resource management (with-driver, with-wait, with-postmortem). Internally, it uses multimethod dispatch to handle browser-specific quirks, a generic polling mechanism for waits, and a composable action builder for complex input sequences. The codebase is well-structured, extensively tested across multiple browsers and runtimes (JVM Clojure and Babashka), and provides clj-kondo hooks for linting its macros. It is primarily a library for integration into other projects (UI testing, web scraping, automation), but also offers a CLI entry point for running IDE scripts.
The LLM identified 3 files worth highlighting for reuse:
Contains `wait-predicate`, a generic polling function that repeatedly evaluates a predicate until it returns truthy or a deadline expires. Uses deadline-based timing (not interval counting) so slow predicate evaluations don't extend the total timeout. Configurable interval and timeout. This is a clean, reusable pattern for any polling scenario (e.g., waiting for async operations, file system changes, network responses) and can be extracted with minimal modification.
Implements a Clojure map-to-XPath DSL. Users write queries like `{:tag :a :fn/text "Press Me"}` and get `.//a[text()="Press Me"]`. Supports attributes, text, position, CSS-like combinators, and logical operators. The conversion is purely functional and stateless, making it easy to extract and reuse in any project that needs to generate XPath expressions programmatically.
Overrides `clojure.test/testing` macro via `alter-var-root` to inject platform/context information (e.g., browser, driver type) into test output. This is a non-obvious pattern for enhancing test reports without modifying test code. The approach is reusable for any project that wants to add custom metadata to test results, though it requires careful handling of macro internals.