Skip to content

Commit 5945ab6

Browse files
Add sanity workflow + BrowserStack Local scenario
Mirrors browserstack/csharp-playwright-browserstack/.github/workflows/sanity-workflow.yml so the repo can be verified pre/post setup via workflow_dispatch with a commit_sha input. - .github/workflows/sanity-workflow.yml: workflow_dispatch + commit_sha input, dotnet 8.0.x on windows-latest, github-script in_progress/completed check-runs, two test phases - public bstackdemo run (browserstackLocal: false) - Local run: spins up python -m http.server 45454 with a title-matching index.html, flips browserstackLocal to true, SDK starts/stops the tunnel, scenario asserts the tunneled page title contains "BrowserStack Local" - Features/LocalSample.feature + StepDefinitions/LocalSampleSteps.cs: BDD analogue of csharp-playwright-browserstack/SampleLocalTest.cs (page.GotoAsync("http://bs-local.com:45454/") + title contains assertion) - Verified locally on BrowserStack build b06134226200d2c2e5550e70de73dec89b835187: 2 sessions (Win11/Chrome 147 + OSX/Ventura/playwright-webkit 26), both browserstack_status=done, status=passed Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 412dc39 commit 5945ab6

3 files changed

Lines changed: 160 additions & 0 deletions

File tree

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Sanity workflow that verifies the xUnit + Reqnroll + Playwright BrowserStack
2+
# SDK sample against a full commit id, mirroring browserstack/csharp-playwright-browserstack.
3+
# Two test runs:
4+
# 1. Public bstackdemo scenario (browserstackLocal: false in yml).
5+
# 2. BrowserStack Local scenario (yml flipped to true; a python http.server
6+
# hosts a tiny title-matching page on port 45454, the SDK starts the tunnel,
7+
# and the test asserts that the cloud browser sees that page through bs-local.com).
8+
9+
name: xUnit Reqnroll Playwright SDK sanity workflow on workflow_dispatch
10+
11+
on:
12+
workflow_dispatch:
13+
inputs:
14+
commit_sha:
15+
description: 'The full commit id to build'
16+
required: true
17+
18+
permissions:
19+
contents: read
20+
checks: write
21+
22+
jobs:
23+
sanity:
24+
runs-on: ${{ matrix.os }}
25+
strategy:
26+
fail-fast: false
27+
max-parallel: 1
28+
matrix:
29+
dotnet: ['8.0.x']
30+
os: [windows-latest]
31+
name: xUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
32+
env:
33+
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
34+
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
35+
36+
steps:
37+
- uses: actions/checkout@v3
38+
with:
39+
ref: ${{ github.event.inputs.commit_sha }}
40+
41+
- uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
42+
id: status-check-in-progress
43+
env:
44+
job_name: xUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
45+
commit_sha: ${{ github.event.inputs.commit_sha }}
46+
with:
47+
github-token: ${{ github.token }}
48+
script: |
49+
const result = await github.rest.checks.create({
50+
owner: context.repo.owner,
51+
repo: context.repo.repo,
52+
name: process.env.job_name,
53+
head_sha: process.env.commit_sha,
54+
status: 'in_progress'
55+
}).catch((err) => ({status: err.status, response: err.response}));
56+
console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`)
57+
if (result.status !== 201) {
58+
console.log('Failed to create check run')
59+
}
60+
61+
- name: Setup dotnet
62+
uses: actions/setup-dotnet@v3
63+
with:
64+
dotnet-version: ${{ matrix.dotnet }}
65+
66+
- name: Strip credential placeholders so env vars take effect
67+
# The yml ships with literal YOUR_USERNAME / YOUR_ACCESS_KEY placeholders;
68+
# the .NET SDK only falls back to env vars when those lines are absent.
69+
shell: bash
70+
working-directory: XunitReqnrollPlaywrightBrowserstack.Tests
71+
run: |
72+
sed -i '/^userName:/d; /^accessKey:/d' browserstack.yml
73+
74+
- name: Install dependencies
75+
run: dotnet build
76+
77+
- name: Run sample tests (public bstackdemo)
78+
working-directory: XunitReqnrollPlaywrightBrowserstack.Tests
79+
run: dotnet test --filter "FullyQualifiedName~BStackDemoCart"
80+
81+
- name: Run local tests (BrowserStack Local + python http.server harness)
82+
shell: bash
83+
working-directory: XunitReqnrollPlaywrightBrowserstack.Tests
84+
run: |
85+
set -u
86+
# 1. Stand up a tiny static page with a known <title>.
87+
mkdir -p "$RUNNER_TEMP/bs-local-harness"
88+
cat > "$RUNNER_TEMP/bs-local-harness/index.html" <<'HTML'
89+
<!doctype html>
90+
<html><head><title>BrowserStack Local Test</title></head>
91+
<body>OK</body></html>
92+
HTML
93+
( cd "$RUNNER_TEMP/bs-local-harness" && python -m http.server 45454 ) &
94+
HTTP_PID=$!
95+
trap 'kill "$HTTP_PID" 2>/dev/null || true' EXIT
96+
sleep 2
97+
# 2. Flip the SDK Local toggle so the SDK starts/stops the tunnel.
98+
sed -i 's/^browserstackLocal: false/browserstackLocal: true/' browserstack.yml
99+
# 3. Run only the local scenario; cloud browser reaches the harness through bs-local.com.
100+
dotnet test --filter "FullyQualifiedName~BStackLocalSample"
101+
102+
- if: always()
103+
uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975
104+
id: status-check-completed
105+
env:
106+
conclusion: ${{ job.status }}
107+
job_name: xUnit Repo ${{ matrix.dotnet }} - ${{ matrix.os }} Sample
108+
commit_sha: ${{ github.event.inputs.commit_sha }}
109+
with:
110+
github-token: ${{ github.token }}
111+
script: |
112+
const result = await github.rest.checks.create({
113+
owner: context.repo.owner,
114+
repo: context.repo.repo,
115+
name: process.env.job_name,
116+
head_sha: process.env.commit_sha,
117+
status: 'completed',
118+
conclusion: process.env.conclusion
119+
}).catch((err) => ({status: err.status, response: err.response}));
120+
console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`)
121+
if (result.status !== 201) {
122+
console.log('Failed to create check run')
123+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Feature: BStackLocalSample
2+
3+
As a developer testing a private host
4+
I want BrowserStack Local to tunnel my localhost to BrowserStack
5+
So that the cloud browser can reach a page only my machine can serve
6+
7+
Scenario: Reach a private host via BrowserStack Local
8+
Given I open the local sample page on bs-local
9+
Then the local sample page title contains "BrowserStack Local"
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using Microsoft.Playwright;
2+
using Reqnroll;
3+
4+
namespace XunitReqnrollPlaywrightBrowserstack.Tests.StepDefinitions;
5+
6+
// Mirrors browserstack/csharp-playwright-browserstack -> SampleLocalTest.cs:
7+
// page.GotoAsync("http://bs-local.com:45454/") + title.Contains("BrowserStack Local")
8+
[Binding]
9+
public class LocalSampleSteps
10+
{
11+
private readonly ScenarioContext _scenario;
12+
private IPage Page => _scenario.Get<IPage>("page");
13+
14+
public LocalSampleSteps(ScenarioContext scenario) => _scenario = scenario;
15+
16+
[Given(@"I open the local sample page on bs-local")]
17+
public async Task OpenLocalSamplePage()
18+
{
19+
await Page.GotoAsync("http://bs-local.com:45454/");
20+
}
21+
22+
[Then(@"the local sample page title contains ""(.*)""")]
23+
public async Task LocalSamplePageTitleContains(string expected)
24+
{
25+
var actual = await Page.TitleAsync();
26+
Assert.Contains(expected, actual);
27+
}
28+
}

0 commit comments

Comments
 (0)