How to use Dispose method of PuppeteerSharp.LauncherBase class

Best Puppeteer-sharp code snippet using PuppeteerSharp.LauncherBase.Dispose

LauncherBase.cs

Source:LauncherBase.cs Github

copy

Full Screen

...44 Process.ErrorDataReceived += (sender, e) => Console.Error.WriteLine(e.Data);45 }46 }47 #endregion48 #region Dispose49 /// <summary>50 /// Finalizer.51 /// </summary>52 ~LauncherBase()53 {54 Dispose(false);55 }56 /// <inheritdoc />57 public void Dispose()58 {59 Dispose(true);60 GC.SuppressFinalize(this);61 }62 /// <summary>63 /// Disposes Base process and any temporary user directory.64 /// </summary>65 /// <param name="disposing">Indicates whether disposal was initiated by <see cref="Dispose()"/> operation.</param>66 protected virtual void Dispose(bool disposing) => _currentState.Dispose(this);67 #endregion68 #region Properties69 /// <summary>70 /// Gets Base process details.71 /// </summary>72 public Process Process { get; }73 /// <summary>74 /// Gets Base endpoint.75 /// </summary>76 public string EndPoint => _startCompletionSource.Task.IsCompleted77 ? _startCompletionSource.Task.Result78 : null;79 /// <summary>80 /// Indicates whether Base process is exiting.81 /// </summary>82 public bool IsExiting => _currentState.IsExiting;83 /// <summary>84 /// Indicates whether Base process has exited.85 /// </summary>86 public bool HasExited => _currentState.IsExited;87 internal TempDirectory TempUserDataDir { get; set; }88 /// <summary>89 /// Gets Base process current state.90 /// </summary>91 protected State CurrentState { get => _currentState; }92 #endregion93 #region Public methods94 /// <summary>95 /// Asynchronously starts Base process.96 /// </summary>97 /// <returns></returns>98 public Task StartAsync() => _currentState.StartAsync(this);99 /// <summary>100 /// Asynchronously waits for graceful Base process exit within a given timeout period.101 /// Kills the Base process if it has not exited within this period.102 /// </summary>103 /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>104 /// <returns></returns>105 public Task EnsureExitAsync(TimeSpan? timeout) => timeout.HasValue106 ? _currentState.ExitAsync(this, timeout.Value)107 : _currentState.KillAsync(this);108 /// <summary>109 /// Asynchronously kills Base process.110 /// </summary>111 /// <returns></returns>112 public Task KillAsync() => _currentState.KillAsync(this);113 /// <summary>114 /// Waits for Base process exit within a given timeout.115 /// </summary>116 /// <param name="timeout">The maximum wait period.</param>117 /// <returns><c>true</c> if Base process has exited within the given <paramref name="timeout"/>,118 /// or <c>false</c> otherwise.</returns>119 public async Task<bool> WaitForExitAsync(TimeSpan? timeout)120 {121 if (timeout.HasValue)122 {123 bool taskCompleted = true;124 await _exitCompletionSource.Task.WithTimeout(125 () =>126 {127 taskCompleted = false;128 }, timeout.Value).ConfigureAwait(false);129 return taskCompleted;130 }131 await _exitCompletionSource.Task.ConfigureAwait(false);132 return true;133 }134 #endregion135 #region Private methods136 /// <summary>137 /// Set Env Variables138 /// </summary>139 /// <param name="environment">The environment.</param>140 /// <param name="customEnv">The customEnv.</param>141 /// <param name="realEnv">The realEnv.</param>142 protected static void SetEnvVariables(IDictionary<string, string> environment, IDictionary<string, string> customEnv, IDictionary realEnv)143 {144 foreach (DictionaryEntry item in realEnv)145 {146 environment[item.Key.ToString()] = item.Value.ToString();147 }148 if (customEnv != null)149 {150 foreach (var item in customEnv)151 {152 environment[item.Key] = item.Value;153 }154 }155 }156 #endregion157 #region State machine158 /// <summary>159 /// Represents state machine for Base process instances. The happy path runs along the160 /// following state transitions: <see cref="Initial"/>161 /// -> <see cref="Starting"/>162 /// -> <see cref="Started"/>163 /// -> <see cref="Exiting"/>164 /// -> <see cref="Exited"/>.165 /// -> <see cref="Disposed"/>.166 /// </summary>167 /// <remarks>168 /// <para>169 /// This state machine implements the following state transitions:170 /// <code>171 /// State Event Target State Action172 /// ======== =================== ============ ==========================================================173 /// Initial --StartAsync------> Starting Start process and wait for endpoint174 /// Initial --ExitAsync-------> Exited Cleanup temp user data175 /// Initial --KillAsync-------> Exited Cleanup temp user data176 /// Initial --Dispose---------> Disposed Cleanup temp user data177 /// Starting --StartAsync------> Starting -178 /// Starting --ExitAsync-------> Exiting Wait for process exit179 /// Starting --KillAsync-------> Killing Kill process180 /// Starting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;181 /// Starting --endpoint ready--> Started Complete StartAsync successfully; Log process start182 /// Starting --process exit----> Exited Complete StartAsync with exception; Cleanup temp user data183 /// Started --StartAsync------> Started -184 /// Started --EnsureExitAsync-> Exiting Start exit timer; Log process exit185 /// Started --KillAsync-------> Killing Kill process; Log process exit186 /// Started --Dispose---------> Disposed Kill process; Log process exit; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;187 /// Started --process exit----> Exited Log process exit; Cleanup temp user data188 /// Exiting --StartAsync------> Exiting - (StartAsync throws InvalidOperationException)189 /// Exiting --ExitAsync-------> Exiting -190 /// Exiting --KillAsync-------> Killing Kill process191 /// Exiting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;192 /// Exiting --exit timeout----> Killing Kill process193 /// Exiting --process exit----> Exited Cleanup temp user data; complete outstanding async operations;194 /// Killing --StartAsync------> Killing - (StartAsync throws InvalidOperationException)195 /// Killing --KillAsync-------> Killing -196 /// Killing --Dispose---------> Disposed Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;197 /// Killing --process exit----> Exited Cleanup temp user data; complete outstanding async operations;198 /// Exited --StartAsync------> Killing - (StartAsync throws InvalidOperationException)199 /// Exited --KillAsync-------> Exited -200 /// Exited --Dispose---------> Disposed -201 /// Disposed --StartAsync------> Disposed -202 /// Disposed --KillAsync-------> Disposed -203 /// Disposed --Dispose---------> Disposed -204 /// </code>205 /// </para>206 /// </remarks>207 protected abstract class State208 {209 #region Predefined states210 /// <summary>211 /// Set initial state.212 /// </summary>213 public static readonly State Initial = new InitialState();214 private static readonly StartingState Starting = new StartingState();215 private static readonly StartedState Started = new StartedState();216 private static readonly ExitingState Exiting = new ExitingState();217 private static readonly KillingState Killing = new KillingState();218 private static readonly ExitedState Exited = new ExitedState();219 private static readonly DisposedState Disposed = new DisposedState();220 #endregion221 #region Properties222 /// <summary>223 /// Get If process exists.224 /// </summary>225 public bool IsExiting => this == Killing || this == Exiting;226 /// <summary>227 /// Get If process is exited.228 /// </summary>229 public bool IsExited => this == Exited || this == Disposed;230 #endregion231 #region Methods232 /// <summary>233 /// Attempts thread-safe transitions from a given state to this state.234 /// </summary>235 /// <param name="p">The Base process</param>236 /// <param name="fromState">The state from which state transition takes place</param>237 /// <returns>Returns <c>true</c> if transition is successful, or <c>false</c> if transition238 /// cannot be made because current state does not equal <paramref name="fromState"/>.</returns>239 protected bool TryEnter(LauncherBase p, State fromState)240 {241 if (Interlocked.CompareExchange(ref p._currentState, this, fromState) == fromState)242 {243 fromState.Leave(p);244 return true;245 }246 return false;247 }248 /// <summary>249 /// Notifies that state machine is about to transition to another state.250 /// </summary>251 /// <param name="p">The Base process</param>252 protected virtual void Leave(LauncherBase p)253 {254 }255 /// <summary>256 /// Handles process start request.257 /// </summary>258 /// <param name="p">The Base process</param>259 /// <returns></returns>260 public virtual Task StartAsync(LauncherBase p) => Task.FromException(InvalidOperation("start"));261 /// <summary>262 /// Handles process exit request.263 /// </summary>264 /// <param name="p">The Base process</param>265 /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>266 /// <returns></returns>267 public virtual Task ExitAsync(LauncherBase p, TimeSpan timeout) => Task.FromException(InvalidOperation("exit"));268 /// <summary>269 /// Handles process kill request.270 /// </summary>271 /// <param name="p">The Base process</param>272 /// <returns></returns>273 public virtual Task KillAsync(LauncherBase p) => Task.FromException(InvalidOperation("kill"));274 /// <summary>275 /// Handles wait for process exit request.276 /// </summary>277 /// <param name="p">The Base process</param>278 /// <returns></returns>279 public virtual Task WaitForExitAsync(LauncherBase p) => p._exitCompletionSource.Task;280 /// <summary>281 /// Handles disposal of process and temporary user directory282 /// </summary>283 /// <param name="p"></param>284 public virtual void Dispose(LauncherBase p) => Disposed.EnterFrom(p, this);285 /// <inheritdoc />286 public override string ToString()287 {288 string name = GetType().Name;289 return name.Substring(0, name.Length - "State".Length);290 }291 private Exception InvalidOperation(string operationName)292 => new InvalidOperationException($"Cannot {operationName} in state {this}");293 /// <summary>294 /// Kills process if it is still alive.295 /// </summary>296 /// <param name="p"></param>297 private static void Kill(LauncherBase p)298 {299 try300 {301 if (!p.Process.HasExited)302 {303 p.Process.Kill();304 }305 }306 catch (InvalidOperationException)307 {308 // Ignore309 }310 }311 #endregion312 #region Concrete state classes313 private class InitialState : State314 {315 public override Task StartAsync(LauncherBase p) => Starting.EnterFromAsync(p, this);316 public override Task ExitAsync(LauncherBase p, TimeSpan timeout)317 {318 Exited.EnterFrom(p, this);319 return Task.CompletedTask;320 }321 public override Task KillAsync(LauncherBase p)322 {323 Exited.EnterFrom(p, this);324 return Task.CompletedTask;325 }326 public override Task WaitForExitAsync(LauncherBase p) => Task.FromException(InvalidOperation("wait for exit"));327 }328 private class StartingState : State329 {330 public Task EnterFromAsync(LauncherBase p, State fromState)331 {332 if (!TryEnter(p, fromState))333 {334 // Delegate StartAsync to current state, because it has already changed since335 // transition to this state was initiated.336 return p._currentState.StartAsync(p);337 }338 return StartCoreAsync(p);339 }340 public override Task StartAsync(LauncherBase p) => p._startCompletionSource.Task;341 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);342 public override Task KillAsync(LauncherBase p) => Killing.EnterFromAsync(p, this);343 public override void Dispose(LauncherBase p)344 {345 p._startCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));346 base.Dispose(p);347 }348 private async Task StartCoreAsync(LauncherBase p)349 {350 var output = new StringBuilder();351 void OnProcessDataReceivedWhileStarting(object sender, DataReceivedEventArgs e)352 {353 if (e.Data != null)354 {355 output.AppendLine(e.Data);356 var match = Regex.Match(e.Data, "^DevTools listening on (ws:\\/\\/.*)");357 if (match.Success)358 {359 p._startCompletionSource.TrySetResult(match.Groups[1].Value);360 }361 }362 }363 void OnProcessExitedWhileStarting(object sender, EventArgs e)364 => p._startCompletionSource.TrySetException(new ProcessException($"Failed to launch Base! {output}"));365 void OnProcessExited(object sender, EventArgs e) => Exited.EnterFrom(p, p._currentState);366 p.Process.ErrorDataReceived += OnProcessDataReceivedWhileStarting;367 p.Process.Exited += OnProcessExitedWhileStarting;368 p.Process.Exited += OnProcessExited;369 CancellationTokenSource cts = null;370 try371 {372 p.Process.Start();373 await Started.EnterFromAsync(p, this).ConfigureAwait(false);374 p.Process.BeginErrorReadLine();375 int timeout = p._options.Timeout;376 if (timeout > 0)377 {378 cts = new CancellationTokenSource(timeout);379 cts.Token.Register(() => p._startCompletionSource.TrySetException(380 new ProcessException($"Timed out after {timeout} ms while trying to connect to Base!")));381 }382 try383 {384 await p._startCompletionSource.Task.ConfigureAwait(false);385 await Started.EnterFromAsync(p, this).ConfigureAwait(false);386 }387 catch388 {389 await Killing.EnterFromAsync(p, this).ConfigureAwait(false);390 throw;391 }392 }393 finally394 {395 cts?.Dispose();396 p.Process.Exited -= OnProcessExitedWhileStarting;397 p.Process.ErrorDataReceived -= OnProcessDataReceivedWhileStarting;398 }399 }400 }401 private class StartedState : State402 {403 public Task EnterFromAsync(LauncherBase p, State fromState)404 {405 if (TryEnter(p, fromState))406 {407 }408 return Task.CompletedTask;409 }410 protected override void Leave(LauncherBase p) { }411 public override Task StartAsync(LauncherBase p) => Task.CompletedTask;412 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);413 public override Task KillAsync(LauncherBase p) => Killing.EnterFromAsync(p, this);414 }415 private class ExitingState : State416 {417 public Task EnterFromAsync(LauncherBase p, State fromState, TimeSpan timeout)418 => !TryEnter(p, fromState) ? p._currentState.ExitAsync(p, timeout) : ExitAsync(p, timeout);419 public override async Task ExitAsync(LauncherBase p, TimeSpan timeout)420 {421 var waitForExitTask = WaitForExitAsync(p);422 await waitForExitTask.WithTimeout(423 async () =>424 {425 await Killing.EnterFromAsync(p, this).ConfigureAwait(false);426 await waitForExitTask.ConfigureAwait(false);427 },428 timeout,429 CancellationToken.None).ConfigureAwait(false);430 }431 public override Task KillAsync(LauncherBase p) => Killing.EnterFromAsync(p, this);432 }433 private class KillingState : State434 {435 public async Task EnterFromAsync(LauncherBase p, State fromState)436 {437 if (!TryEnter(p, fromState))438 {439 // Delegate KillAsync to current state, because it has already changed since440 // transition to this state was initiated.441 await p._currentState.KillAsync(p).ConfigureAwait(false);442 }443 try444 {445 if (!p.Process.HasExited)446 {447 p.Process.Kill();448 }449 }450 catch (InvalidOperationException)451 {452 // Ignore453 return;454 }455 await WaitForExitAsync(p).ConfigureAwait(false);456 }457 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => WaitForExitAsync(p);458 public override Task KillAsync(LauncherBase p) => WaitForExitAsync(p);459 }460 private class ExitedState : State461 {462 public void EnterFrom(LauncherBase p, State fromState)463 {464 while (!TryEnter(p, fromState))465 {466 // Current state has changed since transition to this state was requested.467 // Therefore retry transition to this state from the current state. This ensures468 // that Leave() operation of current state is properly called.469 fromState = p._currentState;470 if (fromState == this)471 {472 return;473 }474 }475 p._exitCompletionSource.TrySetResult(true);476 p.TempUserDataDir?.Dispose();477 }478 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => Task.CompletedTask;479 public override Task KillAsync(LauncherBase p) => Task.CompletedTask;480 public override Task WaitForExitAsync(LauncherBase p) => Task.CompletedTask;481 }482 private class DisposedState : State483 {484 public void EnterFrom(LauncherBase p, State fromState)485 {486 if (!TryEnter(p, fromState))487 {488 // Delegate Dispose to current state, because it has already changed since489 // transition to this state was initiated.490 p._currentState.Dispose(p);491 }492 else if (fromState != Exited)493 {494 Kill(p);495 p._exitCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));496 p.TempUserDataDir?.Dispose();497 }498 }499 public override Task StartAsync(LauncherBase p) => throw new ObjectDisposedException(p.ToString());500 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => throw new ObjectDisposedException(p.ToString());501 public override Task KillAsync(LauncherBase p) => throw new ObjectDisposedException(p.ToString());502 public override void Dispose(LauncherBase p)503 {504 // Nothing to do505 }506 }507 #endregion508 }509 #endregion510 }511}...

