Best Puppeteer-sharp code snippet using PuppeteerSharp.DOMWorld.Detach
Frame.cs
Source:Frame.cs
...11 /// 12 /// <see cref="Frame"/> object's lifecycle is controlled by three events, dispatched on the page object13 /// - <see cref="Page.FrameAttached"/> - fires when the frame gets attached to the page. A Frame can be attached to the page only once14 /// - <see cref="Page.FrameNavigated"/> - fired when the frame commits navigation to a different URL15 /// - <see cref="Page.FrameDetached"/> - fired when the frame gets detached from the page. A Frame can be detached from the page only once16 /// </summary>17 /// <example>18 /// An example of dumping frame tree19 /// <code>20 /// <![CDATA[21 /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions());22 /// var page = await browser.NewPageAsync();23 /// await page.GoToAsync("https://www.google.com/chrome/browser/canary.html");24 /// dumpFrameTree(page.MainFrame, string.Empty);25 /// await browser.CloseAsync();26 /// 27 /// void dumpFrameTree(Frame frame, string indent)28 /// {29 /// Console.WriteLine(indent + frame.Url);30 /// foreach (var child in frame.ChildFrames)31 /// {32 /// dumpFrameTree(child, indent + " ");33 /// }34 /// }35 /// ]]>36 /// </code>37 /// </example>38 public class Frame39 {40 private readonly CDPSession _client;41 internal List<WaitTask> WaitTasks { get; }42 internal string Id { get; set; }43 internal string LoaderId { get; set; }44 internal List<string> LifecycleEvents { get; }45 internal string NavigationURL { get; private set; }46 internal DOMWorld MainWorld { get; }47 internal DOMWorld SecondaryWorld { get; }48 internal Frame(FrameManager frameManager, CDPSession client, Frame parentFrame, string frameId)49 {50 FrameManager = frameManager;51 _client = client;52 ParentFrame = parentFrame;53 Id = frameId;54 if (parentFrame != null)55 {56 ParentFrame.ChildFrames.Add(this);57 }58 WaitTasks = new List<WaitTask>();59 LifecycleEvents = new List<string>();60 MainWorld = new DOMWorld(FrameManager, this, FrameManager.TimeoutSettings);61 SecondaryWorld = new DOMWorld(FrameManager, this, FrameManager.TimeoutSettings);62 }63 #region Properties64 /// <summary>65 /// Gets the child frames of the this frame66 /// </summary>67 public List<Frame> ChildFrames { get; } = new List<Frame>();68 /// <summary>69 /// Gets the frame's name attribute as specified in the tag70 /// If the name is empty, returns the id attribute instead71 /// </summary>72 public string Name { get; private set; }73 /// <summary>74 /// Gets the frame's url75 /// </summary>76 public string Url { get; private set; }77 /// <summary>78 /// Gets a value indicating if the frame is detached or not79 /// </summary>80 public bool Detached { get; set; }81 /// <summary>82 /// Gets the parent frame, if any. Detached frames and main frames return <c>null</c>83 /// </summary>84 public Frame ParentFrame { get; private set; }85 internal FrameManager FrameManager { get; }86 #endregion87 #region Public Methods88 /// <summary>89 /// Navigates to an url90 /// </summary>91 /// <remarks>92 /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will throw an error if:93 /// - there's an SSL error (e.g. in case of self-signed certificates).94 /// - target URL is invalid.95 /// - the `timeout` is exceeded during navigation.96 /// - the remote server does not respond or is unreachable.97 /// - the main resource failed to load.98 /// 99 /// <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> will not throw an error when any valid HTTP status code is returned by the remote server, 100 /// including 404 "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling <see cref="Response.Status"/>101 /// 102 /// > **NOTE** <see cref="GoToAsync(string, int?, WaitUntilNavigation[])"/> either throws an error or returns a main resource response. 103 /// The only exceptions are navigation to `about:blank` or navigation to the same URL with a different hash, which would succeed and return `null`.104 /// 105 /// > **NOTE** Headless mode doesn't support navigation to a PDF document. See the <see fref="https://bugs.chromium.org/p/chromium/issues/detail?id=761295">upstream issue</see>.106 /// </remarks>107 /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>108 /// <param name="options">Navigation parameters.</param>109 /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.</returns>110 /// <seealso cref="GoToAsync(string, int?, WaitUntilNavigation[])"/>111 public Task<Response> GoToAsync(string url, NavigationOptions options) => FrameManager.NavigateFrameAsync(this, url, options);112 /// <summary>113 /// Navigates to an url114 /// </summary>115 /// <param name="url">URL to navigate page to. The url should include scheme, e.g. https://.</param>116 /// <param name="timeout">maximum navigation time in milliseconds. Defaults to 30 seconds. Pass 0117 /// to disable timeout. The default value can be changed by using the <see cref="Page.DefaultNavigationTimeout"/>118 /// property.</param>119 /// <param name="waitUntil">When to consider navigation succeeded, defaults to <see cref="WaitUntilNavigation.Load"/>. Given an array of <see cref="WaitUntilNavigation"/>, navigation is considered to be successful after all events have been fired</param>120 /// <returns>Task which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect</returns>121 public Task<Response> GoToAsync(string url, int? timeout = null, WaitUntilNavigation[] waitUntil = null)122 => GoToAsync(url, new NavigationOptions { Timeout = timeout, WaitUntil = waitUntil });123 /// <summary>124 /// This resolves when the frame navigates to a new URL or reloads.125 /// It is useful for when you run code which will indirectly cause the frame to navigate.126 /// </summary>127 /// <param name="options">navigation options</param>128 /// <returns>Task which resolves to the main resource response. 129 /// In case of multiple redirects, the navigation will resolve with the response of the last redirect.130 /// In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.131 /// </returns>132 /// <remarks>133 /// Usage of the <c>History API</c> <see href="https://developer.mozilla.org/en-US/docs/Web/API/History_API"/> to change the URL is considered a navigation134 /// </remarks>135 /// <example>136 /// <code>137 /// <![CDATA[138 /// var navigationTask =frame.page.WaitForNavigationAsync();139 /// await frame.ClickAsync("a.my-link");140 /// await navigationTask;141 /// ]]>142 /// </code>143 /// </example>144 public Task<Response> WaitForNavigationAsync(NavigationOptions options = null) => FrameManager.WaitForFrameNavigationAsync(this, options);145 /// <summary>146 /// Executes a script in browser context147 /// </summary>148 /// <param name="script">Script to be evaluated in browser context</param>149 /// <remarks>150 /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.151 /// </remarks>152 /// <returns>Task which resolves to script return value</returns>153 /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>154 /// <seealso cref="Page.EvaluateExpressionAsync{T}(string)"/>155 public Task<JToken> EvaluateExpressionAsync(string script) => MainWorld.EvaluateExpressionAsync(script);156 /// <summary>157 /// Executes a script in browser context158 /// </summary>159 /// <typeparam name="T">The type to deserialize the result to</typeparam>160 /// <param name="script">Script to be evaluated in browser context</param>161 /// <remarks>162 /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.163 /// </remarks>164 /// <returns>Task which resolves to script return value</returns>165 /// <seealso cref="EvaluateFunctionAsync{T}(string, object[])"/>166 /// <seealso cref="Page.EvaluateExpressionAsync{T}(string)"/>167 public Task<T> EvaluateExpressionAsync<T>(string script) => MainWorld.EvaluateExpressionAsync<T>(script);168 /// <summary>169 /// Executes a function in browser context170 /// </summary>171 /// <param name="script">Script to be evaluated in browser context</param>172 /// <param name="args">Arguments to pass to script</param>173 /// <remarks>174 /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.175 /// <see cref="JSHandle"/> instances can be passed as arguments176 /// </remarks>177 /// <returns>Task which resolves to script return value</returns>178 /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>179 /// <seealso cref="Page.EvaluateFunctionAsync{T}(string, object[])"/>180 public Task<JToken> EvaluateFunctionAsync(string script, params object[] args) => MainWorld.EvaluateFunctionAsync(script, args);181 /// <summary>182 /// Executes a function in browser context183 /// </summary>184 /// <typeparam name="T">The type to deserialize the result to</typeparam>185 /// <param name="script">Script to be evaluated in browser context</param>186 /// <param name="args">Arguments to pass to script</param>187 /// <remarks>188 /// If the script, returns a Promise, then the method would wait for the promise to resolve and return its value.189 /// <see cref="JSHandle"/> instances can be passed as arguments190 /// </remarks>191 /// <returns>Task which resolves to script return value</returns>192 /// <seealso cref="EvaluateExpressionAsync{T}(string)"/>193 /// <seealso cref="Page.EvaluateFunctionAsync{T}(string, object[])"/>194 public Task<T> EvaluateFunctionAsync<T>(string script, params object[] args) => MainWorld.EvaluateFunctionAsync<T>(script, args);195 /// <summary>196 /// Passes an expression to the <see cref="ExecutionContext.EvaluateExpressionHandleAsync(string)"/>, returns a <see cref="Task"/>, then <see cref="ExecutionContext.EvaluateExpressionHandleAsync(string)"/> would wait for the <see cref="Task"/> to resolve and return its value.197 /// </summary>198 /// <example>199 /// <code>200 /// var frame = page.MainFrame;201 /// const handle = Page.MainFrame.EvaluateExpressionHandleAsync("1 + 2");202 /// </code>203 /// </example>204 /// <returns>Resolves to the return value of <paramref name="script"/></returns>205 /// <param name="script">Expression to be evaluated in the <seealso cref="ExecutionContext"/></param>206 public Task<JSHandle> EvaluateExpressionHandleAsync(string script) => MainWorld.EvaluateExpressionHandleAsync(script);207 /// <summary>208 /// Passes a function to the <see cref="ExecutionContext.EvaluateFunctionAsync(string, object[])"/>, returns a <see cref="Task"/>, then <see cref="ExecutionContext.EvaluateFunctionHandleAsync(string, object[])"/> would wait for the <see cref="Task"/> to resolve and return its value.209 /// </summary>210 /// <example>211 /// <code>212 /// var frame = page.MainFrame;213 /// const handle = Page.MainFrame.EvaluateFunctionHandleAsync("() => Promise.resolve(self)");214 /// return handle; // Handle for the global object.215 /// </code>216 /// <see cref="JSHandle"/> instances can be passed as arguments to the <see cref="ExecutionContext.EvaluateFunctionAsync(string, object[])"/>:217 /// 218 /// const handle = await Page.MainFrame.EvaluateExpressionHandleAsync("document.body");219 /// const resultHandle = await Page.MainFrame.EvaluateFunctionHandleAsync("body => body.innerHTML", handle);220 /// return await resultHandle.JsonValueAsync(); // prints body's innerHTML221 /// </example>222 /// <returns>Resolves to the return value of <paramref name="function"/></returns>223 /// <param name="function">Function to be evaluated in the <see cref="ExecutionContext"/></param>224 /// <param name="args">Arguments to pass to <paramref name="function"/></param>225 public Task<JSHandle> EvaluateFunctionHandleAsync(string function, params object[] args) => MainWorld.EvaluateFunctionHandleAsync(function, args);226 /// <summary>227 /// Gets the <see cref="ExecutionContext"/> associated with the frame.228 /// </summary>229 /// <returns><see cref="ExecutionContext"/> associated with the frame.</returns>230 public Task<ExecutionContext> GetExecutionContextAsync() => MainWorld.GetExecutionContextAsync();231 /// <summary>232 /// Waits for a selector to be added to the DOM233 /// </summary>234 /// <param name="selector">A selector of an element to wait for</param>235 /// <param name="options">Optional waiting parameters</param>236 /// <returns>A task that resolves when element specified by selector string is added to DOM.237 /// Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.</returns>238 /// <seealso cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/>239 /// <seealso cref="Page.WaitForSelectorAsync(string, WaitForSelectorOptions)"/>240 /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception>241 public async Task<ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null)242 {243 var handle = await SecondaryWorld.WaitForSelectorAsync(selector, options).ConfigureAwait(false);244 if (handle == null)245 {246 return null;247 }248 var mainExecutionContext = await MainWorld.GetExecutionContextAsync().ConfigureAwait(false);249 var result = await mainExecutionContext.AdoptElementHandleASync(handle).ConfigureAwait(false);250 await handle.DisposeAsync().ConfigureAwait(false);251 return result;252 }253 /// <summary>254 /// Waits for a selector to be added to the DOM255 /// </summary>256 /// <param name="xpath">A xpath selector of an element to wait for</param>257 /// <param name="options">Optional waiting parameters</param>258 /// <returns>A task which resolves when element specified by xpath string is added to DOM. 259 /// Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM.</returns>260 /// <example>261 /// <code>262 /// <![CDATA[263 /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions());264 /// var page = await browser.NewPageAsync();265 /// string currentURL = null;266 /// page.MainFrame267 /// .WaitForXPathAsync("//img")268 /// .ContinueWith(_ => Console.WriteLine("First URL with image: " + currentURL));269 /// foreach (var current in new[] { "https://example.com", "https://google.com", "https://bbc.com" })270 /// {271 /// currentURL = current;272 /// await page.GoToAsync(currentURL);273 /// }274 /// await browser.CloseAsync();275 /// ]]>276 /// </code>277 /// </example>278 /// <seealso cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/>279 /// <seealso cref="Page.WaitForXPathAsync(string, WaitForSelectorOptions)"/>280 /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception>281 public async Task<ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null)282 {283 var handle = await SecondaryWorld.WaitForXPathAsync(xpath, options).ConfigureAwait(false);284 if (handle == null)285 {286 return null;287 }288 var mainExecutionContext = await MainWorld.GetExecutionContextAsync().ConfigureAwait(false);289 var result = await mainExecutionContext.AdoptElementHandleASync(handle).ConfigureAwait(false);290 await handle.DisposeAsync().ConfigureAwait(false);291 return result;292 }293 /// <summary>294 /// Waits for a timeout295 /// </summary>296 /// <param name="milliseconds"></param>297 /// <returns>A task that resolves when after the timeout</returns>298 /// <seealso cref="Page.WaitForTimeoutAsync(int)"/>299 /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception>300 public Task WaitForTimeoutAsync(int milliseconds) => Task.Delay(milliseconds);301 /// <summary>302 /// Waits for a function to be evaluated to a truthy value303 /// </summary>304 /// <param name="script">Function to be evaluated in browser context</param>305 /// <param name="options">Optional waiting parameters</param>306 /// <param name="args">Arguments to pass to <c>script</c></param>307 /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>308 /// <seealso cref="Page.WaitForFunctionAsync(string, WaitForFunctionOptions, object[])"/>309 /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception>310 public Task<JSHandle> WaitForFunctionAsync(string script, WaitForFunctionOptions options, params object[] args)311 => MainWorld.WaitForFunctionAsync(script, options, args);312 /// <summary>313 /// Waits for an expression to be evaluated to a truthy value314 /// </summary>315 /// <param name="script">Expression to be evaluated in browser context</param>316 /// <param name="options">Optional waiting parameters</param>317 /// <returns>A task that resolves when the <c>script</c> returns a truthy value</returns>318 /// <seealso cref="Page.WaitForExpressionAsync(string, WaitForFunctionOptions)"/>319 /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception>320 public Task<JSHandle> WaitForExpressionAsync(string script, WaitForFunctionOptions options)321 => MainWorld.WaitForExpressionAsync(script, options);322 /// <summary>323 /// Adds a <c><![CDATA[<link rel="stylesheet">]]></c> tag into the page with the desired url or a <c><![CDATA[<link rel="stylesheet">]]></c> tag with the content324 /// </summary>325 /// <param name="options">add style tag options</param>326 /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>327 /// <seealso cref="Page.AddStyleTagAsync(AddTagOptions)"/>328 /// <seealso cref="Page.AddStyleTagAsync(string)"/>329 [Obsolete("Use AddStyleTagAsync instead")]330 public Task<ElementHandle> AddStyleTag(AddTagOptions options) => MainWorld.AddStyleTagAsync(options);331 /// <summary>332 /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content333 /// </summary>334 /// <param name="options">add script tag options</param>335 /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>336 /// <seealso cref="Page.AddScriptTagAsync(AddTagOptions)"/>337 /// <seealso cref="Page.AddScriptTagAsync(string)"/>338 [Obsolete("Use AddScriptTagAsync instead")]339 public Task<ElementHandle> AddScriptTag(AddTagOptions options) => MainWorld.AddScriptTagAsync(options);340 /// <summary>341 /// Adds a <c><![CDATA[<link rel="stylesheet">]]></c> tag into the page with the desired url or a <c><![CDATA[<link rel="stylesheet">]]></c> tag with the content342 /// </summary>343 /// <param name="options">add style tag options</param>344 /// <returns>Task which resolves to the added tag when the stylesheet's onload fires or when the CSS content was injected into frame</returns>345 /// <seealso cref="Page.AddStyleTagAsync(AddTagOptions)"/>346 /// <seealso cref="Page.AddStyleTagAsync(string)"/>347 public Task<ElementHandle> AddStyleTagAsync(AddTagOptions options) => MainWorld.AddStyleTagAsync(options);348 /// <summary>349 /// Adds a <c><![CDATA[<script>]]></c> tag into the page with the desired url or content350 /// </summary>351 /// <param name="options">add script tag options</param>352 /// <returns>Task which resolves to the added tag when the script's onload fires or when the script content was injected into frame</returns>353 /// <seealso cref="Page.AddScriptTagAsync(AddTagOptions)"/>354 /// <seealso cref="Page.AddScriptTagAsync(string)"/>355 public Task<ElementHandle> AddScriptTagAsync(AddTagOptions options) => MainWorld.AddScriptTagAsync(options);356 /// <summary>357 /// Gets the full HTML contents of the page, including the doctype.358 /// </summary>359 /// <returns>Task which resolves to the HTML content.</returns>360 /// <seealso cref="Page.GetContentAsync"/>361 public Task<string> GetContentAsync() => SecondaryWorld.GetContentAsync();362 /// <summary>363 /// Sets the HTML markup to the page364 /// </summary>365 /// <param name="html">HTML markup to assign to the page.</param>366 /// <param name="options">The options</param>367 /// <returns>Task.</returns>368 /// <seealso cref="Page.SetContentAsync(string, NavigationOptions)"/>369 public Task SetContentAsync(string html, NavigationOptions options = null)370 => SecondaryWorld.SetContentAsync(html, options);371 internal void OnLoadingStopped()372 {373 LifecycleEvents.Add("DOMContentLoaded");374 LifecycleEvents.Add("load");375 }376 internal void OnLifecycleEvent(string loaderId, string name)377 {378 if (name == "init")379 {380 LoaderId = loaderId;381 LifecycleEvents.Clear();382 }383 LifecycleEvents.Add(name);384 }385 internal void Navigated(FramePayload framePayload)386 {387 Name = framePayload.Name ?? string.Empty;388 NavigationURL = framePayload.Url;389 Url = framePayload.Url;390 }391 internal void NavigatedWithinDocument(string url) => Url = url;392 internal void Detach()393 {394 Detached = true;395 MainWorld.Detach();396 SecondaryWorld.Detach();397 if (ParentFrame != null)398 {399 ParentFrame.ChildFrames.Remove(this);400 }401 ParentFrame = null;402 }403 #endregion404 }405}...
FrameManager.cs
Source:FrameManager.cs
...30 Client.MessageReceived += Client_MessageReceived;31 }32 #region Properties33 internal event EventHandler<FrameEventArgs> FrameAttached;34 internal event EventHandler<FrameEventArgs> FrameDetached;35 internal event EventHandler<FrameEventArgs> FrameNavigated;36 internal event EventHandler<FrameEventArgs> FrameNavigatedWithinDocument;37 internal event EventHandler<FrameEventArgs> LifecycleEvent;38 internal CDPSession Client { get; }39 internal NetworkManager NetworkManager { get; }40 internal Frame MainFrame { get; set; }41 internal Page Page { get; }42 internal TimeoutSettings TimeoutSettings { get; }43 #endregion44 #region Public Methods45 internal static async Task<FrameManager> CreateFrameManagerAsync(46 CDPSession client,47 Page page,48 bool ignoreHTTPSErrors,49 TimeoutSettings timeoutSettings)50 {51 var frameManager = new FrameManager(client, page, ignoreHTTPSErrors, timeoutSettings);52 var getFrameTreeTask = client.SendAsync<PageGetFrameTreeResponse>("Page.getFrameTree");53 await Task.WhenAll(54 client.SendAsync("Page.enable"),55 getFrameTreeTask).ConfigureAwait(false);56 await frameManager.HandleFrameTreeAsync(new FrameTree(getFrameTreeTask.Result.FrameTree)).ConfigureAwait(false);57 await Task.WhenAll(58 client.SendAsync("Page.setLifecycleEventsEnabled", new PageSetLifecycleEventsEnabledRequest { Enabled = true }),59 client.SendAsync("Runtime.enable"),60 frameManager.NetworkManager.InitializeAsync()).ConfigureAwait(false);61 await frameManager.EnsureIsolatedWorldAsync().ConfigureAwait(false);62 return frameManager;63 }64 internal ExecutionContext ExecutionContextById(int contextId)65 {66 _contextIdToContext.TryGetValue(contextId, out var context);67 return context;68 }69 public async Task<Response> NavigateFrameAsync(Frame frame, string url, NavigationOptions options)70 {71 var referrer = string.IsNullOrEmpty(options.Referer)72 ? NetworkManager.ExtraHTTPHeaders?.GetValueOrDefault(RefererHeaderName)73 : options.Referer;74 var requests = new Dictionary<string, Request>();75 var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;76 using (var watcher = new LifecycleWatcher(this, frame, options?.WaitUntil, timeout))77 {78 try79 {80 var navigateTask = NavigateAsync(Client, url, referrer, frame.Id);81 var task = await Task.WhenAny(82 watcher.TimeoutOrTerminationTask,83 navigateTask).ConfigureAwait(false);84 await task.ConfigureAwait(false);85 task = await Task.WhenAny(86 watcher.TimeoutOrTerminationTask,87 _ensureNewDocumentNavigation ? watcher.NewDocumentNavigationTask : watcher.SameDocumentNavigationTask)88 .ConfigureAwait(false);89 await task.ConfigureAwait(false);90 }91 catch (Exception ex)92 {93 throw new NavigationException(ex.Message, ex);94 }95 return watcher.NavigationResponse;96 }97 }98 private async Task NavigateAsync(CDPSession client, string url, string referrer, string frameId)99 {100 var response = await client.SendAsync<PageNavigateResponse>("Page.navigate", new PageNavigateRequest101 {102 Url = url,103 Referrer = referrer ?? string.Empty,104 FrameId = frameId105 }).ConfigureAwait(false);106 _ensureNewDocumentNavigation = !string.IsNullOrEmpty(response.LoaderId);107 if (!string.IsNullOrEmpty(response.ErrorText))108 {109 throw new NavigationException(response.ErrorText, url);110 }111 }112 public async Task<Response> WaitForFrameNavigationAsync(Frame frame, NavigationOptions options = null)113 {114 var timeout = options?.Timeout ?? TimeoutSettings.NavigationTimeout;115 using (var watcher = new LifecycleWatcher(this, frame, options?.WaitUntil, timeout))116 {117 var raceTask = await Task.WhenAny(118 watcher.NewDocumentNavigationTask,119 watcher.SameDocumentNavigationTask,120 watcher.TimeoutOrTerminationTask121 ).ConfigureAwait(false);122 await raceTask.ConfigureAwait(false);123 return watcher.NavigationResponse;124 }125 }126 #endregion127 #region Private Methods128 private async void Client_MessageReceived(object sender, MessageEventArgs e)129 {130 try131 {132 switch (e.MessageID)133 {134 case "Page.frameAttached":135 OnFrameAttached(e.MessageData.ToObject<PageFrameAttachedResponse>());136 break;137 case "Page.frameNavigated":138 await OnFrameNavigatedAsync(e.MessageData.ToObject<PageFrameNavigatedResponse>(true).Frame).ConfigureAwait(false);139 break;140 case "Page.navigatedWithinDocument":141 OnFrameNavigatedWithinDocument(e.MessageData.ToObject<NavigatedWithinDocumentResponse>(true));142 break;143 case "Page.frameDetached":144 OnFrameDetached(e.MessageData.ToObject<BasicFrameResponse>(true));145 break;146 case "Page.frameStoppedLoading":147 OnFrameStoppedLoading(e.MessageData.ToObject<BasicFrameResponse>(true));148 break;149 case "Runtime.executionContextCreated":150 await OnExecutionContextCreatedAsync(e.MessageData.ToObject<RuntimeExecutionContextCreatedResponse>(true).Context).ConfigureAwait(false);151 break;152 case "Runtime.executionContextDestroyed":153 OnExecutionContextDestroyed(e.MessageData.ToObject<RuntimeExecutionContextDestroyedResponse>(true).ExecutionContextId);154 break;155 case "Runtime.executionContextsCleared":156 OnExecutionContextsCleared();157 break;158 case "Page.lifecycleEvent":159 OnLifeCycleEvent(e.MessageData.ToObject<LifecycleEventResponse>(true));160 break;161 default:162 break;163 }164 }165 catch (Exception ex)166 {167 var message = $"Connection failed to process {e.MessageID}. {ex.Message}. {ex.StackTrace}";168 Client.Close(message);169 }170 }171 private void OnFrameStoppedLoading(BasicFrameResponse e)172 {173 if (_frames.TryGetValue(e.FrameId, out var frame))174 {175 frame.OnLoadingStopped();176 LifecycleEvent?.Invoke(this, new FrameEventArgs(frame));177 }178 }179 private void OnLifeCycleEvent(LifecycleEventResponse e)180 {181 if (_frames.TryGetValue(e.FrameId, out var frame))182 {183 frame.OnLifecycleEvent(e.LoaderId, e.Name);184 LifecycleEvent?.Invoke(this, new FrameEventArgs(frame));185 }186 }187 private void OnExecutionContextsCleared()188 {189 while (_contextIdToContext.Count > 0)190 {191 var contextItem = _contextIdToContext.ElementAt(0);192 _contextIdToContext.Remove(contextItem.Key);193 if (contextItem.Value.World != null)194 {195 contextItem.Value.World.SetContext(null);196 }197 }198 }199 private void OnExecutionContextDestroyed(int executionContextId)200 {201 _contextIdToContext.TryGetValue(executionContextId, out var context);202 if (context != null)203 {204 _contextIdToContext.Remove(executionContextId);205 if (context.World != null)206 {207 context.World.SetContext(null);208 }209 }210 }211 private async Task OnExecutionContextCreatedAsync(ContextPayload contextPayload)212 {213 var frameId = contextPayload.AuxData?.FrameId;214 var frame = !string.IsNullOrEmpty(frameId) ? await GetFrameAsync(frameId).ConfigureAwait(false) : null;215 DOMWorld world = null;216 if (frame != null)217 {218 if (contextPayload.AuxData?.IsDefault == true)219 {220 world = frame.MainWorld;221 }222 else if (contextPayload.Name == UtilityWorldName && !frame.SecondaryWorld.HasContext)223 {224 // In case of multiple sessions to the same target, there's a race between225 // connections so we might end up creating multiple isolated worlds.226 // We can use either.227 world = frame.SecondaryWorld;228 }229 }230 if (contextPayload.AuxData?.Type == DOMWorldType.Isolated)231 {232 _isolatedWorlds.Add(contextPayload.Name);233 }234 var context = new ExecutionContext(Client, contextPayload, world);235 if (world != null)236 {237 world.SetContext(context);238 }239 _contextIdToContext[contextPayload.Id] = context;240 }241 private void OnFrameDetached(BasicFrameResponse e)242 {243 if (_frames.TryGetValue(e.FrameId, out var frame))244 {245 RemoveFramesRecursively(frame);246 }247 }248 private async Task OnFrameNavigatedAsync(FramePayload framePayload)249 {250 var isMainFrame = string.IsNullOrEmpty(framePayload.ParentId);251 var frame = isMainFrame ? MainFrame : await GetFrameAsync(framePayload.Id).ConfigureAwait(false);252 Contract.Assert(isMainFrame || frame != null, "We either navigate top level or have old version of the navigated frame");253 // Detach all child frames first.254 if (frame != null)255 {256 while (frame.ChildFrames.Count > 0)257 {258 RemoveFramesRecursively(frame.ChildFrames[0]);259 }260 }261 // Update or create main frame.262 if (isMainFrame)263 {264 if (frame != null)265 {266 // Update frame id to retain frame identity on cross-process navigation.267 if (frame.Id != null)268 {269 _frames.TryRemove(frame.Id, out _);270 }271 frame.Id = framePayload.Id;272 }273 else274 {275 // Initial main frame navigation.276 frame = new Frame(this, Client, null, framePayload.Id);277 }278 _asyncFrames.AddItem(framePayload.Id, frame);279 MainFrame = frame;280 }281 // Update frame payload.282 frame.Navigated(framePayload);283 FrameNavigated?.Invoke(this, new FrameEventArgs(frame));284 }285 internal Frame[] GetFrames() => _frames.Values.ToArray();286 private void OnFrameNavigatedWithinDocument(NavigatedWithinDocumentResponse e)287 {288 if (_frames.TryGetValue(e.FrameId, out var frame))289 {290 frame.NavigatedWithinDocument(e.Url);291 var eventArgs = new FrameEventArgs(frame);292 FrameNavigatedWithinDocument?.Invoke(this, eventArgs);293 FrameNavigated?.Invoke(this, eventArgs);294 }295 }296 private void RemoveFramesRecursively(Frame frame)297 {298 while (frame.ChildFrames.Count > 0)299 {300 RemoveFramesRecursively(frame.ChildFrames[0]);301 }302 frame.Detach();303 _frames.TryRemove(frame.Id, out _);304 FrameDetached?.Invoke(this, new FrameEventArgs(frame));305 }306 private void OnFrameAttached(PageFrameAttachedResponse frameAttached)307 => OnFrameAttached(frameAttached.FrameId, frameAttached.ParentFrameId);308 private void OnFrameAttached(string frameId, string parentFrameId)309 {310 if (!_frames.ContainsKey(frameId) && _frames.ContainsKey(parentFrameId))311 {312 var parentFrame = _frames[parentFrameId];313 var frame = new Frame(this, Client, parentFrame, frameId);314 _frames[frame.Id] = frame;315 FrameAttached?.Invoke(this, new FrameEventArgs(frame));316 }317 }318 private async Task HandleFrameTreeAsync(FrameTree frameTree)...
DOMWorld.cs
Source:DOMWorld.cs
...39 _contextResolveTaskWrapper = new TaskCompletionSource<ExecutionContext>();40 }41 }42 internal bool HasContext => _contextResolveTaskWrapper?.Task.IsCompleted == true;43 internal void Detach()44 {45 _detached = true;46 while (WaitTasks.Count > 0)47 {48 WaitTasks[0].Terminate(new Exception("waitForFunction failed: frame got detached."));49 }50 }51 internal Task<ExecutionContext> GetExecutionContextAsync()52 {53 if (_detached)54 {55 throw new PuppeteerException($"Execution Context is not available in detached frame \"{Frame.Url}\"(are you trying to evaluate?)");56 }57 return _contextResolveTaskWrapper.Task;...
Detach
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(@"() => {13 const div = document.createElement('div');14 div.textContent = 'Hello, world!';15 document.body.appendChild(div);16 }");17 var world = page.MainFrame.GetWorld();18 await world.DetachAsync();19 await page.EvaluateFunctionAsync(@"() => {20 const div = document.createElement('div');21 div.textContent = 'Hello, world!';22 docment.body.appendChild(div);23 }");24 await browser.CloseAsync();25 }26 }27}
Detach
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(@"() => {13 const div = document.createElement('div');14 div.textContent = 'Hello, world!';15 document.body.appendChild(div);16 }");17 var world = page.MainFrame.GetWorld();18 await world.DetachAsync();19 await page.EvaluateFunctionAsync(@"() => {20 const div = document.createElement('div');21 div.textContent = 'Hello, world!';22 document.body.appendChild(div);23 }");24 await browser.CloseAsync();25 }26 }27}
Detach
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5 {6 static async Task Main(string[] args)7 {8 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);9 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });10 var page = await browser.NewPageAsync();11 Console.WriteLine("Press any key to continue...");12 Console.ReadKey();13 await page.CloseAsync();14 await browser.CloseAsync();15 } Browser
Detach
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5 {6 static async Task Main(string[] args)7 {8 {9 };10 await new BrowserFetcher().DownloadAsync(rowseFetcher.DefaultRevisin);11 var bro = await Puppeteer.LaunchAsync(options);12 var page = await browser.NewPageAsync(); }13 await page.SetViewportAsync(new ViewPortOptions { Width } 1920, Height 1080 });14 await page.WaitForSelectorAsync("input.gLFyf.gsfi");15 await page.TypeAsync("input.gLFyf.gsfi", "PuppeteerSharp");16 await page.ClickAsync("input.gNO89b");17 await page.WaitForSelectorAsync("div#search");18 var world await page.MainFrame.GetWorldAsync();19 var handle await page.EvaluateHandleAsync("document.querySelector('div#search')");20 await world.DetachAsync(handle);21 await page.WaitForTimeoutAsync(2000);22 await browser.CloseAsync();23 }24 }25}26Here is the code to use the Detach() method of the PuppeteerSharp.DOMWorld class:27using System;28using System.Threading.Tasks;29using PuppeteerSharp;30{31 {32 static async Task Main(string[] args)33 {34 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);35 var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });36 var page = await browser.NewPageAsync();37 Console.WriteLine("Press any key to continue...");38 Console.ReadKey();39 await page.DetachAsync();40 await browser.CloseAsync();41 }42 }43}
Detach
Using AI Code Generation
1using PuppeteerSharp;2using System;3using System.Threading.Tasks;4{5 {6 static void Main(string[] args)7 {8 MainAsync().GetAwaiter().GetResult();9 }10 static async Task MainAsync()11 {12 var browser = await Puppeteer.LaunchAsync(new LaunchOptions13 {14 });15 var page = await browser.NewPageAsync();16 var frame = page.MainFrame;17 var world = frame.GetWorld();18 var document = await world.GetDocumentAsync();19 var body = await document.QuerySelectorAsync("body");20 var div = await document.CreateElementAsync("div");21 await div.SetContentAsync("Some text");22 await body.AppendChildAsync(div);23 await page.ScreenshotAsync("screenshot.png");24 await world.DetachAsync();25 await page.ScreenshotAsync("screenshot2.png");26 await browser.CloseAsync();27 }28 }29}
Detach
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 static async Task Main(string[] args)10 {11 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);12 var browser = await Puppeteer.LaunchAsync(new LaunchOptions13 {14 });15 var page = await browser.NewPageAsync();16 var world = page.MainFrame.GetWorld();17 await world.DetachAsync();18 await page.EvaluateExpressionAsync("document.body.appendChild(document.createTextNode('This is added by Puppeteer!'))");19 await page.ScreenshotAsync("2.png");20 await browser.CloseAsync();21 }22 }23}24using System;25using System.Collections.Generic;26using System.Linq;27using System.Text;28using System.Threading.Tasks;29using PuppeteerSharp;30{31 {32 static async Task Main(string[] args)33 {34 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);35 var browser = await Puppeteer.LaunchAsync(new LaunchOptions36 {37 });38 var page = await browser.NewPageAsync();39 var world = page.MainFrame.GetWorld();40 await world.EvaluateHandleAsync("() => document.body.appendChild(document.createTextNode('This is added by Puppeteer!'))");41 await page.ScreenshotAsync("3.png");42 await browser.CloseAsync();43 }44 }45}
Detach
Using AI Code Generation
1var page = await browser.NewPageAsync();2var elementHandle = await page.QuerySelectorAsync("input[name=\"q\"]");3await elementHandle.TypeAsync("PuppeteerSharp");4await elementHandle.PressAsync("Enter");5await page.WaitForNavigationAsync();6var results = await page.QuerySelectorAllAsync("h3.LC20lb");7foreach (var result in results)8{9 Console.WriteLine(await result.EvaluateFunctionAsync<string>("node => node.textContent"));10}11await page.CloseAsync();12var page = await browser.NewPageAsync();13var elementHandle = await page.QuerySelectorAsync("input[name=\"q\"]");14await elementHandle.TypeAsync("PuppeteerSharp");15await elementHandle.PressAsync("Enter");16await page.WaitForNavigationAsync();17var results = await page.QuerySelectorAllAsync("h3.LC20lb");18foreach (var result in results)19{20 Console.WriteLine(await result.EvaluateFunctionAsync<string>("node => node.textContent"));21}22await page.CloseAsync();23var page = await browser.NewPageAsync();24var elementHandle = await page.QuerySelectorAsync("input[name=\"q\"]");25await elementHandle.TypeAsync("PuppeteerSharp");26await elementHandle.PressAsync("Enter");27await page.WaitForNavigationAsync();28var results = await page.QuerySelectorAllAsync("h3.LC20lb");29foreach (var result in results)30{31 Console.WriteLine(await result.EvaluateFunctionAsync<string>("node => node.textContent"));32}33await page.CloseAsync();34var page = await browser.NewPageAsync();35var elementHandle = await page.QuerySelectorAsync("input[name=\"q\"]");36await elementHandle.TypeAsync("PuppeteerSharp");37await elementHandle.PressAsync("Enter");38await page.WaitForNavigationAsync();39var results = await page.QuerySelectorAllAsync("h3.LC20lb");40foreach (var result in results)41{42 Console.WriteLine(await result.EvaluateFunctionAsync<string>("node => node.textContent"));43}
Detach
Using AI Code Generation
1var page = await browser.NewPageAsync();2var world = await page.MainFrame.GetWorldAsync();3var document = await world.GetDocumentAsync();4var body = await document.QuerySelectorAsync("body");5await body.DetachAsync();6var page = await browser.NewPageAsync();7var body = await page.QuerySelectorAsync("body");8await body.DetachAsync();
Detach
Using AI Code Generation
1using System.Threading.Tasks;2using PuppeteerSharp;3{4 {5 statir async Task Main(string[] args)6 {7 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);8 using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions9 {10 }))11 {12 var page = await browser.NewPageAsync();13 await page.ScreenshotAsync("google.png");14 var frame = await page.QuerySelectorAsync("iframe");15 await frame.DetachAsync();16 await Task.Delay(3000);17 }18 }19 }20}21In the above code, we have used the Detach method of the PuppeteerSharp.DOMWorld class to detach a frame from the page. page = await browser.NewPageAsync();22var frame = page.MainFrame;23await frame.DetachAsync();24var page = await browser.NewPageAsync();25await page.DetachAsync();26var page = await browser.NewPageAsync();27var target = page.Target;28await target.DetachAsync();29var page = await browser.NewPageAsync();30await browser.DetachAsync();31var page = await browser.NewPageAsync();32var connection = browser.Connection;33await connection.DetachAsync();34var page = await browser.NewPageAsync();35var session = page.Session;36await session.DetachAsync();37var page = await browser.NewPageAsync();38await page.ClickAsync("button");39var dialog = page.Dialog;
Detach
Using AI Code Generation
1using System.Threading.Tasks;2using PuppeteerSharp;3{4 {5 static async Task Main(string[] args)6 {7 await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultRevision);8 using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions9 {10 }))11 {12 var page = await browser.NewPageAsync();13 await page.ScreenshotAsync("google.png");14 var frame = await page.QuerySelectorAsync("iframe");15 await frame.DetachAsync();16 await Task.Delay(3000);17 }18 }19 }20}
Detach
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using PuppeteerSharp;4{5 {6 static void Main(string[] args)7 {8 MainAsync().Wait();9 }10 static async Task MainAsync()11 {12 using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false }))13 using (var page = await browser.NewPageAsync())14 {15 await page.EvaluateExpressionAsync(@"() => {16 const frame = document.createElement('iframe');17 document.body.appendChild(frame);18 return new Promise(x => frame.onload = x);19 }");20 await page.WaitForSelectorAsync("iframe");21 var frame = page.Frames[1];22 await frame.DetachAsync();23 await page.EvaluateFunctionAsync(@"() => {24 document.querySelector('iframe').remove();25 }");26 }27 }28 }29}
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!!