-
Notifications
You must be signed in to change notification settings - Fork 41
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
Fix Locator.WaitFor for detached
and hidden
states
#852
Conversation
detached
and hidden
statesdetached
and hidden
states
detached
and hidden
statesdetached
and hidden
states
d9ce0fd
to
257bc98
Compare
Some things to consider:
|
Thanks for explaining your thought process on coming to the current implementation.
Agreed.
Agreed. Is this something that we can tackle now or maybe best suited for another PR?
This is a tricky situation if we try to work with the current methods we have. Since func (f *Frame) waitFor(selector string, opts *FrameWaitForSelectorOptions) (error) {
f.log.Debugf("Frame:waitFor", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
document, err := f.document()
if err != nil {
return err
}
_, err = document.waitForSelector(f.ctx, selector, opts)
if err != nil {
return err
}
return nil
} It is duplicating some of the functionality but in this case it feel like a safer option which is more maintainable, with less behavioural changes than if we extend the current |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done! Thanks for adding the succinct commit messages which helped explain the change.
My only feedback is on what i've already commented on regarding whether to extend the waitForSelector
to add a new behaviour. If possible, it would be good to separate the behaviour for waitFor
so that it's clear that it doesn't require the elementHandle
.
If you mean deleting this line specifically from the
It can make sense, although we would have the same situation in See the following diff for the changes to apply from this PRs current version: diffdiff --git a/common/frame.go b/common/frame.go
index 0f36a2d..a857b6a 100644
--- a/common/frame.go
+++ b/common/frame.go
@@ -467,13 +467,7 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio
return nil, err
}
if handle == nil {
- // Handle can be nil only for selectors waiting for 'detached' state,
- // as there is no longer an ElementHandle representing that element
- // in the DOM. Otherwise return error.
- if opts.State != DOMElementStateDetached {
- return nil, fmt.Errorf("waiting for selector %q did not result in any nodes", selector)
- }
- return nil, nil //nolint:nilnil
+ return nil, fmt.Errorf("waiting for selector %q did not result in any nodes", selector)
}
// We always return ElementHandles in the main execution context (aka "DOM world")
@@ -496,6 +490,18 @@ func (f *Frame) waitForSelector(selector string, opts *FrameWaitForSelectorOptio
return handle, nil
}
+func (f *Frame) waitFor(selector string, opts *FrameWaitForSelectorOptions) error {
+ f.log.Debugf("Frame:waitFor", "fid:%s furl:%q sel:%q", f.ID(), f.URL(), selector)
+
+ document, err := f.document()
+ if err != nil {
+ return err
+ }
+
+ _, err = document.waitForSelector(f.ctx, selector, opts)
+ return err
+}
+
// AddScriptTag is not implemented.
func (f *Frame) AddScriptTag(opts goja.Value) {
k6ext.Panic(f.ctx, "Frame.AddScriptTag() has not been implemented yet")
diff --git a/common/locator.go b/common/locator.go
index 9720e56..155c67a 100644
--- a/common/locator.go
+++ b/common/locator.go
@@ -620,6 +620,5 @@ func (l *Locator) WaitFor(opts goja.Value) {
func (l *Locator) waitFor(opts *FrameWaitForSelectorOptions) error {
opts.Strict = true
- _, err := l.frame.waitForSelector(l.selector, opts)
- return err
+ return l.frame.waitFor(l.selector, opts)
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice fix 👍
Actually, let's leave it for now... we might lose some valuable information if we delete this log.
Yep, that's exactly what i was trying to get across, nice 👍 |
👍
Ok! Let me apply these changes, I think you are right, they simplify the implementation at the |
257bc98
to
06fa50c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This commit fixes the condition to wait for a 'hidden' state for a JS element. Now, when the condition is met (the element is no longer visible), waitForSelector function returns the element, as this is still a valid element in the DOM, instead of returning undefined. This will make the call made from the wrapper function 'waitForPredicateFunction': return predicateFn(...args) || continuePolling; evaluate to true and return the JS element instead of hanging on an infinite loop.
This will allow waiting for a selector for which we do not expect an ElementHandle as return. This is useful for example when waiting for 'detached' events.
This commit fixes waiting for a selector to be in 'detached' state. Fixes the injected_script wait for selector condition for 'detached' state, that was returning 'undefined' which eventually caused an infinite loop from the calling polling function 'waitForPredicateFunction' due to the call: return predicateFn(...args) || continuePolling; As 'undefined' returned from the predicate function resulted in returning 'continuePolling' from this condition. Also modifies the Locator.waitFor method in order to call the Frame.waitFor method, instead of Frame.waitForSelector, as in this case, we do not need to retrieve the associated ElementHandle for the selector.
Rename the current test case for WaitFor method in the locator test in order to specify that the state that it's waiting for by default is the 'visible' state. This is also done in order to be coherent when adding more test cases for the other supported states.
Adds test cases for each supported state by locator WaitFor method.
Rebasing main and merging. |
06fa50c
to
01a3aa2
Compare
This PR fixes the
Locator.WaitFor
functionality when the state defined is eitherhidden
ordetached
. Previously, waiting for these two states would result in an infinite pooling loop and eventually a TO error.Besides the integration tests included in the PR, this changes can be tested also using this test browser implemented by @ankur22 and executing the following script:
Take into account that this test will require user interaction to click on the
Detach
button on the top left of the page in order to remove the element that we are waiting for from the DOM.Closes: #736.
Closes: #472.