From a1e1567b7def4af7e26d867241c0b85ed7730e7d Mon Sep 17 00:00:00 2001 From: lread Date: Tue, 24 May 2022 18:48:22 -0400 Subject: [PATCH] road to bb: docs added to user guide [skip ci] Reviewed and updated start of user guide and ensured first getting started examples still run today. Will do more verification of rest of doc (it is big!) bit by bit in the future. Closes #380 --- doc/01-user-guide.adoc | 181 +++++++++++++++++++++++++++-------------- 1 file changed, 119 insertions(+), 62 deletions(-) diff --git a/doc/01-user-guide.adoc b/doc/01-user-guide.adoc index 905193dc..fda18698 100644 --- a/doc/01-user-guide.adoc +++ b/doc/01-user-guide.adoc @@ -5,9 +5,26 @@ :lib-version: 0.4.6 :url-tests: https://github.com/{project-src-coords}/blob/master/test/etaoin/api_test.clj -== Supported OSes & Browsers +== Introduction -The Etaoin unit tests cover: +Etaoin offers the Clojure community a simple way to script web browser interactions from Clojure and Babashka. + +=== History + +Ivan Grishaev (https://github.com/igrishaev[@igrishaev]) created Etaoin and published its first release to Clojars in Feb of 2017. +He and his band of faithful contributors grew Etaoin into a well respected goto library for browser automation. + +In May of 2022, finding his time had gravitated more to back-end development, Ivan offered Etaoin for adoption to clj-commons where it is now currently under the loving care of https://github.com/lread[@lread] and https://github.com/borkdude[@borkdude]. + +=== Interesting Alternatives + +If Etaoin is not your cup of tea, you might also consider: + +* https://github.com/tatut/clj-chrome-devtools[clj-chrome-devtools] + +=== Supported OSes & Browsers + +Etaoin's test suite covers the following OSes and browsers run with both regular Clojure and Babashka: |=== | OS | Chrome | Firefox | Safari | Edge @@ -38,11 +55,15 @@ NOTE: At one point we did also test against PhantomJS, but since work has long a There are two steps to installation: -. Install the library `etaoin` into your clojure code -. Install the drivers for each browser +. Add the `etaoin` library as a dependency to your project +. Install the webdriver for each web browser you'd like control with Etaoin === Installing the etaoin library +==== For Clojure Users + +Etaoin supports Clojure v1.9 and above. + Add the following into `:dependencies` vector in your `project.clj` file: [source,clojure,subs="attributes+"] @@ -50,12 +71,33 @@ Add the following into `:dependencies` vector in your `project.clj` file: [etaoin "{lib-version}"] ---- -Or the following to your `:deps` in your `deps.edn` file: +Or the following under `:deps` in your `deps.edn` file: +[source,clojure,subs="attributes+"] +---- + etaoin/etaoin {:mvn/version "{lib-version}"} +---- + +==== For Bababashka Users + +We recommend the current release of https://book.babashka.org/#_installation[babashka]. + +Add the following under `:deps` to your `bb.edn` file: + [source,clojure,subs="attributes+"] ---- etaoin/etaoin {:mvn/version "{lib-version}"} ---- +The Etaoin feature to <> employs clojure spec. If you are using this feature, you'll need to also enable clojure spec support in Babashka by adding `babashka/spec.alpha` to your `bb.edn` `:deps`: + +[source,clojure] +---- + org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha" + :sha "644a7fc216e43d5da87b07471b0f87d874107d1a"}}} +---- + +See https://github.com/babashka/spec.alpha[babashka/spec.alpha] for current docs. + :url-webdriver: https://www.w3.org/TR/webdriver/ :url-tests: https://github.com/{project-src-coords}/blob/master/test/etaoin/api_test.clj :url-chromedriver: https://sites.google.com/a/chromium.org/chromedriver/ @@ -65,20 +107,26 @@ Or the following to your `:deps` in your `deps.edn` file: :url-webkit: https://webkit.org/blog/6900/webdriver-support-in-safari-10/ :url-edge-dl: https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ -Works with Clojure 1.9 and above. +=== Installing the Browser WebDrivers -=== Installing the Browser Drivers +Etaoin controls web browsers via their WebDrivers. +Each browser has its own WebDriver implementation which must be installed. -This page provides instructions on how to install drivers you need to automate your browser. +[TIP] +==== +If it is not already installed, download the web browser you'd like to control (Chrome, Firefox, Edge) as per normal, which is usually by downloading it from its official site. +Safari comes bundled with macOS. +==== -Install Chrome, Firefox and Edge browsers by downloading them from their official sites. -There won't be a problem on all the platforms. +[TIP] +==== +WebDrivers and browsers are updated regularly to fix bugs. +Use current versions. +==== -Some ways to install the webdrivers you might need: +Some ways to install WebDrivers: * Google link:{url-chromedriver}[Chrome Driver] + -Ensure you install at least v2.28. -v2.27 and below has a bug related to maximizing a window (see <>) ** macOS: `brew install chromedriver` ** Windows: `scoop install chromedriver` ** Download: link:{url-chromedriver-dl}[Official Chromedriver download] @@ -115,91 +163,99 @@ msedgedriver phantomjs --wd ---- -You may run tests for this library by launching: +If you like, you can run Etaoin's test suite to verify your installation. +From a clone of the https://github.com/clj-commons/etaoin[Etaoin GitHub repo]: [source,bash] ---- bb test all ---- +For a smaller sanity test, you might want to run api tests against browsers you are particularly intested in. Example: + +[source,bash] +---- +bb test api --browser chrome +---- + You'll see browser windows open and close in series. -The tests use a local HTML file with a special layout to validate most of the cases. +The tests use a local HTML file with a special layout to validate most interactions. See below for <> if you have problems == Getting started -The good news you may automate your browser directly from the REPL: +The good news is that you can automate your browser directly from your Babashka or Clojure REPL: [source,clojure] ---- -(use 'etaoin.api) -(require '[etaoin.keys :as k]) +(require '[etaoin.api :as api] + '[etaoin.keys :as k]) -(def driver (firefox)) ;; here, a Firefox window should appear +;; Start WebDriver for Firefox +(def driver (api/firefox)) ;; a Firefox window should appear ;; let's perform a quick Wiki session -(go driver "https://en.wikipedia.org/") -(wait-visible driver [{:id :simpleSearch} {:tag :input :name :search}]) -;; search for something -(fill driver {:tag :input :name :search} "Clojure programming language") -(fill driver {:tag :input :name :search} k/enter) -(wait-visible driver {:class :mw-search-results}) +;; navigate to wikipedia +(api/go driver "https://en.wikipedia.org/") +;; wait for the search input to load +(api/wait-visible driver [{:id :simpleSearch} {:tag :input :name :search}]) -;; select an `option` in select-box by visible text -;; -(select driver :country "France") -(get-element-value driver :country) -;;=> "fr" +;; search for something interesting +(api/fill driver {:tag :input :name :search} "Clojure programming language") +(api/fill driver {:tag :input :name :search} k/enter) +(api/wait-visible driver {:class :mw-search-results}) -;; I'm sure the first link is what I was looking for -(click driver [{:class :mw-search-results} {:class :mw-search-result-heading} {:tag :a}]) -(wait-visible driver {:id :firstHeading}) +;; click on first match +(api/click driver [{:class :mw-search-results} {:class :mw-search-result-heading} {:tag :a}]) +(api/wait-visible driver {:id :firstHeading}) -;; let's ensure -(get-url driver) ;; "https://en.wikipedia.org/wiki/Clojure" +;; check our new url location +(api/get-url driver) +;; => "https://en.wikipedia.org/wiki/Clojure" -(get-title driver) ;; "Clojure - Wikipedia" +;; and our new title +(api/get-title driver) +;; => "Clojure - Wikipedia" -(has-text? driver "Clojure") ;; true +;; does page have Clojure in it? +(api/has-text? driver "Clojure") +;; => true -;; navigate on history -(back driver) -(forward driver) -(refresh driver) -(get-title driver) ;; "Clojure - Wikipedia" +;; navigate through history +(api/back driver) +(api/forward driver) +(api/refresh driver) +(api/get-title driver) +;; => "Clojure - Wikipedia" -;; stops Firefox and HTTP server -(quit driver) +;; stops Firefox WebDriver +(api/quit driver) ;; the Firefox Window should close ---- -You see, any function requires a driver instance as the first argument. -So you may simplify it using `doto` macros: +Most api functions require the driver as the first argument. +The `doto` macro can give your code a DSL feel. +A portion of the above rewritten with `doto`: [source,clojure] ---- +(use '[etaoin.api :refer :all]) +(require '[etaoin.keys :as k]) + (def driver (firefox)) + (doto driver (go "https://en.wikipedia.org/") (wait-visible [{:id :simpleSearch} {:tag :input :name :search}]) - ;; ... + (fill {:tag :input :name :search} "Clojure programming language") (fill {:tag :input :name :search} k/enter) (wait-visible {:class :mw-search-results}) - (click :some-button) - ;; ... + (click [{:class :mw-search-results} {:class :mw-search-result-heading} {:tag :a}]) (wait-visible {:id :firstHeading}) - ;; ... (quit)) ---- -In that case, your code looks like a DSL designed just for such purposes. - You can use `fill-multi` to shorten the code like: [source,clojure] @@ -218,8 +274,8 @@ into :textarea "some text"}) ---- -If any exception occurs during a browser session, the external process might hang forever until you kill it manually. -To prevent it, use `with-` macros as follows: +If any exception occurs during a browser session, the WebDrier process might hang forever until you kill it manually. +To prevent that, use `with-` macros as follows: [source,clojure] ---- @@ -229,9 +285,9 @@ To prevent it, use `with-` macros as follows: ...)) ---- -Whatever happens during a session, the process will be stopped anyway. +This will ensure that the WebDriver process is closed regardless of what happens. -== Unit Tests +== Unit Tests as Docs The sections that follow describe, how to use Etaoin. @@ -1892,7 +1948,8 @@ Example: (is found (format "No *.xlsx file found in %s directory." DL-DIR))) ---- -== Running IDE files (new!) +[[selenium-ide]] +== Running Selenium IDE files Etaoin can play the files produced by link:{ide}[Selenium IDE]. It's an official utility to create scenarios interactively.