Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
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