Full Screen

Full Screen

Browser.cs

Source:Browser.cs Github

copy

Full Screen

...218 => (await Connection.SendAsync<BrowserGetVersionResponse>("Browser.getVersion").ConfigureAwait(false)).UserAgent;219 /// <summary>220 /// Disconnects Puppeteer from the browser, but leaves the process running. After calling <see cref="Disconnect"/>, the browser object is considered disposed and cannot be used anymore221 /// </summary>222 public void Disconnect() => Connection.Dispose();223 /// <summary>224 /// Closes Chromium and all of its pages (if any were opened). The browser object itself is considered disposed and cannot be used anymore225 /// </summary>226 /// <returns>Task</returns>227 public Task CloseAsync() => _closeTask ?? (_closeTask = CloseCoreAsync());228 /// <summary>229 /// This searches for a target in this specific browser context.230 /// <example>231 /// <code>232 /// <![CDATA[233 /// await page.EvaluateAsync("() => window.open('https://www.example.com/')");234 /// var newWindowTarget = await browserContext.WaitForTargetAsync((target) => target.Url == "https://www.example.com/");235 /// ]]>236 /// </code>237 /// </example>238 /// </summary>239 /// <param name="predicate">A function to be run for every target</param>240 /// <param name="options">options</param>241 /// <returns>Resolves to the first target found that matches the predicate function.</returns>242 public async Task<Target> WaitForTargetAsync(Func<Target, bool> predicate, WaitForOptions options = null)243 {244 int timeout = options?.Timeout ?? DefaultWaitForTimeout;245 var existingTarget = Targets().FirstOrDefault(predicate);246 if (existingTarget != null)247 {248 return existingTarget;249 }250 var targetCompletionSource = new TaskCompletionSource<Target>(TaskCreationOptions.RunContinuationsAsynchronously);251 void TargetHandler(object sender, TargetChangedArgs e)252 {253 if (predicate(e.Target))254 {255 targetCompletionSource.TrySetResult(e.Target);256 }257 }258 try259 {260 TargetCreated += TargetHandler;261 TargetChanged += TargetHandler;262 return await targetCompletionSource.Task.WithTimeout(timeout).ConfigureAwait(false);263 }264 finally265 {266 TargetCreated -= TargetHandler;267 TargetChanged -= TargetHandler;268 }269 }270 private async Task CloseCoreAsync()271 {272 try273 {274 try275 {276 // Initiate graceful browser close operation but don't await it just yet,277 // because we want to ensure process shutdown first.278 var browserCloseTask = Connection.IsClosed279 ? Task.CompletedTask280 : Connection.SendAsync("Browser.close", null);281 if (Launcher != null)282 {283 // Notify process that exit is expected, but should be enforced if it284 // doesn't occur withing the close timeout.285 var closeTimeout = TimeSpan.FromMilliseconds(CloseTimeout);286 await Launcher.EnsureExitAsync(closeTimeout).ConfigureAwait(false);287 }288 // Now we can safely await the browser close operation without risking keeping chromium289 // process running for indeterminate period.290 await browserCloseTask.ConfigureAwait(false);291 }292 finally293 {294 Disconnect();295 }296 }297 catch (Exception)298 {299 if (Launcher != null)300 {301 await Launcher.KillAsync().ConfigureAwait(false);302 }303 }304 // Ensure that remaining targets are always marked closed, so that asynchronous page close305 // operations on any associated pages don't get blocked.306 foreach (var target in TargetsMap.Values)307 {308 target.CloseTaskWrapper.TrySetResult(false);309 }310 Closed?.Invoke(this, new EventArgs());311 }312 #endregion313 #region Private Methods314 internal void ChangeTarget(Target target)315 {316 var args = new TargetChangedArgs { Target = target };317 TargetChanged?.Invoke(this, args);318 target.BrowserContext.OnTargetChanged(this, args);319 }320 internal async Task<Page> CreatePageInContextAsync(string contextId)321 {322 var createTargetRequest = new TargetCreateTargetRequest323 {324 Url = "about:blank"325 };326 if (contextId != null)327 {328 createTargetRequest.BrowserContextId = contextId;329 }330 string targetId = (await Connection.SendAsync<TargetCreateTargetResponse>("Target.createTarget", createTargetRequest)331 .ConfigureAwait(false)).TargetId;332 var target = TargetsMap[targetId];333 await target.InitializedTask.ConfigureAwait(false);334 return await target.PageAsync().ConfigureAwait(false);335 }336 internal async Task DisposeContextAsync(string contextId)337 {338 await Connection.SendAsync("Target.disposeBrowserContext", new TargetDisposeBrowserContextRequest339 {340 BrowserContextId = contextId341 }).ConfigureAwait(false);342 _contexts.Remove(contextId);343 }344 private async void Connection_Disconnected(object sender, EventArgs e)345 {346 try347 {348 await CloseAsync().ConfigureAwait(false);349 Disconnected?.Invoke(this, new EventArgs());350 }351 catch (Exception ex)352 {353 string message = $"Browser failed to process Connection Close. {ex.Message}. {ex.StackTrace}";354 Connection.Close(message);355 }356 }357 private async void Connect_MessageReceived(object sender, MessageEventArgs e)358 {359 try360 {361 switch (e.MessageID)362 {363 case "Target.targetCreated":364 await CreateTargetAsync(e.MessageData.ToObject<TargetCreatedResponse>(true)).ConfigureAwait(false);365 return;366 case "Target.targetDestroyed":367 await DestroyTargetAsync(e.MessageData.ToObject<TargetDestroyedResponse>(true)).ConfigureAwait(false);368 return;369 case "Target.targetInfoChanged":370 ChangeTargetInfo(e.MessageData.ToObject<TargetCreatedResponse>(true));371 return;372 }373 }374 catch (Exception ex)375 {376 string message = $"Browser failed to process {e.MessageID}. {ex.Message}. {ex.StackTrace}";377 Connection.Close(message);378 }379 }380 private void ChangeTargetInfo(TargetCreatedResponse e)381 {382 if (!TargetsMap.ContainsKey(e.TargetInfo.TargetId))383 {384 throw new InvalidTargetException("Target should exists before ChangeTargetInfo");385 }386 var target = TargetsMap[e.TargetInfo.TargetId];387 target.TargetInfoChanged(e.TargetInfo);388 }389 private async Task DestroyTargetAsync(TargetDestroyedResponse e)390 {391 if (!TargetsMap.ContainsKey(e.TargetId))392 {393 throw new InvalidTargetException("Target should exists before DestroyTarget");394 }395 var target = TargetsMap[e.TargetId];396 TargetsMap.Remove(e.TargetId);397 target.CloseTaskWrapper.TrySetResult(true);398 if (await target.InitializedTask.ConfigureAwait(false))399 {400 var args = new TargetChangedArgs { Target = target };401 TargetDestroyed?.Invoke(this, args);402 target.BrowserContext.OnTargetDestroyed(this, args);403 }404 }405 private async Task CreateTargetAsync(TargetCreatedResponse e)406 {407 var targetInfo = e.TargetInfo;408 string browserContextId = targetInfo.BrowserContextId;409 if (!(browserContextId != null && _contexts.TryGetValue(browserContextId, out var context)))410 {411 context = DefaultContext;412 }413 var target = new Target(414 e.TargetInfo,415 () => Connection.CreateSessionAsync(targetInfo),416 context);417 TargetsMap[e.TargetInfo.TargetId] = target;418 if (await target.InitializedTask.ConfigureAwait(false))419 {420 var args = new TargetChangedArgs { Target = target };421 TargetCreated?.Invoke(this, args);422 context.OnTargetCreated(this, args);423 }424 }425 internal static async Task<Browser> CreateAsync(426 Connection connection,427 string[] contextIds,428 bool ignoreHTTPSErrors,429 ViewPortOptions defaultViewPort,430 LauncherBase launcher)431 {432 var browser = new Browser(connection, contextIds, ignoreHTTPSErrors, defaultViewPort, launcher);433 await connection.SendAsync("Target.setDiscoverTargets", new TargetSetDiscoverTargetsRequest434 {435 Discover = true436 }).ConfigureAwait(false);437 return browser;438 }439 #endregion440 #region IDisposable441 /// <inheritdoc />442 public void Dispose()443 {444 Dispose(true);445 GC.SuppressFinalize(this);446 }447 /// <summary>448 /// Closes <see cref="Connection"/> and any Chromium <see cref="Process"/> that was449 /// created by Puppeteer.450 /// </summary>451 /// <param name="disposing">Indicates whether disposal was initiated by <see cref="Dispose()"/> operation.</param>452 protected virtual void Dispose(bool disposing) => _ = CloseAsync();453 #endregion454 }455}...

