At work we use Selenium and BrowserStack for end-to-end tests in C#. How much work is it to connect Playwright to BrowserStack?
Prerequisites
For BrowserStack we need an account that can run code on the Automate feature. If you do not already have an account, you can create one for free and test BrowserStack.
Preparation
We need the credentials of our account to access BrowserStack. I do not like to add credentials into my code and prefer a .env file (as I do in my Python applications). For C# I tried dotenv.net and created a .env file in my project.
Do not forget to add .env
to your .gitignore!
If the .env
file is no longer tracked in Git, you can add your username and the access key for BrowserStack:
username=****
accessKey=****
Connect to BrowserStack
You find all the code you need to connect to BrowserStack in their documentation. I only changed the code to include the .env
values and set the locale to "en-GB"
to run my browser in English instead of Dutch.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
private static async Task BrowserStack() { DotEnv.Load(); var envVars = DotEnv.Read(); using var playwright = await Playwright.CreateAsync(); Dictionary<string, string> browserstackOptions = new Dictionary<string, string>(); browserstackOptions.Add("name", "Playwright first sample test"); browserstackOptions.Add("build", "playwright-dotnet-1"); browserstackOptions.Add("os", "osx"); browserstackOptions.Add("os_version", "catalina"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, // `playwright-firefox` and `playwright-webkit` browserstackOptions.Add("browser", "chrome"); browserstackOptions.Add("browserstack.username", envVars["username"]); browserstackOptions.Add("browserstack.accessKey", envVars["accessKey"]); string capsJson = JsonConvert.SerializeObject(browserstackOptions); string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capsJson); await using var browser = await playwright.Chromium.ConnectAsync(cdpUrl); var page = await browser.NewPageAsync(new BrowserNewPageOptions() { Locale = "en-GB" }); try { await page.GotoAsync("https://www.google.com/"); await page.GetByRole(AriaRole.Button, new() { NameString = "Accept all" }).ClickAsync(); await page.WaitForURLAsync("https://www.google.com/"); await page.Locator("[aria-label='Search']").ClickAsync(); await page.FillAsync("[aria-label='Search']", "BrowserStack"); await page.Locator("[aria-label='Google Search'] >> nth=0").ClickAsync(); var title = await page.TitleAsync(); if (title == "BrowserStack - Google Search") { // following line of code is responsible for marking the status of the // test on BrowserStack as 'passed'. You can use this code in your after // hook after each test await MarkTestStatus("passed", "Title matched", page); } else { await MarkTestStatus("failed", "Title did not match", page); } } catch (Exception err) { await MarkTestStatus("failed", err.Message, page); } await browser.CloseAsync(); } public static async Task MarkTestStatus(string status, string reason, IPage page) { await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\":" + " {\"status\":\"" + status + "\", \"reason\": \"" + reason + "\"}}"); } |
The MarkTestStatus() method tells BrowserStack if your test was successful or not. That way our tests are marked accordingly in the BrowserStack Dashboard:
BrowserStack records a video for each of our tests, just as it does with Selenium.
Attention: Playwright 1.27.2 marks the build status on BrowserStack, but 1.28 only gives an unmarked status for the same code. If that part does not work for you, wait for a newer version.
Next
Running Playwright on BrowserStack required a bit of copy and paste and worked surprisingly well. For NUnit we best create our own class and inherit from that instead of PageTest. Next week we try to run Playwright on Selenium Grid to see if we get a similar experience.