Browser Testing with F# Canopy
Three years ago, I attended a .NET Users meetup where the speaker demonstrated using F# and Canopy to run UI tests on his website. I found it extremely interesting as it was my introduction to F#, to Canopy, and even to web testing.
Canopy is a F# wrapper around the browser automation framework Selenium.
The below is how to get started with testing on the browser with F# and Canopy.
The requirements to get started with F# and Canopy for web testing are easy:
- Install Visual Studio Code
- .NET Core 2.1 SDK
- Google Chrome Browser (this isn’t required by anything other than this tutorial)
It’s not required, but I like to make development easier with this extension to VS Code.
Create a new folder, and then open powershell to that directory.
Run the following commands
dotnet new xunit -lang F# dotnet add package canopy dotnet add package Selenium.WebDriver.ChromeDriver
Open up Visual Studio Code and then open that folder. It should look something like this:
Click on that file “canopy-core.fsproj” (or whatever you named that folder).
Add the following line as shown in the xml below.
Notice the line is inside the PropertyGroup.
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> <RootNamespace>canopy_core</RootNamespace> <IsPackable>false</IsPackable> <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> </PropertyGroup> <ItemGroup> <Compile Include="Tests.fs" /> <Compile Include="Program.fs" /> </ItemGroup> <ItemGroup> <PackageReference Include="canopy" Version="2.0.1" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" /> <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="2.40.0" /> <PackageReference Include="xunit" Version="2.3.1" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" /> <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" /> </ItemGroup> </Project>
Now from powershell again in that directory, run this command to make sure the project compiles and gives a successful (but empty) test.
Open the file “Tests.fs” that was created automatically, and replace the contents of that file with this.
module Tests open Xunit open canopy.parallell [<Fact>] let ``Hightlight Olivercoding Image Test`` () = use browser = functions.start canopy.types.Chrome functions.url "https://www.olivercoding.com/" browser functions.highlight "#mainLogoDiv" browser functions.sleep 5 Assert.True(true)
From powershell again, rerun this command.
You should see Chrome open, and display this for 5 seconds before closing. Notice that the logo has been highlighted.
The output in powershell will look like this. All tests run successfully.
PS C:\Users\Daniel\Development\canopy-core> dotnet test C:\Users\Daniel\Development\canopy-core\canopy-core.fsproj : warning NU1701: Package 'canopy 2.0.1' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project. Build started, please wait... C:\Users\Daniel\Development\canopy-core\canopy-core.fsproj : warning NU1701: Package 'canopy 2.0.1' was restored using '.NETFramework,Version=v4.6.1' instead of the project target framework '.NETCoreApp,Version=v2.1'. This package may not be fully compatible with your project. Build completed. Test run for C:\Users\Daniel\Development\canopy-core\bin\Debug\netcoreapp2.1\canopy-core.dll(.NETCoreApp,Version=v2.1) Microsoft (R) Test Execution Command Line Tool Version 15.7.0 Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... Total tests: 1. Passed: 1. Failed: 0. Skipped: 0. Test Run Successful. Test execution time: 11.0285 Seconds PS C:\Users\Daniel\Development\canopy-core>
Let’s add a second test to that file “Tests.fs”. This test is an abbreviated version of the standard Canopy examples.
[<Fact>] let ``Test Canopy Page`` () = use browser = functions.start canopy.types.Chrome functions.url "http://lefthandedgoat.github.io/canopy/testpages/" browser Assert.Equal("Welcome", (functions.element "#welcome" browser).Text) Assert.Equal("button not clicked", (functions.element "#button_clicked" browser).Text) Assert.Equal("some Nonsense", (functions.element "#button_clicked" browser).Text)
Rerun the tests and an error will appear.
Starting test execution, please wait... [xUnit.net 00:00:13.9036790] Tests.Test Canopy Page [FAIL] Failed Tests.Test Canopy Page Error Message: Assert.Equal() Failure (pos 0) Expected: some Nonsense Actual: button not clicked (pos 0) Stack Trace: at Tests.Test Canopy Page() in C:\Users\Daniel\Development\canopy-core\Tests.fs:line 21 Total tests: 2. Passed: 1. Failed: 1. Skipped: 0. Test Run Failed. Test execution time: 14.3788 Seconds
Combining Web Testing with a Unit Testing framework makes writing tests for the browser easy. The next steps are to write tests, to write functions for login methods, and to include other browsers for testing. I hope you find testing Chrome browser with F# and Canopy as easy and as enjoyable as I do!