public async Task <string> EnableNetworkEventsAsync()
        {
            var    parameters = new Dictionary <string, object>();         // create empty params list
            CdpMsg msg        = new CdpMsg("Network.enable", parameters);
            string result     = await SendCmdAsync(msg).ConfigureAwait(false);

            return(result);
        }
        //public async Task<WebSocketReceiveResult> CloseBrowserAsync()
        public async Task <string> CloseBrowserAsync()
        {
            // close browser
            var parameters = new Dictionary <string, object>();            // create empty params list
            //CdpMsg msg = new CdpMsg { id = id++, method = "Browser.close", @params = parms };
            CdpMsg msg    = new CdpMsg("Browser.close", parameters);
            string result = await SendCmdAsync(msg).ConfigureAwait(false);

            return(result);
        }
        //public async Task<WebSocketReceiveResult> NavigatePageAsync(string url)
        public async Task <string> NavigatePageAsync(string url)
        {
            // navigate to specified url
            var parameters = new Dictionary <string, object>();            // create empty params list

            parameters.Add("url", url);
            //CdpMsg msg = new CdpMsg { id = id++, method = "Page.navigate", @params = parms };
            CdpMsg msg    = new CdpMsg("Page.navigate", parameters);
            string result = await SendCmdAsync(msg).ConfigureAwait(false);

            return(result);
        }
        //private async Task<WebSocketReceiveResult> SendCmdAsync(CdpMsg msg)
        private async Task <string> SendCmdAsync(CdpMsg msg)
        {
            try
            {
                using (ClientWebSocket ws = new ClientWebSocket())
                {
                    Log($"CdpClient.SendMsg(): Attempting to send cmd {msg.method}, port is {_chromeDebuggingPort}");

                    // load config
                    await CdpConfig.LoadConfigAsync().ConfigureAwait(false);

                    byte[] receiveBytes  = new byte[65536];
                    var    receiveBuffer = new ArraySegment <byte>(receiveBytes);
                    ws.Options.SetBuffer(65536, 65536);                     // (receive 64KB, send 64KB)

#if DEBUG
                    var tokenSource = new CancellationTokenSource(600000);                      // 10 mins
#else
                    var tokenSource = new CancellationTokenSource(10000);                       // 10 secs
#endif
                    CancellationToken cancellationToken = tokenSource.Token;

                    Uri wsUri;
                    if (msg.method.StartsWith("Browser"))
                    {
                        wsUri = this.CdpConfig.BrowserWsUri;
                    }
                    else
                    {
                        wsUri = this.CdpConfig.PageWsUri;
                    }

                    Log($"CdpClient.SendMsg(): Attempting to connect to uri {wsUri}, port is {_chromeDebuggingPort}...");
                    await ws.ConnectAsync(wsUri, cancellationToken).ConfigureAwait(false);

                    Log($"CdpClient.SendMsg(): ...Connected to to uri {wsUri}, port is {_chromeDebuggingPort}");

                    string json  = Json.Serialize <CdpMsg>(msg);
                    byte[] bytes = Encoding.UTF8.GetBytes(json);
                    ArraySegment <byte> sendBuffer = new ArraySegment <byte>(bytes);

                    Log($"About to send CDP cmd {msg.method} to port {_chromeDebuggingPort}...");
                    await ws.SendAsync(sendBuffer, WebSocketMessageType.Text, true, cancellationToken).ConfigureAwait(false);

                    WebSocketReceiveResult result = await ws.ReceiveAsync(receiveBuffer, cancellationToken).ConfigureAwait(false);

                    Log($"...received CDP result for cmd {msg.method}, result = {Json.Serialize(result)}, port is {_chromeDebuggingPort}");

                    // retrive result from buffer
                    if (result.MessageType != WebSocketMessageType.Text)
                    {
                        return($"Unexpected message type: {result.MessageType}");
                    }

                    string msgText = Encoding.UTF8.GetString(receiveBytes, 0, result.Count);
                    Log($"{msg.method}(): returned result {msgText}, port is {_chromeDebuggingPort}");

                    return(msgText);
                }
            }
            catch (Exception ex)
            {
                Log($"Exception occurred: {ex.ToString()}");
                return(null);
            }
        }