How to use GetExecutionContextAsync method of PuppeteerSharp.Frame class

Best Puppeteer-sharp code snippet using PuppeteerSharp.Frame.GetExecutionContextAsync

Run Puppeteer-sharp automation tests on LambdaTest cloud grid

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

ContextTests.cs

Source: ContextTests.cs Github

copy
1using System.Threading.Tasks;
2using Xunit;
3using Xunit.Abstractions;
4
5namespace PuppeteerSharp.Tests.FrameTests
6{
7    [Collection("PuppeteerLoaderFixture collection")]
8    public class ContextTests : PuppeteerPageBaseTest
9    {
10        public ContextTests(ITestOutputHelper output) : base(output)
11        {
12        }
13
14        [Fact]
15        public async Task ShouldWork()
16        {
17            await Page.GoToAsync(TestConstants.EmptyPage);
18            await FrameUtils.AttachFrameAsync(Page, "frame1", TestConstants.EmptyPage);
19            Assert.Equal(2, Page.Frames.Length);
20
21            var context1 = await Page.Frames[0].GetExecutionContextAsync();
22            var context2 = await Page.Frames[1].GetExecutionContextAsync();
23            Assert.NotNull(context1);
24            Assert.NotNull(context2);
25            Assert.NotEqual(context1, context2);
26
27            await Task.WhenAll(
28                context1.EvaluateExpressionAsync("window.a = 1"),
29                context2.EvaluateExpressionAsync("window.a = 2")
30            );
31
32            var a1 = context1.EvaluateExpressionAsync<int>("window.a");
33            var a2 = context2.EvaluateExpressionAsync<int>("window.a");
34
35            await Task.WhenAll(a1, a2);
36
37            Assert.Equal(1, a1.Result);
38            Assert.Equal(2, a2.Result);
39        }
40    }
41}
42
Full Screen

DOMWorld.cs

Source: DOMWorld.cs Github

copy
1using Newtonsoft.Json.Linq;
2using PuppeteerSharp.Helpers;
3using System;
4using System.Collections.Generic;
5using System.Threading.Tasks;
6
7namespace PuppeteerSharp
8{
9    internal class DOMWorld
10    {
11        private readonly FrameManager _frameManager;
12        private readonly TimeoutSettings _timeoutSettings;
13        private bool _detached;
14        private TaskCompletionSource<ExecutionContext> _contextResolveTaskWrapper;
15        private TaskCompletionSource<ElementHandle> _documentCompletionSource;
16
17        internal List<WaitTask> WaitTasks { get; set; }
18
19        internal Frame Frame { get; }
20
21        public DOMWorld(FrameManager frameManager, Frame frame, TimeoutSettings timeoutSettings)
22        {
23            _frameManager = frameManager;
24            Frame = frame;
25            _timeoutSettings = timeoutSettings;
26
27            SetContext(null);
28
29            WaitTasks = new List<WaitTask>();
30            _detached = false;
31        }
32
33        internal void SetContext(ExecutionContext context)
34        {
35            if (context != null)
36            {
37                _contextResolveTaskWrapper.TrySetResult(context);
38                foreach (var waitTask in WaitTasks)
39                {
40                    _ = waitTask.Rerun();
41                }
42            }
43            else
44            {
45                _documentCompletionSource = null;
46                _contextResolveTaskWrapper = new TaskCompletionSource<ExecutionContext>();
47            }
48        }
49
50        internal bool HasContext => _contextResolveTaskWrapper?.Task.IsCompleted == true;
51
52        internal void Detach()
53        {
54            _detached = true;
55            while (WaitTasks.Count > 0)
56            {
57                WaitTasks[0].Terminate(new Exception("waitForFunction failed: frame got detached."));
58            }
59        }
60
61        internal Task<ExecutionContext> GetExecutionContextAsync()
62        {
63            if (_detached)
64            {
65                throw new PuppeteerException($"Execution Context is not available in detached frame \"{Frame.Url}\"(are you trying to evaluate?)");
66            }
67            return _contextResolveTaskWrapper.Task;
68        }
69
70        internal async Task<JSHandle> EvaluateExpressionHandleAsync(string script)
71        {
72            var context = await GetExecutionContextAsync().ConfigureAwait(false);
73            return await context.EvaluateExpressionHandleAsync(script).ConfigureAwait(false);
74        }
75
76        internal async Task<JSHandle> EvaluateFunctionHandleAsync(string script, params object[] args)
77        {
78            var context = await GetExecutionContextAsync().ConfigureAwait(false);
79            return await context.EvaluateFunctionHandleAsync(script, args).ConfigureAwait(false);
80        }
81
82        internal async Task<T> EvaluateExpressionAsync<T>(string script)
83        {
84            var context = await GetExecutionContextAsync().ConfigureAwait(false);
85            return await context.EvaluateExpressionAsync<T>(script).ConfigureAwait(false);
86        }
87        internal async Task<JToken> EvaluateExpressionAsync(string script)
88        {
89            var context = await GetExecutionContextAsync().ConfigureAwait(false);
90            return await context.EvaluateExpressionAsync(script).ConfigureAwait(false);
91        }
92
93        internal async Task<T> EvaluateFunctionAsync<T>(string script, params object[] args)
94        {
95            var context = await GetExecutionContextAsync().ConfigureAwait(false);
96            return await context.EvaluateFunctionAsync<T>(script, args).ConfigureAwait(false);
97        }
98        internal async Task<JToken> EvaluateFunctionAsync(string script, params object[] args)
99        {
100            var context = await GetExecutionContextAsync().ConfigureAwait(false);
101            return await context.EvaluateFunctionAsync(script, args).ConfigureAwait(false);
102        }
103
104        internal Task<string> GetContentAsync() => EvaluateFunctionAsync<string>(@"() => {
105                let retVal = '';
106                if (document.doctype)
107                    retVal = new XMLSerializer().serializeToString(document.doctype);
108                if (document.documentElement)
109                    retVal += document.documentElement.outerHTML;
110                return retVal;
111            }");
112
113        internal async Task SetContentAsync(string html, NavigationOptions options = null)
114        {
115            var waitUntil = options?.WaitUntil ?? new[] { WaitUntilNavigation.Load };
116            var timeout = options?.Timeout ?? _timeoutSettings.NavigationTimeout;
117
118            // We rely upon the fact that document.open() will reset frame lifecycle with "init"
119            // lifecycle event. @see https://crrev.com/608658
120            await EvaluateFunctionAsync(@"html => {
121                document.open();
122                document.write(html);
123                document.close();
124            }", html).ConfigureAwait(false);
125
126            using (var watcher = new LifecycleWatcher(_frameManager, Frame, waitUntil, timeout))
127            {
128                var watcherTask = await Task.WhenAny(
129                    watcher.TimeoutOrTerminationTask,
130                    watcher.LifecycleTask).ConfigureAwait(false);
131
132                await watcherTask.ConfigureAwait(false);
133            }
134        }
135
136        internal async Task<ElementHandle> AddScriptTagAsync(AddTagOptions options)
137        {
138            const string addScriptUrl = @"async function addScriptUrl(url, type) {
139              const script = document.createElement('script');
140              script.src = url;
141              if(type)
142                script.type = type;
143              const promise = new Promise((res, rej) => {
144                script.onload = res;
145                script.onerror = rej;
146              });
147              document.head.appendChild(script);
148              await promise;
149              return script;
150            }";
151            const string addScriptContent = @"function addScriptContent(content, type = 'text/javascript') {
152              const script = document.createElement('script');
153              script.type = type;
154              script.text = content;
155              let error = null;
156              script.onerror = e => error = e;
157              document.head.appendChild(script);
158              if (error)
159                throw error;
160              return script;
161            }";
162
163            async Task<ElementHandle> AddScriptTagPrivate(string script, string urlOrContent, string type)
164            {
165                var context = await GetExecutionContextAsync().ConfigureAwait(false);
166                return (string.IsNullOrEmpty(type)
167                        ? await context.EvaluateFunctionHandleAsync(script, urlOrContent).ConfigureAwait(false)
168                        : await context.EvaluateFunctionHandleAsync(script, urlOrContent, type).ConfigureAwait(false)) as ElementHandle;
169            }
170
171            if (!string.IsNullOrEmpty(options.Url))
172            {
173                var url = options.Url;
174                try
175                {
176                    return await AddScriptTagPrivate(addScriptUrl, url, options.Type).ConfigureAwait(false);
177                }
178                catch (PuppeteerException)
179                {
180                    throw new PuppeteerException($"Loading script from {url} failed");
181                }
182            }
183
184            if (!string.IsNullOrEmpty(options.Path))
185            {
186                var contents = await AsyncFileHelper.ReadAllText(options.Path).ConfigureAwait(false);
187                contents += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
188                return await AddScriptTagPrivate(addScriptContent, contents, options.Type).ConfigureAwait(false);
189            }
190
191            if (!string.IsNullOrEmpty(options.Content))
192            {
193                return await AddScriptTagPrivate(addScriptContent, options.Content, options.Type).ConfigureAwait(false);
194            }
195
196            throw new ArgumentException("Provide options with a `Url`, `Path` or `Content` property");
197        }
198
199        internal async Task<ElementHandle> AddStyleTagAsync(AddTagOptions options)
200        {
201            const string addStyleUrl = @"async function addStyleUrl(url) {
202              const link = document.createElement('link');
203              link.rel = 'stylesheet';
204              link.href = url;
205              const promise = new Promise((res, rej) => {
206                link.onload = res;
207                link.onerror = rej;
208              });
209              document.head.appendChild(link);
210              await promise;
211              return link;
212            }";
213            const string addStyleContent = @"async function addStyleContent(content) {
214              const style = document.createElement('style');
215              style.type = 'text/css';
216              style.appendChild(document.createTextNode(content));
217              const promise = new Promise((res, rej) => {
218                style.onload = res;
219                style.onerror = rej;
220              });
221              document.head.appendChild(style);
222              await promise;
223              return style;
224            }";
225
226            if (!string.IsNullOrEmpty(options.Url))
227            {
228                var url = options.Url;
229                try
230                {
231                    var context = await GetExecutionContextAsync().ConfigureAwait(false);
232                    return (await context.EvaluateFunctionHandleAsync(addStyleUrl, url).ConfigureAwait(false)) as ElementHandle;
233                }
234                catch (PuppeteerException)
235                {
236                    throw new PuppeteerException($"Loading style from {url} failed");
237                }
238            }
239
240            if (!string.IsNullOrEmpty(options.Path))
241            {
242                var contents = await AsyncFileHelper.ReadAllText(options.Path).ConfigureAwait(false);
243                contents += "//# sourceURL=" + options.Path.Replace("\n", string.Empty);
244                var context = await GetExecutionContextAsync().ConfigureAwait(false);
245                return (await context.EvaluateFunctionHandleAsync(addStyleContent, contents).ConfigureAwait(false)) as ElementHandle;
246            }
247
248            if (!string.IsNullOrEmpty(options.Content))
249            {
250                var context = await GetExecutionContextAsync().ConfigureAwait(false);
251                return (await context.EvaluateFunctionHandleAsync(addStyleContent, options.Content).ConfigureAwait(false)) as ElementHandle;
252            }
253
254            throw new ArgumentException("Provide options with a `Url`, `Path` or `Content` property");
255        }
256
257        internal Task<ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)
258            => WaitForSelectorOrXPathAsync(selector, false, options);
259
260        internal Task<ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null)
261            => WaitForSelectorOrXPathAsync(xpath, true, options);
262
263        internal Task<JSHandle> WaitForFunctionAsync(string script, WaitForFunctionOptions options, params object[] args)
264            => new WaitTask(
265                this,
266                script,
267                false,
268                "function",
269                options.Polling,
270                options.PollingInterval,
271                options.Timeout ?? _timeoutSettings.Timeout,
272                args).Task;
273
274        internal Task<JSHandle> WaitForExpressionAsync(string script, WaitForFunctionOptions options)
275            => new WaitTask(
276                this,
277                script,
278                true,
279                "function",
280                options.Polling,
281                options.PollingInterval,
282                options.Timeout ?? _timeoutSettings.Timeout).Task;
283
284        internal Task<string> GetTitleAsync() => EvaluateExpressionAsync<string>("document.title");
285
286        private async Task<ElementHandle> GetDocument()
287        {
288            if (_documentCompletionSource == null)
289            {
290                _documentCompletionSource = new TaskCompletionSource<ElementHandle>(TaskCreationOptions.RunContinuationsAsynchronously);
291                var context = await GetExecutionContextAsync().ConfigureAwait(false);
292                var document = await context.EvaluateExpressionHandleAsync("document").ConfigureAwait(false);
293                _documentCompletionSource.TrySetResult(document as ElementHandle);
294            }
295            return await _documentCompletionSource.Task.ConfigureAwait(false);
296        }
297
298        private async Task<ElementHandle> WaitForSelectorOrXPathAsync(string selectorOrXPath, bool isXPath, WaitForSelectorOptions options = null)
299        {
300            options = options ?? new WaitForSelectorOptions();
301            var timeout = options.Timeout ?? _timeoutSettings.Timeout;
302
303            const string predicate = @"
304              function predicate(selectorOrXPath, isXPath, waitForVisible, waitForHidden) {
305                const node = isXPath
306                  ? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
307                  : document.querySelector(selectorOrXPath);
308                if (!node)
309                  return waitForHidden;
310                if (!waitForVisible && !waitForHidden)
311                  return node;
312                const element = node.nodeType === Node.TEXT_NODE ? node.parentElement : node;
313
314                const style = window.getComputedStyle(element);
315                const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox();
316                const success = (waitForVisible === isVisible || waitForHidden === !isVisible);
317                return success ? node : null;
318
319                function hasVisibleBoundingBox() {
320                  const rect = element.getBoundingClientRect();
321                  return !!(rect.top || rect.bottom || rect.width || rect.height);
322                }
323              }";
324            var polling = options.Visible || options.Hidden ? WaitForFunctionPollingOption.Raf : WaitForFunctionPollingOption.Mutation;
325            var handle = await new WaitTask(
326                this,
327                predicate,
328                false,
329                $"{(isXPath ? "XPath" : "selector")} '{selectorOrXPath}'{(options.Hidden ? " to be hidden" : string.Empty)}",
330                polling,
331                null,
332                timeout,
333                new object[]
334                {
335                    selectorOrXPath,
336                    isXPath,
337                    options.Visible,
338                    options.Hidden
339                }).Task.ConfigureAwait(false);
340
341            if (!(handle is ElementHandle elementHandle))
342            {
343                if (handle != null)
344                {
345                    await handle.DisposeAsync().ConfigureAwait(false);
346                }
347                return null;
348            }
349            return elementHandle;
350        }
351    }
352}
353
Full Screen

ExecutionContextTests.cs

Source: ExecutionContextTests.cs Github

copy
1using System.Threading.Tasks;
2using Xunit;
3using Xunit.Abstractions;
4
5namespace PuppeteerSharp.Tests.FrameTests
6{
7    [Collection("PuppeteerLoaderFixture collection")]
8    public class ExecutionContextTests : PuppeteerPageBaseTest
9    {
10        public ExecutionContextTests(ITestOutputHelper output) : base(output)
11        {
12        }
13
14        [Fact]
15        public async Task ShouldWork()
16        {
17            await Page.GoToAsync(TestConstants.EmptyPage);
18            await FrameUtils.AttachFrameAsync(Page, "frame1", TestConstants.EmptyPage);
19            Assert.Equal(2, Page.Frames.Length);
20
21            var context1 = await Page.MainFrame.GetExecutionContextAsync();
22            var context2 = await Page.FirstChildFrame().GetExecutionContextAsync();
23            Assert.NotNull(context1);
24            Assert.NotNull(context2);
25            Assert.NotEqual(context1, context2);
26            Assert.Equal(Page.MainFrame, context1.Frame);
27            Assert.Equal(Page.FirstChildFrame(), context2.Frame);
28
29            await Task.WhenAll(
30                context1.EvaluateExpressionAsync("window.a = 1"),
31                context2.EvaluateExpressionAsync("window.a = 2")
32            );
33
34            var a1 = context1.EvaluateExpressionAsync<int>("window.a");
35            var a2 = context2.EvaluateExpressionAsync<int>("window.a");
36
37            await Task.WhenAll(a1, a2);
38
39            Assert.Equal(1, a1.Result);
40            Assert.Equal(2, a2.Result);
41        }
42    }
43}
44
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTestÔÇÖs cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)