-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathTest.cs
345 lines (296 loc) · 12 KB
/
Test.cs
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
using System;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Linq;
using NUnit.Framework;
using System.Dynamic;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using SeleniumExtras.WaitHelpers;
// using OpenQA.Selenium.Environment;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Interactions;
using OpenQA.Selenium.Support.UI;
using fastJSON;
// using OpenQA.Selenium.DevTools;
// using DevToolsSessionDomains = OpenQA.Selenium.DevTools.V100.DevToolsSessionDomains;
using System.Threading;
using Utils;
using Extensions;
/**
* Copyright 2022 Serguei Kouzmine
*/
// using System.Net.WebSockets;
using WebSocketSharp;
using Newtonsoft.Json;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Net;
namespace Program {
[TestFixture]
public class Test {
private StringBuilder verificationErrors = new StringBuilder();
// protected IDevToolsSession session;
protected IWebDriver driver;
private WebDriverWait wait;
private Actions actions;
private const int wait_seconds = 30;
private const long wait_poll_milliseconds = 500;
private String webSocketURL = null;
private String devtoolurl = null;
private int id;
private static int port;
[TearDown]
public void cleanup() {
try {
driver.Quit();
} catch (Exception) {
}
Assert.AreEqual("", verificationErrors.ToString());
}
[SetUp]
public void setup() {
var options = new ChromeOptions();
options.SetLoggingPreference(LogType.Driver, OpenQA.Selenium.LogLevel.Debug);
// options.AddArgument("--headless");
driver = new ChromeDriver(options);
wait = new WebDriverWait(driver, TimeSpan.FromSeconds(wait_seconds));
wait.PollingInterval = TimeSpan.FromMilliseconds(wait_poll_milliseconds);
actions = new Actions(driver);
// TODO: With Selenium 3.x the GetLog is getting
// System.NullReferenceException
ILogs logs = driver.Manage().Logs;
// Assert.IsTrue(logs != null);
var entries = logs.GetLog(LogType.Driver);
// NOTE: System.InvalidCastException in runtime:
// Unable to cast object of type 'OpenQA.Selenium.Chrome.ChromeDriver' to type 'OpenQA.Selenium.Remote.RemoteWebDriver'
// see also: https://groups.google.com/g/selenium-users/c/AfIg2xW1JSc
// after upgrading to Selenium 4
// var sessionId = ((RemoteWebDriver)driver).SessionId.ToString();
// Console.WriteLine("session id: " + sessionId);
// will also see:
// Launching chrome: "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --allow-pre-commit-input --disable-background-networking --disable-backgrounding-occluded-windows --disable-client-side-phishing-detection --disable-default-apps --disable-hang-monitor --disable-popup-blocking --disable-prompt-on-repost --disable-sync --enable-automation --enable-blink-features=ShadowDOMV0 --enable-logging --log-level=0 --no-first-run --no-service-autorun --password-store=basic --remote-debugging-port=0 --test-type=webdriver --use-mock-keychain --user-data-dir="C:\Users\Serguei\AppData\Local\Temp\scoped_dir10036_1503715160" data:
foreach (var entry in entries) {
var line = entry.ToString();
if (line.Contains("DevTools HTTP Request: http://localhost")) {
Console.WriteLine("Inspect log: " + line);
devtoolurl = line.FindMatch(@"(?<url>http://localhost:\d+/)");
// TODO: open connection and read
Console.WriteLine("Read configuration from dev tools url: " + devtoolurl);
var restClient = new RestClient(devtoolurl);
foreach (dynamic response in restClient.Get ("json")) {
Console.WriteLine("type: " + response.type);
Console.WriteLine("webSocketDebuggerUrl: " + response.webSocketDebuggerUrl);
webSocketURL = response.webSocketDebuggerUrl;
}
}
}
}
// only works with Chrome:
// SetUp : System.InvalidOperationException : Access to 'file:///C:/developer/sergueik/powershell_selenium/csharp/protractor-net/Test/bin/Debug/resources/ng_datepicker.htm' from script denied
public void GetPageContent(string filename){
driver.Navigate().GoToUrl(new System.Uri(Path.Combine(Directory.GetCurrentDirectory(), filename)).AbsoluteUri);
}
public void GetLocalHostPageContent(string filename) {
driver.Navigate().GoToUrl(String.Format("http://127.0.0.1:{0}/{1}{2}", port, "resources", filename));
}
[Test]
// [Ignore("Ignore a test")]
public void test1() {
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.OnMessage += (sender, e) => {
var data = e.Data;
Console.WriteLine("raw data: " + data);
// does not work
// Dictionary<string,object> result = Extensions.JSONProcessor.Parse<Dictionary<string,object>>(data);
// id = result["id"];
// Console.WriteLine("result id: " + id);
Dictionary<string,object> response = JSON.ToObject<Dictionary<string,object>>(data);
int.TryParse(response["id"].ToString(), out id);
Console.WriteLine("result id: " + id);
var result = (Dictionary<string,object>)response["result"];
var userAgent = result["userAgent"];
Console.WriteLine("result userAgent: " + userAgent);
};
webSocket.Connect();
id = 534427;
var payload = buildGetVersion(id);
Console.WriteLine(String.Format("sending: {0}", payload));
webSocket.Send(payload);
Thread.Sleep(1000);
}
} catch (Exception e) {
// TODO: WebSocketSharp.WebSocketException: The header of a frame cannot be read from the stream.
Console.WriteLine("Exception (ignored): " + e.ToString());
}
driver.Navigate().GoToUrl(devtoolurl + "json/version");
var pageSource = driver.PageSource;
Thread.Sleep(1000);
StringAssert.Contains("Browser", pageSource);
}
[Test]
public void test2() {
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.OnMessage += (sender, e) => {
var data = e.Data;
Console.WriteLine("raw data: " + data);
Dictionary<string,object> response = JSON.ToObject<Dictionary<string,object>>(data);
int.TryParse(response["id"].ToString(), out id);
Console.WriteLine("result id: " + id);
Console.WriteLine("result: " + response["result"]);
};
webSocket.Connect();
this.id = 534427;
var payload = buildClearGeolocationOverrideMessage(id);
webSocket.Send(payload);
Thread.Sleep(1000);
}
} catch (Exception e) {
Console.WriteLine("Exception (ignored): " + e.ToString());
}
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.OnMessage += (sender, e) => {
var data = e.Data;
Console.WriteLine("raw data: " + data);
Dictionary<string,object> response = JSON.ToObject<Dictionary<string,object>>(data);
id = (int)response["id"];
Console.WriteLine("result id: " + id);
var result = (Dictionary<string,object>)response["result"];
var userAgent = result["userAgent"];
Console.WriteLine("result userAgent: " + userAgent);
};
webSocket.Connect();
const double latitude = 37.422290;
const double longitude = -122.084057;
const long accuracy = 100;
id = 534428;
var payload = buildSetGeolocationOverrideMessage(id, latitude, longitude, accuracy);
webSocket.Send(payload);
Thread.Sleep(1000);
}
} catch (Exception e) {
Console.WriteLine("Exception (ignored): " + e.ToString());
}
driver.Navigate().GoToUrl("https://www.google.com/maps");
By locator = By.CssSelector("div[jsaction*='mouseover:mylocation.main']");
wait.Until(ExpectedConditions.ElementIsVisible(locator));
// alternatively do fluent wait .net style
// per https://stackoverflow.com/questions/49866334/c-sharp-selenium-expectedconditions-is-obsolete
//
IList<IWebElement> elements = driver.FindElements(locator);
Assert.IsTrue(elements.Count > 0);
elements[0].Click();
Thread.Sleep(10000);
}
// filtering does not work wuth local files
[Test]
public void test3() {
id = 534424;
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.Connect();
string[]urls = {"*.js"};
var payload = buildSetBlockedURLs(id, urls);
Console.WriteLine(String.Format("sending: {0}", payload));
webSocket.Send(payload);
}
} catch (Exception e) {
Console.WriteLine("Exception (ignored): " + e.ToString());
}
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.Connect();
webSocket.Send(buildClearBrowserCache(id));
}
} catch (Exception e) {
Console.WriteLine("Exception (ignored): " + e.ToString());
}
try {
using (var webSocket = new WebSocket(webSocketURL)) {
webSocket.Connect();
webSocket.Send(buildSetCacheDisabled(id, true));
}
} catch (Exception e) {
Console.WriteLine("Exception (ignored): " + e.ToString());
}
GetPageContent("ng_basic.htm");
By locator = By.CssSelector("body > table > tbody > tr > td:nth-child(1)");
// wait.Until(ExpectedConditions.ElementIsVisible(locator));
IWebElement element = wait.Until(condition => {
try {
// A local variable named 'element' cannot be declared
// in this scope because it would give a different
// meaning to 'element', which is
// already used in a 'parent or current' scope
// to denote something else (CS0136)
var e = driver.FindElement(locator);
return (e.Displayed) ? e : null;
} catch (StaleElementReferenceException) {
return null;
} catch (NoSuchElementException) {
return null;
}
});
Console.WriteLine("Text: " + element.Text);
driver.Navigate().GoToUrl("http://juliemr.github.io/protractor-demo/");
Thread.Sleep(10000);
}
private String buildGetVersion(int id) {
const string message = "Browser.getVersion";
return buildMessage(id, message);
}
private string buildSetGeolocationOverrideMessage (int id, double latitude, double longitude, long accuracy) {
var param = new Dictionary<string,object>();
const string message = "Emulation.setGeolocationOverride";
param["latitude"] = latitude;
param["longitude"] = longitude;
param["accuracy"] = accuracy;
return buildMessage(id, message, param);
}
private String buildClearBrowserCache(int id) {
const string message = "Network.clearBrowserCache";
return buildMessage(id, message);
}
private String buildSetBlockedURLs(int id, string[] urls) {
const string message = "Network.setBlockedURLs";
var param = new Dictionary<string,object>();
param["urls"] = urls;
return buildMessage(id, message, param);
}
private String buildSetCacheDisabled(int id, bool cacheDisabled) {
const string message = "Network.setCacheDisabled";
var param = new Dictionary<string,object>();
param["cacheDisabled"] = false;
return buildMessage(id, message, param);
}
private String buildClearGeolocationOverrideMessage(int id) {
const string message = "Emulation.clearGeolocationOverride";
return buildMessage(id, message);
}
private String buildMessage(int id, String method) {
return buildMessage(id, method, new Dictionary<string,object>());
}
private String buildMessage(int id, String method, Dictionary<string,object> param) {
var message = new Dictionary<string,object>();
message["params"] = param;
message["method"] = method;
message["id"] = id;
var payload = JSON.ToJSON(message);
Console.WriteLine(String.Format("sending: {0}", payload));
return payload;
}
private void processMessage() {
}
private static bool RemoteServerCertificateValidationCallback(object sender,
X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
return true;
}
}
}