Implements web driver test suite and simple test.

This commit is contained in:
Dominik Picheta 2018-05-18 22:33:56 +01:00
commit c6ed9e80c9
8 changed files with 183 additions and 29 deletions

View file

@ -20,13 +20,33 @@ requires "sass"
requires "karax"
requires "webdriver"
# Tasks
task backend, "Runs the forum backend":
task backend, "Compiles and runs the forum backend":
exec "nimble c src/forum.nim"
exec "./src/forum"
task runbackend, "Runs the forum backend":
exec "./src/forum"
task frontend, "Builds the necessary JS frontend":
exec "nimble js src/frontend/forum.nim"
mkDir "public/js"
cpFile "src/frontend/nimcache/forum.js", "public/js/forum.js"
cpFile "src/frontend/nimcache/forum.js", "public/js/forum.js"
task testdb, "Creates a test DB":
exec "nimble c src/setup_nimforum"
exec "./src/setup_nimforum --test"
task devdb, "Creates a test DB":
exec "nimble c src/setup_nimforum"
exec "./src/setup_nimforum --dev"
task test, "Runs tester":
exec "nimble c src/forum.nim"
exec "nimble c -r tests/browsertester"
task fasttest, "Runs tester without recompiling backend":
exec "nimble c -r tests/browsertester"

View file

@ -856,10 +856,6 @@ proc prependRe(s: string): string =
proc initialise() =
randomize()
db = open(connection="nimforum.db", user="postgres", password="",
database="nimforum")
isFTSAvailable = db.getAllRows(sql("SELECT name FROM sqlite_master WHERE " &
"type='table' AND name='post_fts'")).len == 1
config = loadConfig()
if len(config.recaptchaSecretKey) > 0 and len(config.recaptchaSiteKey) > 0:
@ -868,6 +864,11 @@ proc initialise() =
doAssert config.isDev, "Recaptcha required for production!"
echo("[WARNING] No recaptcha secret key specified.")
db = open(connection=config.dbPath, user="", password="",
database="nimforum")
isFTSAvailable = db.getAllRows(sql("SELECT name FROM sqlite_master WHERE " &
"type='table' AND name='post_fts'")).len == 1
let cssLoc = "public" / "css"
if not existsFile(cssLoc / "nimforum.css"):
sass.compileFile(cssLoc / "nimforum.scss", cssLoc / "nimforum.css")

View file

