A Lamdera package. It is not on package.elm-lang.org: the Lamdera compiler provides it, from static.lamdera.com, so lamdera install works and elm install does not.
Group together multiple end to end tests so they are easier to find.
import Effect.Test
Effect.Test.testGroup
"Login tests"
[ Effect.Test.start "Login via homepage" ...
, Effect.Test.start "Login via promotional link" ...
]Configure the end to end test before starting it
import Backend
import Effect.Test
import Frontend
import Test exposing (Test)
import Url
config =
{ frontendApp = Frontend.appFunctions
, backendApp = Backend.appFunctions
, handleHttpRequest = always Effect.Test.UnhandledHttpRequest
, handlePortToJs = always Nothing
, handleFileUpload = always Effect.Test.UnhandledFileUpload
, handleMultipleFilesUpload = always Effect.Test.UnhandledMultiFileUpload
, domain = unsafeUrl "https://my-app.lamdera.app"
}
test : Test
test =
Effect.Test.start "myButton is clickable"
|> Effect.Test.connectFrontend
sessionId0
myDomain
{ width = 1920, height = 1080 }
(\( state, frontendActions ) ->
state
|> frontendActions.click { htmlId = "myButton" }
)
|> Effect.Test.toTest
unsafeUrl : String -> Url
unsafeUrl urlText =
case Url.fromString urlText of
Just url ->
url
Nothing ->
unsafeUrl urlTextAdd a frontend client to the end to end test
import Effect.Test
import Test exposing (Test)
import Url
testApp =
Effect.Test.testApp
Frontend.appFunctions
Backend.appFunctions
(always NetworkError_)
(always Nothing)
(always Nothing)
(unsafeUrl "https://my-app.lamdera.app")
test : Test
test =
testApp "myButton is clickable"
|> Effect.Test.connectFrontend
sessionId0
"/"
{ width = 1920, height = 1080 }
(\( state, frontendActions ) ->
state
|> frontendActions.click { htmlId = "myButton" }
)
|> Effect.Test.toTest
unsafeUrl : String -> Url
unsafeUrl urlText =
case Url.fromString urlText of
Just url ->
url
Nothing ->
unsafeUrl urlTextThe response for an http request.
Note that if the http request was expecting one form of data (for example json) and the response contains a different type of data (for example a String) then the data will automatically be converted.
The exception to this is Texture. If the request is expecting a Texture (this will only happen with Effect.WebGL.Texture.load and Effect.WebGL.Texture.loadWith) then the response has to contain a Texture if you want the request to succeed.
In other words, sending the Bytes that represent that texture won't work.
Who made this http request?
What a client sent over a port that carries Bytes rather than JSON.
File data for when simulating a user uploading a file via Effect.File.Select.file or Effect.File.Select.files
Possible simulated user actions for when Effect.File.Select.file is triggered.
Possible simulated user actions for when Effect.File.Select.files is triggered.
Create a file upload containing binary data
Create a file upload containing text data
FrontendActions contains the possible functions we can call on the client we just connected.
import Effect.Test
import Test exposing (Test)
import Url
config =
{ frontendApp = Frontend.appFunctions
, backendApp = Backend.appFunctions
, handleHttpRequest = always Effect.Test.UnhandledHttpRequest
, handlePortToJs = always Nothing
, handleFileUpload = always Effect.Test.UnhandledFileUpload
, handleMultipleFilesUpload = always Effect.Test.UnhandledMultiFileUpload
, domain = unsafeUrl "https://my-app.lamdera.app"
}
test : Test
test =
Effect.Test.start "myButton is clickable"
|> Effect.Test.connectFrontend
sessionId0
myDomain
{ width = 1920, height = 1080 }
(\( state, frontendActions ) ->
-- frontendActions is a record we can use on this specific frontend we just connected
state
|> frontendActions.click { htmlId = "myButton" }
)
|> Effect.Test.toTest
unsafeUrl : String -> Url
unsafeUrl urlText =
case Url.fromString urlText of
Just url ->
url
Nothing ->
unsafeUrl urlTextDirectly trigger an update on the backend. Normally you shouldn't need to do this as things like Time.every and completed tasks will generate updates automatically.
Similar to wait but this will not trigger any Browser.onAnimationFrame or Time.every subscriptions.
This is useful if you need to move the clock forward a week and it would take too long to simulate it perfectly.
All actions and events that happen within this group can be minimized in the UI. Useful for organizing different parts of your end to end test.
Sometimes you need to decide what should happen next based on some current state. To do that you can write something like this:
import Effect.Test
Effect.Test.andThen
100 -- Simulate 100 milliseconds before performing this action
(\data ->
case List.filterMap isLoginEmail data.httpRequests |> List.head of
Just loginEmail ->
[ Effect.Test.connectFrontend
100
sessionIdFromEmail
"/user-overview"
(\clientIdFromEmail ->
[ ... ]
)
]
Nothing ->
[ Effect.Test.checkState (\_ -> Err "Should have gotten a login email") ]
)Send data to a websocket listener on the backend.
Simulate the server closing a websocket that the backend opened, delivering the close
event (with the given reason) to the backend's websocket onClose listeners. This is the
close-event counterpart to websocketSendString, which delivers to the onData listeners.
Use it to test how the backend reacts to an unexpected websocket close, such as an
authentication failure.
How many milliseconds to delay something by
Make the test fail if it doesn't seem some condition.
Make the test fail if the backend model doesn't seem some condition.
Get all snapshots from a test. This can be used with Effect.Snapshot.uploadSnapshots to perform visual regression testing.
Sometimes it's hard to tell what's going on in an end to end test. One way to make this easier to use the viewer function. It's like a test runner for your browser that also lets you see the frontend of an app as simulated inputs are being triggered.
View your end-to-end tests in a elm reactor style app.
main =
viewer [{- End to end tests go here -}]View your end-to-end tests in a elm reactor style app.
import Effect.Test
main =
Effect.Test.viewerWith
(\image jsonData ->
[{- End to end tests go here -}]
)
|> Effect.Test.addBytesFile "/test.png"
|> Effect.Test.addBytesFile "/data.json"
|> Effect.Test.startViewerView your end-to-end tests in a elm reactor style app.
import Effect.Test
main =
Effect.Test.viewerWith
(\image jsonData ->
[{- End to end tests go here -}]
)
|> Effect.Test.addBytesFile "/test.png"
|> Effect.Test.addBytesFile "/data.json"
|> Effect.Test.startViewerAdd a file containing text data to your tests.
import Effect.Test
main =
Effect.Test.viewerWith
(\text jsonData ->
[{- End to end tests go here -}]
)
|> Effect.Test.addStringFile "/test.txt"
|> Effect.Test.addStringFile "/data.json"
|> Effect.Test.startViewerAdd multiple files containing text data to your tests.
import Effect.Test
main =
Effect.Test.viewerWith
(\dict ->
[{- End to end tests go here -}]
)
|> Effect.Test.addStringFiles [ "/test.txt", "/data.json" ]
|> Effect.Test.startViewerAdd a file containing binary data to your tests.
import Effect.Test
main =
Effect.Test.viewerWith
(\image jsonData ->
[{- End to end tests go here -}]
)
|> Effect.Test.addBytesFile "/test.png"
|> Effect.Test.addBytesFile "/data.json"
|> Effect.Test.startViewerAdd multiple files containing binary data to your tests.
import Effect.Test
main =
Effect.Test.viewerWith
(\dict ->
[{- End to end tests go here -}]
)
|> Effect.Test.addBytesFiles [ "/test.png", "/data.json" ]
|> Effect.Test.startViewerAdd a file containing data for a Effect.WebGL.Texture.Texture to your tests. Right now this is performed with HTTP get requests which means you can only access files in /public (or make get requests to other websites but this isn't recommended)
import Effect.Test
main =
Effect.Test.viewerWith
(\texture ->
[{- End to end tests go here -}]
)
|> Effect.Test.addTextureFile "/texture.png"
|> Effect.Test.startViewerAdd a file containing data for a Effect.WebGL.Texture.Texture to your tests. Right now this is performed with HTTP get requests which means you can only access files in /public (or make get requests to other websites but this isn't recommended)
import Effect.Test
main =
Effect.Test.viewerWith
(\texture ->
[{- End to end tests go here -}]
)
|> Effect.Test.addTextureFileWithOptions
-- WebGL texture options go here
"/texture.png"
|> Effect.Test.startViewerAdd a file containing data for a Effect.WebGL.Texture.Texture to your tests. Right now this is performed with HTTP get requests which means you can only access files in /public (or make get requests to other websites but this isn't recommended)
import Effect.Test
main =
Effect.Test.viewerWith
(\dict ->
[{- End to end tests go here -}]
)
|> Effect.Test.addTextures [ "/cat.png", "/dog.jpg" ]
|> Effect.Test.startViewerAdd a file containing data for a Effect.WebGL.Texture.Texture to your tests. Right now this is performed with HTTP get requests which means you can only access files in /public (or make get requests to other websites but this isn't recommended)
import Effect.Test
main =
Effect.Test.viewerWith
(\dict ->
[{- End to end tests go here -}]
)
|> Effect.Test.addTexturesWithOptions Effect.WebGL.Texture.defaultOptions [ "/cat.png", "/dog.jpg" ]
|> Effect.Test.startViewerIf you want to just run the end to end tests to make sure they work, or automatically check that they pass in your CI pipeline then you can setup a headless test runner with this function:
Create a headless test runner.
import Effect.Test
main =
Effect.Test.viewerWith
(\image jsonData ->
[{- End to end tests go here -}]
)
|> Effect.Test.addBytesFile "/test.png"
|> Effect.Test.addBytesFile "/data.json"
|> Effect.Test.startHeadlessMsg type for a headless end to end test runner.
Loads necessary files and returns a list of tests to run. Useful if you want to create your own test runner.
https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode. The default is DeltaPixels so it's not included here
Test config for a Browser.application app. See the examples folder for how to setup end-to-end tests for your app.
Test config for a Browser.document app. See the examples folder for how to setup end-to-end tests for your app.
Test config for a Browser.element app. See the examples folder for how to setup end-to-end tests for your app.
Test config for a Browser.sandbox app. See the examples folder for how to setup end-to-end tests for your app.
Start a end-to-end test