Best Puppeteer-sharp code snippet using PuppeteerSharp.States.ExitingState.KillAsync
ChromiumProcess.cs
Source:ChromiumProcess.cs  
...135        /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>136        /// <returns></returns>137        public Task EnsureExitAsync(TimeSpan? timeout) => timeout.HasValue138            ? _currentState.ExitAsync(this, timeout.Value)139            : _currentState.KillAsync(this);140        /// <summary>141        /// Asynchronously kills Chromium process.142        /// </summary>143        /// <returns></returns>144        public Task KillAsync() => _currentState.KillAsync(this);145        /// <summary>146        /// Waits for Chromium process exit within a given timeout.147        /// </summary>148        /// <param name="timeout">The maximum wait period.</param>149        /// <returns><c>true</c> if Chromium process has exited within the given <paramref name="timeout"/>,150        /// or <c>false</c> otherwise.</returns>151        public async Task<bool> WaitForExitAsync(TimeSpan? timeout)152        {153            if (timeout.HasValue)154            {155                var completedTask = await Task.WhenAny(_exitCompletionSource.Task, Task.Delay(timeout.Value)).ConfigureAwait(false);156                return completedTask == _exitCompletionSource.Task;157            }158            await _exitCompletionSource.Task.ConfigureAwait(false);159            return true;160        }161        /// <inheritdoc />162        public override string ToString() => $"Chromium process; EndPoint={EndPoint}; State={_currentState}";163        #endregion164        #region Private methods165        private static (List<string> chromiumArgs, TempDirectory tempUserDataDir) PrepareChromiumArgs(LaunchOptions options)166        {167            var chromiumArgs = new List<string>();168            if (!options.IgnoreDefaultArgs)169            {170                chromiumArgs.AddRange(GetDefaultArgs(options));171            }172            else if (options.IgnoredDefaultArgs?.Length > 0)173            {174                chromiumArgs.AddRange(GetDefaultArgs(options).Except(options.IgnoredDefaultArgs));175            }176            else177            {178                chromiumArgs.AddRange(options.Args);179            }180            TempDirectory tempUserDataDir = null;181            if (!chromiumArgs.Any(argument => argument.StartsWith("--remote-debugging-", StringComparison.Ordinal)))182            {183                chromiumArgs.Add("--remote-debugging-port=0");184            }185            var userDataDirOption = chromiumArgs.FirstOrDefault(i => i.StartsWith(UserDataDirArgument, StringComparison.Ordinal));186            if (string.IsNullOrEmpty(userDataDirOption))187            {188                tempUserDataDir = new TempDirectory();189                chromiumArgs.Add($"{UserDataDirArgument}={tempUserDataDir.Path.Quote()}");190            }191            return (chromiumArgs, tempUserDataDir);192        }193        internal static string[] GetDefaultArgs(LaunchOptions options)194        {195            var chromeArguments = new List<string>(DefaultArgs);196            if (!string.IsNullOrEmpty(options.UserDataDir))197            {198                chromeArguments.Add($"{UserDataDirArgument}={options.UserDataDir.Quote()}");199            }200            if (options.Devtools)201            {202                chromeArguments.Add("--auto-open-devtools-for-tabs");203            }204            if (options.Headless)205            {206                chromeArguments.AddRange(new[]{207                    "--headless",208                    "--hide-scrollbars",209                    "--mute-audio"210                });211                if (BrowserFetcher.GetCurrentPlatform() == Platform.Win32)212                {213                    chromeArguments.Add("--disable-gpu");214                }215            }216            if (options.Args.All(arg => arg.StartsWith("-", StringComparison.Ordinal)))217            {218                chromeArguments.Add("about:blank");219            }220            chromeArguments.AddRange(options.Args);221            return chromeArguments.ToArray();222        }223        private static void SetEnvVariables(IDictionary<string, string> environment, IDictionary<string, string> customEnv, IDictionary realEnv)224        {225            foreach (DictionaryEntry item in realEnv)226            {227                environment[item.Key.ToString()] = item.Value.ToString();228            }229            if (customEnv != null)230            {231                foreach (var item in customEnv)232                {233                    environment[item.Key] = item.Value;234                }235            }236        }237        #endregion238        #region State machine239        /// <summary>240        /// Represents state machine for Chromium process instances. The happy path runs along the241        /// following state transitions: <see cref="Initial"/>242        /// -> <see cref="Starting"/>243        /// -> <see cref="Started"/>244        /// -> <see cref="Exiting"/>245        /// -> <see cref="Exited"/>.246        /// -> <see cref="Disposed"/>.247        /// </summary>248        /// <remarks>249        /// <para>250        /// This state machine implements the following state transitions:251        /// <code>252        /// State     Event              Target State Action253        /// ======== =================== ============ ==========================================================254        /// Initial  --StartAsync------> Starting     Start process and wait for endpoint255        /// Initial  --ExitAsync-------> Exited       Cleanup temp user data256        /// Initial  --KillAsync-------> Exited       Cleanup temp user data257        /// Initial  --Dispose---------> Disposed     Cleanup temp user data258        /// Starting --StartAsync------> Starting     -259        /// Starting --ExitAsync-------> Exiting      Wait for process exit260        /// Starting --KillAsync-------> Killing      Kill process261        /// Starting --Dispose---------> Disposed     Kill process; Cleanup temp user data;  throw ObjectDisposedException on outstanding async operations;262        /// Starting --endpoint ready--> Started      Complete StartAsync successfully; Log process start263        /// Starting --process exit----> Exited       Complete StartAsync with exception; Cleanup temp user data264        /// Started  --StartAsync------> Started      -265        /// Started  --EnsureExitAsync-> Exiting      Start exit timer; Log process exit266        /// Started  --KillAsync-------> Killing      Kill process; Log process exit267        /// Started  --Dispose---------> Disposed     Kill process; Log process exit; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;268        /// Started  --process exit----> Exited       Log process exit; Cleanup temp user data269        /// Exiting  --StartAsync------> Exiting      - (StartAsync throws InvalidOperationException)270        /// Exiting  --ExitAsync-------> Exiting      -271        /// Exiting  --KillAsync-------> Killing      Kill process272        /// Exiting  --Dispose---------> Disposed     Kill process; Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;273        /// Exiting  --exit timeout----> Killing      Kill process274        /// Exiting  --process exit----> Exited       Cleanup temp user data; complete outstanding async operations;275        /// Killing  --StartAsync------> Killing      - (StartAsync throws InvalidOperationException)276        /// Killing  --KillAsync-------> Killing      -277        /// Killing  --Dispose---------> Disposed     Cleanup temp user data; throw ObjectDisposedException on outstanding async operations;278        /// Killing  --process exit----> Exited       Cleanup temp user data; complete outstanding async operations;279        /// Exited   --StartAsync------> Killing      - (StartAsync throws InvalidOperationException)280        /// Exited   --KillAsync-------> Exited       -281        /// Exited   --Dispose---------> Disposed     -282        /// Disposed --StartAsync------> Disposed     -283        /// Disposed --KillAsync-------> Disposed     -284        /// Disposed --Dispose---------> Disposed     -285        /// </code>286        /// </para>287        /// </remarks>288        private abstract class State289        {290            #region Predefined states291            public static readonly State Initial = new InitialState();292            private static readonly StartingState Starting = new StartingState();293            private static readonly StartedState Started = new StartedState();294            private static readonly ExitingState Exiting = new ExitingState();295            private static readonly KillingState Killing = new KillingState();296            private static readonly ExitedState Exited = new ExitedState();297            private static readonly DisposedState Disposed = new DisposedState();298            #endregion299            #region Properties300            public bool IsExiting => this == Killing || this == Exiting;301            public bool IsExited => this == Exited || this == Disposed;302            #endregion303            #region Methods304            /// <summary>305            /// Attempts thread-safe transitions from a given state to this state.306            /// </summary>307            /// <param name="p">The Chromium process</param>308            /// <param name="fromState">The state from which state transition takes place</param>309            /// <returns>Returns <c>true</c> if transition is successful, or <c>false</c> if transition310            /// cannot be made because current state does not equal <paramref name="fromState"/>.</returns>311            protected bool TryEnter(ChromiumProcess p, State fromState)312            {313                if (Interlocked.CompareExchange(ref p._currentState, this, fromState) == fromState)314                {315                    fromState.Leave(p);316                    return true;317                }318                return false;319            }320            /// <summary>321            /// Notifies that state machine is about to transition to another state.322            /// </summary>323            /// <param name="p">The Chromium process</param>324            protected virtual void Leave(ChromiumProcess p)325            { }326            /// <summary>327            /// Handles process start request.328            /// </summary>329            /// <param name="p">The Chromium process</param>330            /// <returns></returns>331            public virtual Task StartAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("start"));332            /// <summary>333            /// Handles process exit request.334            /// </summary>335            /// <param name="p">The Chromium process</param>336            /// <param name="timeout">The maximum waiting time for a graceful process exit.</param>337            /// <returns></returns>338            public virtual Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Task.FromException(InvalidOperation("exit"));339            /// <summary>340            /// Handles process kill request.341            /// </summary>342            /// <param name="p">The Chromium process</param>343            /// <returns></returns>344            public virtual Task KillAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("kill"));345            /// <summary>346            /// Handles wait for process exit request.347            /// </summary>348            /// <param name="p">The Chromium process</param>349            /// <returns></returns>350            public virtual Task WaitForExitAsync(ChromiumProcess p) => p._exitCompletionSource.Task;351            /// <summary>352            /// Handles disposal of process and temporary user directory353            /// </summary>354            /// <param name="p"></param>355            public virtual void Dispose(ChromiumProcess p) => Disposed.EnterFrom(p, this);356            public override string ToString()357            {358                var name = GetType().Name;359                return name.Substring(0, name.Length - "State".Length);360            }361            private Exception InvalidOperation(string operationName)362                => new InvalidOperationException($"Cannot {operationName} in state {this}");363            /// <summary>364            /// Kills process if it is still alive.365            /// </summary>366            /// <param name="p"></param>367            private static void Kill(ChromiumProcess p)368            {369                try370                {371                    if (!p.Process.HasExited)372                    {373                        p.Process.Kill();374                    }375                }376                catch (InvalidOperationException)377                {378                    // Ignore379                }380            }381            #endregion382            #region Concrete state classes383            private class InitialState : State384            {385                public override Task StartAsync(ChromiumProcess p) => Starting.EnterFromAsync(p, this);386                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout)387                {388                    Exited.EnterFrom(p, this);389                    return Task.CompletedTask;390                }391                public override Task KillAsync(ChromiumProcess p)392                {393                    Exited.EnterFrom(p, this);394                    return Task.CompletedTask;395                }396                public override Task WaitForExitAsync(ChromiumProcess p) => Task.FromException(InvalidOperation("wait for exit"));397            }398            private class StartingState : State399            {400                public Task EnterFromAsync(ChromiumProcess p, State fromState)401                {402                    if (!TryEnter(p, fromState))403                    {404                        // Delegate StartAsync to current state, because it has already changed since405                        // transition to this state was initiated.406                        return p._currentState.StartAsync(p);407                    }408                    return StartCoreAsync(p);409                }410                public override Task StartAsync(ChromiumProcess p) => p._startCompletionSource.Task;411                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);412                public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);413                public override void Dispose(ChromiumProcess p)414                {415                    p._startCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));416                    base.Dispose(p);417                }418                private async Task StartCoreAsync(ChromiumProcess p)419                {420                    var output = new StringBuilder();421                    void OnProcessDataReceivedWhileStarting(object sender, DataReceivedEventArgs e)422                    {423                        if (e.Data != null)424                        {425                            output.AppendLine(e.Data);426                            var match = Regex.Match(e.Data, "^DevTools listening on (ws:\\/\\/.*)");427                            if (match.Success)428                            {429                                p._startCompletionSource.SetResult(match.Groups[1].Value);430                            }431                        }432                    }433                    void OnProcessExitedWhileStarting(object sender, EventArgs e)434                    {435                        p._startCompletionSource.SetException(new ChromiumProcessException($"Failed to launch Chromium! {output}"));436                    }437                    void OnProcessExited(object sender, EventArgs e)438                    {439                        Exited.EnterFrom(p, p._currentState);440                    }441                    p.Process.ErrorDataReceived += OnProcessDataReceivedWhileStarting;442                    p.Process.Exited += OnProcessExitedWhileStarting;443                    p.Process.Exited += OnProcessExited;444                    CancellationTokenSource cts = null;445                    try446                    {447                        p.Process.Start();448                        await Started.EnterFromAsync(p, this).ConfigureAwait(false);449                        p.Process.BeginErrorReadLine();450                        var timeout = p._options.Timeout;451                        if (timeout > 0)452                        {453                            cts = new CancellationTokenSource(timeout);454                            cts.Token.Register(() => p._startCompletionSource.TrySetException(455                                new ChromiumProcessException($"Timed out after {timeout} ms while trying to connect to Chromium!")));456                        }457                        try458                        {459                            await p._startCompletionSource.Task.ConfigureAwait(false);460                            await Started.EnterFromAsync(p, this).ConfigureAwait(false);461                        }462                        catch463                        {464                            await Killing.EnterFromAsync(p, this).ConfigureAwait(false);465                            throw;466                        }467                    }468                    finally469                    {470                        cts?.Dispose();471                        p.Process.Exited -= OnProcessExitedWhileStarting;472                        p.Process.ErrorDataReceived -= OnProcessDataReceivedWhileStarting;473                    }474                }475            }476            private class StartedState : State477            {478                public Task EnterFromAsync(ChromiumProcess p, State fromState)479                {480                    if (TryEnter(p, fromState))481                    {482                        // Process has not exited or been killed since transition to this state was initiated483                        LogProcessCount(p, Interlocked.Increment(ref _processCount));484                    }485                    return Task.CompletedTask;486                }487                protected override void Leave(ChromiumProcess p)488                    => LogProcessCount(p, Interlocked.Decrement(ref _processCount));489                public override Task StartAsync(ChromiumProcess p) => Task.CompletedTask;490                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Exiting.EnterFromAsync(p, this, timeout);491                public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);492                private static void LogProcessCount(ChromiumProcess p, int processCount)493                {494                    try495                    {496                        p._logger?.LogInformation("Process Count: {ProcessCount}", processCount);497                    }498                    catch499                    {500                        // Prevent logging exception from causing havoc501                    }502                }503            }504            private class ExitingState : State505            {506                public Task EnterFromAsync(ChromiumProcess p, State fromState, TimeSpan timeout)507                {508                    return !TryEnter(p, fromState) ? p._currentState.ExitAsync(p, timeout) : ExitAsync(p, timeout);509                }510                public override async Task ExitAsync(ChromiumProcess p, TimeSpan timeout)511                {512                    var timeoutTask = Task.Delay(timeout);513                    var waitForExitTask = WaitForExitAsync(p);514                    var completedTask = await Task.WhenAny(waitForExitTask, timeoutTask).ConfigureAwait(false);515                    if (completedTask == timeoutTask)516                    {517                        await Killing.EnterFromAsync(p, this).ConfigureAwait(false);518                        await waitForExitTask.ConfigureAwait(false);519                    }520                }521                public override Task KillAsync(ChromiumProcess p) => Killing.EnterFromAsync(p, this);522            }523            private class KillingState : State524            {525                public Task EnterFromAsync(ChromiumProcess p, State fromState)526                {527                    if (!TryEnter(p, fromState))528                    {529                        // Delegate KillAsync to current state, because it has already changed since530                        // transition to this state was initiated.531                        return p._currentState.KillAsync(p);532                    }533                    try534                    {535                        if (!p.Process.HasExited)536                        {537                            p.Process.Kill();538                        }539                    }540                    catch (InvalidOperationException)541                    {542                        // Ignore543                    }544                    return WaitForExitAsync(p);545                }546                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => WaitForExitAsync(p);547                public override Task KillAsync(ChromiumProcess p) => WaitForExitAsync(p);548            }549            private class ExitedState : State550            {551                public void EnterFrom(ChromiumProcess p, State fromState)552                {553                    while (!TryEnter(p, fromState))554                    {555                        // Current state has changed since transition to this state was requested.556                        // Therefore retry transition to this state from the current state. This ensures557                        // that Leave() operation of current state is properly called.558                        fromState = p._currentState;559                        if (fromState == this)560                        {561                            return;562                        }563                    }564                    p._exitCompletionSource.TrySetResult(true);565                    p._tempUserDataDir?.Dispose();566                }567                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => Task.CompletedTask;568                public override Task KillAsync(ChromiumProcess p) => Task.CompletedTask;569                public override Task WaitForExitAsync(ChromiumProcess p) => Task.CompletedTask;570            }571            private class DisposedState : State572            {573                public void EnterFrom(ChromiumProcess p, State fromState)574                {575                    if (!TryEnter(p, fromState))576                    {577                        // Delegate Dispose to current state, because it has already changed since578                        // transition to this state was initiated.579                        p._currentState.Dispose(p);580                    }581                    else if (fromState != Exited)582                    {583                        Kill(p);584                        p._exitCompletionSource.TrySetException(new ObjectDisposedException(p.ToString()));585                        p._tempUserDataDir?.Dispose();586                    }587                }588                public override Task StartAsync(ChromiumProcess p) => throw new ObjectDisposedException(p.ToString());589                public override Task ExitAsync(ChromiumProcess p, TimeSpan timeout) => throw new ObjectDisposedException(p.ToString());590                public override Task KillAsync(ChromiumProcess p) => throw new ObjectDisposedException(p.ToString());591                public override void Dispose(ChromiumProcess p)592                {593                    // Nothing to do594                }595            }596            #endregion597        }598        #endregion599    }600}...LauncherBase.cs
Source:LauncherBase.cs  
...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}...ExitingState.cs
Source:ExitingState.cs  
...22                },23                timeout,24                CancellationToken.None).ConfigureAwait(false);25        }26        public override Task KillAsync(LauncherBase p) => StateManager.Killing.EnterFromAsync(p, this);27    }28}...StartedState.cs
Source:StartedState.cs  
...13            return Task.CompletedTask;14        }15        public override Task StartAsync(LauncherBase p) => Task.CompletedTask;16        public override Task ExitAsync(LauncherBase p, TimeSpan timeout) => new ExitingState(StateManager).EnterFromAsync(p, this, timeout);17        public override Task KillAsync(LauncherBase p) => new KillingState(StateManager).EnterFromAsync(p, this);18    }19}...KillAsync
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5    {6        static async Task Main(string[] args)7        {8            var browser = await Puppeteer.LaunchAsync(new LaunchOptions9            {10                Args = new string[] { "--no-sandbox" }11            });12            var page = await browser.NewPageAsync();13            await page.WaitForTimeoutAsync(5000);14            await browser.CloseAsync();15        }16    }17}18using System;19using System.Threading.Tasks;20using PuppeteerSharp;21{22    {23        static async Task Main(string[] args)24        {25            var browser = await Puppeteer.LaunchAsync(new LaunchOptions26            {27                Args = new string[] { "--no-sandbox" }28            });29            var page = await browser.NewPageAsync();30            await page.WaitForTimeoutAsync(5000);31            await browser.Process.KillAsync();32        }33    }34}35using System;36using System.Threading.Tasks;37using PuppeteerSharp;38{39    {40        static async Task Main(string[] args)41        {42            var browser = await Puppeteer.LaunchAsync(new LaunchOptions43            {44                Args = new string[] { "--no-sandbox" }45            });46            var page = await browser.NewPageAsync();47            await page.WaitForTimeoutAsync(5000);48            await browser.Process.KillAsync();49        }50    }51}52using System;53using System.Threading.Tasks;54using PuppeteerSharp;55{56    {57        static async Task Main(string[] args)58        {59            var browser = await Puppeteer.LaunchAsync(new LaunchOptions60            {KillAsync
Using AI Code Generation
1using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))2{3    var page = await browser.NewPageAsync();4    await page.WaitForSelectorAsync("input[name='q']");5    await page.ClickAsync("input[name='q']");6    await page.Keyboard.TypeAsync("PuppeteerSharp");7    await page.Keyboard.DownAsync("Enter");8    await page.WaitForNavigationAsync();9    await page.CloseAsync();10    await browser.CloseAsync();11}12using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))13{14    var page = await browser.NewPageAsync();15    await page.WaitForSelectorAsync("input[name='q']");16    await page.ClickAsync("input[name='q']");17    await page.Keyboard.TypeAsync("PuppeteerSharp");18    await page.Keyboard.DownAsync("Enter");19    await page.WaitForNavigationAsync();20    await page.CloseAsync();21    await browser.CloseAsync();22}23using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))24{25    var page = await browser.NewPageAsync();26    await page.WaitForSelectorAsync("input[name='q']");27    await page.ClickAsync("input[name='q']");28    await page.Keyboard.TypeAsync("PuppeteerSharp");29    await page.Keyboard.DownAsync("Enter");30    await page.WaitForNavigationAsync();31    await page.CloseAsync();32    await browser.CloseAsync();33}34using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))35{36    var page = await browser.NewPageAsync();37    await page.WaitForSelectorAsync("input[name='q']");38    await page.ClickAsync("input[name='q']");39    await page.Keyboard.TypeAsync("PuppeteerSharp");40    await page.Keyboard.DownAsync("Enter");41    await page.WaitForNavigationAsync();KillAsync
Using AI Code Generation
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using PuppeteerSharp;7{8    {9        public Task KillAsync()10        {11            throw new NotImplementedException();12        }13        public Task OnCloseAsync()14        {15            throw new NotImplementedException();16        }17        public Task OnDisconnectedAsync()18        {19            throw new NotImplementedException();20        }21        public Task OnMessageAsync(string message)22        {23            throw new NotImplementedException();24        }25    }26}27using System;28using System.Collections.Generic;29using System.Linq;30using System.Text;31using System.Threading.Tasks;32using PuppeteerSharp;33{34    {35        public Task KillAsync()36        {37            throw new NotImplementedException();38        }39        public Task OnCloseAsync()40        {41            throw new NotImplementedException();42        }43        public Task OnDisconnectedAsync()44        {45            throw new NotImplementedException();46        }47        public Task OnMessageAsync(string message)48        {49            throw new NotImplementedException();50        }51    }52}53using System;54using System.Collections.Generic;55using System.Linq;56using System.Text;57using System.Threading.Tasks;58using PuppeteerSharp;59{60    {61        public Task KillAsync()62        {63            throw new NotImplementedException();64        }65        public Task OnCloseAsync()66        {67            throw new NotImplementedException();68        }69        public Task OnDisconnectedAsync()70        {71            throw new NotImplementedException();72        }73        public Task OnMessageAsync(string message)74        {75            throw new NotImplementedException();76        }77    }78}79using System;80using System.Collections.Generic;81using System.Linq;82using System.Text;83using System.Threading.Tasks;84using PuppeteerSharp;85{86    {87        public Task KillAsync()88        {89            throw new NotImplementedException();90        }91        public Task OnCloseAsync()92        {93            throw new NotImplementedException();94        }KillAsync
Using AI Code Generation
1using System.Threading.Tasks;2using PuppeteerSharp;3using PuppeteerSharp.States;4{5    {6        public static Task KillAsync(this ExitingState state)7        {8            return state.KillAsync();9        }10    }11}12using System.Threading.Tasks;13using PuppeteerSharp;14using PuppeteerSharp.States;15{16    {17        public static async Task KillAsync(this ExitingState state)18        {19            await state.KillAsync();20        }21    }22}23using System.Threading.Tasks;24using PuppeteerSharp;25using PuppeteerSharp.States;26{27    {28        public static Task KillAsync(this ExitingState state)29        {30            return Task.Run(() => state.KillAsync());31        }32    }33}34using System.Threading.Tasks;35using PuppeteerSharp;36using PuppeteerSharp.States;37{38    {39        public static async Task KillAsync(this ExitingState state)40        {41            await Task.Run(() => state.KillAsync());42        }43    }44}45using System.Threading.Tasks;46using PuppeteerSharp;47using PuppeteerSharp.States;48{49    {50        public static Task KillAsync(this ExitingState state)51        {52            return Task.Run(async () => await state.KillAsync());53        }54    }55}56using System.Threading.Tasks;57using PuppeteerSharp;58using PuppeteerSharp.States;59{60    {61        public static async Task KillAsync(this ExitingState state)62        {63            await Task.Run(async () => awaitKillAsync
Using AI Code Generation
1using PuppeteerSharp;2using System.Threading.Tasks;3{4    {5        static void Main(string[] args)6        {7            MainAsync().GetAwaiter().GetResult();8        }9        static async Task MainAsync()10        {11            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);12            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });13            var page = await browser.NewPageAsync();14            await page.ScreenshotAsync("google.png");15            await browser.CloseAsync();16        }17    }18}19using PuppeteerSharp;20using System.Threading.Tasks;21{22    {23        static void Main(string[] args)24        {25            MainAsync().GetAwaiter().GetResult();26        }27        static async Task MainAsync()28        {29            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);30            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });31            var page = await browser.NewPageAsync();32            await page.ScreenshotAsync("google.png");33            await browser.KillAsync();34        }35    }36}37using PuppeteerSharp;38using System.Threading.Tasks;39{40    {41        static void Main(string[] args)42        {43            MainAsync().GetAwaiter().GetResult();44        }45        static async Task MainAsync()46        {47            await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);48            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });49            var page = await browser.NewPageAsync();50            await page.ScreenshotAsync("google.png");51            await browser.KillAsync();52        }53    }54}55using PuppeteerSharp;56using System.Threading.Tasks;57{58    {KillAsync
Using AI Code Generation
1using PuppeteerSharp.States;2using System;3using System.Threading.Tasks;4{5    {6        static void Main(string[] args)7        {8            MainAsync(args).Wait();9        }10        static async Task MainAsync(string[] args)11        {12            var browser = await Puppeteer.LaunchAsync();13            var page = await browser.NewPageAsync();14            await page.ScreenshotAsync("google.png");15            await browser.CloseAsync();16            await browser.KillAsync();17        }18    }19}20using PuppeteerSharp.States;21using System;22using System.Threading.Tasks;23{24    {25        static void Main(string[] args)26        {27            MainAsync(args).Wait();28        }29        static async Task MainAsync(string[] args)30        {31            var browser = await Puppeteer.LaunchAsync();32            var page = await browser.NewPageAsync();33            await page.ScreenshotAsync("google.png");34            await browser.CloseAsync();35            await browser.Target.KillAsync();36        }37    }38}39using PuppeteerSharp.States;40using System;41using System.Threading.Tasks;42{43    {44        static void Main(string[] args)45        {46            MainAsync(args).Wait();47        }48        static async Task MainAsync(string[] args)49        {50            var browser = await Puppeteer.LaunchAsync();51            var page = await browser.NewPageAsync();52            await page.ScreenshotAsync("google.png");53            await browser.CloseAsync();54            await browser.Target.KillAsync();55        }56    }57}58using PuppeteerSharp.States;59using System;60using System.Threading.Tasks;61{62    {63        static void Main(string[] args)64        {65            MainAsync(args).Wait();66        }67        static async Task MainAsync(string[] args)68        {KillAsync
Using AI Code Generation
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using PuppeteerSharp.States;7using PuppeteerSharp;8{9    {10        public async Task KillAsync()11        {12            await Task.Delay(5000);13        }14    }15}16using System;17using System.Collections.Generic;18using System.Linq;19using System.Text;20using System.Threading.Tasks;21using PuppeteerSharp.States;22using PuppeteerSharp;23{24    {25        public async Task KillAsync()26        {27            await Task.Delay(5000);28        }29    }30}31using System;32using System.Collections.Generic;33using System.Linq;34using System.Text;35using System.Threading.Tasks;36using PuppeteerSharp.States;37using PuppeteerSharp;38{39    {40        public async Task KillAsync()41        {42            await Task.Delay(5000);43        }44    }45}46using System;47using System.Collections.Generic;48using System.Linq;49using System.Text;50using System.Threading.Tasks;51using PuppeteerSharp.States;52using PuppeteerSharp;53{54    {55        public async Task KillAsync()56        {57            await Task.Delay(5000);58        }59    }60}61using System;62using System.Collections.Generic;63using System.Linq;64using System.Text;65using System.Threading.Tasks;66using PuppeteerSharp.States;67using PuppeteerSharp;68{69    {70        public async Task KillAsync()71        {72            await Task.Delay(5000);73        }74    }75}KillAsync
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5    {6        public async Task KillAsync()7        {8            await _state.KillAsync();9        }10    }11}12using System;13using System.Threading.Tasks;14using PuppeteerSharp;15{16    {17        public async Task KillAsync()18        {19        }20    }21}22using System;23using System.Threading.Tasks;24using PuppeteerSharp;25{26    {27        public async Task KillAsync()28        {29            await _browser.CloseAsync();30        }31    }32}33using System;34using System.Threading.Tasks;35using PuppeteerSharp;36{37    {38        public async Task KillAsync()39        {40            await _browser.CloseAsync();41            await _browser.KillAsync();42        }43    }44}45using System;46using System.Threading.Tasks;47using PuppeteerSharp;48{49    {50        public async Task KillAsync()51        {52            await _browser.CloseAsync();53            await _browser.KillAsync();54            await Task.Delay(1000);55            await _browser.KillAsync();56        }57    }58}59using System;60using System.Threading.Tasks;61using PuppeteerSharp;62{63    {64        public async Task KillAsync()65        {66            await _browser.CloseAsync();67            await _browser.KillAsync();68            await Task.Delay(1000);69            await _browser.KillAsync();KillAsync
Using AI Code Generation
1using PuppeteerSharp;2using PuppeteerSharp.States;3var browser = await Puppeteer.LaunchAsync();4var page = await browser.NewPageAsync();5var state = new ExitingState();6await state.KillAsync(browser, page);7await browser.CloseAsync();8using PuppeteerSharp;9using PuppeteerSharp.States;10var browser = await Puppeteer.LaunchAsync();11var page = await browser.NewPageAsync();12var state = new ExitingState();13await state.KillAsync(browser, page);14await browser.CloseAsync();15using PuppeteerSharp;16using PuppeteerSharp.States;17var browser = await Puppeteer.LaunchAsync();18var page = await browser.NewPageAsync();19var state = new ExitingState();20await state.KillAsync(browser, page);21await browser.CloseAsync();22using PuppeteerSharp;23using PuppeteerSharp.States;24var browser = await Puppeteer.LaunchAsync();25var page = await browser.NewPageAsync();26var state = new ExitingState();27await state.KillAsync(browser, page);28await browser.CloseAsync();29using PuppeteerSharp;30using PuppeteerSharp.States;31var browser = await Puppeteer.LaunchAsync();32var page = await browser.NewPageAsync();33var state = new ExitingState();34await state.KillAsync(browser, page);35await browser.CloseAsync();36using PuppeteerSharp;37using PuppeteerSharp.States;38var browser = await Puppeteer.LaunchAsync();39var page = await browser.NewPageAsync();40var state = new ExitingState();41await state.KillAsync(browser, page);42await browser.CloseAsync();43using PuppeteerSharp;44using PuppeteerSharp.States;45var browser = await Puppeteer.LaunchAsync();46var page = await browser.NewPageAsync();KillAsync
Using AI Code Generation
1var page = await browser.NewPageAsync();2await page.ClickAsync("input[name='q']");3await page.Keyboard.TypeAsync("PuppeteerSharp");4await page.Keyboard.DownAsync("Enter");5await page.WaitForNavigationAsync();6await page.KillAsync();7var page = await browser.NewPageAsync();8await page.ClickAsync("input[name='q']");9await page.Keyboard.TypeAsync("PuppeteerSharp");10await page.Keyboard.DownAsync("Enter");11await page.WaitForNavigationAsync();12await page.CloseAsync();13await page.KillAsync();14var page = await browser.NewPageAsync();15await page.ClickAsync("input[name='q']");16await page.Keyboard.TypeAsync("PuppeteerSharp");17await page.Keyboard.DownAsync("Enter");18await page.WaitForNavigationAsync();19await page.CloseAsync();20await page.KillAsync();21var page = await browser.NewPageAsync();22await page.ClickAsync("input[name='q']");23await page.Keyboard.TypeAsync("PuppeteerSharp");24await page.Keyboard.DownAsync("Enter");25await page.WaitForNavigationAsync();26await page.CloseAsync();27await page.KillAsync();28var page = await browser.NewPageAsync();29await page.ClickAsync("input[name='q']");30await page.Keyboard.TypeAsync("PuppeteerSharp");31await page.Keyboard.DownAsync("Enter");32await page.WaitForNavigationAsync();33await page.CloseAsync();34await page.KillAsync();35var page = await browser.NewPageAsync();36await page.ClickAsync("input[name='q']");37await page.Keyboard.TypeAsync("PuppeteerSharp");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.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
