Skip to content

Commit ebbb2c7

Browse files
Merge pull request #3 from kamal-kaur04/csharp-pw-manual
CSharp Playwright - manual flow
2 parents fabc0b3 + 0e2f7ff commit ebbb2c7

File tree

13 files changed

+545
-0
lines changed

13 files changed

+545
-0
lines changed

.gitattributes

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
###############################################################################
2+
# Set default behavior to automatically normalize line endings.
3+
###############################################################################
4+
* text=auto
5+
6+
###############################################################################
7+
# Set default behavior for command prompt diff.
8+
#
9+
# This is need for earlier builds of msysgit that does not have it on by
10+
# default for csharp files.
11+
# Note: This is only used by command line
12+
###############################################################################
13+
#*.cs diff=csharp
14+
15+
###############################################################################
16+
# Set the merge driver for project and solution files
17+
#
18+
# Merging from the command prompt will add diff markers to the files if there
19+
# are conflicts (Merging from VS is not affected by the settings below, in VS
20+
# the diff markers are never inserted). Diff markers may cause the following
21+
# file extensions to fail to load in VS. An alternative would be to treat
22+
# these files as binary and thus will always conflict and require user
23+
# intervention with every merge. To do so, just uncomment the entries below
24+
###############################################################################
25+
#*.sln merge=binary
26+
#*.csproj merge=binary
27+
#*.vbproj merge=binary
28+
#*.vcxproj merge=binary
29+
#*.vcproj merge=binary
30+
#*.dbproj merge=binary
31+
#*.fsproj merge=binary
32+
#*.lsproj merge=binary
33+
#*.wixproj merge=binary
34+
#*.modelproj merge=binary
35+
#*.sqlproj merge=binary
36+
#*.wwaproj merge=binary
37+
38+
###############################################################################
39+
# behavior for image files
40+
#
41+
# image files are treated as binary by default.
42+
###############################################################################
43+
#*.jpg binary
44+
#*.png binary
45+
#*.gif binary
46+
47+
###############################################################################
48+
# diff behavior for common document formats
49+
#
50+
# Convert binary document formats to text before diffing them. This feature
51+
# is only available from the command line. Turn it on by uncommenting the
52+
# entries below.
53+
###############################################################################
54+
#*.doc diff=astextplain
55+
#*.DOC diff=astextplain
56+
#*.docx diff=astextplain
57+
#*.DOCX diff=astextplain
58+
#*.dot diff=astextplain
59+
#*.DOT diff=astextplain
60+
#*.pdf diff=astextplain
61+
#*.PDF diff=astextplain
62+
#*.rtf diff=astextplain
63+
#*.RTF diff=astextplain
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# This job is to test different profiles in sdk branch against full-commit id
2+
# This workflow targets nunit
3+
4+
name: C-sharp Playwright SDK Test workflow on workflow_dispatch
5+
6+
on:
7+
workflow_dispatch:
8+
inputs:
9+
commit_sha:
10+
description: 'The full commit id to build'
11+
required: true
12+
13+
jobs:
14+
comment-run:
15+
runs-on: ${{ matrix.os }}
16+
strategy:
17+
fail-fast: false
18+
max-parallel: 3
19+
matrix:
20+
dotnet: ['6.0.x', '5.0.x', '7.0.x']
21+
os: [ windows-latest ]
22+
name: NUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
23+
env:
24+
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
25+
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
26+
27+
steps:
28+
- uses: actions/checkout@v3
29+
with:
30+
ref: ${{ github.event.inputs.commit_sha }}
31+
- uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
32+
id: status-check-in-progress
33+
env:
34+
job_name: NUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
35+
commit_sha: ${{ github.event.inputs.commit_sha }}
36+
with:
37+
github-token: ${{ github.token }}
38+
script: |
39+
const result = await github.rest.checks.create({
40+
owner: context.repo.owner,
41+
repo: context.repo.repo,
42+
name: process.env.job_name,
43+
head_sha: process.env.commit_sha,
44+
status: 'in_progress'
45+
}).catch((err) => ({status: err.status, response: err.response}));
46+
console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`)
47+
if (result.status !== 201) {
48+
console.log('Failed to create check run')
49+
}
50+
- name: Setup dotnet
51+
uses: actions/setup-dotnet@v3
52+
with:
53+
dotnet-version: ${{ matrix.dotnet }}
54+
55+
- name: Install dependencies
56+
run: dotnet build
57+
58+
- name: Run sample tests
59+
run: dotnet test --filter "Category=sample-test"
60+
61+
- name: Run local tests
62+
run: dotnet test --filter "Category=sample-local-test"
63+
64+
- if: always()
65+
uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
66+
id: status-check-completed
67+
env:
68+
conclusion: ${{ job.status }}
69+
job_name: NUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
70+
commit_sha: ${{ github.event.inputs.commit_sha }}
71+
with:
72+
github-token: ${{ github.token }}
73+
script: |
74+
const result = await github.rest.checks.create({
75+
owner: context.repo.owner,
76+
repo: context.repo.repo,
77+
name: process.env.job_name,
78+
head_sha: process.env.commit_sha,
79+
status: 'completed',
80+
conclusion: process.env.conclusion
81+
}).catch((err) => ({status: err.status, response: err.response}));
82+
console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`)
83+
if (result.status !== 201) {
84+
console.log('Failed to create check run')
85+
}

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
packages
2+
TestResults
3+
TestResult.xml
4+
bin
5+
obj
6+
.vs
7+
.DS_Store

