Smoke Test Examples
(ns page-helpers | |
"All of the following page helpers take a \"page\", which is a map with | |
key names for named elements tied to their CSS selectors. | |
Page is expected to always have keys: | |
- :page-name (string) | |
- :page-id (css selector string) | |
- :page-url (regex to match url) | |
Using this as the first argument allows us to use the while-on and | |
within-modal macros to fill in the page in repeated series of steps (they both | |
just use clojure `doto`)" | |
(:require | |
[clojure.java.io :as io] | |
[taoensso.timbre :as timbre] | |
[clojure.test :refer :all] | |
[clj-webdriver.taxi :as taxi])) | |
(let [c (atom 0)] | |
(defn counter [] | |
(swap! c inc))) | |
(def root-path | |
(str (.getCanonicalPath (clojure.java.io/file ".")) "/screen_shots/smoke_test/")) | |
(io/make-parents (str root-path "touch")) | |
(defn sc-name [modifier] | |
(str root-path "s" (format "%04d" (counter)) modifier ".png")) | |
(defn capture | |
"Takes a screenshot with an incrementing counter of the given page. If | |
modifier argument is provided, it will be appended to the filename (so you can | |
find specific screenshots easier)" | |
([page] | |
(capture page "")) | |
([page modifier] | |
(taxi/take-screenshot :file (sc-name modifier)))) | |
(defn wait-for | |
"Given a page, waits for a named element on that page to exist in the browser | |
using taxi/wait-until. If only a page is provided, the :page-id element will | |
be the one waited for. If the element does not appear, throws an exception | |
after dumping current html and taking a screenshot with -timeout-on-element in | |
the name" | |
([page] | |
(wait-for page :page-id)) | |
([page element] | |
(let [selector (page element)] | |
(try | |
(taxi/wait-until #(taxi/exists? selector)) | |
(catch Exception e | |
(capture page (str "-timeout-on-" element "-" (:page-name page))) | |
(timbre/info (taxi/html "html")) | |
(throw (ex-info (str "Timed out waiting for element: " element | |
" (on " (:page-name page) | |
"), selector was: " selector) | |
{:page-name (:page-name page) | |
:element element | |
:selector selector}))))))) | |
(defn input | |
"Given a page, a named input element on the page, and a value, waits for the | |
input element to be available and inputs the text value in the element. Note | |
that currently this does not clear any previous text in the element if set" | |
[page element value] | |
(wait-for page element) | |
(taxi/input-text (page element) value)) | |
(defn click | |
"Given a page and a named clickable element on the page, waits for the | |
clickable element to be available and then clicks on it." | |
[page element] | |
(wait-for page element) | |
(capture page (str "-before-click-" element "-" (:page-name page))) | |
(taxi/click (page element)) | |
(capture page (str "-after-click-" element "-" (:page-name page)))) | |
(defn get-text | |
"Given a page and a named element on the page, waits for the | |
element to be available and then gets the text." | |
[page element] | |
(wait-for page element) | |
(taxi/text (page element))) | |
(defn is-on? | |
"Returns true if the current url from taxi matches the regex :page-url | |
property on the given page." | |
[page] | |
(boolean (re-matches (page :page-url) | |
(taxi/current-url)))) | |
(defn assert-text | |
"Makes a clojure.test assertion that the named element for a given page | |
matches the expected text" | |
[page element match] | |
(wait-for page element) | |
(let [text (taxi/text (page element))] | |
(is (= match text) | |
(str "expected text in element: " element | |
"(page: " (:page-name page) | |
") to match " match | |
" was: " text)))) | |
(defn check-existence | |
"Checks that an element exists on the current page. | |
Can also pass in false as third argument to | |
check the element does not exist." | |
([page element] | |
(check-existence page element true)) | |
([page element val] | |
(let [selector (page element)] | |
(try | |
(taxi/wait-until | |
#(= val (taxi/exists? selector))) | |
(catch Exception e | |
(capture page (str "-timeout-on-" element "-" (:page-name page))) | |
(timbre/info (taxi/html "html")) | |
(throw (ex-info "check-existence" | |
{:page-name (:page-name page) | |
:element element | |
:selector selector}))))))) | |
(defn assert-on-page | |
"Makes a clojure.test assertion that the current page :page-url property | |
matches taxi/current-url value" | |
[page] | |
(wait-for page) | |
(capture page (str "-assert-page-url-" (:page-name page))) | |
(try | |
(taxi/wait-until #(boolean (re-matches (page :page-url) (taxi/current-url)))) | |
(catch Exception e | |
(throw (ex-info (str "expected current-url to match: " (page :page-url) | |
" (see :page-url for page " (:page-name page) ")") | |
{:page-name (:page-name page)}))))) | |
(defmacro while-on | |
"Takes a page and a list of actions for that page, asserts that the page is | |
currently visible (via :page-id selector) then puts the page as the first | |
argument for the provided actions and runs them." | |
[page & actions] | |
`(doto ~page | |
(assert-on-page) | |
~@actions)) | |
(defmacro within-modal | |
"Like while-on, for use of a modal inside an existing while-on block." | |
[page modal & actions] | |
`(doto ~modal | |
(if (~modal :page-url) (assert-on-page)) | |
~@actions)) |
(def url "http://localhost:8000/") | |
(def dashboard-list | |
{:page-url #".*/(dashboards)?" | |
:page-name "dashboard-list" | |
:page-id "[data-test='all-dashes']" | |
:title-input "[data-test='new-dashboard-title']" | |
:save-button "[data-test='new-dashboard-save-button']" | |
:new-dashboard-button "[data-test='new-dashboard-modal-open']"}) | |
(defn create-dashboard [name] | |
(taxi/to url) ; make sure we start on homepage with new-dashboard-button | |
(while-on pages/dashboard-list | |
(click :new-dashboard-button) | |
(input :title-input name) | |
(click :save-button))) | |
(specification "Dashboard Flow" | |
(behavior "Able to create" | |
(let [prev-count (get-nav-count :dashboard-count) | |
new-dash-title "Campaign Summary"] | |
(capture pages/dashboard-list) | |
(create-dashboard new-dash-title) | |
(taxi/wait-until #(< prev-count | |
(get-nav-count :dashboard-count))) | |
(while-on pages/dashboard | |
(assert-text :title new-dash-title))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment