Best Puppeteer-sharp code snippet using PuppeteerSharp.ExecutionContext.EvaluateFunctionAsync
ElementHandle.cs
Source:ElementHandle.cs  
...121                });122                await Page.SetViewportAsync(newRawViewport.ToObject<ViewPortOptions>()).ConfigureAwait(false);123                needsViewportReset = true;124            }125            await ExecutionContext.EvaluateFunctionAsync(@"function(element) {126                element.scrollIntoView({ block: 'center', inline: 'center', behavior: 'instant'});127            }", this).ConfigureAwait(false);128            await ScrollIntoViewIfNeededAsync().ConfigureAwait(false);129            boundingBox = await BoundingBoxAsync().ConfigureAwait(false);130            if (boundingBox == null)131            {132                throw new PuppeteerException("Node is either not visible or not an HTMLElement");133            }134            var getLayoutMetricsResponse = await Client.SendAsync<GetLayoutMetricsResponse>("Page.getLayoutMetrics").ConfigureAwait(false);135            var clip = boundingBox;136            clip.X += getLayoutMetricsResponse.LayoutViewport.PageX;137            clip.Y += getLayoutMetricsResponse.LayoutViewport.PageY;138            options.Clip = boundingBox.ToClip();139            var imageData = await Page.ScreenshotBase64Async(options).ConfigureAwait(false);140            if (needsViewportReset)141            {142                await Page.SetViewportAsync(viewport).ConfigureAwait(false);143            }144            return imageData;145        }146        /// <summary>147        /// Scrolls element into view if needed, and then uses <see cref="Page.Mouse"/> to hover over the center of the element.148        /// </summary>149        /// <returns>Task which resolves when the element is successfully hovered</returns>150        public async Task HoverAsync()151        {152            await ScrollIntoViewIfNeededAsync().ConfigureAwait(false);153            var (x, y) = await ClickablePointAsync().ConfigureAwait(false);154            await Page.Mouse.MoveAsync(x, y).ConfigureAwait(false);155        }156        /// <summary>157        /// Scrolls element into view if needed, and then uses <see cref="Page.Mouse"/> to click in the center of the element.158        /// </summary>159        /// <param name="options">click options</param>160        /// <exception cref="PuppeteerException">if the element is detached from DOM</exception>161        /// <returns>Task which resolves when the element is successfully clicked</returns>162        public async Task ClickAsync(ClickOptions options = null)163        {164            await ScrollIntoViewIfNeededAsync().ConfigureAwait(false);165            var (x, y) = await ClickablePointAsync().ConfigureAwait(false);166            await Page.Mouse.ClickAsync(x, y, options).ConfigureAwait(false);167        }168        /// <summary>169        /// Uploads files170        /// </summary>171        /// <param name="filePaths">Sets the value of the file input these paths. paths are resolved using <see cref="Path.GetFullPath(string)"/></param>172        /// <remarks>This method expects <c>elementHandle</c> to point to an <c>input element</c> <see href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input"/> </remarks>173        /// <returns>Task</returns>174        public Task UploadFileAsync(params string[] filePaths)175        {176            var files = filePaths.Select(Path.GetFullPath).ToArray();177            var objectId = RemoteObject[MessageKeys.ObjectId].AsString();178            return Client.SendAsync("DOM.setFileInputFiles", new { objectId, files });179        }180        /// <summary>181        /// Scrolls element into view if needed, and then uses <see cref="Touchscreen.TapAsync(decimal, decimal)"/> to tap in the center of the element.182        /// </summary>183        /// <exception cref="PuppeteerException">if the element is detached from DOM</exception>184        /// <returns>Task which resolves when the element is successfully tapped</returns>185        public async Task TapAsync()186        {187            await ScrollIntoViewIfNeededAsync().ConfigureAwait(false);188            var (x, y) = await ClickablePointAsync().ConfigureAwait(false);189            await Page.Touchscreen.TapAsync(x, y).ConfigureAwait(false);190        }191        /// <summary>192        /// Calls <c>focus</c> <see href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus"/> on the element.193        /// </summary>194        /// <returns>Task</returns>195        public Task FocusAsync() => ExecutionContext.EvaluateFunctionAsync("element => element.focus()", this);196        /// <summary>197        /// Focuses the element, and sends a <c>keydown</c>, <c>keypress</c>/<c>input</c>, and <c>keyup</c> event for each character in the text.198        /// </summary>199        /// <param name="text">A text to type into a focused element</param>200        /// <param name="options">type options</param>201        /// <remarks>202        /// To press a special key, like <c>Control</c> or <c>ArrowDown</c> use <see cref="ElementHandle.PressAsync(string, PressOptions)"/>203        /// </remarks>204        /// <example>205        /// <code>206        /// elementHandle.TypeAsync("#mytextarea", "Hello"); // Types instantly207        /// elementHandle.TypeAsync("#mytextarea", "World", new TypeOptions { Delay = 100 }); // Types slower, like a user208        /// </code>209        /// An example of typing into a text field and then submitting the form:210        /// <code>211        /// var elementHandle = await page.GetElementAsync("input");212        /// await elementHandle.TypeAsync("some text");213        /// await elementHandle.PressAsync("Enter");214        /// </code>215        /// </example>216        /// <returns>Task</returns>217        public async Task TypeAsync(string text, TypeOptions options = null)218        {219            await FocusAsync().ConfigureAwait(false);220            await Page.Keyboard.TypeAsync(text, options).ConfigureAwait(false);221        }222        /// <summary>223        /// Focuses the element, and then uses <see cref="Keyboard.DownAsync(string, DownOptions)"/> and <see cref="Keyboard.UpAsync(string)"/>.224        /// </summary>225        /// <param name="key">Name of key to press, such as <c>ArrowLeft</c>. See <see cref="KeyDefinitions"/> for a list of all key names.</param>226        /// <param name="options">press options</param>227        /// <remarks>228        /// If <c>key</c> is a single character and no modifier keys besides <c>Shift</c> are being held down, a <c>keypress</c>/<c>input</c> event will also be generated. The <see cref="DownOptions.Text"/> option can be specified to force an input event to be generated.229        /// </remarks>230        /// <returns></returns>231        public async Task PressAsync(string key, PressOptions options = null)232        {233            await FocusAsync().ConfigureAwait(false);234            await Page.Keyboard.PressAsync(key, options).ConfigureAwait(false);235        }236        /// <summary>237        /// The method runs <c>element.querySelector</c> within the page. If no element matches the selector, the return value resolve to <c>null</c>.238        /// </summary>239        /// <param name="selector">A selector to query element for</param>240        /// <returns>Task which resolves to <see cref="ElementHandle"/> pointing to the frame element</returns>241        public async Task<ElementHandle> QuerySelectorAsync(string selector)242        {243            var handle = await ExecutionContext.EvaluateFunctionHandleAsync(244                "(element, selector) => element.querySelector(selector)",245                this, selector).ConfigureAwait(false);246            if (handle is ElementHandle element)247            {248                return element;249            }250            await handle.DisposeAsync().ConfigureAwait(false);251            return null;252        }253        /// <summary>254        /// Runs <c>element.querySelectorAll</c> within the page. If no elements match the selector, the return value resolve to <see cref="Array.Empty{T}"/>.255        /// </summary>256        /// <param name="selector">A selector to query element for</param>257        /// <returns>Task which resolves to ElementHandles pointing to the frame elements</returns>258        public async Task<ElementHandle[]> QuerySelectorAllAsync(string selector)259        {260            var arrayHandle = await ExecutionContext.EvaluateFunctionHandleAsync(261                "(element, selector) => element.querySelectorAll(selector)",262                this, selector).ConfigureAwait(false);263            var properties = await arrayHandle.GetPropertiesAsync().ConfigureAwait(false);264            await arrayHandle.DisposeAsync().ConfigureAwait(false);265            return properties.Values.OfType<ElementHandle>().ToArray();266        }267        /// <summary>268        /// A utility function to be used with <see cref="Extensions.EvaluateFunctionAsync{T}(Task{JSHandle}, string, object[])"/>269        /// </summary>270        /// <param name="selector">A selector to query element for</param>271        /// <returns>Task which resolves to a <see cref="JSHandle"/> of <c>document.querySelectorAll</c> result</returns>272        public Task<JSHandle> QuerySelectorAllHandleAsync(string selector)273            => ExecutionContext.EvaluateFunctionHandleAsync(274                "(element, selector) => Array.from(element.querySelectorAll(selector))", this, selector);275        /// <summary>276        /// Evaluates the XPath expression relative to the elementHandle. If there's no such element, the method will resolve to <c>null</c>.277        /// </summary>278        /// <param name="expression">Expression to evaluate <see href="https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate"/></param>279        /// <returns>Task which resolves to an array of <see cref="ElementHandle"/></returns>280        public async Task<ElementHandle[]> XPathAsync(string expression)281        {282            var arrayHandle = await ExecutionContext.EvaluateFunctionHandleAsync(283                @"(element, expression) => {284                    const document = element.ownerDocument || element;285                    const iterator = document.evaluate(expression, element, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE);286                    const array = [];287                    let item;288                    while ((item = iterator.iterateNext()))289                        array.push(item);290                    return array;291                }",292                this, expression293            ).ConfigureAwait(false);294            var properties = await arrayHandle.GetPropertiesAsync().ConfigureAwait(false);295            await arrayHandle.DisposeAsync().ConfigureAwait(false);296            return properties.Values.OfType<ElementHandle>().ToArray();297        }298        /// <summary>299        /// This method returns the bounding box of the element (relative to the main frame), 300        /// or null if the element is not visible.301        /// </summary>302        /// <returns>The BoundingBox task.</returns>303        public async Task<BoundingBox> BoundingBoxAsync()304        {305            var result = await GetBoxModelAsync().ConfigureAwait(false);306            if (result == null)307            {308                return null;309            }310            var quad = result.Model.Border;311            var x = new[] { quad[0], quad[2], quad[4], quad[6] }.Min();312            var y = new[] { quad[1], quad[3], quad[5], quad[7] }.Min();313            var width = new[] { quad[0], quad[2], quad[4], quad[6] }.Max() - x;314            var height = new[] { quad[1], quad[3], quad[5], quad[7] }.Max() - y;315            return new BoundingBox(x, y, width, height);316        }317        /// <summary>318        /// returns boxes of the element, or <c>null</c> if the element is not visible. Box points are sorted clock-wise.319        /// </summary>320        /// <returns>Task BoxModel task.</returns>321        public async Task<BoxModel> BoxModelAsync()322        {323            var result = await GetBoxModelAsync().ConfigureAwait(false);324            return result == null325                ? null326                : new BoxModel327                {328                    Content = FromProtocolQuad(result.Model.Content),329                    Padding = FromProtocolQuad(result.Model.Padding),330                    Border = FromProtocolQuad(result.Model.Border),331                    Margin = FromProtocolQuad(result.Model.Margin),332                    Width = result.Model.Width,333                    Height = result.Model.Height334                };335        }336        /// <summary>337        ///Content frame for element handles referencing iframe nodes, or null otherwise.338        /// </summary>339        /// <returns>Resolves to the content frame</returns>340        public async Task<Frame> ContentFrameAsync()341        {342            var nodeInfo = await Client.SendAsync<DomDescribeNodeResponse>("DOM.describeNode", new Dictionary<string, object>343            {344                { MessageKeys.ObjectId, RemoteObject[MessageKeys.ObjectId] }345            }).ConfigureAwait(false);346            return string.IsNullOrEmpty(nodeInfo.Node.FrameId) ? null : _frameManager.Frames[nodeInfo.Node.FrameId];347        }348        /// <summary>349        /// Evaluates if the element is visible in the current viewport.350        /// </summary>351        /// <returns>A task which resolves to true if the element is visible in the current viewport.</returns>352        public Task<bool> IsIntersectingViewportAsync()353            => ExecutionContext.EvaluateFunctionAsync<bool>(@"async element =>354            {355                const visibleRatio = await new Promise(resolve =>356                {357                    const observer = new IntersectionObserver(entries =>358                    {359                        resolve(entries[0].intersectionRatio);360                        observer.disconnect();361                    });362                    observer.observe(element);363                });364                return visibleRatio > 0;365            }", this);366        private async Task<(decimal x, decimal y)> ClickablePointAsync()367        {368            GetContentQuadsResponse result = null;369            try370            {371                result = await Client.SendAsync<GetContentQuadsResponse>("DOM.getContentQuads", new Dictionary<string, object>372                {373                    { MessageKeys.ObjectId, RemoteObject[MessageKeys.ObjectId] }374                }).ConfigureAwait(false);375            }376            catch (Exception ex)377            {378                _logger.LogError(ex.Message);379            }380            if (result == null || result.Quads.Length == 0)381            {382                throw new PuppeteerException("Node is either not visible or not an HTMLElement");383            }384            // Filter out quads that have too small area to click into.385            var quads = result.Quads.Select(FromProtocolQuad).Where(q => ComputeQuadArea(q) > 1);386            if (!quads.Any())387            {388                throw new PuppeteerException("Node is either not visible or not an HTMLElement");389            }390            // Return the middle point of the first quad.391            var quad = quads.First();392            var x = 0m;393            var y = 0m;394            foreach (var point in quad)395            {396                x += point.X;397                y += point.Y;398            }399            return (400                x: x / 4,401                y: y / 4402            );403        }404        private async Task ScrollIntoViewIfNeededAsync()405        {406            var errorMessage = await ExecutionContext.EvaluateFunctionAsync<string>(@"async(element, pageJavascriptEnabled) => {407              if (!element.isConnected)408                return 'Node is detached from document';409              if (element.nodeType !== Node.ELEMENT_NODE)410                return 'Node is not of type HTMLElement';411              // force-scroll if page's javascript is disabled.412              if (!pageJavascriptEnabled) {413                element.scrollIntoView({block: 'center', inline: 'center', behavior: 'instant'});414                return false;415              }416              const visibleRatio = await new Promise(resolve => {417                const observer = new IntersectionObserver(entries => {418                  resolve(entries[0].intersectionRatio);419                  observer.disconnect();420                });...EvaluateTests.cs
Source:EvaluateTests.cs  
...18        [InlineData("() => 7 * 3", 21)] //ShouldWork19        [InlineData("() => Promise.resolve(8 * 7)", 56)] //ShouldAwaitPromise20        public async Task BasicIntFunctionEvaluationTest(string script, object expected)21        {22            var result = await Page.EvaluateFunctionAsync<int>(script);23            Assert.Equal(expected, result);24        }25        [Fact]26        public async Task ShouldTransferBigInt()27        {28            var result = await Page.EvaluateFunctionAsync<BigInteger>("a => a", new BigInteger(42));29            Assert.Equal(new BigInteger(42), result);30        }31        [Theory]32        [InlineData(double.NaN)] //ShouldTransferNaN33        [InlineData(-0)] //ShouldTransferNegative034        [InlineData(double.PositiveInfinity)] //ShouldTransferInfinity35        [InlineData(double.NegativeInfinity)] //ShouldTransferNegativeInfinty36        public async Task BasicTransferTest(object transferObject)37        {38            var result = await Page.EvaluateFunctionAsync<object>("a => a", transferObject);39            Assert.Equal(transferObject, result);40        }41        [Fact]42        public async Task ShouldTransferArrays()43        {44            var result = await Page.EvaluateFunctionAsync<int[]>("a => a", new int[] { 1, 2, 3 });45            Assert.Equal(new int[] { 1, 2, 3 }, result);46        }47        [Fact]48        public async Task ShouldTransferArraysAsArraysNotObjects()49        {50            var result = await Page.EvaluateFunctionAsync<bool>("a => Array.isArray(a)", new int[] { 1, 2, 3 });51            Assert.True(result);52        }53        [Fact]54        public async Task ShouldModifyGlobalEnvironment()55        {56            await Page.EvaluateFunctionAsync("() => window.globalVar = 123");57            Assert.Equal(123, await Page.EvaluateFunctionAsync<int>("() => window.globalVar"));58        }59        [Fact]60        public async Task ShouldEvaluateInThePageContext()61        {62            await Page.GoToAsync(TestConstants.ServerUrl + "/global-var.html");63            Assert.Equal(123, await Page.EvaluateFunctionAsync<int>("() => window.globalVar"));64        }65        [Fact]66        public async Task ShouldReturnUndefinedForObjectsWithSymbols()67            => Assert.Null(await Page.EvaluateFunctionAsync<object>("() => [Symbol('foo4')]"));68        [Fact]69        public async Task ShouldWorkWithUnicodeChars()70            => Assert.Equal(42, await Page.EvaluateFunctionAsync<int>("a => a['䏿å符']", new Dictionary<string, int> { ["䏿å符"] = 42 }));71        [Fact]72        public async Task ShouldThrowWhenEvaluationTriggersReload()73        {74            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(() =>75            {76                return Page.EvaluateFunctionAsync(@"() => {77                    location.reload();78                    return new Promise(() => {});79                }");80            });81            Assert.Contains("Protocol error", exception.Message);82        }83        [Fact]84        public async Task ShouldWorkRightAfterFrameNavigated()85        {86            Task<int> frameEvaluation = null;87            Page.FrameNavigated += (sender, e) =>88            {89                frameEvaluation = e.Frame.EvaluateFunctionAsync<int>("() => 6 * 7");90            };91            await Page.GoToAsync(TestConstants.EmptyPage);92            Assert.Equal(42, await frameEvaluation);93        }94        [Fact]95        public async Task ShouldWorkFromInsideAnExposedFunction()96        {97            await Page.ExposeFunctionAsync("callController", async (int a, int b) =>98            {99                return await Page.EvaluateFunctionAsync<int>("(a, b) => a * b", a, b);100            });101            var result = await Page.EvaluateFunctionAsync<int>(@"async function() {102                return await callController(9, 3);103            }");104            Assert.Equal(27, result);105        }106        [Fact]107        public async Task ShouldRejectPromiseWithExeption()108        {109            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(() =>110            {111                return Page.EvaluateFunctionAsync("() => not_existing_object.property");112            });113            Assert.Contains("not_existing_object", exception.Message);114        }115        [Fact]116        public async Task ShouldSupportThrownStringsAsErrorMessages()117        {118            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(119                () => Page.EvaluateExpressionAsync("throw 'qwerty'"));120            Assert.Contains("qwerty", exception.Message);121        }122        [Fact]123        public async Task ShouldSupportThrownNumbersAsErrorMessages()124        {125            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(126                            () => Page.EvaluateExpressionAsync("throw 100500"));127            Assert.Contains("100500", exception.Message);128        }129        [Fact]130        public async Task SouldReturnComplexObjects()131        {132            dynamic obj = new133            {134                foo = "bar!"135            };136            var result = await Page.EvaluateFunctionAsync("a => a", obj);137            Assert.Equal("bar!", result.foo.ToString());138        }139        [Fact]140        public async Task ShouldReturnBigInt()141        {142            var result = await Page.EvaluateFunctionAsync<object>("() => BigInt(42)");143            Assert.Equal(new BigInteger(42), result);144        }145        [Theory]146        [InlineData("() => NaN", double.NaN)] //ShouldReturnNaN147        [InlineData("() => -0", -0)] //ShouldReturnNegative0148        [InlineData("() => Infinity", double.PositiveInfinity)] //ShouldReturnInfinity149        [InlineData("() => -Infinity", double.NegativeInfinity)] //ShouldReturnNegativeInfinty150        public async Task BasicEvaluationTest(string script, object expected)151        {152            var result = await Page.EvaluateFunctionAsync<object>(script);153            Assert.Equal(expected, result);154        }155        [Fact]156        public async Task ShouldAcceptNullAsOneOfMultipleParameters()157        {158            var result = await Page.EvaluateFunctionAsync<bool>(159                "(a, b) => Object.is(a, null) && Object.is(b, 'foo')",160                null,161                "foo");162            Assert.True(result);163        }164        [Fact]165        public async Task ShouldReturnNullForNonSerializableObjects()166            => Assert.Null(await Page.EvaluateFunctionAsync("() => window"));167        [Fact]168        public async Task ShouldFailForCircularObject()169        {170            var result = await Page.EvaluateFunctionAsync(@"() => {171                const a = {};172                const b = {a};173                a.b = b;174                return a;175            }");176            Assert.Null(result);177        }178        [Fact]179        public async Task ShouldBeAbleToThrowATrickyError()180        {181            var windowHandle = await Page.EvaluateFunctionHandleAsync("() => window");182            PuppeteerException exception = await Assert.ThrowsAsync<MessageException>(() => windowHandle.JsonValueAsync());183            var errorText = exception.Message;184            exception = await Assert.ThrowsAsync<EvaluationFailedException>(() => Page.EvaluateFunctionAsync(@"errorText =>185            {186                throw new Error(errorText);187            }", errorText));188            Assert.Contains(errorText, exception.Message);189        }190        [Theory]191        [InlineData("1 + 5;", 6)] //ShouldAcceptSemiColons192        [InlineData("2 + 5\n// do some math!'", 7)] //ShouldAceptStringComments193        public async Task BasicIntExressionEvaluationTest(string script, object expected)194        {195            var result = await Page.EvaluateExpressionAsync<int>(script);196            Assert.Equal(expected, result);197        }198        [Fact]199        public async Task ShouldAcceptElementHandleAsAnArgument()200        {201            await Page.SetContentAsync("<section>42</section>");202            var element = await Page.QuerySelectorAsync("section");203            var text = await Page.EvaluateFunctionAsync<string>("e => e.textContent", element);204            Assert.Equal("42", text);205        }206        [Fact]207        public async Task ShouldThrowIfUnderlyingElementWasDisposed()208        {209            await Page.SetContentAsync("<section>39</section>");210            var element = await Page.QuerySelectorAsync("section");211            Assert.NotNull(element);212            await element.DisposeAsync();213            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(()214                => Page.EvaluateFunctionAsync<string>("e => e.textContent", element));215            Assert.Contains("JSHandle is disposed", exception.Message);216        }217        [Fact]218        public async Task ShouldThrowIfElementHandlesAreFromOtherFrames()219        {220            await FrameUtils.AttachFrameAsync(Page, "frame1", TestConstants.EmptyPage);221            var bodyHandle = await Page.FirstChildFrame().QuerySelectorAsync("body");222            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(()223                => Page.EvaluateFunctionAsync<string>("body => body.innerHTML", bodyHandle));224            Assert.Contains("JSHandles can be evaluated only in the context they were created", exception.Message);225        }226        [Fact]227        public async Task ShouldSimulateAUserGesture()228            => Assert.True(await Page.EvaluateFunctionAsync<bool>(@"() => {229                document.body.appendChild(document.createTextNode('test'));230                document.execCommand('selectAll');231                return document.execCommand('copy'); 232            }"));233        [Fact]234        public async Task ShouldThrowANiceErrorAfterANavigation()235        {236            var executionContext = await Page.MainFrame.GetExecutionContextAsync();237            await Task.WhenAll(238                Page.WaitForNavigationAsync(),239                executionContext.EvaluateFunctionAsync("() => window.location.reload()")240            );241            var ex = await Assert.ThrowsAsync<EvaluationFailedException>(() =>242            {243                return executionContext.EvaluateFunctionAsync("() => null");244            });245            Assert.Contains("navigation", ex.Message);246        }247        [Fact]248        public async Task ShouldNotThrowAnErrorWhenEvaluationDoesANavigation()249        {250            await Page.GoToAsync(TestConstants.ServerUrl + "/one-style.html");251            var result = await Page.EvaluateFunctionAsync<int[]>(@"() =>252            {253                window.location = '/empty.html';254                return [42];255            }");256            Assert.Equal(new[] { 42 }, result);257        }258        /// <summary>259        /// Original Name "should transfer 100Mb of data from page to node.js"260        /// </summary>261        [Fact]262        public async Task ShouldTransfer100MbOfDataFromPage()263        {264            var a = await Page.EvaluateFunctionAsync<string>("() => Array(100 * 1024 * 1024 + 1).join('a')");265            Assert.Equal(100 * 1024 * 1024, a.Length);266        }267        [Fact]268        public async Task ShouldThrowErrorWithDetailedInformationOnExceptionInsidePromise()269        {270            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(() =>271                Page.EvaluateFunctionAsync(272                    @"() => new Promise(() => {273                        throw new Error('Error in promise');274                    })"));275            Assert.Contains("Error in promise", exception.Message);276        }277        [Fact]278        public async Task ShouldWorkWithDifferentSerializerSettings()279        {280            var result = await Page.EvaluateFunctionAsync<ComplexObjectTestClass>("() => { return { foo: 'bar' }}");281            Assert.Equal("bar", result.Foo);282            result = (await Page.EvaluateFunctionAsync<JToken>("() => { return { Foo: 'bar' }}"))283                .ToObject<ComplexObjectTestClass>(new JsonSerializerSettings());284            Assert.Equal("bar", result.Foo);285            result = await Page.EvaluateExpressionAsync<ComplexObjectTestClass>("var obj = { foo: 'bar' }; obj;");286            Assert.Equal("bar", result.Foo);287            result = (await Page.EvaluateExpressionAsync<JToken>("var obj = { Foo: 'bar' }; obj;"))288                .ToObject<ComplexObjectTestClass>(new JsonSerializerSettings());289            Assert.Equal("bar", result.Foo);290        }291        [Fact]292        public async Task ShouldProperlyIgnoreUndefinedFields()293        {294            var result = await Page.EvaluateFunctionAsync<Dictionary<string, object>>("() => ({a: undefined})");295            Assert.Empty(result);296        }297        [Fact]298        public async Task ShouldProperlySerializeNullFields()299        {300            var result = await Page.EvaluateFunctionAsync<Dictionary<string, object>>("() => ({a: null})");301            Assert.True(result.ContainsKey("a"));302            Assert.Null(result["a"]);303        }304        [Fact]305        public async Task ShouldAcceptObjectHandleAsAnArgument()306        {307            var navigatorHandle = await Page.EvaluateExpressionHandleAsync("navigator");308            var text = await Page.EvaluateFunctionAsync<string>("e => e.userAgent", navigatorHandle);309            Assert.Contains("Mozilla", text);310        }311        [Fact]312        public async Task ShouldAcceptObjectHandleToPrimitiveTypes()313        {314            var aHandle = await Page.EvaluateExpressionHandleAsync("5");315            var isFive = await Page.EvaluateFunctionAsync<bool>("e => Object.is(e, 5)", aHandle);316            Assert.True(isFive);317        }318        [Fact]319        public async Task ShouldWarnOnNestedObjectHandles()320        {321            var handle = await Page.EvaluateFunctionHandleAsync("() => document.body");322            var elementHandle = handle as ElementHandle;323            var exception = await Assert.ThrowsAsync<EvaluationFailedException>(()324                => Page.EvaluateFunctionHandleAsync(325                    "opts => opts.elem.querySelector('p')",326                    new { elem = handle }));327            Assert.Contains("Are you passing a nested JSHandle?", exception.Message);328            //Check with ElementHandle329            exception = await Assert.ThrowsAsync<EvaluationFailedException>(()...DOMWorld.cs
Source:DOMWorld.cs  
...75        {76            var context = await GetExecutionContextAsync().ConfigureAwait(false);77            return await context.EvaluateExpressionAsync(script).ConfigureAwait(false);78        }79        internal async Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)80        {81            var context = await GetExecutionContextAsync().ConfigureAwait(false);82            return await context.EvaluateFunctionAsync<T>(script, args).ConfigureAwait(false);83        }84        internal async Task<JToken> EvaluateFunctionAsync(string script, params object[] args)85        {86            var context = await GetExecutionContextAsync().ConfigureAwait(false);87            return await context.EvaluateFunctionAsync(script, args).ConfigureAwait(false);88        }89        internal Task<string> GetContentAsync() => EvaluateFunctionAsync<string>(@"() => {90                let retVal = '';91                if (document.doctype)92                    retVal = new XMLSerializer().serializeToString(document.doctype);93                if (document.documentElement)94                    retVal += document.documentElement.outerHTML;95                return retVal;96            }");97        internal async Task SetContentAsync(string html, NavigationOptions options = null)98        {99            var waitUntil = options?.WaitUntil ?? new[] { WaitUntilNavigation.Load };100            var timeout = options?.Timeout ?? _timeoutSettings.NavigationTimeout;101            // We rely upon the fact that document.open() will reset frame lifecycle with "init"102            // lifecycle event. @see https://crrev.com/608658103            await EvaluateFunctionAsync(@"html => {104                document.open();105                document.write(html);106                document.close();107            }", html).ConfigureAwait(false);108            using (var watcher = new LifecycleWatcher(_frameManager, Frame, waitUntil, timeout))109            {110                var watcherTask = await Task.WhenAny(111                    watcher.TimeoutOrTerminationTask,112                    watcher.LifecycleTask).ConfigureAwait(false);113                await watcherTask.ConfigureAwait(false);114            }115        }116        internal async Task<ElementHandle> AddScriptTagAsync(AddTagOptions options)117        {...ExecutionContext.cs
Source:ExecutionContext.cs  
...43        /// <param name="script">Script to be evaluated in browser context</param>44        /// <remarks>45        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.46        /// </remarks>47        /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>48        /// <seealso cref="EvaluateExpressionHandleAsync(string)"/>49        /// <returns>Task which resolves to script return value</returns>50        public Task<JToken> EvaluateExpressionAsync(string script) => EvaluateExpressionAsync<JToken>(script);51        /// <summary>52        /// Executes a script in browser context53        /// </summary>54        /// <typeparam name="T">The type to deserialize the result to</typeparam>55        /// <param name="script">Script to be evaluated in browser context</param>56        /// <remarks>57        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.58        /// </remarks>59        /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>60        /// <seealso cref="EvaluateExpressionHandleAsync(string)"/>61        /// <returns>Task which resolves to script return value</returns>62        public Task<T> EvaluateExpressionAsync<T>(string script)63            => RemoteObjectTaskToObject<T>(EvaluateExpressionInternalAsync(true, script));64        internal async Task<JSHandle> EvaluateExpressionHandleAsync(string script)65            => CreateJSHandle(await EvaluateExpressionInternalAsync(false, script).ConfigureAwait(false));66        /// <summary>67        /// Executes a function in browser context68        /// </summary>69        /// <param name="script">Script to be evaluated in browser context</param>70        /// <param name="args">Arguments to pass to script</param>71        /// <remarks>72        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.73        /// <see cref="JSHandle"/> instances can be passed as arguments74        /// </remarks>75        /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>76        /// <returns>Task which resolves to script return value</returns>77        public Task<JToken> EvaluateFunctionAsync(string script, params object[] args) => EvaluateFunctionAsync<JToken>(script, args);78        /// <summary>79        /// Executes a function in browser context80        /// </summary>81        /// <typeparam name="T">The type to deserialize the result to</typeparam>82        /// <param name="script">Script to be evaluated in browser context</param>83        /// <param name="args">Arguments to pass to script</param>84        /// <remarks>85        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.86        /// <see cref="JSHandle"/> instances can be passed as arguments87        /// </remarks>88        /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>89        /// <returns>Task which resolves to script return value</returns>90        public Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)91            => RemoteObjectTaskToObject<T>(EvaluateFunctionInternalAsync(true, script, args));92        internal async Task<JSHandle> EvaluateFunctionHandleAsync(string script, params object[] args)93            => CreateJSHandle(await EvaluateFunctionInternalAsync(false, script, args).ConfigureAwait(false));94        /// <summary>95        /// The method iterates JavaScript heap and finds all the objects with the given prototype.96        /// </summary>97        /// <returns>A task which resolves to a handle to an array of objects with this prototype.</returns>98        /// <param name="prototypeHandle">A handle to the object prototype.</param>99        public async Task<JSHandle> QueryObjectsAsync(JSHandle prototypeHandle)100        {101            if (prototypeHandle.Disposed)102            {103                throw new PuppeteerException("Prototype JSHandle is disposed!");104            }...JSHandle.cs
Source:JSHandle.cs  
...169        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.170        /// <see cref="JSHandle"/> instances can be passed as arguments171        /// </remarks>172        /// <returns>Task which resolves to script return value</returns>173        public Task<JToken> EvaluateFunctionAsync(string script, params object[] args)174        {175            var list = new List<object>(args);176            list.Insert(0, this);177            return ExecutionContext.EvaluateFunctionAsync<JToken>(script, list.ToArray());178        }179        /// <summary>180        /// Executes a function in browser context181        /// </summary>182        /// <typeparam name="T">The type to deserialize the result to</typeparam>183        /// <param name="script">Script to be evaluated in browser context</param>184        /// <param name="args">Arguments to pass to script</param>185        /// <remarks>186        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.187        /// <see cref="JSHandle"/> instances can be passed as arguments188        /// </remarks>189        /// <returns>Task which resolves to script return value</returns>190        public Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)191        {192            var list = new List<object>(args);193            list.Insert(0, this);194            return ExecutionContext.EvaluateFunctionAsync<T>(script, list.ToArray());195        }196        internal object FormatArgument(ExecutionContext context)197        {198            if (ExecutionContext != context)199            {200                throw new PuppeteerException("JSHandles can be evaluated only in the context they were created!");201            }202            if (Disposed)203            {204                throw new PuppeteerException("JSHandle is disposed!");205            }206            var unserializableValue = RemoteObject.UnserializableValue;207            if (unserializableValue != null)208            {...Worker.cs
Source:Worker.cs  
...86        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.87        /// <see cref="JSHandle"/> instances can be passed as arguments88        /// </remarks>89        /// <returns>Task which resolves to script return value</returns>90        public async Task<JToken> EvaluateFunctionAsync(string script, params object[] args)91            => await (await ExecutionContextTask.ConfigureAwait(false)).EvaluateFunctionAsync(script, args).ConfigureAwait(false);92        /// <summary>93        /// Executes a function in the context94        /// </summary>95        /// <typeparam name="T">The type to deserialize the result to</typeparam>96        /// <param name="script">Script to be evaluated in browser context</param>97        /// <param name="args">Arguments to pass to script</param>98        /// <remarks>99        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.100        /// <see cref="JSHandle"/> instances can be passed as arguments101        /// </remarks>102        /// <returns>Task which resolves to script return value</returns>103        public async Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)104            => await (await ExecutionContextTask.ConfigureAwait(false)).EvaluateFunctionAsync<T>(script, args).ConfigureAwait(false);105        /// <summary>106        /// Executes a script in browser context107        /// </summary>108        /// <param name="script">Script to be evaluated in browser context</param>109        /// <remarks>110        /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.111        /// </remarks>112        /// <returns>Task which resolves to script return value</returns>113        /// <seealso cref="ExecutionContext.EvaluateExpressionHandleAsync(string)"/>114        public async Task<JSHandle> EvaluateExpressionHandleAsync(string script)115            => await (await ExecutionContextTask.ConfigureAwait(false)).EvaluateExpressionHandleAsync(script).ConfigureAwait(false);116        internal Task<ExecutionContext> ExecutionContextTask => _executionContextCallback.Task;117        internal async void OnMessageReceived(object sender, MessageEventArgs e)118        {...QueryObjectsTests.cs
Source:QueryObjectsTests.cs  
...18            // Instantiate an object19            await Page.EvaluateExpressionAsync("window.set = new Set(['hello', 'world'])");20            var prototypeHandle = await Page.EvaluateExpressionHandleAsync("Set.prototype");21            var objectsHandle = await Page.QueryObjectsAsync(prototypeHandle);22            var count = await Page.EvaluateFunctionAsync<int>("objects => objects.length", objectsHandle);23            Assert.Equal(1, count);24            var values = await Page.EvaluateFunctionAsync<string[]>("objects => Array.from(objects[0].values())", objectsHandle);25            Assert.Equal(new[] { "hello", "world" }, values);26        }27        [PuppeteerTest("page.spec.ts", "ExecutionContext.queryObjects", "should work for non-blank page")]28        [SkipBrowserFact(skipFirefox: true)]29        public async Task ShouldWorkForNonBlankPage()30        {31            // Instantiate an object32            await Page.GoToAsync(TestConstants.EmptyPage);33            await Page.EvaluateFunctionAsync("() => window.set = new Set(['hello', 'world'])");34            var prototypeHandle = await Page.EvaluateFunctionHandleAsync("() => Set.prototype");35            var objectsHandle = await Page.QueryObjectsAsync(prototypeHandle);36            var count = await Page.EvaluateFunctionAsync<int>("objects => objects.length", objectsHandle);37            Assert.Equal(1, count);38        }39        [PuppeteerTest("page.spec.ts", "ExecutionContext.queryObjects", "should fail for disposed handles")]40        [PuppeteerFact]41        public async Task ShouldFailForDisposedHandles()42        {43            var prototypeHandle = await Page.EvaluateExpressionHandleAsync("HTMLBodyElement.prototype");44            await prototypeHandle.DisposeAsync();45            var exception = await Assert.ThrowsAsync<PuppeteerException>(()46                => Page.QueryObjectsAsync(prototypeHandle));47            Assert.Equal("Prototype JSHandle is disposed!", exception.Message);48        }49        [PuppeteerTest("page.spec.ts", "ExecutionContext.queryObjects", "should fail primitive values as prototypes")]50        [PuppeteerFact]...Extensions.cs
Source:Extensions.cs  
...14        /// <param name="pageFunction">Function to be evaluated in browser context</param>15        /// <param name="args">Arguments to pass to <c>pageFunction</c></param>16        /// <returns>Task which resolves to the return value of <c>pageFunction</c></returns>17        /// <exception cref="SelectorException">If <paramref name="elementHandleTask"/> resolves to <c>null</c></exception>18        public static async Task<T> EvaluateFunctionAsync<T>(this Task<ElementHandle> elementHandleTask, string pageFunction, params object[] args)19        {20            var elementHandle = await elementHandleTask;21            if (elementHandle == null)22            {23                throw new SelectorException($"Error: failed to find element matching selector");24            }25            var newArgs = new object[args.Length + 1];26            newArgs[0] = elementHandle;27            args.CopyTo(newArgs, 1);28            var result = await elementHandle.ExecutionContext.EvaluateFunctionAsync<T>(pageFunction, newArgs);29            await elementHandle.DisposeAsync();30            return result;31        }32        /// <summary>33        /// Runs <paramref name="pageFunction"/> within the frame and passes it the outcome of <paramref name="arrayHandleTask"/> as the first argument. Use only after <see cref="Page.QuerySelectorAllHandleAsync(string)"/>34        /// </summary>35        /// <typeparam name="T"></typeparam>36        /// <param name="arrayHandleTask">A task that returns an <see cref="JSHandle"/> that represents an array of <see cref="ElementHandle"/> that will be used as the first argument in <paramref name="pageFunction"/></param>37        /// <param name="pageFunction">Function to be evaluated in browser context</param>38        /// <param name="args">Arguments to pass to <c>pageFunction</c></param>39        /// <returns>Task which resolves to the return value of <c>pageFunction</c></returns>40        public static async Task<T> EvaluateFunctionAsync<T>(this Task<JSHandle> arrayHandleTask, string pageFunction, params object[] args)41        {42            var arrayHandle = await arrayHandleTask;43            var newArgs = new object[args.Length + 1];44            newArgs[0] = arrayHandle;45            args.CopyTo(newArgs, 1);46            var result = await arrayHandle.ExecutionContext.EvaluateFunctionAsync<T>(pageFunction, newArgs);47            await arrayHandle.DisposeAsync();48            return result;49        }50    }51}...EvaluateFunctionAsync
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5    {6        static void Main(string[] args)7        {8            MainAsync().GetAwaiter().GetResult();9        }10        static async Task MainAsync()11        {12            Browser browser = await Puppeteer.LaunchAsync(new LaunchOptions() { Headless = false });13            Page page = await browser.NewPageAsync();14            var result = await page.EvaluateFunctionAsync("() => 1 + 1");15            Console.WriteLine(result);16            await browser.CloseAsync();17        }18    }19}20using System;21using System.Threading.Tasks;22using PuppeteerSharp;23{24    {25        static void Main(string[] args)26        {27            MainAsync().GetAwaiter().GetResult();28        }29        static async Task MainAsync()30        {31            Browser browser = await Puppeteer.LaunchAsync(new LaunchOptions() { Headless = false });32            Page page = await browser.NewPageAsync();33            var result = await page.EvaluateFunctionAsync("() => 1 + 1");34            Console.WriteLine(result);35            await browser.CloseAsync();36        }37    }38}39using System;40using System.Threading.Tasks;41using PuppeteerSharp;42{43    {44        static void Main(string[] args)45        {46            MainAsync().GetAwaiter().GetResult();47        }48        static async Task MainAsync()49        {50            Browser browser = await Puppeteer.LaunchAsync(new LaunchOptions() { Headless = false });51            Page page = await browser.NewPageAsync();52            var result = await page.EvaluateFunctionAsync("() => 1 + 1");53            Console.WriteLine(result);54            await browser.CloseAsync();55        }56    }57}58using System;59using System.Threading.Tasks;60using PuppeteerSharp;61{62    {EvaluateFunctionAsync
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 LaunchOptions { Headless = false });9            var page = await browser.NewPageAsync();10            var result = await page.EvaluateFunctionAsync("() => 1 + 2");11            Console.WriteLine(result);12            await browser.CloseAsync();13        }14    }15}16using System;17using System.Threading.Tasks;18using PuppeteerSharp;19{20    {21        static async Task Main(string[] args)22        {23            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });24            var page = await browser.NewPageAsync();25            var result = await page.EvaluateFunctionAsync<string>("() => 'Hello World'");26            Console.WriteLine(result);27            await browser.CloseAsync();28        }29    }30}31using System;32using System.Threading.Tasks;33using PuppeteerSharp;34{35    {36        static async Task Main(string[] args)37        {38            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });39            var page = await browser.NewPageAsync();40            var result = await page.EvaluateFunctionAsync<int>("() => 1 + 2");41            Console.WriteLine(result);42            await browser.CloseAsync();43        }44    }45}46using System;47using System.Threading.Tasks;48using PuppeteerSharp;49{50    {51        static async Task Main(string[] args)52        {53            var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });54            var page = await browser.NewPageAsync();EvaluateFunctionAsync
Using AI Code Generation
1var page = await browser.NewPageAsync();2var result = await page.EvaluateFunctionAsync<int>("() => 7 * 3");3Console.WriteLine(result);4await browser.CloseAsync();5var page = await browser.NewPageAsync();6var result = await page.EvaluateFunctionAsync<int>("(a, b) => a * b", 7, 3);7Console.WriteLine(result);8await browser.CloseAsync();9var page = await browser.NewPageAsync();10var result = await page.EvaluateFunctionAsync("() => document.title");11Console.WriteLine(result);12await browser.CloseAsync();13var page = await browser.NewPageAsync();14var result = await page.EvaluateFunctionAsync("() => window.location.href");15Console.WriteLine(result);16await browser.CloseAsync();17var page = await browser.NewPageAsync();18var result = await page.EvaluateFunctionAsync("() => document.querySelector('h1').innerText");19Console.WriteLine(result);20await browser.CloseAsync();21var page = await browser.NewPageAsync();22var result = await page.EvaluateFunctionAsync("() => document.querySelector('h1')");23Console.WriteLine(result);24await browser.CloseAsync();25var page = await browser.NewPageAsync();26var result = await page.EvaluateFunctionAsync("() => document.querySelector('h1').innerText");27Console.WriteLine(result);28await browser.CloseAsync();EvaluateFunctionAsync
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            });11            var page = await browser.NewPageAsync();12            await page.EvaluateFunctionAsync("() => document.querySelector('input').value = 'PuppeteerSharp'");13            await page.PressAsync("input", "Enter");14            await page.WaitForNavigationAsync();15            var result = await page.EvaluateFunctionAsync<int>("() => document.querySelectorAll('h3').length");16            Console.WriteLine(result);17            await browser.CloseAsync();18        }19    }20}EvaluateFunctionAsync
Using AI Code Generation
1var browser = await Puppeteer.LaunchAsync(new LaunchOptions2{3});4var page = await browser.NewPageAsync();5var html = await page.EvaluateFunctionAsync<string>("() => document.documentElement.outerHTML");6Console.WriteLine(html);7await browser.CloseAsync();8var browser = await Puppeteer.LaunchAsync(new LaunchOptions9{10});11var page = await browser.NewPageAsync();12var html = await page.EvaluateFunctionAsync<string>("() => document.documentElement.outerHTML");13Console.WriteLine(html);14await browser.CloseAsync();15var browser = await Puppeteer.LaunchAsync(new LaunchOptions16{17});18var page = await browser.NewPageAsync();19var html = await page.EvaluateFunctionAsync<string>("() => document.documentElement.outerHTML");20Console.WriteLine(html);21await browser.CloseAsync();22var browser = await Puppeteer.LaunchAsync(new LaunchOptions23{24});25var page = await browser.NewPageAsync();26var html = await page.EvaluateFunctionAsync<string>("() => document.documentElement.outerHTML");27Console.WriteLine(html);28await browser.CloseAsync();29var browser = await Puppeteer.LaunchAsync(new LaunchOptions30{31});32var page = await browser.NewPageAsync();EvaluateFunctionAsync
Using AI Code Generation
1var context = await page.GetBrowser().GetDefaultBrowserContextAsync();2var page = await context.NewPageAsync();3var result = await page.EvaluateFunctionAsync("() => document.querySelector('div').innerText");4Console.WriteLine(result);5var page = await browser.NewPageAsync();6var result = await page.EvaluateFunctionAsync("() => document.querySelector('div').innerText");7Console.WriteLine(result);8var page = await browser.NewPageAsync();9var frame = page.MainFrame;10var result = await frame.EvaluateFunctionAsync("() => document.querySelector('div').innerText");11Console.WriteLine(result);12var page = await browser.NewPageAsync();13var element = await page.QuerySelectorAsync("div");14var result = await element.EvaluateFunctionAsync("() => document.querySelector('div').innerText");15Console.WriteLine(result);16var page = await browser.NewPageAsync();17var result = await page.EvaluateFunctionAsync("() => document.querySelector('div').innerText");18Console.WriteLine(result);19var page = await browser.NewPageAsync();20var result = await page.EvaluateFunctionAsync("() => document.querySelector('div').innerText");21Console.WriteLine(result);22var page = await browser.NewPageAsync();23var result = await page.EvaluateFunctionAsync("() => document.querySelector('div').innerText");24Console.WriteLine(result);EvaluateFunctionAsync
Using AI Code Generation
1var page = await browser.NewPageAsync();2var result = await page.EvaluateFunctionAsync("() => 1 + 2");3Console.WriteLine(result.ToString());4Console.ReadLine();5var page = await browser.NewPageAsync();6var result = await page.EvaluateFunctionAsync("() => 1 + 2");7Console.WriteLine(result.ToString());8Console.ReadLine();EvaluateFunctionAsync
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            });11            var page = await browser.NewPageAsync();12            var title = await page.EvaluateFunctionAsync<string>("() => document.title");13            Console.WriteLine(title);14            Console.ReadKey();15        }16    }17}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!!
