From a87d349bd6ad3dd956e0c2a10cfe84c0f4c6ecdc Mon Sep 17 00:00:00 2001 From: Matthew Jaoudi Date: Tue, 20 Feb 2018 14:00:25 -0800 Subject: [PATCH] add basic integration test; --- .gitignore | 4 + dev-resources/public/integration.html | 12 +++ project.clj | 20 +++- src/integration/rid3/integration.cljs | 98 +++++++++++++++++ test/rid3/integration_test.clj | 147 ++++++++++++++++++++++++++ 5 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 dev-resources/public/integration.html create mode 100644 src/integration/rid3/integration.cljs create mode 100644 test/rid3/integration_test.clj diff --git a/.gitignore b/.gitignore index 8961a4c..d59396b 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,13 @@ /dev-resources/public/js/*dev /dev-resources/public/js/examples-dev.js /dev-resources/public/js/basics-dev.js +/dev-resources/public/js/integration.js +/screenshots/* out *.*~ +.lein-failures + pom.xml pom.xml.asc diff --git a/dev-resources/public/integration.html b/dev-resources/public/integration.html new file mode 100644 index 0000000..a5debcf --- /dev/null +++ b/dev-resources/public/integration.html @@ -0,0 +1,12 @@ + + + + + + + +
+ + + + diff --git a/project.clj b/project.clj index 0a9c7a2..f864a94 100644 --- a/project.clj +++ b/project.clj @@ -17,7 +17,8 @@ {:dev {:dependencies [[binaryage/devtools "0.8.2"] [re-frisk "0.3.1"] - [garden "1.3.2"]] + [garden "1.3.2"] + [etaoin "0.2.7"]] :plugins [[lein-figwheel "0.5.10"] [lein-externs "0.1.6"]]}} @@ -79,4 +80,21 @@ :elide-asserts true :closure-defines {goog.DEBUG false} :pretty-print false}} + + ;; integration + {:id "integration-dev" + :source-paths ["src/integration" "src/main" "src/version"] + :figwheel {:on-jsload "rid3.integration/reload"} + :compiler {:main rid3.integration + :optimizations :none + :output-to "dev-resources/public/js/integration.js" + :output-dir "dev-resources/public/js/integration-dev" + :asset-path "js/integration-dev" + :source-map-timestamp true + :preloads [devtools.preload] + :external-config + {:devtools/config + {:features-to-install [:formatters :hints] + :fn-symbol "F" + :print-config-overrides true}}}} ]}) diff --git a/src/integration/rid3/integration.cljs b/src/integration/rid3/integration.cljs new file mode 100644 index 0000000..ff68f85 --- /dev/null +++ b/src/integration/rid3/integration.cljs @@ -0,0 +1,98 @@ +(ns rid3.integration + (:require + [cljs.spec :as spec] + [reagent.core :as reagent] + [re-frisk.core :as rf] + [rid3.core :as rid3])) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Vars + +(defonce app-state (reagent/atom {})) + + +(def height 100) +(def width 100) + +(def margin {:top 16 + :right 16 + :bottom 16 + :left 16}) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Page + +(defn page [app-state] + [:div + [rid3/viz + {:id "test1" + :ratom app-state + :svg {:did-mount (fn [node _] + (-> node + (.attr "height" (+ height + (:top margin) + (:bottom margin))) + (.attr "width" (+ width + (:left margin) + (:right margin)))))} + :main-container {:did-mount (fn [node _] + (-> node + (.attr "transform" + (str "translate(" + (:left margin) + "," + (:top margin) + ")"))))} + :pieces [{:kind :elem + :tag "rect" + :class "my-elem" + :did-mount (fn [node _] + (-> node + (.attr "width" width) + (.attr "height" height) + (.attr "fill" "grey")))} + + {:kind :elem-with-data + :tag "rect" + :class "my-elem-with-data" + :prepare-dataset (fn [ratom] + (clj->js ["A" "B" "C"])) + :did-mount (fn [node _] + (let [x-scale (-> js/d3 + .scaleBand + (.rangeRound #js [0 width]) + (.domain (clj->js ["A" "B" "C"])))] + (-> node + (.attr "x" (fn [d] + (+ (x-scale d) + (/ (.bandwidth x-scale) 4)))) + (.attr "width" (/ (.bandwidth x-scale) + 2)) + (.attr "y" 0) + (.attr "height" (fn [d i] + (/ height (inc i)))) + (.attr "fill" "green"))))}] + }]]) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Initialize App + +(defn dev-setup [] + (when ^boolean js/goog.DEBUG + (enable-console-print!) + (println "dev mode") + (rf/enable-frisk!) + (rf/add-data :app-state app-state) + (spec/check-asserts true))) + +(defn reload [] + (reagent/render [page app-state] + (.getElementById js/document "app"))) + +(defn ^:export main [] + (dev-setup) + (reload)) diff --git a/test/rid3/integration_test.clj b/test/rid3/integration_test.clj new file mode 100644 index 0000000..c7d9251 --- /dev/null +++ b/test/rid3/integration_test.clj @@ -0,0 +1,147 @@ +(ns rid3.integration-test + (:require + [clojure.string :as string] + [clojure.test :refer :all] + [etaoin.api :refer :all])) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Setup + +(def ^:dynamic + *driver*) + +(defn fixture-driver + "Executes a test running a driver. Bounds a driver + with the global *driver* variable." + [f] + (with-chrome {:headless true} driver + (binding [*driver* driver] + (f)))) + + +(use-fixtures + :each ;; start and stop driver for each test + fixture-driver) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Vars + +(def url "http://localhost:3449/integration.html") + +(def screenshot-success-path "screenshots/success") +(def screenshot-failure-path "screenshots/failure") + +(def desktop-env + {:label "desktop" + :width 1920 + :height 1080}) + +(def mobile-env + {:label "mobile" + :width 337 + :height 667}) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Util + +(defn ->screenshot [driver env name] + (screenshot driver + (str screenshot-success-path + "/" + (get env :label) + "_" + name + ".png"))) + + +(defn px [int] + (when int + (str int "px"))) + + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Test + +(defn ->test1 [env] + (testing "basic skeleton of a rid3 component" + (with-postmortem *driver* {:dir screenshot-failure-path} + (doto *driver* + (set-window-size (get env :width) + (get env :height)) + (go url) + (wait-visible {:id "test1"}) + (->screenshot env "test1")) + + ;; NOTE: + ;; a rid3 component has the following structure: + + ;; div#id + ;; svg + ;; g.rid3-main-container + ;; [] + + + ;; div#id + (testing "should have div with id" + (is (exists? *driver* {:css "div#test1"}))) + + ;; svg + (testing "should have svg as child of div with id" + (is (exists? *driver* {:css "#test1 svg"}))) + + (testing "svg should have set dimensions" + (is (= {:width 132 + :height 132} (get-element-size *driver* {:css "#test1 svg"})))) + + ;; g.rid3-main-container + (testing "there should be a g tag with class rid3-main-container" + (is (exists? *driver* {:css "#test1 svg g.rid3-main-container"}))) + + (testing "a rect piece should be inside the main-container" + (is (exists? *driver* {:css (string/join " " + ["#test1" + "svg" + "g.rid3-main-container" + "g.my-elem" + "rect"])}))) + + ;; [] + + ;; :elem + (testing "a rect (:elem piece) should have set dimensions" + (is (= {:width 100 + :height 100} (get-element-size *driver* + {:css (string/join " " + ["#test1" + "svg" + "g.rid3-main-container" + "g.my-elem" + "rect"])})))) + + ;; elem-with-data + (testing ":elem-with-data piece should create multiple rects inside its parent g" + (let [rects (query-all *driver* + {:css (string/join " " + ["#test1" + "svg" + "g.rid3-main-container" + "g.my-elem-with-data" + "rect"])})] + (is (= 3 (count rects))) + (doseq [rect rects] + (is (= "rect" + (get-element-tag-el *driver* rect)))))) + + + ))) + + +(deftest ^:integration + desktop-1920x1080 + (->test1 desktop-env))