/// <summary> /// Waits for a selector to be added to the DOM /// </summary> /// <param name="xpath">A xpath selector of an element to wait for</param> /// <param name="options">Optional waiting parameters</param> /// <returns>A task which resolves when element specified by xpath string is added to DOM. /// Resolves to `null` if waiting for `hidden: true` and xpath is not found in DOM.</returns> /// <example> /// <code> /// <![CDATA[ /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions()); /// var page = await browser.NewPageAsync(); /// string currentURL = null; /// page.MainFrame /// .WaitForXPathAsync("//img") /// .ContinueWith(_ => Console.WriteLine("First URL with image: " + currentURL)); /// foreach (var current in new[] { "https://example.com", "https://google.com", "https://bbc.com" }) /// { /// currentURL = current; /// await page.GoToAsync(currentURL); /// } /// await browser.CloseAsync(); /// ]]> /// </code> /// </example> /// <seealso cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/> /// <seealso cref="Page.WaitForXPathAsync(string, WaitForSelectorOptions)"/> /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception> public async Task <ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null) { var handle = await SecondaryWorld.WaitForXPathAsync(xpath, options).ConfigureAwait(false); if (handle == null) { return(null); } var mainExecutionContext = await MainWorld.GetExecutionContextAsync().ConfigureAwait(false); var result = await mainExecutionContext.AdoptElementHandleASync(handle).ConfigureAwait(false); await handle.DisposeAsync().ConfigureAwait(false); return(result); }
private async Task <ElementHandle> WaitForSelectorOrXPathAsync(string selectorOrXPath, bool isXPath, WaitForSelectorOptions options = null) { options = options ?? new WaitForSelectorOptions(); const string predicate = @" function predicate(selectorOrXPath, isXPath, waitForVisible, waitForHidden) { const node = isXPath ? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue : document.querySelector(selectorOrXPath); if (!node) return waitForHidden; if (!waitForVisible && !waitForHidden) return node; const element = node.nodeType === Node.TEXT_NODE ? node.parentElement : node; const style = window.getComputedStyle(element); const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox(); const success = (waitForVisible === isVisible || waitForHidden === !isVisible); return success ? node : null; function hasVisibleBoundingBox() { const rect = element.getBoundingClientRect(); return !!(rect.top || rect.bottom || rect.width || rect.height); } }"; var polling = options.Visible || options.Hidden ? WaitForFunctionPollingOption.Raf : WaitForFunctionPollingOption.Mutation; var handle = await new WaitTask( this, predicate, false, $"{(isXPath ? "XPath" : "selector")} '{selectorOrXPath}'{(options.Hidden ? " to be hidden" : "")}", polling, null, options.Timeout, new object[] { selectorOrXPath, isXPath, options.Visible, options.Hidden }).Task.ConfigureAwait(false); if (!(handle is ElementHandle elementHandle)) { await handle?.DisposeAsync(); return(null); } return(elementHandle); }
internal Task <ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null) => WaitForSelectorOrXPathAsync(xpath, true, options);
internal Task <ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null) => WaitForSelectorOrXPathAsync(selector, false, options);
/// <summary> /// Waits for a selector to be added to the DOM /// </summary> /// <param name="xpath">A xpath selector of an element to wait for</param> /// <param name="options">Optional waiting parameters</param> /// <returns>A task that resolves when element specified by selector string is added to DOM</returns> /// <example> /// <code> /// <![CDATA[ /// var browser = await Puppeteer.LaunchAsync(new LaunchOptions()); /// var page = await browser.NewPageAsync(); /// string currentURL = null; /// page.MainFrame /// .WaitForXPathAsync("//img") /// .ContinueWith(_ => Console.WriteLine("First URL with image: " + currentURL)); /// foreach (var current in new[] { "https://example.com", "https://google.com", "https://bbc.com" }) /// { /// currentURL = current; /// await page.GoToAsync(currentURL); /// } /// await browser.CloseAsync(); /// ]]> /// </code> /// </example> /// <seealso cref="WaitForSelectorAsync(string, WaitForSelectorOptions)"/> /// <seealso cref="Page.WaitForXPathAsync(string, WaitForSelectorOptions)"/> /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception> public Task <ElementHandle> WaitForXPathAsync(string xpath, WaitForSelectorOptions options = null) => _mainWorld.WaitForXPathAsync(xpath, options);
/// <summary> /// Waits for a selector to be added to the DOM /// </summary> /// <param name="selector">A selector of an element to wait for</param> /// <param name="options">Optional waiting parameters</param> /// <returns>A task that resolves when element specified by selector string is added to DOM</returns> /// <seealso cref="WaitForXPathAsync(string, WaitForSelectorOptions)"/> /// <seealso cref="Page.WaitForSelectorAsync(string, WaitForSelectorOptions)"/> /// <exception cref="WaitTaskTimeoutException">If timeout occurred.</exception> public Task <ElementHandle> WaitForSelectorAsync(string selector, WaitForSelectorOptions options = null) => _mainWorld.WaitForSelectorAsync(selector, options);
internal async Task <ElementHandle> WaitForSelectorOrXPathAsync(string selectorOrXPath, bool isXPath, WaitForSelectorOptions options = null) { options = options ?? new WaitForSelectorOptions(); const string predicate = @" function predicate(selectorOrXPath, isXPath, waitForVisible, waitForHidden) { const node = isXPath ? document.evaluate(selectorOrXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue : document.querySelector(selectorOrXPath); if (!node) return waitForHidden; if (!waitForVisible && !waitForHidden) return node; const element = node.nodeType === Node.TEXT_NODE ? node.parentElement : node; const style = window.getComputedStyle(element); const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox(); const success = (waitForVisible === isVisible || waitForHidden === !isVisible); return success ? node : null; function hasVisibleBoundingBox() { const rect = element.getBoundingClientRect(); return !!(rect.top || rect.bottom || rect.width || rect.height); } }"; var polling = options.Visible || options.Hidden ? WaitForFunctionPollingOption.Raf : WaitForFunctionPollingOption.Mutation; var handle = await WaitForFunctionAsync(predicate, new WaitForFunctionOptions { Timeout = options.Timeout, Polling = polling }, selectorOrXPath, isXPath, options.Visible, options.Hidden); return(handle as ElementHandle); }