Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable filtering visible nodes as an option #636

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Enable filtering visible nodes as an option #636

wants to merge 1 commit into from

Conversation

karelbilek
Copy link
Contributor

@karelbilek karelbilek commented May 29, 2020

Currently, we cannot tell ChromeDP to select all visible nodes without
waiting for them.

If one calls

NodeIDs(selector, WaitVisible, AtLeast(0))

chromeDP selects all nodes with the selector and then wait for them to be visible.
This might hang if it never happens and the node keeps being hidden.

With this PR, we can do

NodeIDs(selector, FilterVisible, AtLeast(0))

However, the following will still hang, since the waiting is done before the filtering;
as we need the nodes to be at least ready to filter them. I think it's OK,
but it might be confusing.

NodeIDs(selector, WaitVisible, FilterVisible, AtLeast(0))

@karelbilek
Copy link
Contributor Author

Creating this as a draft, since I haven't finished the documentation; if you think this approach is fine, I will add it

Currently, we cannot tell ChromeDP to select all visible nodes without
waiting for them.

If one calls
```
NodeIDs(selector, WaitVisible, AtLeast(0))
```

chromeDP selects all nodes with the selector and then wait for them to be visible.
This might hang if it never happens and the node keeps being hidden.

With this PR, we can do
```
NodeIDs(selector, FilterVisible, AtLeast(0))
```

However, the following will still hang, since the waiting is done before the filtering;
as we need the nodes to be at least ready to filter them. I think it's OK,
but it might be confusing.

```
NodeIDs(selector, WaitVisible, FilterVisible, AtLeast(0))
```
@karelbilek
Copy link
Contributor Author

One way to fix the confusing issue that I wrote below is to have two waiting functions; one NodeReady that will be called always and not user settable, and one other that is user settable, and run after filtering.

@@ -34,6 +34,7 @@ type Selector struct {
by func(context.Context, *cdp.Node) ([]cdp.NodeID, error)
wait func(context.Context, *cdp.Frame, ...cdp.NodeID) ([]*cdp.Node, error)
after func(context.Context, ...*cdp.Node) error
filter func(context.Context, *cdp.Node) (bool, error)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this before wait

@@ -277,6 +296,12 @@ func ByFunc(f func(context.Context, *cdp.Node) ([]cdp.NodeID, error)) QueryOptio
}
}

func FilterFunc(f func(context.Context, *cdp.Node) (bool, error)) QueryOption {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs docs

@@ -194,6 +195,24 @@ func (s *Selector) Do(ctx context.Context) error {
if nodes == nil || err != nil {
continue
}

if s.filter != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, we should think about moving this before "wait" in the future, but that would require an API-breaking refactor. because, ideally, the steps would be:

nodes, err := s.findNodes(...)
if nodes == nil || err != nil { continue }

if s.filter != nil { ... }
if s.wait != nil { ... }
if s.after != nil { ... }

This is useful, because imagine if you wanted to do FilterVisible, NodeEnabled to find all text inputs which are visible, then wait for them to be enabled (so that you can type into them). The order here is very important; with the current order, if there is a non-visible element which is disabled, you would first wait for it to be enabled, so you would block forever before the filter does its thing.

We don't have to do this change here, but I would add a TODO.

@@ -0,0 +1,38 @@
package chromedp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file is tiny, I would not add it. just add the funcs elsewhere like util.go, even though I hate that name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are small files a problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants