question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add ElementHandle.WaitForSelectorAsync()

See original GitHub issue

Hello. Could we add WaitForSelectorAsync for ElementHandle There are few reasons for such functionality

  1. Performance. There is no reason to query whole document if we can query only subset
  2. And when you have multiple similar nodes and you want to monitor one certain node, and there is no way to do this.

Currently I have second issue. And here is how I solve it with extension method. I used reflection because WaitTask is internal


public static Task<ElementHandle> WaitForSelectorAsync(this ElementHandle element, string selector, WaitForSelectorOptions options = null)
            => WaitForSelectorOrXPathAsync(element, selector, false, options);
public static Task<ElementHandle> WaitForXPathAsync(this ElementHandle element, string xpath, WaitForSelectorOptions options = null)
            => WaitForSelectorOrXPathAsync(element, xpath, true, options);

public static async Task<ElementHandle> WaitForSelectorOrXPathAsync(this ElementHandle element, string selectorOrXPath, bool isXPath, WaitForSelectorOptions options = null)
        {
            options = options ?? new WaitForSelectorOptions();
            const string predicate = @"
              function predicate(rootElement,selectorOrXPath, isXPath, waitForVisible, waitForHidden) {
                const node = isXPath
                  ? rootElement.evaluate(selectorOrXPath, rootElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
                  : rootElement.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 type = typeof(WaitForFunctionPollingOption).Assembly.GetType("PuppeteerSharp.WaitTask");
            var consturtor= type.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)[0];
           var waitTask = consturtor.Invoke(new object[]
           {
               element.ExecutionContext.Frame,
               predicate,
               false,
               $"{(isXPath ? "XPath" : "selector")} '{selectorOrXPath}'{(options.Hidden ? " to be hidden" : "")}",
               options.Polling,
               options.PollingInterval,
               options.Timeout,
               new object[]
               {
                   element,
                   selectorOrXPath,
                   isXPath,
                   options.Visible,
                   options.Hidden
               }
           });
           var p = type.GetProperty("Task", BindingFlags.Instance | BindingFlags.NonPublic);

          Task<JSHandle> t=  (Task<JSHandle>) p.GetValue(waitTask);
          JSHandle handle = await  t.ConfigureAwait(false);

            return handle as ElementHandle;
        }

There is only few changes.

========================== Also please explain me what this line do var polling = options.Visible || options.Hidden ? WaitForFunctionPollingOption.Raf : WaitForFunctionPollingOption.Mutation;

I can see that no one use variable ‘polling’

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
Gdocalcommented, Feb 2, 2019

@kblok I would appreciate if you can do it

1reaction
kblokcommented, Feb 2, 2019

Our bad on the Polling code. I don’t want to add here any API which is not on Puppeteer.

I think you could add that feature on https://github.com/hlaueriksson/puppeteer-sharp-contrib

cc @hlaueriksson

Read more comments on GitHub >

github_iconTop Results From Across the Web

puppeteer: how to wait until an element is visible?
click() // I want to do something like that waitElemenentVisble('.btnNext ') const btnNext = await page.$('.btnNext'); await btnNext.click ...
Read more >
ElementHandle
ElementHandle prevents DOM element from garbage collection unless the handle is ... eval() would wait for the promise to resolve and return its...
Read more >
Use PuppeteerSharp.Page.WaitForSelectorAsync in ...
Use the WaitForSelectorAsync method in PuppeteerSharp package in your next Puppeteer-sharp project with LambdaTest Automation Testing Advisor.
Read more >
ElementHandle | Playwright .NET
ElementHandle represents an in-page DOM element. ElementHandles can be created with the Page.QuerySelectorAsync() method. Discouraged.
Read more >
Use PuppeteerSharp.ElementHandle.ClickAsync in ...
Use the ClickAsync method in PuppeteerSharp package in your next Puppeteer-sharp project with LambdaTest Automation Testing Advisor.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found