Skip to content

Commit 81e241d

Browse files
authored
Add wait-url-change macro to make tests more reliable (#675)
* Add wait-url-change macro to make tests more reliable This macro uses wait-predicate to poll the WebDriver for a change in the URL, thus eliminating some race conditions that were causing flaky test failures. * Update wait-url-change to wait for URL to match a regex In addition to waiting for the URL to change, wait-url-change also waits for the new URL to match a regex (with re-find).
1 parent 5beefe3 commit 81e241d

File tree

2 files changed

+94
-109
lines changed

2 files changed

+94
-109
lines changed

CHANGELOG.adoc

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ A release with an intentional breaking changes is marked with:
3838
** {issue}656[#656]: Correctly describe behavior when query's parameter is a string. The User Guide and `query` doc strings say that a string passed to `query` is interpreted as an XPath expression. In fact, `query` interprets this as either XPath or CSS depending on the setting of the driver's `:locator` parameter, which can be changed. ({person}dgr[@dgr])
3939
* Quality
4040
** {issue}640[#640]: Significantly improved test coverage. ({person}dgr[@dgr])
41+
** {issue}646[#646]: Fixed race condition leading to unreliable test. ({person}dgr[@dgr])
42+
** {issue}674[#674]: Fixed race condition leading to unreliable test. ({person}dgr[@dgr])
4143

4244
== v1.1.41 [minor breaking] - 2024-08-14 [[v1.1.41]]
4345

test/etaoin/api_test.clj

+92-109
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,22 @@
129129
report-browsers
130130
test-server)
131131

132+
(defn reload-test-page
133+
[]
134+
(e/go *driver* (test-server-url "test.html"))
135+
(e/wait-visible *driver* {:id :document-end}))
136+
137+
(defmacro wait-url-change
138+
[re & body]
139+
`(let [old-url# (e/get-url *driver*)]
140+
~@body
141+
(e/wait-predicate (fn [] (let [new-url# (e/get-url *driver*)]
142+
(and (not= old-url# new-url#)
143+
(re-find ~re new-url#))))
144+
{:timeout 30 ; 30 second timeout total
145+
:interval 0.100 ; poll at 100 msec interval
146+
:message "Timeout waiting for URL change"})))
147+
132148
(deftest test-browser-conditionals
133149
(testing "Chrome conditionals"
134150
(e/when-chrome *driver*
@@ -187,42 +203,28 @@
187203
(is (e/selected? *driver* :vehicle3)))
188204

189205
(deftest test-submit
190-
(doto *driver*
191-
(e/fill-multi {:simple-input 1
192-
:simple-password 2
193-
:simple-textarea 3})
194-
(e/submit :simple-input)
195-
;; Both Safari and Firefox need a slight delay here before the URL
196-
;; corresponding to the submitted form is valid. Chrome and Edge
197-
;; seem to do OK without. As of Aug 28, 2024.
198-
(e/when-safari (e/wait 3))
199-
(e/when-firefox (e/wait 3))
200-
(-> e/get-url
201-
(str/ends-with? "?login=1&password=2&message=3")
202-
is)))
206+
(e/fill-multi *driver* {:simple-input 1
207+
:simple-password 2
208+
:simple-textarea 3})
209+
(wait-url-change #"login"
210+
(e/submit *driver* :simple-input))
211+
(is (str/ends-with? (e/get-url *driver*) "?login=1&password=2&message=3")))
203212

204213
(deftest test-input
205214
(testing "fill multiple inputs"
206215
;; Test with map form
207-
(doto *driver*
208-
(e/fill-multi {:simple-input 1
209-
:simple-password 2
210-
:simple-textarea 3})
211-
(e/click :simple-submit)
212-
(e/when-safari (e/wait 3))
213-
(-> e/get-url
214-
(str/ends-with? "?login=1&password=2&message=3")
215-
is))
216+
(e/fill-multi *driver* {:simple-input 1
217+
:simple-password 2
218+
:simple-textarea 3})
219+
(wait-url-change #"login" (e/click *driver* :simple-submit))
220+
(is (str/ends-with? (e/get-url *driver*) "?login=1&password=2&message=3"))
216221
;; Test with vector form
217-
(doto *driver*
218-
(e/fill-multi [:simple-input 1
219-
:simple-password 2
220-
:simple-textarea 3])
221-
(e/click :simple-submit)
222-
(e/when-safari (e/wait 3))
223-
(-> e/get-url
224-
(str/ends-with? "?login=1&password=2&message=3")
225-
is)))
222+
(e/fill-multi *driver*
223+
[:simple-input 4
224+
:simple-password 5
225+
:simple-textarea 6])
226+
(wait-url-change #"login" (e/click *driver* :simple-submit))
227+
(is (str/ends-with? (e/get-url *driver*) "?login=4&password=5&message=6")))
226228
(testing "fill-multi bad inputs"
227229
(is (thrown+? [:type :etaoin/argument]
228230
(e/fill-multi *driver* #{:set :is :not :allowed})))
@@ -231,26 +233,20 @@
231233
(is (thrown+? [:type :etaoin/argument]
232234
(e/fill-multi *driver* [:vector :with :odd :length :is :not :allowed]))))
233235
(testing "fill human multiple inputs"
234-
(doto *driver*
235-
;; Test with map form
236-
(e/fill-human-multi {:simple-input "login"
237-
:simple-password "123"
238-
:simple-textarea "text"})
239-
(e/click :simple-submit)
240-
(e/when-safari (e/wait 3))
241-
(-> e/get-url
242-
(str/ends-with? "?login=login&password=123&message=text")
243-
is))
244-
(doto *driver*
245-
;; Test with vector form
246-
(e/fill-human-multi [:simple-input "login"
247-
:simple-password "123"
248-
:simple-textarea "text"])
249-
(e/click :simple-submit)
250-
(e/when-safari (e/wait 3))
251-
(-> e/get-url
252-
(str/ends-with? "?login=login&password=123&message=text")
253-
is)))
236+
;; Test with map form
237+
(e/fill-human-multi *driver*
238+
{:simple-input "login"
239+
:simple-password "123"
240+
:simple-textarea "text"})
241+
(wait-url-change #"login" (e/click *driver* :simple-submit))
242+
(is (str/ends-with? (e/get-url *driver*) "?login=login&password=123&message=text"))
243+
;; Test with vector form
244+
(e/fill-human-multi *driver*
245+
[:simple-input "login2"
246+
:simple-password "456"
247+
:simple-textarea "text2"])
248+
(wait-url-change #"login" (e/click *driver* :simple-submit))
249+
(is (str/ends-with? (e/get-url *driver*) "?login=login2&password=456&message=text2")))
254250
(testing "fill-human-multi bad inputs"
255251
(is (thrown+? [:type :etaoin/argument]
256252
(e/fill-multi *driver* #{:set :is :not :allowed})))
@@ -259,35 +255,27 @@
259255
(is (thrown+? [:type :etaoin/argument]
260256
(e/fill-multi *driver* [:vector :with :odd :length :is :not :allowed]))))
261257
(testing "fill multiple vars"
262-
(doto *driver*
263-
(e/fill :simple-input 1 "test" 2 \space \A)
264-
(e/click :simple-submit)
265-
(e/when-safari (e/wait 3))
266-
(-> e/get-url
267-
(str/ends-with? "?login=1test2+A&password=&message=")
268-
is)))
258+
(e/fill *driver* :simple-input 1 "test" 2 \space \A)
259+
(wait-url-change #"login" (e/click *driver* :simple-submit))
260+
(is (str/ends-with? (e/get-url *driver*) "?login=1test2+A&password=&message=")))
269261
(testing "fill active"
270-
(doto *driver*
271-
(e/click :simple-input)
272-
(e/fill-active "MyLogin")
273-
(e/click :simple-password)
274-
(e/fill-active "MyPassword")
275-
(e/click :simple-textarea)
276-
(e/fill-active "Some text")
277-
(e/click :simple-submit)
278-
(e/when-safari (e/wait 3)))
262+
(e/click *driver* :simple-input)
263+
(e/fill-active *driver* "MyLogin")
264+
(e/click *driver* :simple-password)
265+
(e/fill-active *driver* "MyPassword")
266+
(e/click *driver* :simple-textarea)
267+
(e/fill-active *driver* "Some text")
268+
(wait-url-change #"login" (e/click *driver* :simple-submit))
279269
(is (str/ends-with? (e/get-url *driver*)
280270
"?login=MyLogin&password=MyPassword&message=Some+text")))
281271
(testing "fill active human"
282-
(doto *driver*
283-
(e/click :simple-input)
284-
(e/fill-human-active "MyLogin2")
285-
(e/click :simple-password)
286-
(e/fill-human-active "MyPassword2")
287-
(e/click :simple-textarea)
288-
(e/fill-human-active "Some text 2")
289-
(e/click :simple-submit)
290-
(e/when-safari (e/wait 3)))
272+
(e/click *driver* :simple-input)
273+
(e/fill-human-active *driver* "MyLogin2")
274+
(e/click *driver* :simple-password)
275+
(e/fill-human-active *driver* "MyPassword2")
276+
(e/click *driver* :simple-textarea)
277+
(e/fill-human-active *driver* "Some text 2")
278+
(wait-url-change #"login" (e/click *driver* :simple-submit))
291279
(is (str/ends-with? (e/get-url *driver*)
292280
"?login=MyLogin2&password=MyPassword2&message=Some+text+2"))))
293281

@@ -324,27 +312,27 @@
324312

325313
(deftest test-clear
326314
(testing "simple clear"
327-
(doto *driver*
328-
(e/fill {:id :simple-input} "test")
329-
(e/clear {:id :simple-input})
330-
(e/click {:id :simple-submit})
331-
(e/when-safari (e/wait 3))
332-
(-> e/get-url
333-
(str/ends-with? "?login=&password=&message=")
334-
is)))
315+
(e/fill *driver* {:id :simple-input} "test")
316+
(e/clear *driver* {:id :simple-input})
317+
(wait-url-change #"login" (e/click *driver* {:id :simple-submit}))
318+
(is (str/ends-with? (e/get-url *driver*) "?login=&password=&message=")))
335319

336320
(testing "multiple clear"
337-
(doto *driver*
338-
(e/fill-multi {:simple-input 1
339-
:simple-password 2
340-
:simple-textarea 3})
341-
(e/clear :simple-input
342-
:simple-password
343-
:simple-textarea)
344-
(e/when-safari (e/wait 3))
345-
(-> e/get-url
346-
(str/ends-with? "?login=&password=&message=")
347-
is))))
321+
;; Note that we need to reload the test page here because the URL
322+
;; from the first test is the same as the second and thus if we
323+
;; didn't do this we couldn't detect whether anything happened
324+
;; after the first test.
325+
(reload-test-page)
326+
(e/fill-multi *driver*
327+
{:simple-input 1
328+
:simple-password 2
329+
:simple-textarea 3})
330+
(e/clear *driver*
331+
:simple-input
332+
:simple-password
333+
:simple-textarea)
334+
(wait-url-change #"login" (e/click *driver* {:id :simple-submit}))
335+
(is (str/ends-with? (e/get-url *driver*) "?login=&password=&message="))))
348336

349337
(deftest test-enabled
350338
(doto *driver*
@@ -427,14 +415,10 @@
427415
(is (= inner-html result))))
428416

429417
(deftest test-title
430-
(doto *driver*
431-
(-> e/get-title (= "Webdriver Test Document") is)))
418+
(is (= (e/get-title *driver*) "Webdriver Test Document")))
432419

433420
(deftest test-url
434-
(doto *driver*
435-
(-> e/get-url
436-
(str/ends-with? "/test.html")
437-
is)))
421+
(is (str/ends-with? (e/get-url *driver*) "/test.html")))
438422

439423
(deftest test-css-props
440424
(testing "single css"
@@ -821,12 +805,11 @@
821805

822806
(deftest test-set-hash
823807
(testing "set hash"
824-
(doto *driver*
825-
(e/set-hash "hello")
826-
(-> e/get-hash (= "hello") is)
827-
(-> e/get-url (str/ends-with? "/test.html#hello") is)
828-
(e/set-hash "goodbye")
829-
(-> e/get-url (str/ends-with? "/test.html#goodbye") is))))
808+
(e/set-hash *driver* "hello")
809+
(is (= (e/get-hash *driver*) "hello"))
810+
(is (str/ends-with? (e/get-url *driver*) "/test.html#hello"))
811+
(e/set-hash *driver* "goodbye")
812+
(is (str/ends-with? (e/get-url *driver*) "/test.html#goodbye"))))
830813

831814
(deftest test-query
832815
(testing "finding an element by id keyword"
@@ -1159,8 +1142,8 @@
11591142
(e/add-pointer-click-el textarea)
11601143
e/add-pause
11611144
(e/add-pointer-click-el submit))]
1162-
(e/perform-actions *driver* keyboard mouse)
1163-
(e/wait 1)
1145+
(wait-url-change #"login"
1146+
(e/perform-actions *driver* keyboard mouse))
11641147
(is (str/ends-with? (e/get-url *driver*) "?login=1&password=2&message=3")))))
11651148

11661149
(deftest test-shadow-dom

0 commit comments

Comments
 (0)