From 08e8b304656e55fe1960b96776e6ff334bb01021 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Wed, 7 Feb 2024 17:00:42 +0000 Subject: [PATCH 01/16] Trying to trace error source on Node 16. #30 --- src/sitefoxtest/e2etests.cljs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index eeffcb2..fdec2b9 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -13,7 +13,7 @@ ;(def browser-type pw/chromium) -(def host "127.0.0.1") +(def host "localhost") (def base-url (str "http://" host ":8000")) (def log (j/call-in js/console [:log :bind] js/console " ---> ")) @@ -35,6 +35,7 @@ :detach true}) port-info (wait-for-port #js {:host host :port port}) pid (j/get server :pid)] + (log "Setting up stdout listener.") (j/call-in server [:stdout :on] "data" (fn [data] (doseq [[re-string listener-fn] @log-listeners] @@ -64,10 +65,11 @@ (defn catch-fail [err done server & [browser]] (when err - (.error js/console (j/get err :stack))) + (.error js/console err)) (is (nil? err) (str "Error in test: " (.toString err))) - (j/call server :kill) + (when (and server (j/get server :kill)) + (j/call server :kill)) (when browser (.close browser)) (done)) @@ -80,6 +82,7 @@ (p/catch (p/let [res (js/fetch base-url) text (.text res)] + (log "Starting test checks.") (is (j/get-in server [:process :pid]) "Server is running?") (is (j/get server :open) "Server port is open?") (is (j/get res :ok) "Was server response ok?") From 6aecd9ecba20cb18f86e18ed3cdce97a03b7f12d Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Wed, 7 Feb 2024 17:11:44 +0000 Subject: [PATCH 02/16] Enable experimental Fetch so v16 works. #30 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d96ab64..058ba53 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "docs": "nbb bin/generate-docs.cljs", "pre-publish": "npm run sync-deps; nbb bin/update-readme-versions.cljs; npm run docs; echo Changes:; git log --oneline `git rev-list --tags --max-count=1`..; echo; echo 'Now commit changes and run `git tag vX.Y.Z`.'", "test": "rm -f ./tests.sqlite; SECRET=testing TESTING=1 DATABASE_URL=sqlite://./tests.sqlite npx shadow-cljs compile test", - "test-e2e": "nbb --classpath src src/sitefoxtest/e2etests.cljs", + "test-e2e": "NODE_OPTIONS='--experimental-fetch --no-warnings' nbb --classpath src src/sitefoxtest/e2etests.cljs", "watch": "SECRET=watching TESTING=1 shadow-cljs watch test" } } From b519b617e1d86077b52d23b932d2df89ae173e1b Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Wed, 7 Feb 2024 17:17:37 +0000 Subject: [PATCH 03/16] Increase e2e test browser timeout for OSX slowness. #30. --- src/sitefoxtest/e2etests.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index fdec2b9..6bad26a 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -15,6 +15,7 @@ (def host "localhost") (def base-url (str "http://" host ":8000")) +(def browser-timeout 5000) (def log (j/call-in js/console [:log :bind] js/console " ---> ")) (def log-listeners (atom #{})) @@ -57,7 +58,7 @@ (defn get-browser [] (p/let [browser (.launch pw/chromium #js {:headless (not (nil? (j/get env "CI"))) - :timeout 3000}) + :timeout browser-timeout}) context (.newContext browser) page (.newPage context)] (.setDefaultTimeout page 3000) From 752368cb64a0e0b1a7c1920cc87d10066bdd5c0f Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Wed, 7 Feb 2024 17:28:53 +0000 Subject: [PATCH 04/16] Increase OSX timeout again. #30 --- src/sitefoxtest/e2etests.cljs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 6bad26a..0f68b31 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -15,7 +15,7 @@ (def host "localhost") (def base-url (str "http://" host ":8000")) -(def browser-timeout 5000) +(def browser-timeout 60000) (def log (j/call-in js/console [:log :bind] js/console " ---> ")) (def log-listeners (atom #{})) @@ -65,6 +65,7 @@ {:browser browser :context context :page page})) (defn catch-fail [err done server & [browser]] + (log "Caught test error.") (when err (.error js/console err)) (is (nil? err) From 7c4bee7eddd363c085a0ef75abcbc513523f5373 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 08:41:08 +0000 Subject: [PATCH 05/16] Sign out test. #30 --- src/sitefoxtest/e2etests.cljs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 0f68b31..3afc1ee 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -100,6 +100,11 @@ content (.content page)] (is (includes? content text) message))) +(defn check-for-no-text [page text selector message] + (p/let [_ (-> page (.waitForSelector selector)) + content (.content page)] + (is (not (includes? content text)) message))) + (deftest nbb-auth (t/testing "Auth against Sitefox on nbb tests." (async done @@ -128,6 +133,11 @@ (.goto page base-url) (check-for-text page "Signed in" "User is correctly signed in on homepage.")) + ; click "Sign out" + (-> page (.locator "a[href='/auth/sign-out']") .click) + (check-for-no-text page "Signed in" "a[href='/auth/sign-in']" + "User is correctly signed out on homepage.") + (log "Closing resources.") (j/call server :kill) (.close browser) From 92270c8c4be0bf306f48380be3b22fbf6ba2a234 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 08:42:54 +0000 Subject: [PATCH 06/16] Code layout. --- src/sitefoxtest/e2etests.cljs | 53 ++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 3afc1ee..a02dc55 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -40,7 +40,8 @@ (j/call-in server [:stdout :on] "data" (fn [data] (doseq [[re-string listener-fn] @log-listeners] - (let [matches (.match (.toString data) (js/RegExp. re-string "s"))] + (let [matches (.match (.toString data) + (js/RegExp. re-string "s"))] (when matches (listener-fn matches) (swap! log-listeners disj [re-string listener-fn])))) @@ -80,15 +81,21 @@ (t/testing "Basic test of Sitefox on nbb." (async done (p/let [_ (log "Test: basic-site-test") - server (run-server "examples/nbb" "npm i --no-save; npm run serve" 8000)] + server (run-server "examples/nbb" + "npm i --no-save; npm run serve" + 8000)] (p/catch (p/let [res (js/fetch base-url) text (.text res)] (log "Starting test checks.") - (is (j/get-in server [:process :pid]) "Server is running?") - (is (j/get server :open) "Server port is open?") - (is (j/get res :ok) "Was server response ok?") - (is (includes? text "Hello") "Server response includes 'Hello' text?") + (is (j/get-in server [:process :pid]) + "Server is running?") + (is (j/get server :open) + "Server port is open?") + (is (j/get res :ok) + "Was server response ok?") + (is (includes? text "Hello") + "Server response includes 'Hello' text?") (log "Test done. Killing server.") (j/call server :kill) (log "After server.") @@ -109,7 +116,9 @@ (t/testing "Auth against Sitefox on nbb tests." (async done (p/let [_ (log "Test: nbb-auth") - server (run-server "examples/nbb-auth" "npm i --no-save; npm run serve" 8000) + server (run-server "examples/nbb-auth" + "npm i --no-save; npm run serve" + 8000) {:keys [page browser]} (get-browser)] (p/catch (p/do! @@ -119,19 +128,31 @@ ; click "Sign up" (-> page (.locator "a[href='/auth/sign-up']") .click) ; fill out details and sign up - (-> page (.locator "input[name='email']") (.fill "goober@example.com")) - (-> page (.locator "input[name='email2']") (.fill "goober@example.com")) - (-> page (.locator "input[name='password']") (.fill "tester")) - (-> page (.locator "input[name='password2']") (.fill "tester")) - - (p/let [[log-items] (p/all [(listen-to-log "verify-url (?http.*?)[\n$]") - (-> page (.locator "button:has-text('Sign up')") .click)]) + (-> page (.locator "input[name='email']") + (.fill "goober@example.com")) + (-> page (.locator "input[name='email2']") + (.fill "goober@example.com")) + (-> page (.locator "input[name='password']") + (.fill "tester")) + (-> page (.locator "input[name='password2']") + (.fill "tester")) + + (p/let [[log-items] + (p/all [(listen-to-log + "verify-url (?http.*?)[\n$]") + (-> page + (.locator "button:has-text('Sign up')") + .click)]) url (j/get-in log-items [:groups :url])] ; click on the verification link (.goto page url) - (check-for-text page "Signed in" "User is correctly signed in after verification.") + (check-for-text + page "Signed in" + "User is correctly signed in after verification.") (.goto page base-url) - (check-for-text page "Signed in" "User is correctly signed in on homepage.")) + (check-for-text + page "Signed in" + "User is correctly signed in on homepage.")) ; click "Sign out" (-> page (.locator "a[href='/auth/sign-out']") .click) From b21ef6bfcf45d371e4e11da305270b1cf07e44ab Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 08:51:12 +0000 Subject: [PATCH 07/16] More sign in tests including failed sign in. #30 --- src/sitefoxtest/e2etests.cljs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index a02dc55..6f0effa 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -159,6 +159,34 @@ (check-for-no-text page "Signed in" "a[href='/auth/sign-in']" "User is correctly signed out on homepage.") + ; sign in again + (.goto page base-url) + ; click "Sign in" + (-> page (.locator "a[href='/auth/sign-in']") .click) + + ; do a failed sign in + (-> page (.locator "input[name='email']") + (.fill "goober@example.com")) + (-> page (.locator "input[name='password']") + (.fill "testerwrong")) + (-> page + (.locator "button:has-text('Sign in')") + .click) + (check-for-text page "Invalid email or password" + "Incorrect password shows a message.") + + ; successful sign in + (-> page (.locator "input[name='password']") + (.fill "tester")) + (-> page + (.locator "button:has-text('Sign in')") + .click) + (check-for-text + page "Signed in" + "User is correctly signed in again.") + + ; test forgot password flow + (log "Closing resources.") (j/call server :kill) (.close browser) From 172873d8eb87b9df72c5365b7a972ae9368d45f3 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 11:49:44 +0000 Subject: [PATCH 08/16] Completed auth testing. #30 --- src/sitefoxtest/e2etests.cljs | 100 +++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 20 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 6f0effa..3071cd8 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -28,6 +28,11 @@ (spawnSync "npm i --no-save" #js {:cwd path :stdio "inherit" :shell true}) + ; delete any old database hanging around + (spawnSync "rm -f database.sqlite" + #js {:cwd path + :stdio "inherit" + :shell true}) ; now run the server (log "Spawning server.") (p/let [server (spawn server-command #js {:cwd path @@ -39,6 +44,7 @@ (log "Setting up stdout listener.") (j/call-in server [:stdout :on] "data" (fn [data] + ;(print data) (doseq [[re-string listener-fn] @log-listeners] (let [matches (.match (.toString data) (js/RegExp. re-string "s"))] @@ -77,7 +83,7 @@ (.close browser)) (done)) -(deftest basic-site-test +#_ (deftest basic-site-test (t/testing "Basic test of Sitefox on nbb." (async done (p/let [_ (log "Test: basic-site-test") @@ -112,6 +118,43 @@ content (.content page)] (is (not (includes? content text)) message))) +(defn check-failed-sign-in + [page password] + (p/do! + ; sign in again + (.goto page base-url) + ; click "Sign in" + (-> page (.locator "a[href='/auth/sign-in']") .click) + + ; do a failed sign in + (-> page (.locator "input[name='email']") + (.fill "goober@example.com")) + (-> page (.locator "input[name='password']") + (.fill password)) + (-> page + (.locator "button:has-text('Sign in')") + .click) + (check-for-text page "Invalid email or password" + "Incorrect password shows a message."))) + +(defn sign-out [page] + ; click "Sign out" + (-> page (.locator "a[href='/auth/sign-out']") .click) + (check-for-no-text page "Signed in" "a[href='/auth/sign-in']" + "User is correctly signed out on homepage.")) + +(defn sign-in [page password] + (p/do! + ; successful sign in + (-> page (.locator "input[name='password']") + (.fill password)) + (-> page + (.locator "button:has-text('Sign in')") + .click) + (check-for-text + page "Signed in" + "User is correctly signed in again."))) + (deftest nbb-auth (t/testing "Auth against Sitefox on nbb tests." (async done @@ -154,38 +197,55 @@ page "Signed in" "User is correctly signed in on homepage.")) - ; click "Sign out" - (-> page (.locator "a[href='/auth/sign-out']") .click) - (check-for-no-text page "Signed in" "a[href='/auth/sign-in']" - "User is correctly signed out on homepage.") + (print "sign out") + (sign-out page) - ; sign in again - (.goto page base-url) + (print "check failed sign in") + (check-failed-sign-in page "testerwrong") + + (print "sign in again") + (sign-in page "tester") + + (print "forgot password") + ; test forgot password flow + (-> page (.locator "a[href='/auth/sign-out']") .click) ; click "Sign in" (-> page (.locator "a[href='/auth/sign-in']") .click) - - ; do a failed sign in + ; click "Forgot password link" + (-> page (.locator "a[href='/auth/reset-password']") .click) + ; fill out the forgot password form (-> page (.locator "input[name='email']") (.fill "goober@example.com")) - (-> page (.locator "input[name='password']") - (.fill "testerwrong")) - (-> page - (.locator "button:has-text('Sign in')") - .click) - (check-for-text page "Invalid email or password" - "Incorrect password shows a message.") - ; successful sign in + (p/let [[log-items] + (p/all [(listen-to-log + "verify-url (?http.*?)[\n$]") + (-> page + (.locator + "button:has-text('Reset password')") + .click)]) + url (j/get-in log-items [:groups :url])] + (check-for-text page "Reset password link sent" + "User has been notified of reset email.") + (.goto page url)) + + ; enter updated passwords (-> page (.locator "input[name='password']") - (.fill "tester")) + (.fill "testagain")) + (-> page (.locator "input[name='password2']") + (.fill "testagain")) (-> page - (.locator "button:has-text('Sign in')") + (.locator "button:has-text('Update password')") .click) (check-for-text page "Signed in" "User is correctly signed in again.") - ; test forgot password flow + ; check sign in fails with old password + (sign-out page) + (check-failed-sign-in page "tester") + ; check successful sign in with new password + (sign-in page "testagain") (log "Closing resources.") (j/call server :kill) From 84872023cd7ed3d99a5c567fa3a2f4f9b8a02553 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 11:55:43 +0000 Subject: [PATCH 09/16] Uncommented test. #30 --- src/sitefoxtest/e2etests.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 3071cd8..156d69b 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -83,7 +83,7 @@ (.close browser)) (done)) -#_ (deftest basic-site-test +(deftest basic-site-test (t/testing "Basic test of Sitefox on nbb." (async done (p/let [_ (log "Test: basic-site-test") From e7ab100b2555379b733744feae9ca6a0aa0156e5 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 12:26:33 +0000 Subject: [PATCH 10/16] Upgraded nbb version in forms example. #30 --- examples/form-validation/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/form-validation/package.json b/examples/form-validation/package.json index 289e592..7dea089 100644 --- a/examples/form-validation/package.json +++ b/examples/form-validation/package.json @@ -2,7 +2,7 @@ "dependencies": { "filewatcher": "^3.0.1", "minimal-stylesheet": "^0.1.0", - "nbb": "0.0.97", + "nbb": "^1.2.180", "node-input-validator": "^4.4.1", "react": "^17.0.2", "react-dom": "^17.0.2", From 8d9110a882f65c46bd8b4c5f07d25bb7163abdaa Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 12:27:13 +0000 Subject: [PATCH 11/16] Linter fix in forms example. --- examples/form-validation/webserver.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/form-validation/webserver.cljs b/examples/form-validation/webserver.cljs index 779633e..79e897c 100644 --- a/examples/form-validation/webserver.cljs +++ b/examples/form-validation/webserver.cljs @@ -72,7 +72,7 @@ (email-form data)) (.send res rendered-html))) -(defn handle-csrf-error [err req res n] +(defn handle-csrf-error [err _req res n] (if (= (aget err "code") "EBADCSRFTOKEN") (-> res (.status 403) From 84800f90e326b21a1658ba518b26e4e7172cf0bd Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 12:28:29 +0000 Subject: [PATCH 12/16] Initial forms test with validation fail success. #30 --- src/sitefoxtest/e2etests.cljs | 45 +++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 156d69b..d1b932d 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -254,10 +254,45 @@ (done)) #(catch-fail % done server browser)))))) -#_ (defmethod cljs.test/report [:cljs.test/default :end-run-tests] [m] - (print "report") - (if (cljs.test/successful? m) - (println "Success!") - (println "FAIL"))) +(deftest nbb-forms + (t/testing "Sitefox forms and CSRF on nbb tests." + (async done + (p/let [_ (log "Test: nbb-forms") + server (run-server "examples/form-validation" + "npm i --no-save; npm run serve" + 8000) + {:keys [page browser]} (get-browser)] + (p/catch + (p/do! + (.goto page base-url) + + ; fill out bad form details + (-> page (.locator "input[name='name']") + (.fill "")) + (-> page (.locator "input[name='date']") + (.fill "SEPTEMBER THE NOTHING")) + (-> page (.locator "input[name='count']") + (.fill "XYZ")) + + (-> page (.locator "button[type='submit']") .click) + + (check-for-text + page "You must enter a name between 5 and 20 characters." + "Name validation failed successfully.") + + (check-for-text + page "You must enter a valid date in YYYY-MM-DD format." + "Date validation failed successfully.") + + (check-for-text + page "You must enter a quantity between 5 and 10." + "Count validation failed successfully.") + + (log "Closing resources.") + (j/call server :kill) + (.close browser) + (log "Resources closed.") + (done)) + #(catch-fail % done server browser)))))) (t/run-tests *ns*) From e01279ee1cf914d85476acc5bdd8829cb8e87080 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 12:29:11 +0000 Subject: [PATCH 13/16] Remove superfluous npm install in server tests. #30 --- src/sitefoxtest/e2etests.cljs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index d1b932d..7dfda82 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -23,11 +23,6 @@ (j/assoc! env "BIND_ADDRESS" host) (defn run-server [path server-command port] - ; first run npm init in the folder - (log "Installing server deps.") - (spawnSync "npm i --no-save" #js {:cwd path - :stdio "inherit" - :shell true}) ; delete any old database hanging around (spawnSync "rm -f database.sqlite" #js {:cwd path From daf37a44ee1aaf246131916bb5cae8ceb2dbc3d9 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 21:03:17 +0000 Subject: [PATCH 14/16] New test for correctly filling out form. #30 --- src/sitefoxtest/e2etests.cljs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 7dfda82..4f357d3 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -283,6 +283,24 @@ page "You must enter a quantity between 5 and 10." "Count validation failed successfully.") + ; fill out form correctly + + (.goto page base-url) + + ; fill out bad form details + (-> page (.locator "input[name='name']") + (.fill "Bilbo")) + (-> page (.locator "input[name='date']") + (.fill "2023-06-01")) + (-> page (.locator "input[name='count']") + (.fill "7")) + + (-> page (.locator "button[type='submit']") .click) + + (check-for-text + page "Form complete." + "Form submits sucessfully.") + (log "Closing resources.") (j/call server :kill) (.close browser) From 3eefd764c9372521555373de6dd329526f24d1a0 Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 21:22:02 +0000 Subject: [PATCH 15/16] Successfully test failed CSRF. #30 --- src/sitefoxtest/e2etests.cljs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index 4f357d3..ca650ba 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -301,6 +301,26 @@ page "Form complete." "Form submits sucessfully.") + ; fill out form correctly but fail csrf + (.goto page base-url) + + ; fill out bad form details + (-> page (.locator "input[name='name']") + (.fill "Bilbo")) + (-> page (.locator "input[name='date']") + (.fill "2023-06-01")) + (-> page (.locator "input[name='count']") + (.fill "7")) + ; modify csrf field + (-> page + (.evaluate "document.querySelector('input[name=\"_csrf\"]').value='BOGUS'")) + + (-> page (.locator "button[type='submit']") .click) + + (check-for-text + page "The form was tampered with." + "CSRF error caught sucessfully.") + (log "Closing resources.") (j/call server :kill) (.close browser) From ff1a762edaaed6a2f7d8d297bf88ddbfffa615dc Mon Sep 17 00:00:00 2001 From: Chris McCormick Date: Mon, 12 Feb 2024 21:36:49 +0000 Subject: [PATCH 16/16] Check dual parallel form CSRF tokens. #30 --- src/sitefoxtest/e2etests.cljs | 40 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/sitefoxtest/e2etests.cljs b/src/sitefoxtest/e2etests.cljs index ca650ba..8ceefdf 100644 --- a/src/sitefoxtest/e2etests.cljs +++ b/src/sitefoxtest/e2etests.cljs @@ -249,6 +249,20 @@ (done)) #(catch-fail % done server browser)))))) +(defn check-form-submit [page] + (p/do! + ; fill out bad form details + (-> page (.locator "input[name='name']") + (.fill "Bilbo")) + (-> page (.locator "input[name='date']") + (.fill "2023-06-01")) + (-> page (.locator "input[name='count']") + (.fill "7")) + (-> page (.locator "button[type='submit']") .click) + (check-for-text + page "Form complete." + "Form submits sucessfully."))) + (deftest nbb-forms (t/testing "Sitefox forms and CSRF on nbb tests." (async done @@ -256,7 +270,7 @@ server (run-server "examples/form-validation" "npm i --no-save; npm run serve" 8000) - {:keys [page browser]} (get-browser)] + {:keys [page context browser]} (get-browser)] (p/catch (p/do! (.goto page base-url) @@ -287,19 +301,7 @@ (.goto page base-url) - ; fill out bad form details - (-> page (.locator "input[name='name']") - (.fill "Bilbo")) - (-> page (.locator "input[name='date']") - (.fill "2023-06-01")) - (-> page (.locator "input[name='count']") - (.fill "7")) - - (-> page (.locator "button[type='submit']") .click) - - (check-for-text - page "Form complete." - "Form submits sucessfully.") + (check-form-submit page) ; fill out form correctly but fail csrf (.goto page base-url) @@ -321,6 +323,16 @@ page "The form was tampered with." "CSRF error caught sucessfully.") + ; sanity check by running multiple CSRF checks in parallel forms + + ; open another form to get a new csrf token + (p/let [page2 (.newPage context)] + (.goto page2 base-url) + ; then reload the first page to get a new token + (.goto page (str base-url "?hello=1")) + ; check the second tab can still successfully submit + (check-form-submit page2)) + (log "Closing resources.") (j/call server :kill) (.close browser)