40 internal string webSocketUrl {
get;
set; } =
null;
41 internal static Dictionary<DevToolsMethods, Func<Newtonsoft.Json.Linq.JObject,
object>> resultExtractors {
get;
set; }
45 Process process = browser.MagicHelper.LaunchBrowser((
Browser)browser, URL);
51 dynamic targets = await communicator.SendCommand<
object>(DevToolsMethods.TargetGetTargets,
new { },
null).ConfigureAwait(
false);
54 if (targets ==
null || targets.result ==
null || targets.result.targetInfos ==
null)
56 GPAL.
PublishSimpleEvent(GPALEventType.WARNING,
"No targets found after closing tab",
null, GPALObjectType.None);
59 foreach (dynamic target
in targets.result.targetInfos)
61 string targetType = target.type?.ToString();
62 string targetUrl = target.url?.ToString();
63 if (targetType ==
"page" && targetUrl !=
null)
67 return target.targetId?.ToString();
72 var availableUrls =
string.Join(
", ", ((Newtonsoft.Json.Linq.JArray)targets.result.targetInfos)
73 .Where(t => t[
"type"]?.ToString() ==
"page")
74 .Select(t => t[
"url"]?.ToString() ??
"null"));
75 GPAL.
PublishSimpleEvent(GPALEventType.WARNING, $
"No page target found after closing tab. Available page URLs: [{availableUrls}]",
null, GPALObjectType.None);
88 internal static string GetWebSocketUrl(
string puppeteerUrl,
int waitMilliseconds = 20_000)
91 Exception lastException =
null;
92 Stopwatch waited = Stopwatch.StartNew();
95 while (
null == retVal && waited.ElapsedMilliseconds < waitMilliseconds)
106 HttpWebRequest request = (HttpWebRequest)WebRequest.Create($
"{puppeteerUrl.Replace("localhost
", "127.0.0.1
")}/json/version");
107 request.Method =
"GET";
108 request.Timeout = 2_000;
109 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
110 using StreamReader reader =
new StreamReader(response.GetResponseStream());
111 string json = reader.ReadToEnd();
112 var versionInfo = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
113 retVal = versionInfo[
"webSocketDebuggerUrl"];
126 if (
null != retVal && 1 < attempts)
127 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Browser debug port at [{puppeteerUrl}] answered after [{waited.ElapsedMilliseconds}]ms and [{attempts}] attempts",
null, GPALObjectType.None);
128 else if (
null == retVal)
129 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Puppeteer WebSocket URL from [{puppeteerUrl}], no answer in [{waited.ElapsedMilliseconds}]ms over [{attempts}] attempts",
null, GPALObjectType.None, lastException);
152 internal static string GetChromePath()
156 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
158 return ResolveExePath(
162 Path.Combine(localAppData,
@"Google\Chrome\Application\chrome.exe")
166 @"C:\Program Files\Google\Chrome\Application\chrome.exe",
167 @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
171 @"C:\Program Files\Google\Chrome Beta\Application\chrome.exe",
172 @"C:\Program Files\Google\Chrome Dev\Application\chrome.exe"
178 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Chrome path.",
null, GPALObjectType.None, ex);
186 internal static string GetEdgePath()
190 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
192 return ResolveExePath(
196 Path.Combine(localAppData,
@"Microsoft\Edge\Application\msedge.exe"),
197 Path.Combine(localAppData,
@"Microsoft\Edge Beta\Application\msedge.exe"),
198 Path.Combine(localAppData,
@"Microsoft\Edge Dev\Application\msedge.exe"),
199 Path.Combine(localAppData,
@"Microsoft\Edge SxS\Application\msedge.exe")
203 @"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
204 @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
211 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving MS Edge path.",
null, GPALObjectType.None, ex);
219 internal static string GetFirefoxPath()
223 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
225 return ResolveExePath(
229 Path.Combine(localAppData,
@"Mozilla Firefox\firefox.exe"),
230 Path.Combine(localAppData,
@"Mozilla Firefox Nightly\firefox.exe")
234 @"C:\Program Files\Mozilla Firefox\firefox.exe",
235 @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
239 @"C:\Program Files\Firefox Developer Edition\firefox.exe"
245 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Firefox path.",
null, GPALObjectType.None, ex);
253 private static string ResolveExePath(
string exeName,
string[] userPaths,
string[] systemPaths,
string[] variantPaths)
255 string result =
null;
259 string keyPath =
@"Software\Microsoft\Windows\CurrentVersion\App Paths\" + exeName;
261 Func<string>[] resolvers =
new Func<string>[]
263 () => GetFromRegistry(RegistryHive.LocalMachine, keyPath, RegistryView.Registry64),
264 () => GetFromRegistry(RegistryHive.LocalMachine, keyPath, RegistryView.Registry32),
265 () => GetFromRegistry(RegistryHive.CurrentUser, keyPath, RegistryView.Default),
266 () => GetFromWhere(exeName),
267 () => GetFromPaths(userPaths),
268 () => GetFromPaths(systemPaths),
269 () => GetFromPaths(variantPaths)
272 foreach (var resolver
in resolvers)
291 private static string GetFromRegistry(RegistryHive hive,
string keyPath, RegistryView view)
295 using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
296 using (var key = baseKey.OpenSubKey(keyPath))
300 object value = key.GetValue(
string.Empty);
303 string path = value.ToString();
304 if (!
string.IsNullOrWhiteSpace(path) && File.Exists(path))
323 private static string GetFromWhere(
string exeName)
327 var psi =
new ProcessStartInfo
331 RedirectStandardOutput =
true,
332 UseShellExecute =
false,
333 CreateNoWindow =
true
336 using (var process = Process.Start(psi))
340 string line = process.StandardOutput.ReadLine();
341 if (!
string.IsNullOrWhiteSpace(line) && File.Exists(line))
359 private static string GetFromPaths(
string[] paths)
366 foreach (var path
in paths)
368 if (!
string.IsNullOrWhiteSpace(path) && File.Exists(path))
378 public static string GetScreenMaxSize()
383 foreach (Screen screen
in Screen.AllScreens)
385 if (screen.Bounds.Width > maxWidth)
387 maxWidth = screen.Bounds.Width;
390 if (screen.Bounds.Height > maxHeight)
392 maxHeight = screen.Bounds.Height;
396 return $
"{maxWidth},{maxHeight}";
398 public static string GetScreenWidth()
402 foreach (Screen screen
in Screen.AllScreens)
404 if (screen.Bounds.Width > maxWidth)
406 maxWidth = screen.Bounds.Width;
410 return $
"{maxWidth}";
412 public static string GetScreenHeight()
416 foreach (Screen screen
in Screen.AllScreens)
418 if (screen.Bounds.Height > maxHeight)
420 maxHeight = screen.Bounds.Height;
424 return $
"{maxHeight}";
427 public static int GetScreenWidthInt()
431 foreach (Screen screen
in Screen.AllScreens)
433 if (screen.Bounds.Width > maxWidth)
435 maxWidth = screen.Bounds.Width;
441 public static int GetScreenHeightInt()
445 foreach (Screen screen
in Screen.AllScreens)
447 if (screen.Bounds.Height > maxHeight)
449 maxHeight = screen.Bounds.Height;