Full Screen

Full Screen

State.cs

Source:State.cs Github

copy

Full Screen

...9 /// -> <see cref="StateManager.Starting"/>10 /// -> <see cref="StateManager.Started"/>11 /// -> <see cref="StateManager.Exiting"/>12 /// -> <see cref="StateManager.Exited"/>.13 /// -> <see cref="StateManager.Disposed"/>.14 /// </summary>15 /// <remarks>16 /// <para>17 /// This state machine implements the following state transitions:18 /// <code>19 /// State Event Target State Action20 /// ======== =================== ============ ==========================================================21 /// Initial --StartAsync------> Starting Start process and wait for endpoint22 /// Initial --ExitAsync-------> Exited Cleanup temp user data23 /// Initial --KillAsync-------> Exited Cleanup temp user data24 /// Initial --Dispose---------> Disposed Cleanup temp user data25 /// Starting --StartAsync------> Starting -26 /// Starting --ExitAsync-------> Exiting Wait for process exit27 /// Starting --KillAsync-------> Killing Kill process28 /// Starting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;29 /// Starting --endpoint ready--> Started Complete StartAsync successfully; Log process start30 /// Starting --process exit----> Exited Complete StartAsync with exception; Cleanup temp user data31 /// Started --StartAsync------> Started -32 /// Started --EnsureExitAsync-> Exiting Start exit timer; Log process exit33 /// Started --KillAsync-------> Killing Kill process; Log process exit34 /// Started --Dispose---------> Disposed Kill process; Log process exit; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;35 /// Started --process exit----> Exited Log process exit; Cleanup temp user data36 /// Exiting --StartAsync------> Exiting - (StartAsync throws InvalidOperationException)37 /// Exiting --ExitAsync-------> Exiting -38 /// Exiting --KillAsync-------> Killing Kill process39 /// Exiting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;40 /// Exiting --exit timeout----> Killing Kill process41 /// Exiting --process exit----> Exited Cleanup temp user data; complete outstanding async operations;42 /// Killing --StartAsync------> Killing - (StartAsync throws InvalidOperationException)43 /// Killing --KillAsync-------> Killing -44 /// Killing --Dispose---------> Disposed Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;45 /// Killing --process exit----> Exited Cleanup temp user data; complete outstanding async operations;46 /// Exited --StartAsync------> Killing - (StartAsync throws InvalidOperationException)47 /// Exited --KillAsync-------> Exited -48 /// Exited --Dispose---------> Disposed -49 /// Disposed --StartAsync------> Disposed -50 /// Disposed --KillAsync-------> Disposed -51 /// Disposed --Dispose---------> Disposed -52 /// </code>53 /// </para>54 /// </remarks>55 internal abstract class State56 {57 public State(StateManager stateManager)58 {59 StateManager = stateManager;60 }61 public StateManager StateManager { get; set; }62 public bool IsExiting => this == StateManager.Killing || this == StateManager.Exiting;63 public bool IsExited => this == StateManager.Exited || this == StateManager.Disposed;64 internal virtual void Leave(LauncherBase p)65 {66 }67 public virtual Task EnterFromAsync(LauncherBase p, State fromState) => EnterFromAsync(p, fromState, TimeSpan.Zero);68 public virtual Task EnterFromAsync(LauncherBase p, State fromState, TimeSpan timeout) => Task.FromException(InvalidOperation("enterFrom"));69 public virtual Task StartAsync(LauncherBase p) => Task.FromException(InvalidOperation("start"));70 public virtual Task ExitAsync(LauncherBase p, TimeSpan timeout) => Task.FromException(InvalidOperation("exit"));71 public virtual Task KillAsync(LauncherBase p) => Task.FromException(InvalidOperation("kill"));72 public virtual Task WaitForExitAsync(LauncherBase p) => p.ExitCompletionSource.Task;73 public virtual void Dispose(LauncherBase p) => StateManager.Disposed.EnterFromAsync(p, this, TimeSpan.Zero);74 public override string ToString()75 {76 var name = GetType().Name;77 return name.Substring(0, name.Length - "State".Length);78 }79 private Exception InvalidOperation(string operationName)80 => new InvalidOperationException($"Cannot {operationName} in state {this}");81 protected static void Kill(LauncherBase p)82 {83 try84 {85 if (!p.Process.HasExited)86 {87 p.Process.Kill();...