CSharp-Playwright-BrowserStack.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 25.0.1706.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharp-Playwright-BrowserStack", "CSharp-Playwright-BrowserStack\CSharp-Playwright-BrowserStack.csproj", "{D309DDB3-1E3B-428B-B00B-1257F2532079}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{D309DDB3-1E3B-428B-B00B-1257F2532079}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{D309DDB3-1E3B-428B-B00B-1257F2532079}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{D309DDB3-1E3B-428B-B00B-1257F2532079}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{D309DDB3-1E3B-428B-B00B-1257F2532079}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {4977FC04-06AD-47AF-90C6-66010738CC2D}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using Microsoft.Playwright;
2+
using Newtonsoft.Json;
3+
using NUnit.Framework;
4+
using BrowserStack;
5+
using Newtonsoft.Json.Linq;
6+
7+
namespace CSharpPlaywrightBrowserStack
8+
{
9+
[TestFixture]
10+
public class BrowserStackNUnitTest
11+
{
12+
protected IBrowser browser;
13+
protected IPage page;
14+
protected string profile;
15+
protected string environment;
16+
protected string configFile;
17+
18+
private Local browserStackLocal;
19+
20+
public BrowserStackNUnitTest(string profile, string environment, string configFile)
21+
{
22+
this.profile = profile;
23+
this.environment = environment;
24+
this.configFile = configFile;
25+
}
26+
27+
[SetUp]
28+
public async Task Init()
29+
{
30+
// Get Configuration for correct profile
31+
string currentDirectory = Directory.GetCurrentDirectory();
32+
string path = Path.Combine(currentDirectory, configFile);
33+
JObject config = JObject.Parse(File.ReadAllText(path));
34+
if (config is null)
35+
throw new Exception("Configuration not found!");
36+
37+
// Get Environment specific capabilities
38+
JObject capabilitiesJsonArr = config.GetValue("environments") as JObject;
39+
JObject capabilities = capabilitiesJsonArr.GetValue(environment) as JObject;
40+
41+
// Get Common Capabilities
42+
JObject commonCapabilities = config.GetValue("capabilities") as JObject;
43+
44+
// Merge Capabilities
45+
capabilities.Merge(commonCapabilities);
46+
47+
// Get username and accesskey
48+
string? username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
49+
if (username is null)
50+
username = config.GetValue("user").ToString();
51+
52+
string? accessKey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
53+
if (accessKey is null)
54+
accessKey = config.GetValue("key").ToString();
55+
56+
capabilities["browserstack.user"] = username;
57+
capabilities["browserstack.key"] = accessKey;
58+
59+
// Start Local if browserstack.local is set to true
60+
if (profile.Equals("local") && accessKey is not null)
61+
{
62+
capabilities["browserstack.local"] = true;
63+
browserStackLocal = new Local();
64+
List<KeyValuePair<string, string>> bsLocalArgs = new List<KeyValuePair<string, string>>() {
65+
new KeyValuePair<string, string>("key", accessKey)
66+
};
67+
foreach (var localOption in config.GetValue("localOptions") as JObject)
68+
{
69+
if (localOption.Value is not null)
70+
{
71+
bsLocalArgs.Add(new KeyValuePair<string, string>(localOption.Key, localOption.Value.ToString()));
72+
}
73+
}
74+
browserStackLocal.start(bsLocalArgs);
75+
}
76+
77+
string capsJson = JsonConvert.SerializeObject(capabilities);
78+
string cdpUrl = "wss://cdp.browserstack.com/playwright?caps=" + Uri.EscapeDataString(capsJson);
79+
80+
var playwright = await Playwright.CreateAsync();
81+
browser = await playwright.Chromium.ConnectAsync(cdpUrl);
82+
page = await browser.NewPageAsync();
83+
}
84+
85+
[TearDown]
86+
public async Task Cleanup()
87+
{
88+
if (browser != null)
89+
{
90+
browser.CloseAsync();
91+
}
92+
if (browserStackLocal != null)
93+
{
94+
browserStackLocal.stop();
95+
}
96+
}
97+
98+
public static async Task SetStatus(IPage browserPage, bool passed)
99+
{
100+
if (browserPage is not null)
101+
{
102+
if (passed)
103+
await browserPage.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\"passed\", \"reason\": \"Test Passed!\"}}");
104+
else
105+
await browserPage.EvaluateAsync("_ => {}", "browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\":\"failed\", \"reason\": \"Test Failed!\"}}");
106+
}
107+
}
108+
}
109+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<RootNamespace>CSharpPlaywrightBrowserStack</RootNamespace>
6+
<AssemblyName>CSharpPlaywrightBrowserStack</AssemblyName>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
<IsPackable>false</IsPackable>
10+
</PropertyGroup>
11+
<ItemGroup>
12+
<PackageReference Include="log4net" Version="2.0.15" />
13+
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
14+
<PackageReference Include="BrowserStackLocal" Version="2.3.1" />
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
16+
<PackageReference Include="NUnit" Version="3.13.3" />
17+
<PackageReference Include="NUnit.Analyzers" Version="3.6.1">
18+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
19+
<PrivateAssets>all</PrivateAssets>
20+
</PackageReference>
21+
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
22+
<PackageReference Include="Microsoft.Playwright" Version="1.36.0" />
23+
24+
<Content Include="local.conf.json">
25+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
26+
</Content>
27+
<Content Include="parallel.conf.json">
28+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
29+
</Content>
30+
<Content Include="single.conf.json">
31+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
32+
</Content>
33+
</ItemGroup>
34+
<ItemGroup>
35+
<None Remove="local.conf.json" />
36+
<None Remove="parallel.conf.json" />
37+
<None Remove="single.conf.json" />
38+
</ItemGroup>
39+
</Project>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using NUnit.Framework;
2+
3+
namespace CSharpPlaywrightBrowserStack
4+
{
5+
[TestFixture("local", "chrome", "local.conf.json")]
6+
[Category("sample-local-test")]
7+
public class LocalTest : BrowserStackNUnitTest
8+
{
9+
public LocalTest(string profile, string environment, string configFile) : base(profile, environment, configFile) { }
10+
11+
[Test]
12+
public async Task HealthCheck()
13+
{
14+
try
15+
{
16+
// Navigate to the base url
17+
await page.GotoAsync("http://bs-local.com:45454/");
18+
19+
// Verify if BrowserStackLocal running
20+
var title = await page.TitleAsync();
21+
StringAssert.Contains("BrowserStack Local", title);
22+
SetStatus(page, title.Contains("BrowserStack Local"));
23+
} catch (Exception)
24+
{
25+
SetStatus(page, false);
26+
throw;
27+
}
28+
}
29+
}
30+
}
31+
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using NUnit.Framework;
2+
3+
namespace CSharpPlaywrightBrowserStack
4+
{
5+
[TestFixture("parallel", "chrome", "parallel.conf.json")]
6+
[TestFixture("parallel", "playwright-firefox", "parallel.conf.json")]
7+
[TestFixture("parallel", "playwright-webkit", "parallel.conf.json")]
8+
[Parallelizable(ParallelScope.Fixtures)]
9+
[Category("sample-parallel-test")]
10+
public class ParallelTest : SingleTest
11+
{
12+
public ParallelTest(string profile, string environment, string configFile) : base(profile, environment, configFile) { }
13+
}
14+
}

0 commit comments

Comments
 (0)