Skip to content

Add support for macOS #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Dec 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ namespace BrowserStack_Unit_Tests
[TestClass]
public class BrowserStackTunnelTests
{
static readonly OperatingSystem os = Environment.OSVersion;
static readonly string homepath = os.Platform.ToString() == "Unix" ?
Environment.GetFolderPath(Environment.SpecialFolder.Personal) :
Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
static readonly string binaryName = os.Platform.ToString() == "Unix" ? "BrowserStackLocal-darwin-x64" : "BrowserStackLocal.exe";
private TunnelClass tunnel;
[TestMethod]
public void TestInitialState()
Expand All @@ -33,17 +38,17 @@ public void TestBinaryPathOnNull()
{
tunnel = new TunnelClass();
tunnel.addBinaryPath(null);
string expectedPath = Path.Combine(Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"), ".browserstack");
expectedPath = Path.Combine(expectedPath, "BrowserStackLocal.exe");
string expectedPath = Path.Combine(homepath, ".browserstack");
expectedPath = Path.Combine(expectedPath, binaryName);
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
}
[TestMethod]
public void TestBinaryPathOnEmpty()
{
tunnel = new TunnelClass();
tunnel.addBinaryPath("");
string expectedPath = Path.Combine(Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"), ".browserstack");
expectedPath = Path.Combine(expectedPath, "BrowserStackLocal.exe");
string expectedPath = Path.Combine(homepath, ".browserstack");
expectedPath = Path.Combine(expectedPath, binaryName);
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
}
[TestMethod]
Expand All @@ -55,18 +60,18 @@ public void TestBinaryPathOnFallback()
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);

tunnel.fallbackPaths();
expectedPath = Path.Combine(Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"), ".browserstack");
expectedPath = Path.Combine(expectedPath, "BrowserStackLocal.exe");
expectedPath = Path.Combine(homepath, ".browserstack");
expectedPath = Path.Combine(expectedPath, binaryName);
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);

tunnel.fallbackPaths();
expectedPath = Directory.GetCurrentDirectory();
expectedPath = Path.Combine(expectedPath, "BrowserStackLocal.exe");
expectedPath = Path.Combine(expectedPath, binaryName);
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);

tunnel.fallbackPaths();
expectedPath = Path.GetTempPath();
expectedPath = Path.Combine(expectedPath, "BrowserStackLocal.exe");
expectedPath = Path.Combine(expectedPath, binaryName);
Assert.AreEqual(tunnel.getBinaryAbsolute(), expectedPath);
}
[TestMethod]
Expand All @@ -79,7 +84,7 @@ public void TestBinaryPathOnNoMoreFallback()
tunnel.fallbackPaths();
Assert.Throws(typeof(Exception),
new TestDelegate(testFallbackException),
"Binary not found or failed to launch. Make sure that BrowserStackLocal.exe is not already running."
"Binary not found or failed to launch. Make sure that BrowserStackLocal is not already running."
);
}
[TestMethod]
Expand Down
51 changes: 43 additions & 8 deletions BrowserStackLocal/BrowserStackLocal/BrowserStackTunnel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@ public enum LocalState { Idle, Connecting, Connected, Error, Disconnected };

