Run vanilla web form submission simulation when there is no onsubmit handler and a form submit button is clicked.

This commit is contained in:
Dillon Kearns 2022-03-20 13:07:28 -07:00
parent a437459865
commit ef6f80ff01
3 changed files with 77 additions and 30 deletions

View File

@ -28,7 +28,7 @@ module ProgramTest exposing
, simulateLastEffect
, fail, createFailed
, getOutgoingPortValues
, SimpleState, fillInDom, onFormSubmit, submitForm, updateCookieJar
, SimpleState, fillInDom, onFormSubmit, updateCookieJar
)
{-| A `ProgramTest` simulates the execution of an Elm program
@ -810,6 +810,28 @@ simulateComplexQuery functionName complexQuery =
Err (ViewAssertionFailed ("ProgramTest." ++ functionName) (Html.map (\_ -> ()) (program.view state.currentModel)) highlight queryFailure)
{-| -}
simulateComplexQueryOrSubmit : String -> (ComplexQuery (Query.Single msg) -> ComplexQuery (ComplexQuery.MsgOrSubmit msg)) -> ProgramTest model msg effect -> ProgramTest model msg effect
simulateComplexQueryOrSubmit functionName complexQuery programTest =
andThen
(\program state ->
let
view =
Program.renderView program state.currentModel
in
case ComplexQuery.run (complexQuery (ComplexQuery.succeed view)) of
( _, Ok (ComplexQuery.SubmitMsg msg) ) ->
TestState.update msg program state
( _, Ok ComplexQuery.Submit ) ->
submitFormInner programTest program state
( highlight, Err queryFailure ) ->
Err (ViewAssertionFailed ("ProgramTest." ++ functionName) (Html.map (\_ -> ()) (program.view state.currentModel)) highlight queryFailure)
)
programTest
assertComplexQuery : String -> (ComplexQuery (Query.Single msg) -> ComplexQuery ignored) -> ProgramTest model msg effect -> ProgramTest model msg effect
assertComplexQuery functionName complexQuery =
andThen <|
@ -844,29 +866,19 @@ simulateDomEvent findTarget ( eventName, eventValue ) =
andThen (simulateHelper ("simulateDomEvent " ++ String.Extra.escape eventName) findTarget ( eventName, eventValue ))
submitForm : ProgramTest model msg effect -> ProgramTest model msg effect
submitForm program_ =
--andThen (simulateHelper ("simulateDomEvent " ++ String.Extra.escape eventName) findTarget ( eventName, eventValue ))
program_
|> andThen
(\state testState ->
case onFormSubmit program_ of
Just onFormSubmitFn ->
let
_ =
Debug.log "-> Submit form" ""
in
testState
|> TestState.queueEffect state
(onFormSubmitFn
testState.domFields
)
|> Result.andThen (TestState.drain state)
submitFormInner : ProgramTest model msg effect -> Program model msg effect sub -> TestState model msg effect -> Result Failure (TestState model msg effect)
submitFormInner programTest state testState =
case onFormSubmit programTest of
Just onFormSubmitFn ->
testState
|> TestState.queueEffect state
(onFormSubmitFn
testState.domFields
)
|> Result.andThen (TestState.drain state)
Nothing ->
--Ok state
Debug.todo ""
)
Nothing ->
Ok testState
{-| Simulates clicking a button.
@ -884,7 +896,7 @@ clickButton buttonText =
functionDescription =
"clickButton " ++ String.Extra.escape buttonText
checks : List ( String, ComplexQuery (Query.Single msg) -> ComplexQuery msg )
checks : List ( String, ComplexQuery (Query.Single msg) -> ComplexQuery (ComplexQuery.MsgOrSubmit msg) )
checks =
[ ( "<button> with text"
, findNotDisabled (Just "find button")
@ -894,6 +906,7 @@ clickButton buttonText =
, Selector.containing [ Selector.text buttonText ]
]
>> ComplexQuery.simulate Test.Html.Event.click
>> ComplexQuery.map ComplexQuery.SubmitMsg
)
, ( "<button> with <img> with alt text"
, findNotDisabled (Just "find button")
@ -906,6 +919,7 @@ clickButton buttonText =
]
]
>> ComplexQuery.simulate Test.Html.Event.click
>> ComplexQuery.map ComplexQuery.SubmitMsg
)
, ( "<button> with aria-label"
, findNotDisabled (Just "find button")
@ -915,6 +929,7 @@ clickButton buttonText =
, Selector.attribute (Html.Attributes.attribute "aria-label" buttonText)
]
>> ComplexQuery.simulate Test.Html.Event.click
>> ComplexQuery.map ComplexQuery.SubmitMsg
)
, ( "any element with role=\"button\" and text"
, findNotDisabled (Just "find button")
@ -930,6 +945,7 @@ clickButton buttonText =
, Selector.containing [ Selector.text buttonText ]
]
>> ComplexQuery.simulate Test.Html.Event.click
>> ComplexQuery.map ComplexQuery.SubmitMsg
)
, ( "any element with role=\"button\" and aria-label"
, findNotDisabled (Just "find button")
@ -945,6 +961,7 @@ clickButton buttonText =
, Selector.attribute (Html.Attributes.attribute "aria-label" buttonText)
]
>> ComplexQuery.simulate Test.Html.Event.click
>> ComplexQuery.map ComplexQuery.SubmitMsg
)
, ( "<form> with submit <button> with text"
, ComplexQuery.findButNot (Just "find form")
@ -982,7 +999,7 @@ clickButton buttonText =
]
]
}
>> ComplexQuery.simulate Test.Html.Event.submit
>> ComplexQuery.simulateSubmit
)
, ( "<form> with submit <input> with value"
, ComplexQuery.findButNot (Just "find form")
@ -1015,11 +1032,11 @@ clickButton buttonText =
]
]
}
>> ComplexQuery.simulate Test.Html.Event.submit
>> ComplexQuery.simulateSubmit
)
]
in
simulateComplexQuery functionDescription
simulateComplexQueryOrSubmit functionDescription
(ComplexQuery.exactlyOneOf "Expected one of the following to exist" checks)

