Skip to content

Commit 80568b8

Browse files
authored
fix: Update Node path to compile with appium 2 and make him cross-platform (#659)
* fix: Update WindowsNode path to compile with appium 2 refactor: Move Appium.js path retrieval to helpers.paths class * refactor!: Retrieve npm prefix path and use cross-platform commands to get appium script * fix: npm install prefix and npm install path mixup * fix: make PathToNode compatible with both Windows and Unix-based systems * chore: Remove redundant NodePaths from the resources * chore: Remove comment section * chore: Add exception if npm path cannot be detected * chore: Rename _pathToCustomizedAppiumJs * chore: Add timeout for RunCommand chore: Remove private var envPlatform * chore: Optimize code performance * chore: Optimize path readability on Windows platforms * chore: Switch from `npm list -g --depth=0` to `npm -g root` for better performance * chore: Remove comment section * chore: Throw specific exception for npm commands * chore: Move declaration near reference * chore: Rename GetAppiumJsPath * chore: Improve NPM path not found exception * chore: Rename resource file name * chore: Remove path replacement and add XML DOC * chore: Verify exit code on RunCommand() from Npm * chore: Use GetNpmExecutablePath() on all platforms * chore: log command upon errorin RunCommand() * chore: Improve NpmNotFoundException log * chore: Rename GetAppiumPackageIndexPath() * chore: Simplify InitAppiumPackageIndexPath() * chore: Simplify paths creation * chore: More exceptions mapping for RunCommand * fix: More exceptions improvements in RunCommand() * fix: Exceptions makeover pt. 3 * fix: npm typo * chore: Minimise try-catch * chore: Remove unnecessary using
1 parent 006ca35 commit 80568b8

File tree

10 files changed

+178
-74
lines changed

10 files changed

+178
-74
lines changed

test/integration/Properties/Resources.Designer.cs

Lines changed: 5 additions & 35 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/integration/Properties/Resources.resx

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,15 +118,6 @@
118118
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119119
</resheader>
120120
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
121-
<data name="PathToLinuxNode" type="System.Resources.ResXFileRef, System.Windows.Forms">
122-
<value>..\helpers\PathToLinuxNode;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
123-
</data>
124-
<data name="PathToMacOSNode" type="System.Resources.ResXFileRef, System.Windows.Forms">
125-
<value>..\helpers\PathToMacOSNode;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
126-
</data>
127-
<data name="PathToWindowsNode" type="System.Resources.ResXFileRef, System.Windows.Forms">
128-
<value>..\helpers\PathToWindowsNode;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
129-
</data>
130121
<data name="ApiDemos_debug" type="System.Resources.ResXFileRef, System.Windows.Forms">
131122
<value>..\apps\ApiDemos-debug.apk;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
132123
</data>

test/integration/ServerTests/AppiumLocalServerLaunchingTest.cs

Lines changed: 5 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
using System.Net;
55
using System.Text;
66
using System.Threading;
7-
using Appium.Net.Integration.Tests.Properties;
7+
using Appium.Net.Integration.Tests.Helpers;
88
using NUnit.Framework;
9-
using OpenQA.Selenium;
109
using OpenQA.Selenium.Appium;
1110
using OpenQA.Selenium.Appium.Enums;
1211
using OpenQA.Selenium.Appium.Service;
@@ -18,15 +17,12 @@ namespace Appium.Net.Integration.Tests.ServerTests
1817
[TestFixture]
1918
public class AppiumLocalServerLaunchingTest
2019
{
21-
private string _pathToCustomizedAppiumJs;
20+
private string _pathToAppiumPackageIndex;
2221
private string _testIp;
2322

2423
[OneTimeSetUp]
2524
public void BeforeAll()
2625
{
27-
var isWindows = Platform.CurrentPlatform.IsPlatformType(PlatformType.Windows);
28-
var isMacOs = Platform.CurrentPlatform.IsPlatformType(PlatformType.Mac);
29-
var isLinux = Platform.CurrentPlatform.IsPlatformType(PlatformType.Linux);
3026

3127
IPHostEntry host;
3228
var hostName = Dns.GetHostName();
@@ -41,25 +37,7 @@ public void BeforeAll()
4137
}
4238
Console.WriteLine(_testIp);
4339

44-
byte[] bytes;
45-
if (isWindows)
46-
{
47-
bytes = Resources.PathToWindowsNode;
48-
_pathToCustomizedAppiumJs = Encoding.UTF8.GetString(bytes);
49-
return;
50-
}
51-
if (isMacOs)
52-
{
53-
bytes = Resources.PathToMacOSNode;
54-
_pathToCustomizedAppiumJs = Encoding.UTF8.GetString(bytes);
55-
return;
56-
}
57-
if (isLinux)
58-
{
59-
bytes = Resources.PathToLinuxNode;
60-
_pathToCustomizedAppiumJs = Encoding.UTF8.GetString(bytes);
61-
return;
62-
}
40+
_pathToAppiumPackageIndex = new Paths().PathToAppiumPackageIndex;
6341
}
6442

6543
[Test]
@@ -105,7 +83,7 @@ public void CheckAbilityToBuildServiceUsingNodeDefinedInProperties()
10583
AppiumLocalService service = null;
10684
try
10785
{
108-
var definedNode = _pathToCustomizedAppiumJs;
86+
var definedNode = _pathToAppiumPackageIndex;
10987
Environment.SetEnvironmentVariable(AppiumServiceConstants.AppiumBinaryPath, definedNode);
11088
service = AppiumLocalService.BuildDefaultService();
11189
service.Start();
@@ -124,7 +102,7 @@ public void CheckAbilityToBuildServiceUsingNodeDefinedExplicitly()
124102
AppiumLocalService service = null;
125103
try
126104
{
127-
service = new AppiumServiceBuilder().WithAppiumJS(new FileInfo(_pathToCustomizedAppiumJs)).Build();
105+
service = new AppiumServiceBuilder().WithAppiumJS(new FileInfo(_pathToAppiumPackageIndex)).Build();
128106
service.Start();
129107
Assert.AreEqual(true, service.IsRunning);
130108
}

test/integration/helpers/Npm.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
using System;
2+
using System.ComponentModel;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
6+
namespace Appium.Net.Integration.Tests.helpers
7+
{
8+
internal class Npm
9+
{
10+
11+
public static string GetNpmPrefixPath()
12+
{
13+
string npmPath = GetNpmExecutablePath();
14+
string npmPrefixPath = RunCommand(npmPath, "-g root");
15+
16+
return npmPrefixPath.Trim();
17+
}
18+
19+
private static string RunCommand(string command, string arguments, int timeoutMilliseconds = 30000)
20+
{
21+
int exitCode;
22+
string output;
23+
try
24+
{
25+
using (Process process = new Process
26+
{
27+
StartInfo = new ProcessStartInfo
28+
{
29+
FileName = command,
30+
Arguments = arguments,
31+
RedirectStandardOutput = true,
32+
RedirectStandardError = true,
33+
UseShellExecute = false,
34+
CreateNoWindow = true,
35+
}
36+
})
37+
{
38+
process.Start();
39+
40+
output = process.StandardOutput.ReadToEnd();
41+
string errorOutput = process.StandardError.ReadToEnd();
42+
_ = process.WaitForExit(timeoutMilliseconds);
43+
44+
exitCode = process.ExitCode;
45+
}
46+
if ((exitCode == 1) && command.Contains("npm"))
47+
{
48+
Console.WriteLine($"npm Error upon command: `{arguments}`. {output}");
49+
throw new NpmUnknownCommandException($"Command: `{arguments}` exited with code {exitCode}. Error: {output}");
50+
}
51+
52+
return output;
53+
}
54+
55+
catch (Win32Exception ex) when (command.Contains("npm"))
56+
{
57+
Console.WriteLine(ex.Message);
58+
throw new NpmNotFoundException($"npm not found under {command}", ex);
59+
}
60+
}
61+
62+
private static string GetNpmExecutablePath()
63+
{
64+
string commandName = IsWindows() ? "where" : "which";
65+
string result = RunCommand(commandName, "npm");
66+
67+
string npmPath;
68+
69+
string[] lines = result?.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
70+
71+
if (IsWindows())
72+
{
73+
npmPath = lines?.FirstOrDefault(line => !string.IsNullOrWhiteSpace(line) && line.EndsWith("npm.cmd"));
74+
}
75+
else
76+
{
77+
npmPath = lines?.FirstOrDefault(line => !string.IsNullOrWhiteSpace(line));
78+
}
79+
80+
if (string.IsNullOrWhiteSpace(npmPath))
81+
{
82+
throw new NpmNotFoundException("NPM executable not found. Please make sure the NPM executable is installed and check the configured PATH environment variable.");
83+
}
84+
85+
return npmPath;
86+
}
87+
88+
private static bool IsWindows()
89+
{
90+
return Environment.OSVersion.Platform == PlatformID.Win32NT;
91+
}
92+
}
93+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
3+
namespace Appium.Net.Integration.Tests.helpers
4+
{
5+
public class NpmNotFoundException : Exception
6+
{
7+
public NpmNotFoundException()
8+
: base("Node Package Manager (npm) cannot be found. Make sure Node.js is installed and present in PATH.")
9+
{
10+
}
11+
12+
public NpmNotFoundException(string message)
13+
: base(message)
14+
{
15+
}
16+
17+
public NpmNotFoundException(string message, Exception innerException)
18+
: base(message, innerException)
19+
{
20+
}
21+
}
22+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System;
2+
3+
namespace Appium.Net.Integration.Tests.helpers
4+
{
5+
public class NpmUnknownCommandException : Exception
6+
{
7+
public NpmUnknownCommandException()
8+
: base("Unknown npm command encountered. ")
9+
{
10+
}
11+
12+
public NpmUnknownCommandException(string message)
13+
: base(message)
14+
{
15+
}
16+
}
17+
}

test/integration/helpers/PathToLinuxNode

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/integration/helpers/PathToMacOSNode

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/integration/helpers/PathToWindowsNode

Lines changed: 0 additions & 1 deletion
This file was deleted.

test/integration/helpers/Paths.cs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Appium.Net.Integration.Tests.helpers;
2+
using System.IO;
3+
4+
namespace Appium.Net.Integration.Tests.Helpers
5+
{
6+
internal class Paths
7+
{
8+
private string _pathToAppiumPackageIndex;
9+
10+
public string PathToAppiumPackageIndex
11+
{
12+
get
13+
{
14+
if (_pathToAppiumPackageIndex == null)
15+
{
16+
InitAppiumPackageIndexPath();
17+
}
18+
return _pathToAppiumPackageIndex;
19+
}
20+
}
21+
22+
/// <summary>
23+
/// Initializes the Appium package index path by combining the components "appium" and "index.js" with the npm prefix path.
24+
/// </summary>
25+
/// <remarks>
26+
/// This method sets the _pathToAppiumPackageIndex variable by combining the specified components with the npm prefix path.
27+
/// </remarks>
28+
private void InitAppiumPackageIndexPath()
29+
{
30+
string[] appiumJsPathComponents = { "appium", "index.js" };
31+
string npmPath = Npm.GetNpmPrefixPath();
32+
33+
_pathToAppiumPackageIndex = Path.Combine(npmPath, Path.Combine(appiumJsPathComponents));
34+
}
35+
}
36+
}

0 commit comments

Comments
 (0)