How to use ExitAsync method of PuppeteerSharp.States.InitialState class

Best Puppeteer-sharp code snippet using PuppeteerSharp.States.InitialState.ExitAsync

ChromiumProcess.cs

Source:ChromiumProcess.cs Github

copy

Full Screen

...137 /// Kills the Chromium process if it has not exited within this period.138 /// </summary>139 /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>140 /// <returns></returns>141 public Task EnsureExitAsync(TimeSpan? timeout) => timeout.HasValue142 ? _currentState.ExitAsync(this, timeout.Value)143 : _currentState.KillAsync(this);144 /// <summary>145 /// Asynchronously kills Chromium process.146 /// </summary>147 /// <returns></returns>148 public Task KillAsync() => _currentState.KillAsync(this);149 /// <summary>150 /// Waits for Chromium process exit within a given timeout.151 /// </summary>152 /// <param name="timeout">The maximum wait period.</param>153 /// <returns><c>true</c> if Chromium process has exited within the given <paramref name="timeout"/>,154 /// or <c>false</c> otherwise.</returns>155 public async Task<bool> WaitForExitAsync(TimeSpan? timeout)156 {157 if (timeout.HasValue)158 {159 var taskCompleted = true;160 await _exitCompletionSource.Task.WithTimeout(() =>161 {162 taskCompleted = false;163 }, timeout.Value).ConfigureAwait(false);164 return taskCompleted;165 }166 await _exitCompletionSource.Task.ConfigureAwait(false);167 return true;168 }169 /// <inheritdoc />170 public override string ToString() => $"Chromium process; EndPoint={EndPoint}; State={_currentState}";171 #endregion172 #region Private methods173 private static (List<string> chromiumArgs, TempDirectory tempUserDataDir) PrepareChromiumArgs(LaunchOptions options)174 {175 var chromiumArgs = new List<string>();176 if (!options.IgnoreDefaultArgs)177 {178 chromiumArgs.AddRange(GetDefaultArgs(options));179 }180 else if (options.IgnoredDefaultArgs?.Length > 0)181 {182 chromiumArgs.AddRange(GetDefaultArgs(options).Except(options.IgnoredDefaultArgs));183 }184 else185 {186 chromiumArgs.AddRange(options.Args);187 }188 TempDirectory tempUserDataDir = null;189 if (!chromiumArgs.Any(argument => argument.StartsWith("--remote-debugging-", StringComparison.Ordinal)))190 {191 chromiumArgs.Add("--remote-debugging-port=0");192 }193 var userDataDirOption = chromiumArgs.FirstOrDefault(i => i.StartsWith(UserDataDirArgument, StringComparison.Ordinal));194 if (string.IsNullOrEmpty(userDataDirOption))195 {196 tempUserDataDir = new TempDirectory();197 chromiumArgs.Add($"{UserDataDirArgument}={tempUserDataDir.Path.Quote()}");198 }199 return (chromiumArgs, tempUserDataDir);200 }201 internal static string[] GetDefaultArgs(LaunchOptions options)202 {203 var chromeArguments = new List<string>(DefaultArgs);204 if (!string.IsNullOrEmpty(options.UserDataDir))205 {206 chromeArguments.Add($"{UserDataDirArgument}={options.UserDataDir.Quote()}");207 }208 if (options.Devtools)209 {210 chromeArguments.Add("--auto-open-devtools-for-tabs");211 }212 if (options.Headless)213 {214 chromeArguments.AddRange(new[]{215 "--headless",216 "--hide-scrollbars",217 "--mute-audio"218 });219 }220 if (options.Args.All(arg => arg.StartsWith("-", StringComparison.Ordinal)))221 {222 chromeArguments.Add("about:blank");223 }224 chromeArguments.AddRange(options.Args);225 return chromeArguments.ToArray();226 }227 private static void SetEnvVariables(IDictionary<string, string> environment, IDictionary<string, string> customEnv, IDictionary realEnv)228 {229 foreach (DictionaryEntry item in realEnv)230 {231 environment[item.Key.ToString()] = item.Value.ToString();232 }233 if (customEnv != null)234 {235 foreach (var item in customEnv)236 {237 environment[item.Key] = item.Value;238 }239 }240 }241 #endregion242 #region State machine243 /// <summary>244 /// Represents state machine for Chromium process instances. The happy path runs along the245 /// following state transitions: <see cref="Initial"/>246 /// -> <see cref="Starting"/>247 /// -> <see cref="Started"/>248 /// -> <see cref="Exiting"/>249 /// -> <see cref="Exited"/>.250 /// -> <see cref="Disposed"/>.251 /// </summary>252 /// <remarks>253 /// <para>254 /// This state machine implements the following state transitions:255 /// <code>256 /// State Event Target State Action257 /// ======== =================== ============ ==========================================================258 /// Initial --StartAsync------> Starting Start process and wait for endpoint259 /// Initial --ExitAsync-------> Exited Cleanup temp user data260 /// Initial --KillAsync-------> Exited Cleanup temp user data261 /// Initial --Dispose---------> Disposed Cleanup temp user data262 /// Starting --StartAsync------> Starting -263 /// Starting --ExitAsync-------> Exiting Wait for process exit264 /// Starting --KillAsync-------> Killing Kill process265 /// Starting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;266 /// Starting --endpoint ready--> Started Complete StartAsync successfully; Log process start267 /// Starting --process exit----> Exited Complete StartAsync with exception; Cleanup temp user data268 /// Started --StartAsync------> Started -269 /// Started --EnsureExitAsync-> Exiting Start exit timer; Log process exit270 /// Started --KillAsync-------> Killing Kill process; Log process exit271 /// Started --Dispose---------> Disposed Kill process; Log process exit; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;272 /// Started --process exit----> Exited Log process exit; Cleanup temp user data273 /// Exiting --StartAsync------> Exiting - (StartAsync throws InvalidOperationException)274 /// Exiting --ExitAsync-------> Exiting -275 /// Exiting --KillAsync-------> Killing Kill process276 /// Exiting --Dispose---------> Disposed Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;277 /// Exiting --exit timeout----> Killing Kill process278 /// Exiting --process exit----> Exited Cleanup temp user data; complete outstanding async operations;279 /// Killing --StartAsync------> Killing - (StartAsync throws InvalidOperationException)280 /// Killing --KillAsync-------> Killing -281 /// Killing --Dispose---------> Disposed Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;282 /// Killing --process exit----> Exited Cleanup temp user data; complete outstanding async operations;283 /// Exited --StartAsync------> Killing - (StartAsync throws InvalidOperationException)284 /// Exited --KillAsync-------> Exited -285 /// Exited --Dispose---------> Disposed -286 /// Disposed --StartAsync------> Disposed -287 /// Disposed --KillAsync-------> Disposed -288 /// Disposed --Dispose---------> Disposed -289 /// </code>290 /// </para>291 /// </remarks>292 private abstract class State293 {294 #region Predefined states295 public static readonly State Initial = new InitialState();296 private static readonly StartingState Starting = new StartingState();297 private static readonly StartedState Started = new StartedState();298 private static readonly ExitingState Exiting = new ExitingState();299 private static readonly KillingState Killing = new KillingState();300 private static readonly ExitedState Exited = new ExitedState();301 private static readonly DisposedState Disposed = new DisposedState();302 #endregion303 #region Properties304 public bool IsExiting => this == Killing || this == Exiting;305 public bool IsExited => this == Exited || this == Disposed;306 #endregion307 #region Methods308 /// <summary>309 /// Attempts thread-safe transitions from a given state to this state.310 /// </summary>311 /// <param name="p">The Chromium process</param>312 /// <param name="fromState">The state from which state transition takes place</param>313 /// <returns>Returns <c>true</c> if transition is successful, or <c>false</c> if transition314 /// cannot be made because current state does not equal <paramref name="fromState"/>.</returns>315 protected bool TryEnter(ChromiumProcess p, State fromState)316 {317 if (Interlocked.CompareExchange(ref p._currentState, this, fromState) == fromState)318 {319 fromState.Leave(p);320 return true;321 }322 return false;323 }324 /// <summary>325 /// Notifies that state machine is about to transition to another state.326 /// </summary>327 /// <param name="p">The Chromium process</param>328 protected virtual void Leave(ChromiumProcess p)329 { }330 /// <summary>331 /// Handles process start request.332 /// </summary>333 /// <param name="p">The Chromium process</param>334 /// <returns></returns>335 public virtual Task StartAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("start"));336 /// <summary>337 /// Handles process exit request.338 /// </summary>339 /// <param name="p">The Chromium process</param>340 /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>341 /// <returns></returns>342 public virtual Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Task.FromException(InvalidOperation("exit"));343 /// <summary>344 /// Handles process kill request.345 /// </summary>346 /// <param name="p">The Chromium process</param>347 /// <returns></returns>348 public virtual Task KillAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("kill"));349 /// <summary>350 /// Handles wait for process exit request.351 /// </summary>352 /// <param name="p">The Chromium process</param>353 /// <returns></returns>354 public virtual Task WaitForExitAsync(ChromiumProcess p) => p._exitCompletionSource.Task;355 /// <summary>356 /// Handles disposal of process and temporary user directory357 /// </summary>358 /// <param name="p"></param>359 public virtual void Dispose(ChromiumProcess p) => Disposed.EnterFrom(p, this);360 public override string ToString()361 {362 var name = GetType().Name;363 return name.Substring(0, name.Length - "State".Length);364 }365 private Exception InvalidOperation(string operationName)366 => new InvalidOperationException($"Cannot {operationName} in state {this}");367 /// <summary>368 /// Kills process if it is still alive.369 /// </summary>370 /// <param name="p"></param>371 private static void Kill(ChromiumProcess p)372 {373 try374 {375 if (!p.Process.HasExited)376 {377 p.Process.Kill();378 }379 }380 catch (InvalidOperationException)381 {382 // Ignore383 }384 }385 #endregion386 #region Concrete state classes387 private class InitialState : State388 {389 public override Task StartAsync(ChromiumProcess p) => Starting.EnterFromAsync(p, this);390 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout)391 {392 Exited.EnterFrom(p, this);393 return Task.CompletedTask;394 }395 public override Task KillAsync(ChromiumProcess p)396 {397 Exited.EnterFrom(p, this);398 return Task.CompletedTask;399 }400 public override Task WaitForExitAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("wait for exit"));401 }402 private class StartingState : State403 {404 public Task EnterFromAsync(ChromiumProcess p, State fromState)405 {406 if (!TryEnter(p, fromState))407 {408 // Delegate StartAsync to current state, because it has already changed since409 // transition to this state was initiated.410 return p._currentState.StartAsync(p);411 }412 return StartCoreAsync(p);413 }414 public override Task StartAsync(ChromiumProcess p) => p._startCompletionSource.Task;415 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);416 public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);417 public override void Dispose(ChromiumProcess p)418 {419 p._startCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));420 base.Dispose(p);421 }422 private async Task StartCoreAsync(ChromiumProcess p)423 {424 var output = new StringBuilder();425 void OnProcessDataReceivedWhileStarting(object sender, DataReceivedEventArgs e)426 {427 if (e.Data != null)428 {429 output.AppendLine(e.Data);430 var match = Regex.Match(e.Data, "^DevTools listening on (ws:\\/\\/.*)");431 if (match.Success)432 {433 p._startCompletionSource.TrySetResult(match.Groups[1].Value);434 }435 }436 }437 void OnProcessExitedWhileStarting(object sender, EventArgs e)438 => p._startCompletionSource.TrySetException(new ChromiumProcessException($"Failed to launch Chromium! {output}"));439 void OnProcessExited(object sender, EventArgs e) => Exited.EnterFrom(p, p._currentState);440 p.Process.ErrorDataReceived += OnProcessDataReceivedWhileStarting;441 p.Process.Exited += OnProcessExitedWhileStarting;442 p.Process.Exited += OnProcessExited;443 CancellationTokenSource cts = null;444 try445 {446 p.Process.Start();447 await Started.EnterFromAsync(p, this).ConfigureAwait(false);448 p.Process.BeginErrorReadLine();449 var timeout = p._options.Timeout;450 if (timeout > 0)451 {452 cts = new CancellationTokenSource(timeout);453 cts.Token.Register(() => p._startCompletionSource.TrySetException(454 new ChromiumProcessException($"Timed out after {timeout} ms while trying to connect to Chromium!")));455 }456 try457 {458 await p._startCompletionSource.Task.ConfigureAwait(false);459 await Started.EnterFromAsync(p, this).ConfigureAwait(false);460 }461 catch462 {463 await Killing.EnterFromAsync(p, this).ConfigureAwait(false);464 throw;465 }466 }467 finally468 {469 cts?.Dispose();470 p.Process.Exited -= OnProcessExitedWhileStarting;471 p.Process.ErrorDataReceived -= OnProcessDataReceivedWhileStarting;472 }473 }474 }475 private class StartedState : State476 {477 public Task EnterFromAsync(ChromiumProcess p, State fromState)478 {479 if (TryEnter(p, fromState))480 {481 // Process has not exited or been killed since transition to this state was initiated482 LogProcessCount(p, Interlocked.Increment(ref _processCount));483 }484 return Task.CompletedTask;485 }486 protected override void Leave(ChromiumProcess p)487 => LogProcessCount(p, Interlocked.Decrement(ref _processCount));488 public override Task StartAsync(ChromiumProcess p) => Task.CompletedTask;489 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);490 public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);491 private static void LogProcessCount(ChromiumProcess p, int processCount)492 {493 try494 {495 p._logger?.LogInformation("Process Count: {ProcessCount}", processCount);496 }497 catch498 {499 // Prevent logging exception from causing havoc500 }501 }502 }503 private class ExitingState : State504 {505 public Task EnterFromAsync(ChromiumProcess p, State fromState, TimeSpan timeout)506 => !TryEnter(p, fromState) ? p._currentState.ExitAsync(p, timeout) : ExitAsync(p, timeout);507 public override async Task ExitAsync(ChromiumProcess p, TimeSpan timeout)508 {509 var waitForExitTask = WaitForExitAsync(p);510 await waitForExitTask.WithTimeout(async () =>511 {512 await Killing.EnterFromAsync(p, this).ConfigureAwait(false);513 await waitForExitTask.ConfigureAwait(false);514 }, timeout).ConfigureAwait(false);515 }516 public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);517 }518 private class KillingState : State519 {520 public async Task EnterFromAsync(ChromiumProcess p, State fromState)521 {522 if (!TryEnter(p, fromState))523 {524 // Delegate KillAsync to current state, because it has already changed since525 // transition to this state was initiated.526 await p._currentState.KillAsync(p).ConfigureAwait(false);527 }528 try529 {530 if (!p.Process.HasExited)531 {532 p.Process.Kill();533 }534 }535 catch (InvalidOperationException)536 {537 // Ignore538 return;539 }540 await WaitForExitAsync(p).ConfigureAwait(false);541 }542 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => WaitForExitAsync(p);543 public override Task KillAsync(ChromiumProcess p) => WaitForExitAsync(p);544 }545 private class ExitedState : State546 {547 public void EnterFrom(ChromiumProcess p, State fromState)548 {549 while (!TryEnter(p, fromState))550 {551 // Current state has changed since transition to this state was requested.552 // Therefore retry transition to this state from the current state. This ensures553 // that Leave() operation of current state is properly called.554 fromState = p._currentState;555 if (fromState == this)556 {557 return;558 }559 }560 p._exitCompletionSource.TrySetResult(true);561 p._tempUserDataDir?.Dispose();562 }563 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Task.CompletedTask;564 public override Task KillAsync(ChromiumProcess p) => Task.CompletedTask;565 public override Task WaitForExitAsync(ChromiumProcess p) => Task.CompletedTask;566 }567 private class DisposedState : State568 {569 public void EnterFrom(ChromiumProcess p, State fromState)570 {571 if (!TryEnter(p, fromState))572 {573 // Delegate Dispose to current state, because it has already changed since574 // transition to this state was initiated.575 p._currentState.Dispose(p);576 }577 else if (fromState != Exited)578 {579 Kill(p);580 p._exitCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));581 p._tempUserDataDir?.Dispose();582 }583 }584 public override Task StartAsync(ChromiumProcess p) => throw new ObjectDisposedException(p.ToString());585 public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => throw new ObjectDisposedException(p.ToString());586 public override Task KillAsync(ChromiumProcess p) => throw new ObjectDisposedException(p.ToString());587 public override void Dispose(ChromiumProcess p)588 {589 // Nothing to do590 }591 }592 #endregion593 }594 #endregion595 }596}...

