Skip to content

Commit 8cf4afe

Browse files
committed
[dotnet] initial implementation of Selenium Manager
1 parent aab6eaf commit 8cf4afe

File tree

3 files changed

+174
-3
lines changed

3 files changed

+174
-3
lines changed

dotnet/src/webdriver/DriverService.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,23 @@ protected DriverService(string servicePath, int port, string driverServiceExecut
6565
string executablePath = Path.Combine(servicePath, driverServiceExecutableName);
6666
if (!File.Exists(executablePath))
6767
{
68-
throw new DriverServiceNotFoundException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exist. The driver can be downloaded at {1}", executablePath, driverServiceDownloadUrl));
68+
try
69+
{
70+
executablePath = SeleniumManager.DriverPath(driverServiceExecutableName);
71+
}
72+
catch (Exception e)
73+
{
74+
// No-op; entirely a fall-back feature
75+
}
76+
77+
if (File.Exists(executablePath))
78+
{
79+
servicePath = Path.GetDirectoryName(executablePath);
80+
}
81+
else
82+
{
83+
throw new DriverServiceNotFoundException(string.Format(CultureInfo.InvariantCulture, "The file {0} does not exist. The driver can be downloaded at {1}", executablePath, driverServiceDownloadUrl));
84+
}
6985
}
7086

7187
this.driverServicePath = servicePath;
@@ -74,12 +90,12 @@ protected DriverService(string servicePath, int port, string driverServiceExecut
7490
}
7591

7692
/// <summary>
77-
/// Occurs when the driver process is starting.
93+
/// Occurs when the driver process is starting.
7894
/// </summary>
7995
public event EventHandler<DriverProcessStartingEventArgs> DriverProcessStarting;
8096

8197
/// <summary>
82-
/// Occurs when the driver process has completely started.
98+
/// Occurs when the driver process has completely started.
8399
/// </summary>
84100
public event EventHandler<DriverProcessStartedEventArgs> DriverProcessStarted;
85101

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// <copyright file="SeleniumManager.cs" company="WebDriver Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
// </copyright>
18+
19+
using System;
20+
using System.Collections.Generic;
21+
using System.Diagnostics;
22+
using System.Globalization;
23+
using System.IO;
24+
using System.Text;
25+
using System.Threading;
26+
using OpenQA.Selenium.Internal;
27+
28+
namespace OpenQA.Selenium
29+
{
30+
/// <summary>
31+
/// Wrapper for the Selenium Manager binary.
32+
/// </summary>
33+
public static class SeleniumManager
34+
{
35+
private static string binary;
36+
private static readonly List<string> KnownDrivers = new List<string>() {
37+
"geckodriver.exe",
38+
"chromedriver.exe"
39+
};
40+
41+
/// <summary>
42+
/// Determines the location of the correct driver.
43+
/// </summary>
44+
/// <param name="driverName">Which driver the service needs.</param>
45+
/// <returns>
46+
/// The location of the driver.
47+
/// </returns>
48+
public static string DriverPath(string driverName)
49+
{
50+
if (!KnownDrivers.Contains(driverName))
51+
{
52+
throw new WebDriverException("Unable to locate driver with name: " + driverName);
53+
}
54+
var binaryFile = Binary;
55+
if (binaryFile == null) return null;
56+
57+
var arguments = "--driver " + driverName.Replace(".exe", "");
58+
var output = RunCommand(binaryFile, arguments);
59+
return output.Replace("INFO\t", "").TrimEnd();
60+
}
61+
62+
/// <summary>
63+
/// Gets the location of the correct Selenium Manager binary.
64+
/// </summary>
65+
private static string Binary
66+
{
67+
get
68+
{
69+
if (string.IsNullOrEmpty(binary))
70+
{
71+
string folder = "windows";
72+
string extension = ".exe";
73+
74+
if (!Environment.OSVersion.Platform.ToString().StartsWith("Win"))
75+
{
76+
throw new WebDriverException("Selenium Manager only supports Windows in .NET at this time");
77+
}
78+
79+
try
80+
{
81+
string name = "selenium-manager-" + folder;
82+
Stream fileStream = ResourceUtilities.GetResourceStream(name, name);
83+
BinaryReader binReader = new BinaryReader(fileStream, Encoding.ASCII);
84+
byte[] fileBytes = binReader.ReadBytes((int)fileStream.Length);
85+
binReader.Close();
86+
fileStream.Close();
87+
88+
string directoryName = string.Format(CultureInfo.InvariantCulture, "webdriver.{0}",
89+
Guid.NewGuid().ToString("N"));
90+
var path = Path.Combine(Path.GetTempPath(), directoryName + "/" + folder);
91+
Directory.CreateDirectory(path);
92+
var filePath = Path.Combine(path, "selenium-manager" + extension);
93+
94+
using (BinaryWriter binWriter = new BinaryWriter(File.Open(filePath, FileMode.Create)))
95+
{
96+
binWriter.Flush();
97+
binWriter.Write(fileBytes);
98+
binWriter.Close();
99+
}
100+
101+
binary = filePath;
102+
}
103+
catch (Exception ex)
104+
{
105+
throw new WebDriverException("Unable to obtain Selenium Manager", ex);
106+
}
107+
}
108+
109+
return binary;
110+
}
111+
}
112+
113+
/// <summary>
114+
/// Executes a process with the given arguments.
115+
/// </summary>
116+
/// <param name="fileName">The path to the Selenium Manager.</param>
117+
/// <param name="arguments">The switches to be used by Selenium Manager.</param>
118+
/// <returns>
119+
/// the standard output of the execution.
120+
/// </returns>
121+
private static string RunCommand(string fileName, string arguments)
122+
{
123+
Process process = new Process();
124+
process.StartInfo.FileName = fileName;
125+
process.StartInfo.Arguments = arguments;
126+
process.StartInfo.UseShellExecute = false;
127+
process.StartInfo.RedirectStandardOutput = true;
128+
129+
try
130+
{
131+
process.Start();
132+
}
133+
catch (Exception ex)
134+
{
135+
throw new WebDriverException("Error starting process: " + process, ex);
136+
}
137+
138+
String output = process.StandardOutput.ReadToEnd();
139+
140+
if (!output.StartsWith("INFO")) {
141+
throw new WebDriverException("Invalid response from process: " + process);
142+
}
143+
144+
return output;
145+
}
146+
}
147+
}

dotnet/src/webdriver/WebDriver.csproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@
117117
<Visible>False</Visible>
118118
<LogicalName>webdriver_prefs.json</LogicalName>
119119
</EmbeddedResource>
120+
<EmbeddedResource Include="$(ProjectDir)..\..\..\common\manager\windows\selenium-manager.exe">
121+
<Visible>False</Visible>
122+
<LogicalName>selenium-manager-windows</LogicalName>
123+
</EmbeddedResource>
120124
<EmbeddedResource Include="$(ProjectDir)..\..\..\bazel-bin\javascript\webdriver\atoms\get-attribute.js">
121125
<Visible>False</Visible>
122126
<LogicalName>get-attribute.js</LogicalName>
@@ -140,6 +144,10 @@
140144
<Visible>False</Visible>
141145
<LogicalName>webdriver_prefs.json</LogicalName>
142146
</EmbeddedResource>
147+
<EmbeddedResource Include="$(ProjectDir)../../../common/manager/windows/selenium-manager.exe">
148+
<Visible>False</Visible>
149+
<LogicalName>selenium-manager-windows</LogicalName>
150+
</EmbeddedResource>
143151
<EmbeddedResource Include="$(ProjectDir)../../../bazel-bin/javascript/webdriver/atoms/get-attribute.js">
144152
<Visible>False</Visible>
145153
<LogicalName>get-attribute.js</LogicalName>

0 commit comments

Comments
 (0)