-
-
Notifications
You must be signed in to change notification settings - Fork 132
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
Implement wait_for_selector #236
base: main
Are you sure you want to change the base?
Changes from 8 commits
c58767f
83ca882
051617d
8d98b79
0f0fbe0
53edf60
cf74591
3b09739
c153714
0489d60
c052bd2
6bd16ef
02a2df6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,33 @@ def body | |
evaluate("document.documentElement.outerHTML") | ||
end | ||
|
||
def wait_for_selector(css: nil, xpath: nil, timeout: 3000, interval: 100) | ||
evaluate_func(%( | ||
function(selector, isXpath, timeout, interval) { | ||
var attempts = 0; | ||
var max = timeout / interval; | ||
function waitForSelector(resolve, reject) { | ||
if (attempts > ((max < 1) ? 1 : max)) { | ||
return reject(new Error("Not found element match the selector: " + selector)); | ||
} | ||
var element = isXpath | ||
? document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue | ||
: document.querySelector(selector); | ||
if (element !== null) { | ||
return resolve(element); | ||
} | ||
setTimeout(function () { | ||
waitForSelector(resolve, reject); | ||
}, interval); | ||
attempts++; | ||
} | ||
return new Promise(function (resolve, reject) { | ||
waitForSelector(resolve, reject); | ||
}); | ||
} | ||
), css || xpath, css.nil? && !xpath.nil?, timeout, interval, awaitPromise: true) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was feeling like this arguments list was a little crowded, and also noticed this function could be incorrectly called without raising an exception: one of def wait_for_selector(css: nil, xpath: nil, timeout: 3000, interval: 100)
raise ArgumentError.new("Provide :css or :xpath, but not both") if css && xpath
raise ArgumentError.new("Provide :css or :xpath") unless css || xpath
evaluate_func(<<~JS, css || xpath, !!xpath, timeout, interval, awaitPromise: true)
function(selector, isXpath, timeout, interval) {
var attempts = 0;
The guard clauses protect the arguments from being called incorrectly, and also simplify the resolution to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. well, it looks like too much for one method to be responsible for selector/XPath and also for validations. def wait_for_selector(css, **options)
wait_for_element(css: css, **options)
end
def wait_for_xpath(xpath, **options)
wait_for_element(xpath: xpath, **options)
end The point to merge two ways of element-find logic was a follow a DRY principle for a common JS function, especially this part: var element = isXpath
? document.evaluate(selector, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue
: document.querySelector(selector); therefore, I think, we can find a way to refactor it with a private function by passing a js function, gimme see closer, will do an update soon. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice one, yes, I think this is a better direction. Consider |
||
end | ||
|
||
def xpath(selector, within: nil) | ||
expr = <<~JS | ||
function(selector, within) { | ||
|
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.
To be more consistent with the rest of the gem, would you mind changing this to use a
JS
heredoc? This is helpful because many editors support code highlighting in the language specified:Original:
VS:
Subl:
Code:
I haven't tried the code out yet, but I'm looking forward to this feature!
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.
it makes sense, will change, thanks!