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)
101 HttpWebRequest request = (HttpWebRequest)WebRequest.Create($
"{puppeteerUrl}/json/version");
102 request.Method =
"GET";
103 request.Timeout = 2_000;
104 HttpWebResponse response = (HttpWebResponse)request.GetResponse();
105 using StreamReader reader =
new StreamReader(response.GetResponseStream());
106 string json = reader.ReadToEnd();
107 var versionInfo = JsonSerializer.Deserialize<Dictionary<string, string>>(json);
108 retVal = versionInfo[
"webSocketDebuggerUrl"];
121 if (
null != retVal && 1 < attempts)
122 GPAL.
PublishSimpleEvent(GPALEventType.DEBUG, $
"Browser debug port at [{puppeteerUrl}] answered after [{waited.ElapsedMilliseconds}]ms and [{attempts}] attempts",
null, GPALObjectType.None);
123 else if (
null == retVal)
124 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Puppeteer WebSocket URL from [{puppeteerUrl}], no answer in [{waited.ElapsedMilliseconds}]ms over [{attempts}] attempts",
null, GPALObjectType.None, lastException);
147 internal static string GetChromePath()
151 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
153 return ResolveExePath(
157 Path.Combine(localAppData,
@"Google\Chrome\Application\chrome.exe")
161 @"C:\Program Files\Google\Chrome\Application\chrome.exe",
162 @"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
166 @"C:\Program Files\Google\Chrome Beta\Application\chrome.exe",
167 @"C:\Program Files\Google\Chrome Dev\Application\chrome.exe"
173 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Chrome path.",
null, GPALObjectType.None, ex);
181 internal static string GetEdgePath()
185 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
187 return ResolveExePath(
191 Path.Combine(localAppData,
@"Microsoft\Edge\Application\msedge.exe"),
192 Path.Combine(localAppData,
@"Microsoft\Edge Beta\Application\msedge.exe"),
193 Path.Combine(localAppData,
@"Microsoft\Edge Dev\Application\msedge.exe"),
194 Path.Combine(localAppData,
@"Microsoft\Edge SxS\Application\msedge.exe")
198 @"C:\Program Files\Microsoft\Edge\Application\msedge.exe",
199 @"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
206 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving MS Edge path.",
null, GPALObjectType.None, ex);
214 internal static string GetFirefoxPath()
218 string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
220 return ResolveExePath(
224 Path.Combine(localAppData,
@"Mozilla Firefox\firefox.exe"),
225 Path.Combine(localAppData,
@"Mozilla Firefox Nightly\firefox.exe")
229 @"C:\Program Files\Mozilla Firefox\firefox.exe",
230 @"C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
234 @"C:\Program Files\Firefox Developer Edition\firefox.exe"
240 GPAL.
PublishSimpleEvent(GPALEventType.EXCEPTION, $
"ERROR retrieving Firefox path.",
null, GPALObjectType.None, ex);
248 private static string ResolveExePath(
string exeName,
string[] userPaths,
string[] systemPaths,
string[] variantPaths)
250 string result =
null;
254 string keyPath =
@"Software\Microsoft\Windows\CurrentVersion\App Paths\" + exeName;
256 Func<string>[] resolvers =
new Func<string>[]
258 () => GetFromRegistry(RegistryHive.LocalMachine, keyPath, RegistryView.Registry64),
259 () => GetFromRegistry(RegistryHive.LocalMachine, keyPath, RegistryView.Registry32),
260 () => GetFromRegistry(RegistryHive.CurrentUser, keyPath, RegistryView.Default),
261 () => GetFromWhere(exeName),
262 () => GetFromPaths(userPaths),
263 () => GetFromPaths(systemPaths),
264 () => GetFromPaths(variantPaths)
267 foreach (var resolver
in resolvers)
286 private static string GetFromRegistry(RegistryHive hive,
string keyPath, RegistryView view)
290 using (var baseKey = RegistryKey.OpenBaseKey(hive, view))
291 using (var key = baseKey.OpenSubKey(keyPath))
295 object value = key.GetValue(
string.Empty);
298 string path = value.ToString();
299 if (!
string.IsNullOrWhiteSpace(path) && File.Exists(path))
318 private static string GetFromWhere(
string exeName)
322 var psi =
new ProcessStartInfo
326 RedirectStandardOutput =
true,
327 UseShellExecute =
false,
328 CreateNoWindow =
true
331 using (var process = Process.Start(psi))
335 string line = process.StandardOutput.ReadLine();
336 if (!
string.IsNullOrWhiteSpace(line) && File.Exists(line))
354 private static string GetFromPaths(
string[] paths)
361 foreach (var path
in paths)
363 if (!
string.IsNullOrWhiteSpace(path) && File.Exists(path))
373 public static string GetScreenMaxSize()
378 foreach (Screen screen
in Screen.AllScreens)
380 if (screen.Bounds.Width > maxWidth)
382 maxWidth = screen.Bounds.Width;
385 if (screen.Bounds.Height > maxHeight)
387 maxHeight = screen.Bounds.Height;
391 return $
"{maxWidth},{maxHeight}";
393 public static string GetScreenWidth()
397 foreach (Screen screen
in Screen.AllScreens)
399 if (screen.Bounds.Width > maxWidth)
401 maxWidth = screen.Bounds.Width;
405 return $
"{maxWidth}";
407 public static string GetScreenHeight()
411 foreach (Screen screen
in Screen.AllScreens)
413 if (screen.Bounds.Height > maxHeight)
415 maxHeight = screen.Bounds.Height;
419 return $
"{maxHeight}";
422 public static int GetScreenWidthInt()
426 foreach (Screen screen
in Screen.AllScreens)
428 if (screen.Bounds.Width > maxWidth)
430 maxWidth = screen.Bounds.Width;
436 public static int GetScreenHeightInt()
440 foreach (Screen screen
in Screen.AllScreens)
442 if (screen.Bounds.Height > maxHeight)
444 maxHeight = screen.Bounds.Height;