Skip to content

Commit 3012a29

Browse files
authored
Merge pull request #55 from browserstack/release_v3_0_0
Release v3.0.0
2 parents d4a023f + 46e30df commit 3012a29

File tree

12 files changed

+197
-167
lines changed

12 files changed

+197
-167
lines changed

.github/workflows/cd.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
msbuild BrowserStackLocalIntegrationTests -t:restore -p:Configuration=Release
2424
msbuild BrowserStackLocalIntegrationTests -t:build -p:Configuration=Release
2525
- name: Setup .NET Core
26-
uses: actions/setup-dotnet@v1
26+
uses: actions/setup-dotnet@v3
2727
with:
28-
dotnet-version: 3.1.301
28+
dotnet-version: 7.0.410
2929
- name: Run Integration Tests
3030
env:
3131
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@ jobs:
2323
msbuild BrowserStackLocalIntegrationTests -t:restore -p:Configuration=Release
2424
msbuild BrowserStackLocalIntegrationTests -t:build -p:Configuration=Release
2525
- name: Setup .NET Core
26-
uses: actions/setup-dotnet@v1
26+
uses: actions/setup-dotnet@v3
2727
with:
28-
dotnet-version: 3.1.301
28+
dotnet-version: 7.0.410
2929
- name: Run Integration Tests
3030
env:
3131
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}

BrowserStackLocal/BrowserStackLocal Unit Tests/BrowserStackLocal Unit Tests.csproj

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<PropertyGroup>
33
<RootNamespace>BrowserStackLocal_Unit_TestsRootNamespace>
44
<AssemblyName>BrowserStackLocal Unit TestsAssemblyName>
5-
<TargetFrameworks>net45;netcoreapp3.1TargetFrameworks>
5+
<TargetFrameworks>net7.0TargetFrameworks>
66
<GenerateAssemblyInfo>falseGenerateAssemblyInfo>
77
<Title>BrowserStackLocal Unit TestsTitle>
88
<Product>BrowserStackLocal Unit TestsProduct>
@@ -18,15 +18,10 @@
1818
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
1919
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
2020
ItemGroup>
21-
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
21+
<ItemGroup Condition=" '$(TargetFramework)' == 'net7.0' ">
2222
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
2323
<Reference Include="BrowserStackLocal">
24-
<HintPath>..\BrowserStackLocal\bin\Debug\net20\BrowserStackLocal.dllHintPath>
25-
Reference>
26-
ItemGroup>
27-
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp3.1' ">
28-
<Reference Include="BrowserStackLocal">
29-
<HintPath>..\BrowserStackLocal\bin\Debug\netstandard2.0\BrowserStackLocal.dllHintPath>
24+
<HintPath>..\BrowserStackLocal\bin\$(Configuration)\net7.0\BrowserStackLocal.dllHintPath>
3025
Reference>
3126
ItemGroup>
3227
39-
Project>
34+
Project>