public class BrowserStackTunnel : IDisposable
{
static readonly string binaryName = "BrowserStackLocal.exe";
static readonly string downloadURL = "https://s3.amazonaws.com/browserStack/browserstack-local/BrowserStackLocal.exe";
static readonly string binaryName = isDarwin() ? "BrowserStackLocal-darwin-x64" : "BrowserStackLocal.exe";
static readonly string downloadURL = isDarwin() ?
"https://bstack-local-prod.s3.amazonaws.com/BrowserStackLocal-darwin-x64" :
"https://bstack-local-prod.s3.amazonaws.com/BrowserStackLocal.exe";
static readonly string homepath = isDarwin() ?
Environment.GetFolderPath(Environment.SpecialFolder.Personal) :
Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
public static readonly string[] basePaths = new string[] {
Path.Combine(Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"), ".browserstack"),
Path.Combine(homepath, ".browserstack"),
Directory.GetCurrentDirectory(),
Path.GetTempPath() };

Expand All @@ -32,6 +37,12 @@ public class BrowserStackTunnel : IDisposable

Process process = null;

static Boolean isDarwin()
{
OperatingSystem os = Environment.OSVersion;
return os.Platform.ToString() == "Unix";
}

public virtual void addBinaryPath(string binaryAbsolute)
{
if (binaryAbsolute == null || binaryAbsolute.Trim().Length == 0)
Expand Down Expand Up @@ -60,11 +71,37 @@ public virtual void fallbackPaths()
{
if (basePathsIndex >= basePaths.Length - 1)
{
throw new Exception("Binary not found or failed to launch. Make sure that BrowserStackLocal.exe is not already running.");
throw new Exception("Binary not found or failed to launch. Make sure that BrowserStackLocal is not already running.");
}
basePathsIndex++;
binaryAbsolute = Path.Combine(basePaths[basePathsIndex], binaryName);
}

public void modifyBinaryPermission()
{
if (isDarwin())
{
try
{
using (Process proc = Process.Start("/bin/bash", $"-c \"chmod 0755 {this.binaryAbsolute}\""))
{
proc.WaitForExit();
}
}
catch
{
throw new Exception("Error in changing permission for file " + this.binaryAbsolute);
}
}
else
{
DirectoryInfo dInfo = new DirectoryInfo(binaryAbsolute);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
}
}

public void downloadBinary()
{
string binaryDirectory = Path.Combine(this.binaryAbsolute, "..");
Expand All @@ -82,10 +119,7 @@ public void downloadBinary()
throw new Exception("Error accessing file " + binaryAbsolute);
}

DirectoryInfo dInfo = new DirectoryInfo(binaryAbsolute);
DirectorySecurity dSecurity = dInfo.GetAccessControl();
dSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.NoPropagateInherit, AccessControlType.Allow));
dInfo.SetAccessControl(dSecurity);
modifyBinaryPermission();
}

public virtual void Run(string accessKey, string folder, string logFilePath, string processType)
Expand Down Expand Up @@ -158,6 +192,7 @@ private void RunProcess(string arguments, string processType)
else if (connectionState.ToString().ToLower().Equals("disconnected"))
{
SetTunnelState(LocalState.Disconnected);
throw new Exception("Error while executing BrowserStackLocal " + processType + " " + e.Data);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ namespace BrowserStackLocalIntegrationTests
{
public class IntegrationTests
{
static readonly OperatingSystem os = Environment.OSVersion;
static readonly string binaryName = os.Platform.ToString() == "Unix" ? "BrowserStackLocal-darwin-x64" : "BrowserStackLocal";
private static string username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
private static string accesskey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");

private List<KeyValuePair<string, string>> options = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("key", accesskey),
new KeyValuePair<string, string>("verbose", "true"),
new KeyValuePair<string, string>("forcelocal", "true"),
new KeyValuePair<string, string>("binarypath", "C:\\Users\\Admin\\Desktop\\BrowserStackLocal.exe"),
new KeyValuePair<string, string>("logfile", "C:\\Users\\Admin\\Desktop\\local.log"),
};

[Test]
Expand All @@ -33,7 +33,7 @@ void startWithOptions()
}

Assert.DoesNotThrow(new TestDelegate(startWithOptions));
Process[] binaryInstances = Process.GetProcessesByName("BrowserStackLocal");
Process[] binaryInstances = Process.GetProcessesByName(binaryName);
Assert.AreNotEqual(binaryInstances.Length, 0);

IWebDriver driver;
Expand All @@ -54,7 +54,7 @@ void startWithOptions()
driver.Quit();
local.stop();

binaryInstances = Process.GetProcessesByName("BrowserStackLocal");
binaryInstances = Process.GetProcessesByName(binaryName);
Assert.AreEqual(binaryInstances.Length, 0);
}

Expand All @@ -76,7 +76,7 @@ public void TestBinaryState()
[TearDown]
public void TestCleanup()
{
foreach(Process p in Process.GetProcessesByName("BrowserStackLocal"))
foreach(Process p in Process.GetProcessesByName(binaryName))
{
p.Kill();
}
Expand Down