internal async Task InitAsync() { var targetId = _page.Target.TargetId; _session = await _page.Target.CreateCDPSessionAsync(); var args = new JObject { { "expression", new JValue("self.paramsForReuse") }, { "returnByValue", new JValue(true) } }; var getParamsForReuseTask = _session.SendAsync("Runtime.evaluate", args); var targetObject = $"{{ targetId: '{targetId}' }}"; var getWindowForTargetTask = _app.Session.SendAsync("Browser.getWindowForTarget", JObject.Parse(targetObject)); var color = new JObject { { "color", new JObject { { "r", new JValue(_options.BgColor.R) }, { "g", new JValue(_options.BgColor.G) }, { "b", new JValue(_options.BgColor.B) }, { "a", new JValue(_options.BgColor.A) }, } } }; await _session.SendAsync("Emulation.setDefaultBackgroundColorOverride", color); var response = await getParamsForReuseTask; _paramsForReuse = response.Value<object>(); var window = await getWindowForTargetTask; await InitBoundsAsync(window); await ConfigureIpcMethodsOnceAsync(); }
public async Task SetIconAsync(string icon) { var buffer = File.ReadAllBytes(icon); var iconObject = new JObject() { { "image", Convert.ToBase64String(buffer) } }; await _session.SendAsync("Browser.setDockTile", iconObject); }
internal static async Task <string> ReadProtocolStreamStringAsync(CDPSession client, string handle, string path) { var result = new StringBuilder(); var fs = !string.IsNullOrEmpty(path) ? AsyncFileHelper.CreateStream(path, FileMode.Create) : null; try { var eof = false; while (!eof) { var response = await client.SendAsync <IOReadResponse>("IO.read", new IOReadRequest { Handle = handle }).ConfigureAwait(false); eof = response.Eof; result.Append(response.Data); if (fs != null) { var data = Encoding.UTF8.GetBytes(response.Data); await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false); } } await client.SendAsync("IO.close", new IOCloseRequest { Handle = handle }).ConfigureAwait(false); return(result.ToString()); } finally { fs?.Dispose(); } }
/// <summary> /// Dispatches a <c>mousemove</c> event. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="options"></param> /// <returns>Task</returns> public async Task MoveAsync(decimal x, decimal y, MoveOptions options = null) { options = options ?? new MoveOptions(); decimal fromX = _x; decimal fromY = _y; _x = x; _y = y; int steps = options.Steps; for (var i = 1; i <= steps; i++) { await _client.SendAsync("Input.dispatchMouseEvent", new Dictionary <string, object>(){ { "type", "mouseMoved" }, { "button", _button }, { "x", fromX + ((_x - fromX) * ((decimal)i / steps)) }, { "y", fromY + ((_y - fromY) * ((decimal)i / steps)) }, { "modifiers", _keyboard.Modifiers } }).ConfigureAwait(false); } }
/// <summary> /// Dispatches a <c>mousemove</c> event. /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <param name="options"></param> /// <returns>Task</returns> public async Task MoveAsync(decimal x, decimal y, MoveOptions options = null) { options = options ?? new MoveOptions(); decimal fromX = _x; decimal fromY = _y; _x = x; _y = y; int steps = options.Steps; for (var i = 1; i <= steps; i++) { await _client.SendAsync("Input.dispatchMouseEvent", new InputDispatchMouseEventRequest { Type = MouseEventType.MouseMoved, Button = _button, X = fromX + ((_x - fromX) * ((decimal)i / steps)), Y = fromY + ((_y - fromY) * ((decimal)i / steps)), Modifiers = _keyboard.Modifiers }).ConfigureAwait(false); } }
internal static async Task <byte[]> ReadProtocolStreamByteAsync(CDPSession client, string handle, string path) { IEnumerable <byte> result = null; var eof = false; var fs = !string.IsNullOrEmpty(path) ? AsyncFileHelper.CreateStream(path, FileMode.Create) : null; try { while (!eof) { var response = await client.SendAsync <IOReadResponse>("IO.read", new IOReadRequest { Handle = handle }).ConfigureAwait(false); eof = response.Eof; var data = Convert.FromBase64String(response.Data); result = result == null ? data : result.Concat(data); if (fs != null) { await fs.WriteAsync(data, 0, data.Length).ConfigureAwait(false); } } await client.SendAsync("IO.close", new IOCloseRequest { Handle = handle }).ConfigureAwait(false); return(result.ToArray()); } finally { fs?.Dispose(); } }
/// <summary> /// Dispatches a <c>keydown</c> event /// </summary> /// <param name="key">Name of key to press, such as <c>ArrowLeft</c>. <see cref="KeyDefinitions"/> for a list of all key names.</param> /// <param name="options">down options</param> /// <remarks> /// If <c>key</c> is a single character and no modifier keys besides <c>Shift</c> are being held down, a <c>keypress</c>/<c>input</c> event will also generated. The <c>text</c> option can be specified to force an input event to be generated. /// If <c>key</c> is a modifier key, <c>Shift</c>, <c>Meta</c>, <c>Control</c>, or <c>Alt</c>, subsequent key presses will be sent with that modifier active. To release the modifier key, use <see cref="UpAsync(string)"/> /// After the key is pressed once, subsequent calls to <see cref="DownAsync(string, DownOptions)"/> will have <see href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat">repeat</see> set to <c>true</c>. To release the key, use <see cref="UpAsync(string)"/> /// </remarks> /// <returns>Task</returns> public async Task DownAsync(string key, DownOptions options = null) { var description = KeyDescriptionForString(key); var autoRepeat = _pressedKeys.Contains(description.Code); _pressedKeys.Add(description.Code); Modifiers |= ModifierBit(key); var text = options?.Text == null ? description.Text : options.Text; await _client.SendAsync("Input.dispatchKeyEvent", new Dictionary <string, object>(){ { "type", text != null ? "keyDown" : "rawKeyDown" }, { "modifiers", Modifiers }, { "windowsVirtualKeyCode", description.KeyCode }, { "code", description.Code }, { "key", description.Key }, { "text", text }, { "unmodifiedText", text }, { "autoRepeat", autoRepeat }, { "location", description.Location }, { "isKeypad", description.Location == 3 } }); }
private async Task <JObject> ResolveAsync(JObject @params) { DebugServer("resolve {0}", Url); if (_done) { throw new Exception("Already resolved given request"); } @params["interceptionId"] = _params["interceptionId"]; _done = true; return(await _session.SendAsync("Network.continueInterceptedRequest", @params)); }
internal Task StartAsync(CoverageStartOptions options) { if (_enabled) { throw new InvalidOperationException("JSCoverage is already enabled"); } _resetOnNavigation = options.ResetOnNavigation; _enabled = true; _scriptURLs.Clear(); _scriptSources.Clear(); _client.MessageReceived += client_MessageReceived; return(Task.WhenAll( _client.SendAsync("Profiler.enable"), _client.SendAsync("Profiler.startPreciseCoverage", new { callCount = false, detailed = true }), _client.SendAsync("Debugger.enable"), _client.SendAsync("Debugger.setSkipAllPauses", new { skip = true }) )); }
internal static async Task ReleaseObject(CDPSession client, dynamic remoteObject, ILogger logger) { if (remoteObject.objectId == null) { return; } try { await client.SendAsync("Runtime.releaseObject", new { remoteObject.objectId }); } catch (Exception ex) { // Exceptions might happen in case of a page been navigated or closed. // Swallow these since they are harmless and we don't leak anything in this case. logger.LogWarning(ex.ToString()); } }
internal static async Task ReleaseObjectAsync(CDPSession client, RemoteObject remoteObject) { if (remoteObject.ObjectId == null) { return; } try { await client.SendAsync("Runtime.releaseObject", new RuntimeReleaseObjectRequest { ObjectId = remoteObject.ObjectId }).ConfigureAwait(false); } catch { } }
public async Task <Dictionary <string, decimal> > AccessPageAndGetMetricsByTrl(string url) { var page = await Browser.NewPageAsync(); CDPSession cpd = await page.Target.CreateCDPSessionAsync(); await cpd.SendAsync("Performance.enable"); var metrics1 = await MetricsAsync(cpd); Response response; try { response = await page.GoToAsync(url); if (response == null) { throw new Exception("Null Response for " + url); } var metrics2 = await MetricsAsync(cpd); System.Threading.Thread.Sleep(10000); var metrics3 = await MetricsAsync(cpd); foreach (var metric1 in metrics1) { var m2 = metrics2[metric1.Key]; var m3 = metrics3[metric1.Key]; Console.WriteLine($"{metric1.Key,30} | {metric1.Value,15} | {m2,15} | {m3,15}"); } return(metrics2); } catch (Exception e) { throw e; } finally { await page.CloseAsync(); } }
internal static async Task ReleaseObject(CDPSession client, JToken remoteObject, ILogger logger) { var objectId = remoteObject[MessageKeys.ObjectId]?.AsString(); if (objectId == null) { return; } try { await client.SendAsync("Runtime.releaseObject", new { objectId }).ConfigureAwait(false); } catch (Exception ex) { // Exceptions might happen in case of a page been navigated or closed. // Swallow these since they are harmless and we don't leak anything in this case. logger.LogWarning(ex.ToString()); } }
internal Task StartAsync(CoverageStartOptions options) { if (_enabled) { throw new InvalidOperationException("CSSCoverage is already enabled"); } _resetOnNavigation = options.ResetOnNavigation; _enabled = true; _stylesheetURLs.Clear(); _stylesheetSources.Clear(); _client.MessageReceived += Client_MessageReceived; return(Task.WhenAll( _client.SendAsync("DOM.enable"), _client.SendAsync("CSS.enable"), _client.SendAsync("CSS.startRuleUsageTracking"))); }
private async Task <Dictionary <string, decimal> > MetricsAsync(CDPSession cdp) { var response = await cdp.SendAsync <PerformanceGetMetricsResponse>("Performance.getMetrics"); return(BuildMetricsObject(response.Metrics)); }