Full Screen

Full Screen

LauncherBase.cs

Source:LauncherBase.cs Github

copy

Full Screen

...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

InitialState.cs

Source:InitialState.cs Github

copy

Full Screen

...7 public InitialState(StateManager stateManager) : base(stateManager)8 {9 }10 public override Task StartAsync(LauncherBase p) => StateManager.Starting.EnterFromAsync(p, this, TimeSpan.Zero);11 public override Task ExitAsync(LauncherBase p, TimeSpan timeout)12 {13 StateManager.Exited.EnterFromAsync(p, this);14 return Task.CompletedTask;15 }16 public override Task KillAsync(LauncherBase p)17 {18 StateManager.Exited.EnterFromAsync(p, this);19 return Task.CompletedTask;20 }21 public override Task WaitForExitAsync(LauncherBase p) => Task.FromException(InvalidOperation("wait for exit"));22 private Exception InvalidOperation(string v)23 {24 throw new NotImplementedException();25 }26 }27}...

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1await browser.CloseAsync();2await browser.CloseAsync();3await browser.CloseAsync();4await browser.CloseAsync();5await browser.CloseAsync();6await browser.CloseAsync();7await browser.CloseAsync();8await browser.CloseAsync();9await browser.CloseAsync();10await browser.CloseAsync();11await browser.CloseAsync();12await browser.CloseAsync();13await browser.CloseAsync();14await browser.CloseAsync();15await browser.CloseAsync();16await browser.CloseAsync();17await browser.CloseAsync();18await browser.CloseAsync();

