forked from appium/dotnet-client
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAppiumLocalServiceTests.cs
More file actions
185 lines (162 loc) · 7.01 KB
/
AppiumLocalServiceTests.cs
File metadata and controls
185 lines (162 loc) · 7.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
using NUnit.Framework;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using OpenQA.Selenium.Appium.Service;
using OpenQA.Selenium.Appium.Service.Options;
namespace Appium.Net.Integration.Tests.ServerTests
{
[TestFixture]
public class AppiumLocalServiceTests
{
private AppiumLocalService appiumServer;
[OneTimeSetUp]
public void GlobalSetup()
{
// OptionCollector can be customized as needed
var optionCollector = new OptionCollector();
// Try to get Appium path from environment variable or npm root -g
string appiumPath = Environment.GetEnvironmentVariable(AppiumServiceConstants.AppiumBinaryPath);
if (string.IsNullOrEmpty(appiumPath))
{
try
{
bool isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
var startInfo = new ProcessStartInfo
{
// On Windows, using 'cmd /c' is often more reliable for resolving PATHs
FileName = isWindows ? "cmd.exe" : "npm",
Arguments = isWindows ? "/c npm root -g" : "root -g",
RedirectStandardOutput = true,
RedirectStandardError = true, // Capture errors too!
UseShellExecute = false,
CreateNoWindow = true
};
using var process = Process.Start(startInfo);
string output = process.StandardOutput.ReadToEnd()?.Trim();
string error = process.StandardError.ReadToEnd()?.Trim();
process.WaitForExit();
if (!string.IsNullOrEmpty(output))
{
appiumPath = Path.Combine(output, "appium", "build", "lib", "main.js");
}
else if (!string.IsNullOrEmpty(error))
{
Console.WriteLine($"NPM Error: {error}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Process failed: {ex.Message}");
}
}
if (string.IsNullOrEmpty(appiumPath) || !File.Exists(appiumPath))
{
Assert.Ignore("Appium is not installed or not found on this machine. Skipping AppiumLocalServiceTests.");
}
appiumServer = new AppiumServiceBuilder()
.WithAppiumJS(new FileInfo(appiumPath))
.WithIPAddress("127.0.0.1")
.UsingAnyFreePort()
.WithArguments(optionCollector)
.Build();
appiumServer.Start();
// Check that the server is running after startup
Assert.That(appiumServer.IsRunning, Is.True, "Appium server should be running after Start()");
}
[OneTimeTearDown]
public void GlobalTeardown()
{
appiumServer?.Dispose();
}
private AppiumLocalService CreateService()
{
// Use dummy values for constructor
return (AppiumLocalService)Activator.CreateInstance(
typeof(AppiumLocalService),
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new object[]
{
new System.IO.FileInfo("node"),
"",
System.Net.IPAddress.Loopback,
4723,
TimeSpan.FromSeconds(5),
null
},
null
);
}
private MethodInfo GetTryGracefulShutdownOnWindows()
{
return typeof(AppiumLocalService).GetMethod(
"TryGracefulShutdownOnWindows",
BindingFlags.Instance | BindingFlags.NonPublic
);
}
[Test]
public void TryGracefulShutdownOnWindows_ReturnsTrue_WhenProcessIsNull()
{
var service = CreateService();
var method = GetTryGracefulShutdownOnWindows();
Assert.That(method, Is.Not.Null, "TryGracefulShutdownOnWindows method not found. Check for signature or name changes.");
var result = (bool)method.Invoke(service, new object[] { null, 5000 });
Assert.That(result, Is.True);
}
[Test]
public void TryGracefulShutdownOnWindows_ReturnsTrue_WhenProcessHasExited()
{
var service = CreateService();
var method = GetTryGracefulShutdownOnWindows();
Assert.That(method, Is.Not.Null, "TryGracefulShutdownOnWindows method not found. Check for signature or name changes.");
var proc = new Process();
proc.Dispose();
bool result;
try
{
result = (bool)method.Invoke(service, new object[] { proc, 5000 });
}
catch (TargetInvocationException ex) when (ex.InnerException is InvalidOperationException)
{
result = true;
}
Assert.That(result, Is.True);
}
[Test]
public void TryGracefulShutdownOnWindows_ReturnsFalse_WhenNotWindows()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("Test only valid on non-Windows platforms.");
}
var service = CreateService();
var method = GetTryGracefulShutdownOnWindows();
Assert.That(method, Is.Not.Null, "TryGracefulShutdownOnWindows method not found. Check for signature or name changes.");
var proc = Process.GetCurrentProcess();
var result = (bool)method.Invoke(service, new object[] { proc, 5000 });
Assert.That(result, Is.False);
}
[Test]
public void TryGracefulShutdownOnWindows_RealProcess_DoesNotThrow()
{
var method = typeof(AppiumLocalService)
.GetMethod("TryGracefulShutdownOnWindows", BindingFlags.Instance | BindingFlags.NonPublic);
Assert.That(method, Is.Not.Null, "TryGracefulShutdownOnWindows method not found. Check for signature or name changes.");
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Assert.Ignore("Test only valid on Windows platforms.");
}
var result = (bool)method.Invoke(appiumServer, new object[] { GetAppiumProcess(appiumServer), 5000 });
Assert.That(result, Is.True.Or.False, "Method should not throw and should return a bool.");
}
private Process GetAppiumProcess(AppiumLocalService service)
{
// Use reflection to access the private 'Service' field
var field = typeof(AppiumLocalService).GetField("Service", BindingFlags.Instance | BindingFlags.NonPublic);
return (Process)field.GetValue(service);
}
}
}