Skip to content

Commit 46b0cdf

Browse files
authored
feat: Migrate AppiumLocalService to Appium 2 (#529)
*migration to appium2.0 [Removal of /wd/hub] * Removal of redundent using on Integration.Tests.Properties * Add test for StartService using basePath flag Add Support for basePath argument Add BasePath to common Appium server arguments Add StatusUrl const to appiumService Add CreateStatusUrl function Update link to list of common Appium server arguments * Work with ArgsList for cleaner code * Skip GenerateArgsList if it's not null * Minor code fixes Remove unused Exceptions variables Fix unused span parameter
1 parent d408678 commit 46b0cdf

File tree

5 files changed

+106
-20
lines changed

5 files changed

+106
-20
lines changed

src/Appium.Net/Appium/Service/AppiumLocalService.cs

+70-14
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using System.Collections.Generic;
1919
using System.Diagnostics;
2020
using System.IO;
21+
using System.Linq;
2122
using System.Net;
2223
using System.Runtime.CompilerServices;
2324

@@ -32,6 +33,7 @@ public class AppiumLocalService : ICommandServer
3233
private readonly TimeSpan InitializationTimeout;
3334
private readonly IDictionary<string, string> EnvironmentForProcess;
3435
private Process Service;
36+
private List<string> ArgsList;
3537

3638
/// <summary>
3739
/// Creates an instance of AppiumLocalService without special settings
@@ -40,11 +42,11 @@ public class AppiumLocalService : ICommandServer
4042
public static AppiumLocalService BuildDefaultService() => new AppiumServiceBuilder().Build();
4143

4244
internal AppiumLocalService(
43-
FileInfo nodeJS,
44-
string arguments,
45-
IPAddress ip,
45+
FileInfo nodeJS,
46+
string arguments,
47+
IPAddress ip,
4648
int port,
47-
TimeSpan initializationTimeout,
49+
TimeSpan initializationTimeout,
4850
IDictionary<string, string> environmentForProcess)
4951
{
5052
NodeJS = nodeJS;
@@ -58,7 +60,7 @@ internal AppiumLocalService(
5860
/// <summary>
5961
/// The base URL for the managed appium server.
6062
/// </summary>
61-
public Uri ServiceUrl => new Uri($"http://{IP.ToString()}:{Convert.ToString(Port)}/wd/hub");
63+
public Uri ServiceUrl => new Uri($"http://{IP}:{Convert.ToString(Port)}");
6264

6365
/// <summary>
6466
/// Event that can be used to capture the output of the service
@@ -131,7 +133,7 @@ private void DestroyProcess()
131133
{
132134
Service.Kill();
133135
}
134-
catch (Exception ignored)
136+
catch
135137
{
136138
}
137139
finally
@@ -175,26 +177,80 @@ public bool IsRunning
175177
}
176178
}
177179

178-
private bool Ping(TimeSpan span)
180+
private string GetArgsValue(string argStr)
179181
{
180-
bool pinged = false;
182+
int idx;
183+
idx= ArgsList.IndexOf(argStr);
184+
return ArgsList[idx + 1];
185+
}
181186

182-
Uri status;
187+
private string ParseBasePath()
188+
{
189+
if (ArgsList.Contains("--base-path"))
190+
{
191+
return GetArgsValue("--base-path");
192+
}
193+
else if (ArgsList.Contains("-pa"))
194+
{
195+
return GetArgsValue("-pa");
196+
}
197+
return AppiumServiceConstants.DefaultBasePath;
198+
}
183199

200+
private void GenerateArgsList()
201+
{
202+
ArgsList = Arguments.Split(' ').ToList();
203+
}
204+
private Uri CreateStatusUrl()
205+
{
206+
Uri status;
184207
Uri service = ServiceUrl;
208+
209+
if (ArgsList == null)
210+
{
211+
GenerateArgsList();
212+
}
213+
string basePath = ParseBasePath();
214+
bool defBasePath = basePath.Equals(AppiumServiceConstants.DefaultBasePath);
215+
185216
if (service.IsLoopback || IP.ToString().Equals(AppiumServiceConstants.DefaultLocalIPAddress))
186217
{
187-
status = new Uri("http://localhost:" + Convert.ToString(Port) + "/wd/hub/status");
218+
var tmpStatus = "http://localhost:" + Convert.ToString(Port);
219+
if (defBasePath)
220+
{
221+
status = new Uri(tmpStatus + AppiumServiceConstants.StatusUrl);
222+
}
223+
else
224+
{
225+
status = new Uri(tmpStatus + basePath + AppiumServiceConstants.StatusUrl);
226+
}
188227
}
189228
else
190229
{
191-
status = new Uri(service.ToString() + "/status");
230+
if (defBasePath)
231+
{
232+
status = new Uri(service, AppiumServiceConstants.StatusUrl);
233+
}
234+
else
235+
{
236+
status = new Uri(service, basePath + AppiumServiceConstants.StatusUrl);
237+
}
192238
}
239+
return status;
240+
}
241+
242+
private bool Ping(TimeSpan span)
243+
{
244+
bool pinged = false;
245+
246+
Uri status;
247+
248+
status = CreateStatusUrl();
193249

194-
DateTime endTime = DateTime.Now.Add(this.InitializationTimeout);
250+
DateTime endTime = DateTime.Now.Add(span);
195251
while (!pinged & DateTime.Now < endTime)
196252
{
197-
HttpWebRequest request = (HttpWebRequest) HttpWebRequest.Create(status);
253+
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(status);
198254
HttpWebResponse response = null;
199255
try
200256
{
@@ -203,7 +259,7 @@ private bool Ping(TimeSpan span)
203259
pinged = true;
204260
}
205261
}
206-
catch (Exception e)
262+
catch
207263
{
208264
pinged = false;
209265
}

src/Appium.Net/Appium/Service/AppiumServiceConstants.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ public sealed class AppiumServiceConstants
3737
internal readonly static string Bash = "/bin/bash";
3838
internal readonly static string CmdExe = "cmd.exe";
3939
internal readonly static string Node = "node";
40-
40+
4141
internal static readonly string DefaultLocalIPAddress = "127.0.0.1";
4242
internal static readonly int DefaultAppiumPort = 4723;
43+
internal static readonly string StatusUrl = "/status";
44+
internal static readonly string DefaultBasePath = "/";
4345

4446
internal static readonly string AppiumFolder = "appium";
4547
internal static readonly string BinFolder = "bin";

src/Appium.Net/Appium/Service/Options/GeneralOptionList.cs

+11-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace OpenQA.Selenium.Appium.Service.Options
2020
///<summary>
2121
/// Here is the list of common Appium server arguments.
2222
/// All flags are optional, but some are required in conjunction with certain others.
23-
/// The full list is available here: http://appium.io/slate/en/master/?ruby#appium-server-arguments
23+
/// The full list is available here: https://appium.io/docs/en/writing-running-appium/server-args/
2424
/// </summary>
2525
public sealed class GeneralOptionList : BaseOptionList
2626
{
@@ -30,6 +30,16 @@ public sealed class GeneralOptionList : BaseOptionList
3030
public static KeyValuePair<string, string> Shell(string value) =>
3131
GetKeyValuePair("--shell", value);
3232

33+
/// <summary>
34+
/// Initial path segment where the Appium/WebDriver API will be hosted. Every endpoint will be behind this segment. <br/>
35+
/// Default: for Appium 2.0: / ; for Appium 1: /wd/hub <br/>
36+
/// Example: --base-path /my/path/prefix
37+
/// </summary>
38+
/// <param name="value"></param>
39+
/// <returns></returns>
40+
public static KeyValuePair<string, string> BasePath(string value) =>
41+
GetKeyValuePair("--base-path", value);
42+
3343
///<summary>
3444
/// callback IP Address (default: same as address) <br/>
3545
/// Sample <br/>

test/integration/Properties/Resources.Designer.cs

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/ServerTests/AppiumLocalServerLaunchingTest.cs

+18
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,24 @@ public void CheckAbilityToStartServiceUsingFlags()
184184
}
185185
}
186186

187+
[Test]
188+
public void CheckAbilityToStartServiceUsingBasePathFlag()
189+
{
190+
AppiumLocalService service = null;
191+
var args = new OptionCollector().AddArguments(GeneralOptionList.BasePath("/wd/hub"));
192+
try
193+
{
194+
service = new AppiumServiceBuilder().WithArguments(args).Build();
195+
service.Start();
196+
Assert.IsTrue(service.IsRunning);
197+
}
198+
finally
199+
{
200+
service?.Dispose();
201+
}
202+
}
203+
204+
187205
[Test]
188206
public void CheckAbilityToStartServiceUsingCapabilities()
189207
{

0 commit comments

Comments
 (0)