Full Screen

Full Screen

ChromiumStartingState.cs

Source:ChromiumStartingState.cs Github

copy

Full Screen

...23 }24 public override Task StartAsync(LauncherBase p) => p.StartCompletionSource.Task;25 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => StateManager.Exiting.EnterFromAsync(p, this, timeout);26 public override Task KillAsync(LauncherBase p) => StateManager.Killing.EnterFromAsync(p, this);27 public override void Dispose(LauncherBase p)28 {29 p.StartCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));30 base.Dispose(p);31 }32 protected virtual async Task StartCoreAsync(LauncherBase p)33 {34 var output = new StringBuilder();35 void OnProcessDataReceivedWhileStarting(object sender, DataReceivedEventArgs e)36 {37 if (e.Data != null)38 {39 output.AppendLine(e.Data);40 var match = Regex.Match(e.Data, "^DevTools listening on (ws:\\/\\/.*)");41 if (match.Success)42 {43 p.StartCompletionSource.TrySetResult(match.Groups[1].Value);44 }45 }46 }47 void OnProcessExitedWhileStarting(object sender, EventArgs e)48 => p.StartCompletionSource.TrySetException(new ProcessException($"Failed to launch browser! {output}"));49 void OnProcessExited(object sender, EventArgs e) => StateManager.Exited.EnterFrom(p, StateManager.CurrentState);50 p.Process.ErrorDataReceived += OnProcessDataReceivedWhileStarting;51 p.Process.Exited += OnProcessExitedWhileStarting;52 p.Process.Exited += OnProcessExited;53 CancellationTokenSource cts = null;54 try55 {56 p.Process.Start();57 await StateManager.Started.EnterFromAsync(p, this).ConfigureAwait(false);58 p.Process.BeginErrorReadLine();59 var timeout = p.Options.Timeout;60 if (timeout > 0)61 {62 cts = new CancellationTokenSource(timeout);63 cts.Token.Register(() => p.StartCompletionSource.TrySetException(64 new ProcessException($"Timed out after {timeout} ms while trying to connect to Base!")));65 }66 try67 {68 await p.StartCompletionSource.Task.ConfigureAwait(false);69 await StateManager.Started.EnterFromAsync(p, this).ConfigureAwait(false);70 }71 catch72 {73 await StateManager.Killing.EnterFromAsync(p, this).ConfigureAwait(false);74 throw;75 }76 }77 finally78 {79 cts?.Dispose();80 p.Process.Exited -= OnProcessExitedWhileStarting;81 p.Process.ErrorDataReceived -= OnProcessDataReceivedWhileStarting;82 }83 }84 }85}...

