public async Task <IBrowser> ConnectAsync(string wsEndpoint, BrowserTypeConnectOptions options = null) { options ??= new BrowserTypeConnectOptions(); var headers = new List <KeyValuePair <string, string> >(options.Headers ?? new Dictionary <string, string>()) { new KeyValuePair <string, string>("x-playwright-browser", Name), }.ToDictionary(pair => pair.Key, pair => pair.Value); JsonPipe pipe = (await _channel.ConnectAsync(wsEndpoint: wsEndpoint, headers: headers, slowMo: options.SlowMo, timeout: options.Timeout).ConfigureAwait(false)).Object; void ClosePipe() { pipe.CloseAsync().IgnoreException(); } #pragma warning disable CA2000 // Dispose objects before losing scope var connection = new Connection(); #pragma warning restore CA2000 connection.MarkAsRemote(); connection.Close += (_, _) => ClosePipe(); string closeError = null; Browser browser = null; void OnPipeClosed() { // Emulate all pages, contexts and the browser closing upon disconnect. foreach (BrowserContext context in browser?.BrowserContextsList.ToArray() ?? Array.Empty <BrowserContext>()) { foreach (Page page in context.PagesList.ToArray()) { page.OnClose(); } context.OnClose(); } browser?.DidClose(); connection.DoClose(closeError != null ? closeError : DriverMessages.BrowserClosedExceptionMessage); } pipe.Closed += (_, _) => OnPipeClosed(); connection.OnMessage = async(object message) => { try { await pipe.SendAsync(message).ConfigureAwait(false); } catch (Exception e) when(DriverMessages.IsSafeCloseError(e)) { // swallow exception } catch { OnPipeClosed(); } }; pipe.Message += (_, message) => { try { connection.Dispatch(message); } catch (Exception ex) { closeError = ex.ToString(); _channel.Connection.TraceMessage("pw:dotnet", $"Dispatching error: {ex.Message}\n{ex.StackTrace}"); ClosePipe(); } }; async Task <IBrowser> CreateBrowserAsync() { var playwright = await connection.InitializePlaywrightAsync().ConfigureAwait(false); playwright.Connection = connection; if (playwright.PreLaunchedBrowser == null) { ClosePipe(); throw new ArgumentException("Malformed endpoint. Did you use launchServer method?"); } browser = playwright.PreLaunchedBrowser; browser.ShouldCloseConnectionOnClose = true; browser.Disconnected += (_, _) => ClosePipe(); browser.LocalUtils = Playwright.Utils; return(playwright.PreLaunchedBrowser); } var task = CreateBrowserAsync(); var timeout = options?.Timeout != null ? (int)options.Timeout : 30_000; return(await task.WithTimeout(timeout, _ => throw new TimeoutException($"BrowserType.ConnectAsync: Timeout {options.Timeout}ms exceeded")).ConfigureAwait(false)); }
/// <inheritdoc /> public async Task <IBrowser> ConnectAsync(ConnectOptions options = null) => (await _channel.ConnectAsync(options).ConfigureAwait(false)).Object;