Skip to content

Commit

Permalink
Merge pull request clj-commons#438 from lread/lread-bb-http-client-lite2
Browse files Browse the repository at this point in the history
road to bb: http client lite & bb tests
  • Loading branch information
lread authored May 24, 2022
2 parents 28de96f + 5f06572 commit a89c9a3
Show file tree
Hide file tree
Showing 11 changed files with 153 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{:config-paths ^:replace [] ;; don't adopt any user preferences

:cljc {:features [:clj]}
:hooks
;; for now we'll use the simple macroexpand, can move to hooks for finer grained errors later
{:macroexpand
Expand Down
5 changes: 0 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
;; TODO: lread move to bb tasks

.PHONY: kill
kill:
pkill chromedriver || true
Expand All @@ -9,7 +7,6 @@ kill:

IMAGE := etaoin

;; TODO: lread: have never tried, test, fix if necessary
.PHONY: docker-build
docker-build:
docker build --no-cache -t ${IMAGE}:latest .
Expand All @@ -20,7 +17,6 @@ check-host:
$(error The HOST variable is not set, please do `export HOST=$$HOST` first)
endif

;; TODO: lread: have never tried, test, fix if necessary
# works only on mac + quartz
.PHONY: docker-test-display
docker-test-display: check-host
Expand All @@ -32,7 +28,6 @@ docker-test-display: check-host
bb test all || \
xhost -

;; TODO: lread: have never tried, test, fix if necessary
.PHONY: docker-test
docker-test:
docker run --rm \
Expand Down
16 changes: 13 additions & 3 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.9.0"} ;; min clojure version
babashka/fs {:mvn/version "0.1.6"}
clj-http/clj-http {:mvn/version "3.10.1"}
clj-http/clj-http {:mvn/version "3.10.1"} ;; for jvm use
org.clj-commons/clj-http-lite {:mvn/version "0.4.392"} ;; for babashka use
cheshire/cheshire {:mvn/version "5.9.0"}
org.clojure/tools.cli {:mvn/version "1.0.194"}
org.clojure/tools.logging {:mvn/version "0.3.1"}}
Expand All @@ -10,5 +11,14 @@
:debug {:extra-paths ["env/dev/resources"]}
:test {:extra-paths ["test" "env/test/resources"]
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}
ch.qos.logback/logback-classic {:mvn/version "1.3.0-alpha16"}}
:main-opts ["-m" "cognitect.test-runner"]}}}
ch.qos.logback/logback-classic {:mvn/version "1.3.0-alpha16"}
;; for http-client which uses apache http client 4.x which uses commons logging
org.slf4j/jcl-over-slf4j {:mvn/version "2.0.0-alpha7"}}
:main-opts ["-m" "cognitect.test-runner"]}
:script {:extra-paths ["script"]}
;; for babashka testing, needed for eatoin.ide
:bb-spec {:extra-deps {org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "644a7fc216e43d5da87b07471b0f87d874107d1a"}}}
;; for babashka testing, allows us to use cognitect test-runner
:bb-test {:extra-deps {org.clojure/tools.namespace {:git/url "https://github.com/babashka/tools.namespace"
:git/sha "a13b037215e21a2e71aa34b27e1dd52c801a2a7b"}}}}}
6 changes: 6 additions & 0 deletions doc/cljdoc.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{:cljdoc.doc/tree
[["Readme" {:file "README.adoc"}]
["Changelog" {:file "CHANGELOG.adoc"}]
["User Guide" {:file "doc/01-user-guide.adoc"}]
["Developer Guide" {:file "doc/02-developer-guide.adoc"}]]
:cljdoc/languages ["clj"]}
5 changes: 5 additions & 0 deletions env/dev/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
</encoder>
</appender>

<!-- uncomment org.apache.http for more details when using clj-http -->
<!--logger name="org.apache.http" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger -->

<logger name="etaoin" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
Expand Down
9 changes: 9 additions & 0 deletions script/bb_test_runner.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(ns bb-test-runner
(:require [taoensso.timbre :as timer]
[cognitect.test-runner :as test-runner]))

;; default log level for bb is debug, change it to info
(alter-var-root #'taoensso.timbre/*config* #(assoc % :min-level :info))

(defn -main [& args]
(apply test-runner/-main args))
4 changes: 2 additions & 2 deletions script/helper/shell.clj
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@
(if (= :win (os/get-os))
(let [full-cmd (if (seq args)
;; naive, but fine for our uses for now, adjust as necessary
(str cmd " " (string/join " " args))
(str cmd " " (string/join " " (map #(str "'" % "'") args)))
cmd)]
(tasks/shell opts "powershell" "-command"
;; powershell -command does not automatically propagate exit code,
;; hence the secret exit sauce here
(str full-cmd ";exit $LASTEXITCODE") ))
(str full-cmd ";exit $LASTEXITCODE")))
(apply tasks/shell opts cmd args))))


Expand Down
129 changes: 84 additions & 45 deletions script/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,37 @@
[helper.shell :as shell]
[lread.status-line :as status]))

