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.
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.
You 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
withSession2 as convenience functions for
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.
You 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
This package makes it easy to run Selenium tests in the background, using either Xvfb or the headless mode of your browser.
Many browsers now have the ability to natively run in headless mode. For example, passing these modified
introduceWebDriver will run using headless Firefox.
Xvfb 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.
Xvfb and ffmpeg must be installed in the test environment to use these features.
As discussed above, recording video doesn't work in headless (
--headless) mode. It requires normal (
--current) or Xvfb (
Using 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
If you use Sandwich's runSandwichWithCommandLineArgs in conjunction with introduceWebDriverOptions, then you can take advantage of the built-in command line arguments
--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:
Because every Sandwich test tree has an associated directory in the filesystem, it's easy to capture screenshots during a test.
By 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.
If 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
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
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
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.