Full Screen

Full Screen

ExitAsync

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 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);9 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });10 var page = await browser.NewPageAsync();11 await page.WaitForSelectorAsync("input[name=q]");12 await page.TypeAsync("input[name=q]", "Hello World");13 await page.ClickAsync("input[name=btnK]");14 await page.WaitForNavigationAsync();15 await browser.CloseAsync();16 }17 }18}19using System;20using System.Threading.Tasks;21using PuppeteerSharp;22{23 {24 static async Task Main(string[] args)25 {26 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);27 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });28 var page = await browser.NewPageAsync();29 await page.WaitForSelectorAsync("input[name=q]");30 await page.TypeAsync("input[name=q]", "Hello World");31 await page.ClickAsync("input[name=btnK]");32 await page.WaitForNavigationAsync();33 await browser.ExitAsync();34 }35 }36}37using System;38using System.Threading.Tasks;39using PuppeteerSharp;40{41 {42 static async Task Main(string[] args)43 {44 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);45 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });46 var page = await browser.NewPageAsync();47 await page.WaitForSelectorAsync("input[name=q]");48 await page.TypeAsync("input[name=q]", "Hello World");49 await page.ClickAsync("input[name=btnK]");50 await page.WaitForNavigationAsync();51 await browser.ExitAsync();52 }53 }54}

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1var browser = await Puppeteer.LaunchAsync(new LaunchOptions2{3 Args = new[] { "--no-sandbox" }4});5var page = await browser.NewPageAsync();6Console.WriteLine(await page.GetContentAsync());7await page.CloseAsync();8await browser.CloseAsync();9await browser.ExitAsync();10var browser = await Puppeteer.LaunchAsync(new LaunchOptions11{12 Args = new[] { "--no-sandbox" }13});14var page = await browser.NewPageAsync();15Console.WriteLine(await page.GetContentAsync());16await page.CloseAsync();17await browser.CloseAsync();18await browser.KillAsync();19var browser = await Puppeteer.LaunchAsync(new LaunchOptions20{21 Args = new[] { "--no-sandbox" }22});23var page = await browser.NewPageAsync();24Console.WriteLine(await page.GetContentAsync());25await page.CloseAsync();26await browser.CloseAsync();27await browser.KillChrome();28var browser = await Puppeteer.LaunchAsync(new LaunchOptions29{30 Args = new[] { "--no-sandbox" }31});32var page = await browser.NewPageAsync();33Console.WriteLine(await page.GetContentAsync());34await page.CloseAsync();35await browser.CloseAsync();36await browser.KillChrome();37var browser = await Puppeteer.LaunchAsync(new LaunchOptions38{39 Args = new[] { "--no-sandbox" }40});41var page = await browser.NewPageAsync();42Console.WriteLine(await page.GetContentAsync());43await page.CloseAsync();44await browser.CloseAsync();45await browser.KillChrome();

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1var browser = await Puppeteer.LaunchAsync( new LaunchOptions { Headless = false });2 var page = await browser.NewPageAsync();3 await page.WaitForSelectorAsync( "input[title='Search']" );4 await page.TypeAsync( "input[title='Search']" , "Hello World" );5 await page.Keyboard.PressAsync( "Enter" );6 await page.WaitForNavigationAsync();7 await page.ScreenshotAsync( "screenshot.png" );8 await browser.CloseAsync();9var browser = await Puppeteer.LaunchAsync( new LaunchOptions { Headless = false });10 var page = await browser.NewPageAsync();11 await page.WaitForSelectorAsync( "input[title='Search']" );12 await page.TypeAsync( "input[title='Search']" , "Hello World" );13 await page.Keyboard.PressAsync( "Enter" );14 await page.WaitForNavigationAsync();15 await page.ScreenshotAsync( "screenshot.png" );16 await browser.ExitAsync();17var browser = await Puppeteer.LaunchAsync( new LaunchOptions { Headless = false });18 var page = await browser.NewPageAsync();19 await page.WaitForSelectorAsync( "input[title='Search']" );20 await page.TypeAsync( "input[title='Search']" , "Hello World" );21 await page.Keyboard.PressAsync( "Enter" );22 await page.WaitForNavigationAsync();23 await page.ScreenshotAsync( "screenshot.png" );24 await browser.ExitAsync();25var browser = await Puppeteer.LaunchAsync( new LaunchOptions { Headless = false });26 var page = await browser.NewPageAsync();27 await page.GoToAsync( "

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });2var page = await browser.NewPageAsync();3await page.WaitForSelectorAsync("input[name=q]");4await page.TypeAsync("input[name=q]", "PuppeteerSharp");5await page.Keyboard.PressAsync("Enter");6await page.WaitForNavigationAsync();7await page.ScreenshotAsync("google.png");8await browser.CloseAsync();9await browser.ExitAsync();10var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });11var page = await browser.NewPageAsync();12await page.WaitForSelectorAsync("input[name=q]");13await page.TypeAsync("input[name=q]", "PuppeteerSharp");14await page.Keyboard.PressAsync("Enter");15await page.WaitForNavigationAsync();16await page.ScreenshotAsync("google.png");17await browser.CloseAsync();18await browser.KillAsync();19var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });20var page = await browser.NewPageAsync();21await page.WaitForSelectorAsync("input[name=q]");22await page.TypeAsync("input[name=q]", "PuppeteerSharp");23await page.Keyboard.PressAsync("Enter");24await page.WaitForNavigationAsync();25await page.ScreenshotAsync("google.png");26await browser.CloseAsync();27await browser.KillAsync();28var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true });29var page = await browser.NewPageAsync();30await page.WaitForSelectorAsync("input[name=q]");31await page.TypeAsync("input[name=q]", "PuppeteerSharp");32await page.Keyboard.PressAsync("Enter");33await page.WaitForNavigationAsync();34await page.ScreenshotAsync("google.png");35await browser.CloseAsync();36await browser.KillAsync();

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

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

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1var state = new InitialState();2await state.ExitAsync();3await state.ExitAsync();4await state.ExitAsync();5var state = new InitialState();6await state.ExitAsync();7await state.ExitAsync();8await state.ExitAsync();9var state = new InitialState();10await state.ExitAsync();11await state.ExitAsync();12await state.ExitAsync();13var state = new InitialState();14await state.ExitAsync();15await state.ExitAsync();16await state.ExitAsync();17var state = new InitialState();18await state.ExitAsync();19await state.ExitAsync();20await state.ExitAsync();21var state = new InitialState();22await state.ExitAsync();23await state.ExitAsync();24await state.ExitAsync();25var state = new InitialState();26await state.ExitAsync();27await state.ExitAsync();28await state.ExitAsync();29var state = new InitialState();30await state.ExitAsync();31await state.ExitAsync();32await state.ExitAsync();33var state = new InitialState();34await state.ExitAsync();35await state.ExitAsync();36await state.ExitAsync();37var state = new InitialState();38await state.ExitAsync();39await state.ExitAsync();40await state.ExitAsync();41var state = new InitialState();42await state.ExitAsync();43await state.ExitAsync();44await state.ExitAsync();

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1await page.WaitForSelectorAsync("input[name=q]");2await page.TypeAsync("input[name=q]", "PuppeteerSharp");3await page.ClickAsync("input[name=btnK]");4await page.WaitForNavigationAsync();5await page.CloseAsync();6await page.WaitForSelectorAsync("input[name=q]");7await page.TypeAsync("input[name=q]", "PuppeteerSharp");8await page.ClickAsync("input[name=btnK]");9await page.WaitForNavigationAsync();10await page.CloseAsync();11await page.WaitForSelectorAsync("input[name=q]");12await page.TypeAsync("input[name=q]", "PuppeteerSharp");13await page.ClickAsync("input[name=btnK]");14await page.WaitForNavigationAsync();15await page.CloseAsync();16await page.WaitForSelectorAsync("input[name=q]");17await page.TypeAsync("input[name=q]", "PuppeteerSharp");18await page.ClickAsync("input[name=btnK]");19await page.WaitForNavigationAsync();20await page.CloseAsync();21await page.WaitForSelectorAsync("input[name=q]");22await page.TypeAsync("input[name=q]", "PuppeteerSharp");23await page.ClickAsync("input[name=btnK]");24await page.WaitForNavigationAsync();25await page.CloseAsync();26await page.WaitForSelectorAsync("input[name=q]");27await page.TypeAsync("input[name=q]", "PuppeteerSharp");28await page.ClickAsync("input[name=btnK]");29await page.WaitForNavigationAsync();30await page.CloseAsync();

Full Screen

Full Screen

ExitAsync

Using AI Code Generation

copy

Full Screen

1var exitcode = await state.ExitAsync();2var exitcode = state.Exit();3var exitcode = await state.ExitAsync();4var exitcode = state.Exit();5var exitcode = await state.ExitAsync();6var exitcode = state.Exit();7var exitcode = await state.ExitAsync();8var exitcode = state.Exit();9var exitcode = await state.ExitAsync();10var exitcode = state.Exit();11var exitcode = await state.ExitAsync();12var exitcode = state.Exit();13var exitcode = await state.ExitAsync();14var exitcode = state.Exit();15var exitcode = await state.ExitAsync();16var exitcode = state.Exit();17var exitcode = await state.ExitAsync();18var exitcode = state.Exit();

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