(defn- test-def [os id browser]
(defn- test-def [os id platform browser]
{:os os
:cmd (->> ["bb test" id
(str "--platform=" platform)
(when browser (str "--browser=" browser))
(when (= "ubuntu" os) "--launch-virtual-display")]
(remove nil?)
(string/join " "))
:desc (->> [id os browser]
:desc (->> [id os browser platform]
(remove nil?)
(string/join " "))})

(defn- github-actions-matrix []
(let [oses ["macos" "ubuntu" "windows"]
ide-browsers ["chrome" "firefox"]
api-browsers ["chrome" "firefox" "edge" "safari"]]
api-browsers ["chrome" "firefox" "edge" "safari"]
platforms ["jvm" "bb"]]
(->> (concat
(for [os oses]
(test-def os "unit" nil))
(for [os oses
platform platforms]
(test-def os "unit" platform nil))
(for [os oses
platform platforms
browser ide-browsers]
(test-def os "ide" browser))
(test-def os "ide" platform browser))
(for [os oses
platform platforms
browser api-browsers
:when (not (or (and (= "ubuntu" os) (some #{browser} ["edge" "safari"]))
(and (= "windows" os) (= "safari" browser))))]
(test-def os "api" browser)))
(test-def os "api" platform browser)))
(sort-by :desc)
(into []))))

Expand All @@ -57,62 +62,96 @@
(Thread/sleep 500)
(recur))))))))