BrowserStackLocal/BrowserStackLocal Unit Tests/BrowserStackTunnelTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ public void TestInitialState()
3030
public void TestBinaryPathIsSet()
3131
{
3232
tunnel = new TunnelClass();
33-
tunnel.addBinaryPath("dummyPath");
33+
tunnel.addBinaryPath("dummyPath", "");
3434
Assert.AreEqual(tunnel.getBinaryAbsolute(), "dummyPath");
3535
}
3636
[TestMethod]
3737
public void TestBinaryPathOnNull()
3838
{
3939
tunnel = new TunnelClass();
40-
tunnel.addBinaryPath(null);
40+
tunnel.addBinaryPath(null, "");
4141
string expectedPath = Path.Combine(homepath, ".browserstack");
4242
expectedPath = Path.Combine(expectedPath, binaryName);
4343
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
@@ -46,7 +46,7 @@ public void TestBinaryPathOnNull()
4646
public void TestBinaryPathOnEmpty()
4747
{
4848
tunnel = new TunnelClass();
49-
tunnel.addBinaryPath("");
49+
tunnel.addBinaryPath("", "");
5050
string expectedPath = Path.Combine(homepath, ".browserstack");
5151
expectedPath = Path.Combine(expectedPath, binaryName);
5252
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
@@ -56,7 +56,7 @@ public void TestBinaryPathOnFallback()
5656
{
5757
string expectedPath = "dummyPath";
5858
tunnel = new TunnelClass();
59-
tunnel.addBinaryPath("dummyPath");
59+
tunnel.addBinaryPath("dummyPath", "");
6060
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
6161

6262
tunnel.fallbackPaths();
@@ -78,7 +78,7 @@ public void TestBinaryPathOnFallback()
7878
public void TestBinaryPathOnNoMoreFallback()
7979
{
8080
tunnel = new TunnelClass();
81-
tunnel.addBinaryPath("dummyPath");
81+
tunnel.addBinaryPath("dummyPath", "");
8282
tunnel.fallbackPaths();
8383
tunnel.fallbackPaths();
8484
tunnel.fallbackPaths();

BrowserStackLocal/BrowserStackLocal Unit Tests/LocalTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ public void TestWorksForBinaryPath()
107107
tunnelMock.Setup(mock => mock.Run("dummyKey", "", logAbsolute, "start"));
108108
local.setTunnel(tunnelMock.Object);
109109
local.start(options);
110-
tunnelMock.Verify(mock => mock.addBinaryPath("dummyPath"), Times.Once);
110+
tunnelMock.Verify(mock => mock.addBinaryPath("dummyPath", ""), Times.Once);
111111
tunnelMock.Verify(mock => mock.addBinaryArguments(It.IsRegex("-logFile \"" + logAbsolute + "\" .*")), Times.Once());
112112
tunnelMock.Verify(mock => mock.Run("dummyKey", "", logAbsolute, "start"), Times.Once());
113113
local.stop();
@@ -129,7 +129,7 @@ public void TestWorksWithBooleanOptions()
129129
tunnelMock.Setup(mock => mock.Run("dummyKey", "", logAbsolute, "start"));
130130
local.setTunnel(tunnelMock.Object);
131131
local.start(options);
132-
tunnelMock.Verify(mock => mock.addBinaryPath(""), Times.Once);
132+
tunnelMock.Verify(mock => mock.addBinaryPath("", ""), Times.Once);
133133
tunnelMock.Verify(mock => mock.addBinaryArguments(It.IsRegex("-vvv.*-force.*-forcelocal.*-forceproxy.*-onlyAutomate.*")), Times.Once());
134134
tunnelMock.Verify(mock => mock.Run("dummyKey", "", logAbsolute, "start"), Times.Once());
135135
local.stop();
@@ -152,7 +152,7 @@ public void TestWorksWithValueOptions()
152152
tunnelMock.Setup(mock =>mock.Run("dummyKey", "", logAbsolute, "start"));
153153
local.setTunnel(tunnelMock.Object);
154154
local.start(options);
155-
tunnelMock.Verify(mock => mock.addBinaryPath(""), Times.Once);
155+
tunnelMock.Verify(mock => mock.addBinaryPath("", ""), Times.Once);
156156
tunnelMock.Verify(mock => mock.addBinaryArguments(
157157
It.IsRegex("-localIdentifier.*dummyIdentifier.*dummyHost.*-proxyHost.*dummyHost.*-proxyPort.*dummyPort.*-proxyUser.*dummyUser.*-proxyPass.*dummyPass.*")
158158
), Times.Once());
@@ -175,7 +175,7 @@ public void TestWorksWithCustomOptions()
175175
tunnelMock.Setup(mock => mock.Run("dummyKey", "", logAbsolute, "start"));
176176
local.setTunnel(tunnelMock.Object);
177177
local.start(options);
178-
tunnelMock.Verify(mock => mock.addBinaryPath(""), Times.Once);
178+
tunnelMock.Verify(mock => mock.addBinaryPath("", ""), Times.Once);
179179
tunnelMock.Verify(mock => mock.addBinaryArguments(
180180
It.IsRegex("-customBoolKey1.*-customBoolKey2.*-customKey1.*customValue1.*-customKey2.*customValue2.*")
181181
), Times.Once());
@@ -200,7 +200,7 @@ public void TestCallsFallbackOnFailure()
200200
});
201201
local.setTunnel(tunnelMock.Object);
202202
local.start(options);
203-
tunnelMock.Verify(mock => mock.addBinaryPath(""), Times.Once);
203+
tunnelMock.Verify(mock => mock.addBinaryPath("", ""), Times.Once);
204204
tunnelMock.Verify(mock => mock.addBinaryArguments(It.IsRegex("-logFile \"" + logAbsolute + "\" .*")), Times.Once());
205205
tunnelMock.Verify(mock => mock.Run("dummyKey", "", logAbsolute, "start"), Times.Exactly(2));
206206
tunnelMock.Verify(mock => mock.fallbackPaths(), Times.Once());
@@ -219,7 +219,7 @@ public void TestKillsTunnel()
219219
local.setTunnel(tunnelMock.Object);
220220
local.start(options);
221221
local.stop();
222-
tunnelMock.Verify(mock => mock.addBinaryPath(""), Times.Once);
222+
tunnelMock.Verify(mock => mock.addBinaryPath("", ""), Times.Once);
223223
tunnelMock.Verify(mock => mock.addBinaryArguments(It.IsRegex("-logFile \"" + logAbsolute + "\" .*")), Times.Once());
224224
tunnelMock.Verify(mock => mock.Run("dummyKey", "", logAbsolute, "start"), Times.Once());
225225
}

BrowserStackLocal/BrowserStackLocal/BrowserStackLocal.csproj

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<PropertyGroup>
33
<RootNamespace>BrowserStackRootNamespace>
44
<AssemblyName>BrowserStackLocalAssemblyName>
5-
<TargetFrameworks>net20;netstandard2.0TargetFrameworks>
5+
<TargetFramework>net7.0TargetFramework>
66
<GenerateAssemblyInfo>falseGenerateAssemblyInfo>
77
<Title>BrowserStackLocalTitle>
88
<Product>BrowserStackLocalProduct>
99
<Description>C# Bindings for BrowserStack LocalDescription>
10-
<Version>2.4.0Version>
11-
<AssemblyVersion>2.4.0AssemblyVersion>
12-
<FileVersion>2.4.0FileVersion>
10+
<Version>3.0.0Version>
11+
<AssemblyVersion>3.0.0AssemblyVersion>
12+
<FileVersion>3.0.0FileVersion>
1313
<Authors>BrowserStackAuthors>
1414
<Company>BrowserStackCompany>
1515
<Copyright>Copyright © 2016Copyright>
@@ -18,9 +18,6 @@
1818
<ItemGroup>
1919
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
2020
ItemGroup>
21-
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
22-
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="4.7.0" />
23-
ItemGroup>
2421
<ItemGroup>
2522
<None Include="MIT-LICENSE.txt" Pack="true" PackagePath="" />
2623
ItemGroup>

BrowserStackLocal/BrowserStackLocal/BrowserStackTunnel.cs

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88
using System.Security.Principal;
99
using Newtonsoft.Json.Linq;
1010

11+
12+
using System.Collections.Generic;
13+
using System.Net.Http;
14+
using System.Threading.Tasks;
15+
using Newtonsoft.Json;
16+
1117
namespace BrowserStack
1218
{
1319
public enum LocalState { Idle, Connecting, Connected, Error, Disconnected };
@@ -16,7 +22,11 @@ public class BrowserStackTunnel : IDisposable
1622
{
1723
static readonly string uname = Util.GetUName();
1824
static readonly string binaryName = GetBinaryName();
19-
static readonly string downloadURL = "https://www.browserstack.com/local-testing/downloads/binaries/" + binaryName;
25+
26+
private static string userAgent = "";
27+
private string sourceUrl = null;
28+
private bool isFallbackEnabled = false;
29+
private Exception downloadFailureException = null;
2030

2131
static readonly string homepath = !IsWindows() ?
2232
Environment.GetFolderPath(Environment.SpecialFolder.Personal) :
@@ -41,7 +51,7 @@ static bool IsDarwin(string osName)
4151
{
4252
return osName.Contains("darwin");
4353
}
44-
54+
4555

4656
static bool IsWindows()
4757
{
@@ -84,8 +94,15 @@ static string GetBinaryName()
8494
return "BrowserStackLocal.exe";
8595
}
8696

87-
public virtual void addBinaryPath(string binaryAbsolute)
97+
public virtual void addBinaryPath(string binaryAbsolute, string accessKey, bool fallbackEnabled = false, Exception failureException = null)
8898
{
99+
if (basePathsIndex == -1)
100+
{
101+
/* Called at most twice (primary & a fallback) */
102+
isFallbackEnabled = fallbackEnabled;
103+
downloadFailureException = failureException;
104+
fetchSourceUrl(accessKey);
105+
}
89106
if (binaryAbsolute == null || binaryAbsolute.Trim().Length == 0)
90107
{
91108
binaryAbsolute = Path.Combine(basePaths[++basePathsIndex], binaryName);
@@ -102,14 +119,19 @@ public virtual void addBinaryArguments(string binaryArguments)
102119
this.binaryArguments = binaryArguments;
103120
}
104121

105-
public BrowserStackTunnel()
122+
public BrowserStackTunnel(string userAgentParam)
106123
{
124+
userAgent = userAgentParam;
107125
localState = LocalState.Idle;
108126
output = new StringBuilder();
109127
}
110128

111129
public virtual void fallbackPaths()
112130
{
131+
if (File.Exists(binaryAbsolute))
132+
{
133+
File.Delete(binaryAbsolute);
134+
}
113135
if (basePathsIndex >= basePaths.Length - 1)
114136
{
115137
throw new Exception("Binary not found or failed to launch. Make sure that BrowserStackLocal is not already running.");
@@ -121,7 +143,7 @@ public virtual void fallbackPaths()
121143
public void modifyBinaryPermission()
122144
{
123145
if (!IsWindows())
124-
{
146+
{
125147
try
126148
{
127149
using (Process proc = Process.Start("/bin/bash", $"-c \"chmod 0755 {this.binaryAbsolute}\""))
@@ -143,16 +165,58 @@ public void modifyBinaryPermission()
143165
}
144166
}
145167

168+
private string fetchSourceUrl(string accessKey)
169+
{
170+
var url = "https://local.browserstack.com/binary/api/v1/endpoint";
171+
172+
using (var client = new HttpClient())
173+
{
174+
var data = new Dictionary<string, object>
175+
{
176+
{ "auth_token", accessKey }
177+
};
178+
179+
if (isFallbackEnabled)
180+
{
181+
data["error_message"] = downloadFailureException.Message;
182+
}
183+
184+
var jsonData = JsonConvert.SerializeObject(data);
185+
var content = new StringContent(jsonData, Encoding.UTF8, "application/json");
186+
187+
client.DefaultRequestHeaders.Add("User-Agent", userAgent);
188+
if (isFallbackEnabled)
189+
{
190+
client.DefaultRequestHeaders.Add("X-Local-Fallback-Cloudflare", "true");
191+
}
192+
193+
var response = client.PostAsync(url, content).Result;
194+
195+
response.EnsureSuccessStatusCode();
196+
197+
var responseString = response.Content.ReadAsStringAsync().Result;
198+
199+
var jsonResponse = JObject.Parse(responseString);
200+
201+
if (jsonResponse["error"] != null)
202+
{
203+
throw new Exception((string)jsonResponse["error"]);
204+
}
205+
206+
sourceUrl = jsonResponse["data"]?["endpoint"]?.ToString();
207+
return sourceUrl;
208+
}
209+
}
210+
146211
public void downloadBinary()
147212
{
148213
string binaryDirectory = Path.Combine(this.binaryAbsolute, "..");
149-
//string binaryAbsolute = Path.Combine(binaryDirectory, binaryName);
150214

151215
Directory.CreateDirectory(binaryDirectory);
152216

153217
using (var client = new WebClient())
154218
{
155-
client.DownloadFile(downloadURL, this.binaryAbsolute);
219+
client.DownloadFile(sourceUrl + "/" + binaryName, this.binaryAbsolute);
156220
}
157221

158222
if (!File.Exists(binaryAbsolute))

0 commit comments

Comments
 (0)