Selenium integration
Setting up Selenium tests normally requires manual work to obtain the Selenium server JAR file and a driver program for your browser, launch the server, and connect to the server with your client library. It can be error-prone to make sure the versions are compatible and everything runs smoothly.
The sandwich-webdriver
extension streamlines this by automatically downloading the latest compatible binary files and introducing the contexts you need to use the webdriver package within Sandwich. Here's how easy it is to get started:
To see a demo, try running stack run demo-webdriver
in the Sandwich repo.
#
Browser sessionsYou can start a Selenium session using the withSession
function. It accepts a string key representing the name of the session. Each time a new session name is seen, it will be created if it doesn't already exist.
The library provides withSession1
/withSession2
as convenience functions for withSession "browser1"
/withSession "browser2"
, but you can use your own keys if you need.
For example, the code below opens two windows with a different site in each.
#
Window positioningYou can use the functions in Test.Sandwich.WebDriver.Windows to arrange browser windows on the screen. This is useful when you want to watch two browsers simultaneously accessing a collaborative app.
The code below extends the previous example with window positioning. You can find this in the webdriver-positioning
demo.
#
Launching browsers in the backgroundThis package makes it easy to run Selenium tests in the background, using either Xvfb or the headless mode of your browser.
#
HeadlessMany browsers now have the ability to natively run in headless mode. For example, passing these modified WdOptions
to introduceWebDriver
will run using headless Firefox.
Alternatively, if you use Sandwich's runSandwichWithCommandLineArgs in conjunction with introduceWebDriverOptions, you can enable headless mode by passing --headless
.
#
XvfbXvfb can be used to run your browser on a separate, "virtual" X11 display, different from the one connected to your monitor. This was more useful before headless browser modes existed, but it's still important because it gives you the ability to record video. When a Selenium test is running on an Xvfb display, you can use ffmpeg to record videos of the test runs for later examination.
Xvfb mode can be configured manually just like headless mode.
Or, if you use Sandwich's runSandwichWithCommandLineArgs in conjunction with introduceWebDriverOptions, you can enable Xvfb mode by passing --xvfb
.
note
Xvfb and ffmpeg must be installed in the test environment to use these features.
#
Recording videosAs discussed above, recording video doesn't work in headless (--headless
) mode. It requires normal (--current
) or Xvfb (--xvfb
) mode.
#
ManuallyUsing the methods in Test.Sandwich.WebDriver.Video, you can wrap arbitrary sections of a test in video recording. The example below can be found in the webdriver-video
demo.
You can also wrap video around multiple tests by using the around node, or around individual tests using aroundEach, etc.
#
With command line optionsIf you use Sandwich's runSandwichWithCommandLineArgs in conjunction with introduceWebDriverOptions, then you can take advantage of the built-in command line arguments --individual-videos
and --error-videos
. The former will record videos of every individual test and store them in the corresponding folder on disk. The latter will do the same, but will delete the videos if the test ran successfully, so you only end up with error videos.
You can try this out by running:
#
ScreenshotsBecause every Sandwich test tree has an associated directory in the filesystem, it's easy to capture screenshots during a test.
#
Custom Selenium and driver binariesBy default, the WebDriver machinery will obtain the Selenium JAR and driver binaries from the web automatically. However, you can also manually configure which ones are used by passing a disk path.
Alternatively, you can pass DownloadSeleniumFrom with a URL to download, and similarly for the other options. Please see the Haddocks for more details.
#
Running tests in parallel with a webdriver poolIf you have a lot of test files, you probably want to run them in parallel so the test suite finishes faster. However, you probably don't want to run them all in parallel, since running that many browser sessions could bog down your CI machine. A good solution is to use Data.Pool to introduce a fixed-size pool of reusable WebDriver contexts.
You can follow along with this example in the webdriver-pool
demo.
The first thing we need to do is come up with a label and introduce a pool of the desired size.
There's some plumbing here because we want to pipe the command line options through. The important part is at the end, where we make a pool that knows how to allocate and deallocate WebDrivers using the lower-level allocateWebDriver'
and cleanupWebDriver'
functions.
Next, we make another introduce node to claim a WebDriver from the pool.
There's also some plumbing here where we tweak the node options of this to play better with test timing. This code obtains the pool context, then claims a WebDriver to pass to its sub-nodes. It also cleans up at the end by calling closeAllSessions
.
Having written these functions, we can finally write our tests. The following will run all the tests, up to four at a time, re-using the WebDrivers among them.
Of course, in real use you probably want to introduce different tests to run in parallel. You can use Test Discovery to automatically generate them.