@ -93,11 +93,11 @@ when defined(js):
if state.loading:
tdiv(class="loading")
elif user.isNone:
button(class="btn btn-primary btn-sm",
button(id="signup-btn", class="btn btn-primary btn-sm",
onClick=(e: Event, n: VNode) => state.signupModal.show()):
italic(class="fas fa-user-plus")
text " Sign up"
button(class="btn btn-primary btn-sm",
button(id="login-btn", class="btn btn-primary btn-sm",
onClick=(e: Event, n: VNode) => state.loginModal.show()):
italic(class="fas fa-sign-in-alt")
text " Log in"

View file

@ -7,21 +7,30 @@
#
# Script to initialise the nimforum.
import strutils, db_sqlite, os, times, json
import strutils, db_sqlite, os, times, json, options
import auth, frontend/user
proc backup(path: string) =
proc backup(path: string, contents: Option[string]=none[string]()) =
if existsFile(path):
if contents.isSome() and readFile(path) == contents.get():
# Don't backup if the files are equivalent.
echo("Not backing up because new file is the same.")
return
let backupPath = path & "." & $getTime().toUnix()
echo(path, " already exists. Moving to ", backupPath)
moveFile(path, backupPath)
proc initialiseDb(admin: tuple[username, password, email: string]) =
let path = getCurrentDir() / "nimforum.db"
backup(path)
proc initialiseDb(admin: tuple[username, password, email: string],
filename="nimforum.db") =
let path = getCurrentDir() / filename
if "-dev" notin filename and "-test" notin filename:
backup(path)
var db = open(connection="nimforum.db", user="", password="",
removeFile(path)
var db = open(connection=path, user="", password="",
database="nimforum")
const
@ -198,10 +207,10 @@ proc initialiseConfig(
name, hostname: string,
recaptcha: tuple[siteKey, secretKey: string],
smtp: tuple[address, user, password: string],
isDev: bool
isDev: bool,
dbPath: string
) =
let path = getCurrentDir() / "forum.json"
backup(path)
var j = %{
"name": %name,
@ -211,23 +220,47 @@ proc initialiseConfig(
"smtpAddress": %smtp.address,
"smtpUser": %smtp.user,
"smtpPassword": %smtp.password,
"isDev": %isDev
"isDev": %isDev,
"dbPath": %dbPath
}
backup(path, some($j))
writeFile(path, $j)
when isMainModule:
if paramCount() > 0 and paramStr(1) == "--dev":
echo("Initialising nimforum for development...")
initialiseConfig(
"Development Forum",
"localhost.local",
recaptcha=("", ""),
smtp=("", "", ""),
isDev=true
)
if paramCount() > 0:
case paramStr(1)
of "--dev":
let dbPath = "nimforum-dev.db"
echo("Initialising nimforum for development...")
initialiseConfig(
"Development Forum",
"localhost.local",
recaptcha=("", ""),
smtp=("", "", ""),
isDev=true,
dbPath
)
initialiseDb(
admin=("admin", "admin", "admin@localhost.local")
)
initialiseDb(
admin=("admin", "admin", "admin@localhost.local"),
dbPath
)
of "--test":
let dbPath = "nimforum-test.db"
echo("Initialising nimforum for testing...")
initialiseConfig(
"Test Forum",
"localhost.local",
recaptcha=("", ""),
smtp=("", "", ""),
isDev=true,
dbPath
)
initialiseDb(
admin=("admin", "admin", "admin@localhost.local"),
dbPath
)
else:
quit("--dev|--test")

View file

@ -25,6 +25,7 @@ type
recaptchaSecretKey*: string
recaptchaSiteKey*: string
isDev*: bool
dbPath*: string
var docConfig: StringTableRef
@ -45,6 +46,7 @@ proc loadConfig*(filename = getCurrentDir() / "forum.json"): Config =
result.recaptchaSecretKey = root{"recaptchaSecretKey"}.getStr("")
result.recaptchaSiteKey = root{"recaptchaSiteKey"}.getStr("")
result.isDev = root{"isDev"}.getBool()
result.dbPath = root{"dbPath"}.getStr("nimforum.db")
except:
echo("[WARNING] Couldn't read config file: ", filename)

68
tests/browsertester.nim Normal file
View file

@ -0,0 +1,68 @@
import options, osproc, streams, threadpool, os, strformat, httpclient
import webdriver
proc runProcess(cmd: string) =
let p = startProcess(
cmd,
options={
poStdErrToStdOut,
poEvalCommand
}
)
let o = p.outputStream
while p.running and (not o.atEnd):
echo cmd.substr(0, 10), ": ", o.readLine()
p.close()
const backend = "forum"
const port = 5000
const baseUrl = "http://localhost:" & $port & "/"
template withBackend(body: untyped): untyped =
## Starts a new backend instance with a fresh DB.
doAssert(execCmd("nimble testdb") == QuitSuccess)
spawn runProcess("nimble runbackend")
defer:
discard execCmd("killall " & backend)
echo("Waiting for server...")
var success = false
for i in 0..5:
sleep(5000)
try:
let client = newHttpClient()
doAssert client.getContent(baseUrl).len > 0
success = true
break
except:
echo("Failed to getContent")
doAssert success
body
import browsertests/scenario1
when isMainModule:
spawn runProcess("geckodriver -p 4444 --log config")
defer:
discard execCmd("killall geckodriver")
doAssert(execCmd("nimble frontend") == QuitSuccess)
echo("Waiting for geckodriver to startup...")
sleep(5000)
try:
let driver = newWebDriver()
let session = driver.createSession()
withBackend:
scenario1.test(session, baseUrl)
session.close()
except:
sleep(10000) # See if we can grab any more output.
raise

1
tests/browsertester.nims Normal file
View file

@ -0,0 +1 @@
--threads:on

View file

@ -0,0 +1,29 @@
import unittest, options, os
import webdriver
proc waitForLoad(session: Session) =
sleep(2000)
while true:
let loading = session.findElement(".loading")
if loading.isNone: return
sleep(1000)
proc test*(session: Session, baseUrl: string) =
session.navigate(baseUrl)
waitForLoad(session)
# Sanity checks
test "shows sign up":
let signUp = session.findElement("#signup-btn")
check signUp.get().getText() == "Sign up"
test "shows log in":
let signUp = session.findElement("#login-btn")
check signUp.get().getText() == "Log in"
test "is empty":
let thread = session.findElement("tr > td.thread-title")
check thread.isNone()