diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..386c5c1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+bin
+obj
+.DS_Store
+.vs
+local.log
+BrowserStackLocal.exe
diff --git a/PlaywrightDotnetTests.csproj b/PlaywrightDotnetTests.csproj
new file mode 100644
index 0000000..2aa95a6
--- /dev/null
+++ b/PlaywrightDotnetTests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/PlaywrightDotnetTests.sln b/PlaywrightDotnetTests.sln
new file mode 100644
index 0000000..f5b1c1a
--- /dev/null
+++ b/PlaywrightDotnetTests.sln
@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.810.14
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaywrightDotnetTests", "PlaywrightDotnetTests.csproj", "{DAF08465-4D94-4B65-AB98-C0965E732F81}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DAF08465-4D94-4B65-AB98-C0965E732F81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DAF08465-4D94-4B65-AB98-C0965E732F81}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DAF08465-4D94-4B65-AB98-C0965E732F81}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DAF08465-4D94-4B65-AB98-C0965E732F81}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {7FAE2CF5-37B9-4938-B8F6-00B4DD9EFE94}
+ EndGlobalSection
+EndGlobal
diff --git a/PlaywrightLocalTest.cs b/PlaywrightLocalTest.cs
new file mode 100644
index 0000000..5030481
--- /dev/null
+++ b/PlaywrightLocalTest.cs
@@ -0,0 +1,152 @@
+using Microsoft.Playwright;
+using System.Threading.Tasks;
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using BrowserStack;
+using System.Collections;
+
+class PlaywrightLocalTest
+{
+
+ public static async Task main(string[] args)
+ {
+ // The following capability variables contains the set of os/browser environments where you want to run your tests. You can choose to alter this list according to your needs. Read more on https://browserstack.com/docs/automate/playwright/browsers-and-os
+ try
+ {
+ ArrayList capabilitiesList = getCapabilitiesList();
+ Task[] taskList = new Task[capabilitiesList.Count];
+
+ Local local = new Local();
+
+ List> bsLocalArgs = new List>();
+ bsLocalArgs.Add(new KeyValuePair("key", "BROWSERSTACK_ACCESS_KEY"));
+ bsLocalArgs.Add(new KeyValuePair("localIdentifier", "Test123"));
+
+ local.start(bsLocalArgs);
+
+ for (int i = 0; i < capabilitiesList.Count; i++)
+ {
+ string capsJson;
+ capsJson = JsonConvert.SerializeObject(capabilitiesList[i]);
+ var task = Executetestwithcaps(capsJson);
+ taskList[i] = task;
+ }
+
+ await Task.WhenAll(taskList);
+ local.stop();
+
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+
+ static ArrayList getCapabilitiesList()
+ {
+ ArrayList capabilitiesList = new ArrayList();
+
+ string? BROWSERSTACK_USERNAME = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
+ string? BROWSERSTACK_ACCESS_KEY = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
+
+ Dictionary windowsChromeCap = new Dictionary();
+ windowsChromeCap.Add("browser", "chrome"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
+ windowsChromeCap.Add("browser_version", "latest");
+ windowsChromeCap.Add("os", "Windows");
+ windowsChromeCap.Add("os_version", "11");
+ windowsChromeCap.Add("build", "browserstack-build-1");
+ windowsChromeCap.Add("buildTag", "Regression");
+ windowsChromeCap.Add("browserstack.debug", "true");
+ windowsChromeCap.Add("browserstack.networkLogs", "true");
+ windowsChromeCap.Add("browserstack.console", "info");
+ windowsChromeCap.Add("browserstack.local", "true");
+ windowsChromeCap.Add("browserstack.localIdentifier", "Test123");
+ windowsChromeCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ windowsChromeCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(windowsChromeCap);
+
+
+ Dictionary venturaWebkitCap = new Dictionary();
+ venturaWebkitCap.Add("browser", "playwright-webkit"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
+ venturaWebkitCap.Add("browser_version", "latest");
+ venturaWebkitCap.Add("os", "osx");
+ venturaWebkitCap.Add("os_version", "Ventura");
+ venturaWebkitCap.Add("build", "browserstack-build-1");
+ venturaWebkitCap.Add("buildTag", "Regression");
+ venturaWebkitCap.Add("browserstack.debug", "true");
+ venturaWebkitCap.Add("browserstack.networkLogs", "true");
+ venturaWebkitCap.Add("browserstack.console", "info");
+ venturaWebkitCap.Add("browserstack.local", "true");
+ venturaWebkitCap.Add("browserstack.localIdentifier", "Test123");
+ venturaWebkitCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ venturaWebkitCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(venturaWebkitCap);
+
+ Dictionary windowsFirefoxCap = new Dictionary();
+ windowsFirefoxCap.Add("browser", "playwright-firefox"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`\
+ windowsFirefoxCap.Add("browser_version", "latest");
+ windowsFirefoxCap.Add("os", "Windows");
+ windowsFirefoxCap.Add("os_version", "11");
+ windowsFirefoxCap.Add("build", "browserstack-build-1");
+ windowsFirefoxCap.Add("buildTag", "Regression");
+ windowsFirefoxCap.Add("browserstack.debug", "true");
+ windowsFirefoxCap.Add("browserstack.networkLogs", "true");
+ windowsFirefoxCap.Add("browserstack.console", "info");
+ windowsFirefoxCap.Add("browserstack.local", "true");
+ windowsFirefoxCap.Add("browserstack.localIdentifier", "Test123");
+ windowsFirefoxCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ windowsFirefoxCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(windowsFirefoxCap);
+
+ return capabilitiesList;
+ }
+
+ public static async Task Executetestwithcaps(string capabilities)
+ {
+ using var playwright = await Playwright.CreateAsync();
+ string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capabilities);
+
+ await using var browser = await playwright.Chromium.ConnectAsync(cdpUrl);
+ var page = await browser.NewPageAsync();
+ try
+ {
+ await MarkTestName(page);
+ page.SetDefaultTimeout(60000);
+ await page.GotoAsync("http://localhost:3000/");
+ await page.Locator("#\\31 > .shelf-item__buy-btn").ClickAsync();
+
+ var text = await page.Locator("#__next > div > div > div.float-cart.float-cart--open > div.float-cart__content > div.float-cart__shelf-container > div > div.shelf-item__details > p.title").TextContentAsync();
+
+ if (text == "iPhone 12")
+ {
+ await MarkTestStatus("passed", "Item Added", page);
+ }
+ else
+ {
+ await MarkTestStatus("failed", "Test Failed", page);
+ }
+ }
+ catch (Exception err)
+ {
+ Console.WriteLine(err.Message);
+ await MarkTestStatus("failed", "Something Failed", 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 + "\"}}");
+ }
+
+ public static async Task MarkTestName(IPage page)
+ {
+ string? thisFile = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();
+ string[] result = thisFile.Split(new char[] { '/' });
+ string[] filenameResult = result.Last().Split(new char[] { '.' });
+ string? testName = filenameResult.First();
+
+ await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionName\", \"arguments\": {\"name\":\"" + testName + "\"}}");
+ }
+}
diff --git a/PlaywrightParallelTest.cs b/PlaywrightParallelTest.cs
new file mode 100644
index 0000000..1d715fe
--- /dev/null
+++ b/PlaywrightParallelTest.cs
@@ -0,0 +1,133 @@
+using Microsoft.Playwright;
+using System;
+using System.Threading;
+using Newtonsoft.Json;
+using System.Collections;
+
+class PlaywrightParallelTest
+{
+ public static async Task main(string[] args)
+ {
+ // The following capability variables contains the set of os/browser environments where you want to run your tests. You can choose to alter this list according to your needs. Read more on https://browserstack.com/docs/automate/playwright/browsers-and-os
+ try
+ {
+ ArrayList capabilitiesList = getCapabilitiesList();
+ Task[] taskList = new Task[capabilitiesList.Count];
+
+ for (int i = 0; i < capabilitiesList.Count; i++)
+ {
+ string capsJson;
+ capsJson = JsonConvert.SerializeObject(capabilitiesList[i]);
+ var task = Executetestwithcaps(capsJson);
+ taskList[i] = task;
+ }
+
+ await Task.WhenAll(taskList);
+
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e);
+ }
+ }
+ static ArrayList getCapabilitiesList()
+ {
+ ArrayList capabilitiesList = new ArrayList();
+
+ string? BROWSERSTACK_USERNAME = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
+ string? BROWSERSTACK_ACCESS_KEY = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
+
+
+ Dictionary windowsChromeCap = new Dictionary();
+ windowsChromeCap.Add("browser", "chrome"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
+ windowsChromeCap.Add("browser_version", "latest");
+ windowsChromeCap.Add("os", "Windows");
+ windowsChromeCap.Add("os_version", "11");
+ windowsChromeCap.Add("build", "browserstack-build-1");
+ windowsChromeCap.Add("buildTag", "Regression");
+ windowsChromeCap.Add("browserstack.debug", "true");
+ windowsChromeCap.Add("browserstack.networkLogs", "true");
+ windowsChromeCap.Add("browserstack.console", "info");
+ windowsChromeCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ windowsChromeCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(windowsChromeCap);
+
+
+ Dictionary venturaWebkitCap = new Dictionary();
+ venturaWebkitCap.Add("browser", "playwright-webkit"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`
+ venturaWebkitCap.Add("browser_version", "latest");
+ venturaWebkitCap.Add("os", "osx");
+ venturaWebkitCap.Add("os_version", "Ventura");
+ venturaWebkitCap.Add("build", "browserstack-build-1");
+ venturaWebkitCap.Add("buildTag", "Regression");
+ venturaWebkitCap.Add("browserstack.debug", "true");
+ venturaWebkitCap.Add("browserstack.networkLogs", "true");
+ venturaWebkitCap.Add("browserstack.console", "info");
+ venturaWebkitCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ venturaWebkitCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(venturaWebkitCap);
+
+ Dictionary windowsFirefoxCap = new Dictionary();
+ windowsFirefoxCap.Add("browser", "playwright-firefox"); // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit`\
+ windowsFirefoxCap.Add("browser_version", "latest");
+ windowsFirefoxCap.Add("os", "Windows");
+ windowsFirefoxCap.Add("os_version", "11");
+ windowsFirefoxCap.Add("build", "browserstack-build-1");
+ windowsFirefoxCap.Add("buildTag", "Regression");
+ windowsFirefoxCap.Add("browserstack.debug", "true");
+ windowsFirefoxCap.Add("browserstack.networkLogs", "true");
+ windowsFirefoxCap.Add("browserstack.console", "info");
+ windowsFirefoxCap.Add("browserstack.username", BROWSERSTACK_USERNAME);
+ windowsFirefoxCap.Add("browserstack.accessKey", BROWSERSTACK_ACCESS_KEY);
+ capabilitiesList.Add(windowsFirefoxCap);
+
+ return capabilitiesList;
+ }
+
+ //Executetestwithcaps function takes capabilities from 'SampleTestCase' function and executes the test
+ public static async Task Executetestwithcaps(string capabilities)
+ {
+ using var playwright = await Playwright.CreateAsync();
+ string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capabilities);
+
+ await using var browser = await playwright.Chromium.ConnectAsync(cdpUrl);
+ var page = await browser.NewPageAsync();
+ try
+ {
+ await MarkTestName(page);
+ page.SetDefaultTimeout(60000);
+ await page.GotoAsync("https://bstackdemo.com/");
+ await page.Locator("#\\31 > .shelf-item__buy-btn").ClickAsync();
+
+ var text = await page.Locator("#__next > div > div > div.float-cart.float-cart--open > div.float-cart__content > div.float-cart__shelf-container > div > div.shelf-item__details > p.title").TextContentAsync();
+
+ if (text == "iPhone 12")
+ {
+ await MarkTestStatus("passed", "Item Added", page);
+ }
+ else
+ {
+ await MarkTestStatus("failed", "Test Failed", page);
+ }
+ }
+ catch (Exception err)
+ {
+ Console.WriteLine(err.Message);
+ await MarkTestStatus("failed", "Something Failed", 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 + "\"}}");
+ }
+ public static async Task MarkTestName(IPage page)
+ {
+ string? thisFile = new System.Diagnostics.StackTrace(true).GetFrame(0).GetFileName();
+ string[] result = thisFile.Split(new char[] { '/' });
+ string[] filenameResult = result.Last().Split(new char[] { '.' });
+ string? testName = filenameResult.First();
+
+ await page.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionName\", \"arguments\": {\"name\":\"" + testName + "\"}}");
+ }
+}
diff --git a/Program.cs b/Program.cs
new file mode 100644
index 0000000..bcd3417
--- /dev/null
+++ b/Program.cs
@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+
+namespace PlaywrightTesting
+{
+ class Program
+ {
+ public static async Task Main(string[] args)
+ {
+ switch (args[0])
+ {
+ case "parallel":
+ Console.WriteLine("Running Parallel Test");
+ await PlaywrightParallelTest.main(args);
+ break;
+ case "local":
+ Console.WriteLine("Running Local Test");
+ await PlaywrightLocalTest.main(args);
+ break;
+ default:
+ Console.WriteLine("Running Single Test by default");
+ await PlaywrightParallelTest.main(args);
+ break;
+ }
+ }
+ }
+}
diff --git a/README.md b/README.md
index d381fe3..8f317cd 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,39 @@
-# csharp-playwright-browserstack
-Creating a sample repo for different Playwright languages and runners
+# Testing with playwright-browserstack in C#
+
+[Playwright](https://playwright.dev/dotnet/) Integration with BrowserStack.
+
+
+
+## Setup
+
+* Clone the repo and run `cd csharp-playwright-browserstack`
+* Set `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY` as environment variables with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings)
+* Run `dotnet build`
+
+## Running your tests
+
+- To run a parallel test, run command `dotnet run parallel`
+
+ ### [Web application hosted on internal environment] Running your tests on BrowserStack using BrowserStackLocal
+
+ #### Prerequisites
+
+ - Clone the [BrowserStack demo application](https://github.com/browserstack/browserstack-demo-app) repository.
+ ```sh
+ git clone https://github.com/browserstack/browserstack-demo-app
+ ```
+ - Please follow the README.md on the BrowserStack demo application repository to install and start the dev server on localhost.
+ - Note: You may need to provide additional BrowserStackLocal arguments to successfully connect your localhost environment with BrowserStack infrastructure. (e.g if you are behind firewalls, proxy or VPN).
+ - Further details for successfully creating a BrowserStackLocal connection can be found here:
+
+ - [Local Testing with Automate](https://www.browserstack.com/local-testing/automate)
+
+ #### Running the test using Local Testing:
+ - You can then run the sample Local test using `dotnet run local`
+
+
+## Notes
+* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
+
+## Additional Resources
+* [Documentation for writing Automate test scripts with BrowserStack](https://www.browserstack.com/docs/automate/playwright)