(def args-usage "Valid args:
(api|ide) [--browser=<edge|safari|firefox|chrome>]... [--launch-virtual-display]
(unit|all) [--launch-virtual-display]
(def valid-browsers ["chrome" "firefox" "edge" "safari"])
(def valid-platforms ["jvm" "bb"])

(defn valid-opts [opts]
(format "<%s>" (string/join "|" opts)))

(def args-usage (-> "Valid args:
(api|ide) [--browser=BROWSER]... [--launch-virtual-display] [--platform=PLATFORM]
(unit|all) [--launch-virtual-display] [--platform=PLATFORM]
matrix-for-ci [--format=json]
--help
Commands:
unit Run only unit tests
api Run only api tests, optionally specifying browsers to override defaults
ide Run only ide tests, optionally specifying browsers to override defaults
unit Run unit tests
api Run api tests
ide Run ide tests
all Run all tests using browser defaults
matrix-for-ci Return text matrix for GitHub Actions
Options:
--launch-virtual-display Launch a virtual display for browsers (use on linux only)
--browser=BROWSER {{valid-browsers}} overrides defaults
--platform=PLATFORM {{valid-platforms}} [default: jvm]
--launch-virtual-display Launch a virtual display for browsers
--help Show this help
Notes:
- ide tests default to firefox and chrome only.
- api tests default browsers based on OS on which they are run.
- launching a virtual display is necessary for GitHub Actions but not so for CircleCI")
- launching a virtual display is necessary for GitHub Actions but not for CircleCI"
(string/replace "{{valid-browsers}}" (valid-opts valid-browsers))
(string/replace "{{valid-platforms}}" (valid-opts valid-platforms))))

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(cond
(get opts "matrix-for-ci")
(if (= "json" (get opts "--format"))
(status/line :detail (-> (github-actions-matrix)
(json/generate-string #_{:pretty true})))
(status/line :detail (->> (github-actions-matrix)
(doric/table [:os :cmd :desc]))))
(let [browsers (->> (get opts "--browser") (keep identity))
platform (get opts "--platform")]
(when (or (not-every? (set valid-browsers) browsers)
(and platform (not (some #{platform} valid-platforms))))
(status/die 1 args-usage))
(cond
(get opts "matrix-for-ci")
(if (= "json" (get opts "--format"))
(status/line :detail (-> (github-actions-matrix)
(json/generate-string #_{:pretty true})))
(status/line :detail (->> (github-actions-matrix)
(doric/table [:os :cmd :desc]))))

:else
(let [clojure-args (cond
(get opts "api") "-M:test --namespace etaoin.api-test"
(get opts "ide") "-M:test --namespace etaoin.ide-test"
(get opts "unit") "-M:test --namespace-regex '.*unit.*-test$'"
:else "-M:test")
browsers (->> (get opts "--browser") (keep identity))
env (cond-> {}
(seq browsers)
(assoc (if (get opts "api")
"ETAOIN_TEST_DRIVERS"
"ETAOIN_IDE_TEST_DRIVERS")
(mapv keyword browsers))
:else
(let [env (cond-> {}
(seq browsers)
(assoc (if (get opts "api")
"ETAOIN_TEST_DRIVERS"
"ETAOIN_IDE_TEST_DRIVERS")
(mapv keyword browsers))

(get opts "--launch-virtual-display")
(assoc "DISPLAY" ":99.0"))
shell-opts (if (seq env)
{:extra-env env}
{})]
(when (get opts "--launch-virtual-display")
(status/line :head "Launching virtual display")
(launch-xvfb))
(status/line :head "Running tests")
(shell/clojure shell-opts clojure-args)))))
(get opts "--launch-virtual-display")
(assoc "DISPLAY" ":99.0"))
shell-opts (if (seq env)
{:extra-env env}
{})
test-id (cond
(get opts "api") "api"
(get opts "ide") "ide"
(get opts "unit") "unit"
:else "all")
cp-args (case platform
"jvm" ["-M:test"]
"bb" (let [aliases (cond-> ":script:bb-test:test"
(not= "api" test-id) (str ":bb-spec"))]
["--classpath"
(with-out-str (shell/clojure "-Spath" (str "-A" aliases)))
"--main" "bb-test-runner"]))
test-runner-args (case test-id
"api" ["--namespace" "etaoin.api-test"]
"ide" ["--namespace" "etaoin.ide-test"]
"unit" ["--namespace-regex" ".*unit.*-test$"]
"all" [])
test-cmd-args (concat cp-args test-runner-args)]
(when (get opts "--launch-virtual-display")
(status/line :head "Launching virtual display")
(launch-xvfb))
(status/line :head "Running %s tests on %s%s"
test-id
platform
(if (seq browsers)
(str " against browsers: " (string/join ", " browsers))
""))
(case platform
"jvm" (apply shell/clojure shell-opts test-cmd-args)
"bb" (apply shell/command shell-opts "bb" test-cmd-args)))))))

(main/when-invoked-as-script
(apply -main *command-line-args*))
Expand Down
34 changes: 23 additions & 11 deletions src/etaoin/client.clj → src/etaoin/client.cljc
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
(ns etaoin.client
(:require [clojure.string :as str]
[clojure.tools.logging :as log]
[clj-http.client :as client]
[cheshire.core :refer [parse-string]]
#?(:bb [clj-http.lite.client :as client]
:clj [clj-http.client :as client])
[cheshire.core :as json]
[slingshot.slingshot :refer [throw+]]))

;;
Expand All @@ -24,12 +25,19 @@
(def timeout (read-timeout))

(def default-api-params
{:as :json
:accept :json
:content-type :json
:socket-timeout (* 1000 timeout)
:conn-timeout (* 1000 timeout)
:debug false})
#?(:bb
{:accept :json
:content-type :json
:socket-timeout (* 1000 timeout)
:conn-timeout (* 1000 timeout)
:debug false}
:clj
{:as :json
:accept :json
:content-type :json
:socket-timeout (* 1000 timeout)
:conn-timeout (* 1000 timeout)
:debug false}))

;;
;; helpers
Expand All @@ -52,7 +60,7 @@
(defn- parse-json [body]
(let [body* (str/replace body #"Invalid Command Method -" "")]
(try
(parse-string body* true)
(json/parse-string body* true)
(catch Throwable _ body))))

(defn- error-response [body]
Expand All @@ -74,7 +82,10 @@
{:url url
:method method
:throw-exceptions false})
(= :post method) (assoc :form-params (-> payload (or {}))))
(= :post method)
#?(:bb (assoc :body (.getBytes (json/generate-string (or payload {}))
"UTF-8"))
:clj (assoc :form-params (or payload {}))))

_ (log/debugf "%s %s:%s %6s %s %s"
(name driver-type)
Expand All @@ -85,7 +96,8 @@
(-> payload (or "")))

resp (client/request params)
body (:body resp)
body #?(:bb (-> resp :body parse-json)
:clj (:body resp))
error (delay {:type :etaoin/http-error
:status (:status resp)
:driver driver
Expand Down
7 changes: 5 additions & 2 deletions test/etaoin/api_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
(is (selected? *driver* :vehicle3)))

(deftest test-input
(testing "fill multiple imputs"
(testing "fill multiple inputs"
(doto *driver*
(fill-multi {:simple-input 1
:simple-password 2
Expand Down Expand Up @@ -614,7 +614,10 @@
:bar [true nil "Hello"]})))))

(deftest test-add-script
(let [js-url (-> "js/inject.js" io/resource str)]
(let [js-url (-> "js/inject.js" io/resource
fs/file .toURI .toURL ;; little extra dance here for bb on Windows,
;; otherwise slash after file: is ommitted and therefore invalid
str)]
(testing "adding a script"
(add-script *driver* js-url)
(wait 1)
Expand Down
7 changes: 5 additions & 2 deletions test/etaoin/test_report.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@

(def ^:dynamic *context*)

(def platform
(if (System/getProperty "babashka.version") "bb" "jvm"))

(defmethod clojure.test/report :begin-test-var [m]
(let [test-name (-> m :var meta :name)]
(if (bound? #'*context*)
(println (format "=== %s [%s]" test-name *context*))
(println (format "=== %s" test-name)))))
(println (format "=== %s [%s][%s]" test-name platform *context*))
(println (format "=== %s [%s]" test-name platform)))))

0 comments on commit a89c9a3

Please sign in to comment.