View File

@ -1,4 +1,4 @@
module ProgramTest.ComplexQuery exposing (ComplexQuery, Failure(..), FailureContext, FailureContext1(..), Highlight, Priority, check, exactlyOneOf, find, findButNot, run, simulate, succeed)
module ProgramTest.ComplexQuery exposing (ComplexQuery, Failure(..), FailureContext, FailureContext1(..), Highlight, MsgOrSubmit(..), Priority, check, exactlyOneOf, find, findButNot, map, run, simulate, simulateSubmit, succeed)
import Json.Encode as Json
import ProgramTest.TestHtmlHacks as TestHtmlHacks
@ -14,6 +14,11 @@ type ComplexQuery a
= QueryResult State Highlight (List FailureContext1) (Result Failure a)
map : (a -> b) -> ComplexQuery a -> ComplexQuery b
map function (QueryResult state highlight failures result) =
QueryResult state highlight failures (Result.map function result)
succeed : a -> ComplexQuery a
succeed a =
QueryResult initState Set.empty [] (Ok a)
@ -279,6 +284,31 @@ findButNot description highlight { good, bads, onError } prev =
|> checkBads (List.length good) bads
type MsgOrSubmit msg
= SubmitMsg msg
| Submit
simulateSubmit : ComplexQuery (Query.Single msg) -> ComplexQuery (MsgOrSubmit msg)
simulateSubmit prev =
case prev of
QueryResult state prevHighlight prevContext (Err err) ->
QueryResult state prevHighlight prevContext (Err err)
QueryResult state prevHighlight prevContext (Ok source) ->
case
source
|> Test.Html.Event.simulate Test.Html.Event.submit
|> Test.Html.Event.toResult
of
Err message ->
-- TODO include details of the form to submit, etc.? Or gather that context elsewhere?
QueryResult state prevHighlight prevContext (Ok Submit)
Ok msg ->
QueryResult state prevHighlight prevContext (Ok (SubmitMsg msg))
simulate : ( String, Json.Value ) -> ComplexQuery (Query.Single msg) -> ComplexQuery msg
simulate event prev =
case prev of

View File

@ -21,7 +21,7 @@ suite =
PagesTest.start "/login" mockData
|> ProgramTest.ensureBrowserUrl (Expect.equal "https://localhost:1234/login")
|> ProgramTest.fillInDom "name" "Name" "Jane"
|> ProgramTest.submitForm
|> ProgramTest.clickButton "Login"
|> ProgramTest.ensureBrowserUrl (Expect.equal "https://localhost:1234/greet")
|> ProgramTest.ensureViewHas
[ text "Hello Jane!"
@ -32,7 +32,7 @@ suite =
PagesTest.start "/login" mockData
|> ProgramTest.ensureBrowserUrl (Expect.equal "https://localhost:1234/login")
|> ProgramTest.fillInDom "name" "Name" "Jane"
|> ProgramTest.submitForm
|> ProgramTest.clickButton "Login"
|> ProgramTest.ensureBrowserUrl (Expect.equal "https://localhost:1234/greet")
|> ProgramTest.routeChange "/login"
|> ProgramTest.ensureBrowserUrl (Expect.equal "https://localhost:1234/login")