Full Screen

Full Screen

ExitedState.cs

Source:ExitedState.cs Github

copy

Full Screen

...20 return;21 }22 }23 p.ExitCompletionSource.TrySetResult(true);24 p.TempUserDataDir?.Dispose();25 }26 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => Task.CompletedTask;27 public override Task KillAsync(LauncherBase p) => Task.CompletedTask;28 public override Task WaitForExitAsync(LauncherBase p) => Task.CompletedTask;29 }30}...

Full Screen

Full Screen

DisposedState.cs

Source:DisposedState.cs Github

copy

Full Screen

1using System;2using System.Threading.Tasks;3namespace PuppeteerSharp.States4{5 internal class DisposedState : State6 {7 public DisposedState(StateManager stateManager) : base(stateManager)8 {9 }10 public override Task EnterFromAsync(LauncherBase p, State fromState, TimeSpan timeSpan)11 {12 if (fromState == StateManager.Exited)13 {14 return null;15 }16 Kill(p);17 p.ExitCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));18 p.TempUserDataDir?.Dispose();19 return null;20 }21 public override Task StartAsync(LauncherBase p) => throw new ObjectDisposedException(p.ToString());22 public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => throw new ObjectDisposedException(p.ToString());23 public override Task KillAsync(LauncherBase p) => throw new ObjectDisposedException(p.ToString());24 public override void Dispose(LauncherBase p)25 {26 // Nothing to do27 }28 }29}...

Full Screen

Full Screen

Dispose

Using AI Code Generation

copy

Full Screen

1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5 {6 static async Task Main(string[] args)7 {8 {9 Args = new string[] { "--no-sandbox" }10 };11 using (var launcher = await Puppeteer.LaunchAsync(options))12 {13 var page = await launcher.NewPageAsync();14 await page.ScreenshotAsync("google.png");15 }16 }17 }18}19using System;20using System.Threading.Tasks;21using PuppeteerSharp;22{23 {24 static async Task Main(string[] args)25 {26 {27 Args = new string[] { "--no-sandbox" }28 };29 var launcher = await Puppeteer.LaunchAsync(options);30 var page = await launcher.NewPageAsync();31 await page.ScreenshotAsync("google.png");32 await page.DisposeAsync();33 await launcher.DisposeAsync();34 }35 }36}37using System;38using System.Threading.Tasks;39using PuppeteerSharp;40{41 {42 static async Task Main(string[] args)43 {44 {45 Args = new string[] { "--no-sandbox" }46 };47 var launcher = await Puppeteer.LaunchAsync(options);48 var page = await launcher.NewPageAsync();49 await page.ScreenshotAsync("google.png");50 await launcher.CloseAsync();51 }52 }53}54using System;55using System.Threading.Tasks;56using PuppeteerSharp;57{58 {59 static async Task Main(string[] args)60 {61 {

Full Screen

Full Screen

Dispose

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp;2using System;3using System.Threading.Tasks;4{5 {6 static async Task Main(string[] args)7 {8 var options = new LaunchOptions { Headless = true };9 using (var browser = await Puppeteer.LaunchAsync(options))10 {11 var page = await browser.NewPageAsync();12 Console.WriteLine(page.Title);13 await page.ScreenshotAsync("google.png");14 }15 }16 }17}

Full Screen

Full Screen

Dispose

Using AI Code Generation

copy

Full Screen

1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5 {6 static void Main(string[] args)7 {8 Console.WriteLine("Hello World!");9 var task = MainAsync();10 task.Wait();11 }12 static async Task MainAsync()13 {14 var browser = await Puppeteer.LaunchAsync(new LaunchOptions15 {16 Args = new string[] { "--no-sandbox" }17 });18 var page = await browser.NewPageAsync();19 await page.ScreenshotAsync("google.png");20 await browser.CloseAsync();21 }22 }23}24using System;25using System.Threading.Tasks;26using PuppeteerSharp;27{28 {29 static void Main(string[] args)30 {31 Console.WriteLine("Hello World!");32 var task = MainAsync();33 task.Wait();34 }35 static async Task MainAsync()36 {37 var browser = await Puppeteer.LaunchAsync(new LaunchOptions38 {39 Args = new string[] { "--no-sandbox" }40 });41 var page = await browser.NewPageAsync();42 await page.ScreenshotAsync("google.png");43 await page.DisposeAsync();44 await browser.CloseAsync();45 }46 }47}48using System;49using System.Threading.Tasks;50using PuppeteerSharp;51{52 {53 static void Main(string[] args)54 {55 Console.WriteLine("Hello World!");56 var task = MainAsync();57 task.Wait();58 }59 static async Task MainAsync()60 {61 var browser = await Puppeteer.LaunchAsync(new LaunchOptions62 {63 Args = new string[] { "--no-sandbox" }64 });65 var page = await browser.NewPageAsync();66 await page.ScreenshotAsync("google.png");67 await page.DisposeAsync();68 await browser.DisposeAsync();69 }70 }71}

Full Screen

Full Screen

Dispose

Using AI Code Generation

copy

Full Screen

1using PuppeteerSharp;2using System;3using System.Threading.Tasks;4{5 {6 static async Task Main(string[] args)7 {8 var options = new LaunchOptions { Headless = true };9 using (var browser = await Puppeteer.LaunchAsync(options))10 {11 var page = await browser.NewPageAsync();12 await page.ScreenshotAsync("google.png");13 }14 }15 }16}17using PuppeteerSharp;18using System;19using System.Threading.Tasks;20{21 {22 static async Task Main(string[] args)23 {24 var options = new LaunchOptions { Headless = true };25 var browser = await Puppeteer.LaunchAsync(options);26 var page = await browser.NewPageAsync();27 await page.ScreenshotAsync("google.png");28 await browser.CloseAsync();29 }30 }31}32using PuppeteerSharp;33using System;34using System.Threading.Tasks;35{36 {37 static async Task Main(string

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful