Skip to content

3.1.0: arm64 + proxy passthrough for binary download (LOC-6563)#57

Open
yashdsaraf wants to merge 4 commits into
masterfrom
LOC-6563-arm64-proxy-parity
Open

3.1.0: arm64 + proxy passthrough for binary download (LOC-6563)#57
yashdsaraf wants to merge 4 commits into
masterfrom
LOC-6563-arm64-proxy-parity

Conversation

@yashdsaraf
Copy link
Copy Markdown
Collaborator

@yashdsaraf yashdsaraf commented Jun 1, 2026

Summary

  • Linux arm64 supportRuntimeInformation.OSArchitecture == Architecture.Arm64 selects BrowserStackLocal-linux-arm64. arm64 wins over alpine to match the Node SDK ordering.
  • Proxy passthrough on binary downloadproxyHost/proxyPort from Local.start(options) are now also threaded into the endpoint POST and the binary GET. fetchSourceUrl (HttpClient) and downloadBinary (WebClient) both honor the proxy now. Users behind enterprise proxies can finally download.
  • GetBinaryName() made public — test fixtures (BrowserStackTunnelTests.cs, IntegrationTests.cs) now use it as a single source of truth instead of hardcoded binaryName ternaries.

CloudFront migration was already done in this binding (see fetchSourceUrl — already prod). This PR closes the remaining LOC-6563 items: arm64 + proxy.

Background

Tracks LOC-6563. Ruby parity PR ships in coordination — see browserstack-local-ruby#39.

Files

  • `BrowserStackLocal/BrowserStackLocal/BrowserStackTunnel.cs` — arm64 branch, public GetBinaryName, proxy fields, SetProxy, proxy in fetchSourceUrl + downloadBinary
  • `BrowserStackLocal/BrowserStackLocal/Local.cs` — captures proxy on addArgs, pushes to tunnel before download
  • `BrowserStackLocal/BrowserStackLocal/BrowserStackLocal.csproj` — 3.0.0 → 3.1.0
  • `BrowserStackLocal/BrowserStackLocal Unit Tests/BrowserStackTunnelTests.cs` — binaryName via BrowserStackTunnel.GetBinaryName()
  • `BrowserStackLocal/BrowserStackLocalIntegrationTests/IntegrationTests.cs` — same

Test plan

  • `dotnet build BrowserStackLocal -p:Configuration=Release` — 0 errors
  • `dotnet build BrowserStackLocalIntegrationTests -p:Configuration=Release` — 0 errors (what CI actually runs)
  • `.github/workflows/ci.yml` passes on `windows-latest` (builds + runs IntegrationTests)
  • Manual on darwin: `dotnet run` on `BrowserStackLocalExample` downloads + connects
  • Manual on Linux arm64 — picks `BrowserStackLocal-linux-arm64`
  • Manual behind a forward proxy — `Local.start({"proxyHost", ..., "proxyPort", ...})` downloads via proxy
  • `dotnet test BrowserStackLocalIntegrationTests --no-build -p:Configuration=Release` passes with a real `BROWSERSTACK_ACCESS_KEY`

Pre-existing — NOT addressed in this PR

The `BrowserStackLocal Unit Tests` project does not compile in HEAD:

  • `TunnelClass : BrowserStackTunnel` is missing a constructor matching the required `BrowserStackTunnel(string userAgentParam)`
  • `LocalTests.cs` has Moq + optional-args expression-tree errors (CS0854)

Neither `.github/workflows/ci.yml` nor `.github/workflows/cd.yml` build or run this project — both target `BrowserStackLocalIntegrationTests` only. Left alone per scope; happy to file a follow-up.

🤖 Generated with Claude Code

yashdsaraf and others added 2 commits June 1, 2026 22:47
- GetBinaryName made public and adds Linux arm64 branch via
  RuntimeInformation.OSArchitecture. arm64 wins over alpine to match
  the Node SDK ordering.
- BrowserStackTunnel.SetProxy(host, port) + proxyHost/proxyPort fields.
- fetchSourceUrl builds HttpClientHandler with Proxy = WebProxy(host, port)
  when proxy is set.
- downloadBinary sets WebClient.Proxy = WebProxy(host, port) when set.
  (Keeping WebClient; proxy plumbing on it is one line.)
- Local.addArgs captures proxyHost/proxyPort on local fields in addition
  to appending to argumentString. Local.start calls tunnel.SetProxy(...)
  before DownloadVerifyAndRunBinary.
- Test fixtures derive binaryName from BrowserStackTunnel.GetBinaryName()
  so arm64 CI hosts pick the right binary.

Tracks LOC-6563.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Local.cs addArgs: int.TryParse failure now logs to stderr instead
  of silently dropping the proxy on download with no signal to the user.
- BrowserStackTunnel.cs: doc comment on proxyHost/proxyPort fields
  documents the required ordering (SetProxy before addBinaryPath).
- BrowserStackTunnelTests.cs: 2 new unit tests covering GetBinaryName
  return-set and SetProxy no-throw contract. Adds the missing
  TunnelClass constructor that broke compile pre-this-PR.
- LocalTests.cs: 3 new unit tests covering proxy-options-to-tunnel
  plumbing (with proxy, without proxy, with invalid port). Fixes
  pre-existing CS0854 errors on Mock.Verify expressions with
  optional args, and pre-existing missing-ctor errors on
  Mock<BrowserStackTunnel>().

Project now compiles for the first time in years; 5 new tests pass,
11 pre-existing tests still fail with pre-existing assertion bugs
(unchanged behavior; CI does not run this project anyway).

Code review findings #3, #4, #5 from LOC-6563 review.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yashdsaraf yashdsaraf requested review from a team, AdityaHirapara, kamal-kaur04 and rounak610 and removed request for a team and kamal-kaur04 June 1, 2026 18:29
@yashdsaraf yashdsaraf marked this pull request as ready for review June 1, 2026 18:31
@yashdsaraf yashdsaraf requested a review from a team as a code owner June 1, 2026 18:31
yashdsaraf and others added 2 commits June 2, 2026 11:12
Matches what Node SDK already does on every HTTP request (rails
endpoint POST AND CDN binary GET). Until this commit, the WebClient
binary download was the only request without a UA header, which
made CloudFront/CloudFlare access logs unfilterable by binding+version.

Now every outbound HTTP from this binding sends:

  User-Agent: browserstack-local-csharp/<version>

Same value the HttpClient already sent on the rails endpoint POST.

Follow-up to the code review pass on LOC-6563.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Why: the 3.x binding's only net7-specific touchpoint is the
`Architecture.Arm64` enum (added in .NET Core 3.0 / netstandard 2.1).
Everything else (HttpClient, WebClient, WebProxy, Process, ACL APIs)
is available since netstandard 2.0 / net6.0.

Targeting net6.0 instead lets net6.0 SDK consumers stay on 3.x without
being forced to upgrade their runtime to net7+. .NET 5 and netcoreapp
3.1 still aren't covered — but per the SDK agent's 7-day BigQuery,
those TFMs have zero C# SDK traffic, so the practical impact is nil.

Net effect: removes the LOC-6563 rollout's hardest constraint
(forcing SDK to drop net6.0 from <TargetFrameworks> in order to
adopt 3.1.0). The 7 hard-blocked enterprise accounts on .NET 6.0.36
(group_id=934837 et al., 14 users, 623 weekly events) stay supported.

Also updates test project TFMs and HintPaths from net7.0 to net6.0
so the local build chain matches.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
var url = "https://local.browserstack.com/binary/api/v1/endpoint";

using (var client = new HttpClient())
HttpClientHandler handler = new HttpClientHandler();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in today's standup, it was decided to find alternative of HttpClientHandler so that we can support dotnet6 as well? are we going ahead with this library?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is compatible already apparently. Not sure why this was called out as deprecated in binding version 3.0.0.
I ran a test e2e with dotnet 6.0 and it worked -- https://browserstack.atlassian.net/browse/LOC-6563?focusedCommentId=2082879

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added .net6.0 back in this commit d968e36

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants