From 5ce99a5a3d4fa77a4f05d9a62c18b9526376f353 Mon Sep 17 00:00:00 2001 From: Joey Yakimowich-Payne Date: Tue, 18 Feb 2020 13:56:38 -0700 Subject: [PATCH] Add tests and improve testing experience --- tests/browsertester.nim | 4 +- tests/browsertests/categories.nim | 74 ++++++++++++++++++++++++++++++- tests/browsertests/common.nim | 40 +++++++++++++++-- 3 files changed, 111 insertions(+), 7 deletions(-) diff --git a/tests/browsertester.nim b/tests/browsertester.nim index 6a5c374..8b6c046 100644 --- a/tests/browsertester.nim +++ b/tests/browsertester.nim @@ -23,7 +23,7 @@ const baseUrl = "http://localhost:" & $port & "/" template withBackend(body: untyped): untyped = ## Starts a new backend instance. - spawn runProcess("nimble -y runbackend") + spawn runProcess("nimble -y testbackend") defer: discard execCmd("killall " & backend) @@ -46,6 +46,8 @@ template withBackend(body: untyped): untyped = import browsertests/[scenario1, threads, issue181, categories] proc main() = + # Kill any already running instances + discard execCmd("killall geckodriver") spawn runProcess("geckodriver -p 4444 --log config") defer: discard execCmd("killall geckodriver") diff --git a/tests/browsertests/categories.nim b/tests/browsertests/categories.nim index 70be70b..d56b47c 100644 --- a/tests/browsertests/categories.nim +++ b/tests/browsertests/categories.nim @@ -1,4 +1,4 @@ -import unittest, options, common +import unittest, options, common, os import webdriver @@ -43,6 +43,65 @@ proc categoriesUserTests(session: Session, baseUrl: string) = ensureExists title, LinkTextSelector + test "can navigate to categories page": + with session: + click "#categories-btn" + + ensureExists "#categories-list" + + test "can view post under category": + with session: + + # create a few threads + click "#new-thread-btn" + sendKeys "#thread-title", "Post 1" + + selectCategory "fun" + sendKeys "#reply-textarea", "Post 1" + + click "#create-thread-btn" + navigate baseUrl + + + click "#new-thread-btn" + sendKeys "#thread-title", "Post 2" + + selectCategory "announcements" + sendKeys "#reply-textarea", "Post 2" + + click "#create-thread-btn" + navigate baseUrl + + + click "#new-thread-btn" + sendKeys "#thread-title", "Post 3" + + selectCategory "default" + sendKeys "#reply-textarea", "Post 3" + + click "#create-thread-btn" + navigate baseUrl + + + click "#categories-btn" + ensureExists "#categories-list" + + click "#category-default" + checkText "#threads-list .thread-title", "Post 3" + for element in session.waitForElements("#threads-list .category-name"): + # Have to user "innerText" because elements are hidden on this page + assert element.getProperty("innerText") == "Default" + + selectCategory "announcements" + checkText "#threads-list .thread-title", "Post 2" + for element in session.waitForElements("#threads-list .category-name"): + assert element.getProperty("innerText") == "Announcements" + + selectCategory "fun" + checkText "#threads-list .thread-title", "Post 1" + for element in session.waitForElements("#threads-list .category-name"): + assert element.getProperty("innerText") == "Fun" + session.logout() proc categoriesAdminTests(session: Session, baseUrl: string) = @@ -76,6 +135,17 @@ proc categoriesAdminTests(session: Session, baseUrl: string) = checkText "#category-selection .selected-category", name + test "category adding disabled on admin logout": + with session: + navigate(baseUrl & "c/0") + ensureExists "#add-category" + logout() + + checkIsNone "#add-category" + navigate baseUrl + + login "admin", "admin" + session.logout() proc test*(session: Session, baseUrl: string) = @@ -84,4 +154,4 @@ proc test*(session: Session, baseUrl: string) = categoriesUserTests(session, baseUrl) categoriesAdminTests(session, baseUrl) - session.navigate(baseUrl) \ No newline at end of file + session.navigate(baseUrl) diff --git a/tests/browsertests/common.nim b/tests/browsertests/common.nim index e967abd..9d8b61a 100644 --- a/tests/browsertests/common.nim +++ b/tests/browsertests/common.nim @@ -8,13 +8,22 @@ const actionDelayMs {.intdefine.} = 0 macro with*(obj: typed, code: untyped): untyped = ## Execute a set of statements with an object expectKind code, nnkStmtList - result = code + + template checkCompiles(res, default) = + when compiles(res): + res + else: + default + + result = code.copy # Simply inject obj into call for i in 0 ..< result.len: - if result[i].kind in {nnkCommand, nnkCall}: + if result[i].kind in {nnkCommand, nnkCall} and $result[i][0].toStrLit != "assert": result[i].insert(1, obj) + result = getAst(checkCompiles(result, code)) + proc elementIsSome(element: Option[Element]): bool = return element.isSome @@ -73,8 +82,31 @@ proc waitForElement*( sleep(actionDelayMs) while true: - let loading = session.findElement(selector, strategy) - if waitCondition(loading): + try: + let loading = session.findElement(selector, strategy) + if waitCondition(loading): + return loading + finally: + discard + sleep(pollTime) + waitTime += pollTime + + if waitTime > timeout: + doAssert false, "Wait for load time exceeded" + +proc waitForElements*( + session: Session, selector: string, strategy=CssSelector, + timeout=20000, pollTime=50 +): seq[Element] = + var waitTime = 0 + + when actionDelayMs > 0: + sleep(actionDelayMs) + + while true: + let loading = session.findElements(selector, strategy) + echo loading + if loading.len > 0: return loading sleep(pollTime) waitTime += pollTime