Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/lucky_flow.cr
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,23 @@ class LuckyFlow
LuckyFlow::Registry.current_driver.try(&.reset)
end

def self.wait_for_server(timeout : Time::Span = 5.seconds)
uri = URI.parse(settings.base_uri)
host = uri.host || "127.0.0.1"
port = uri.port || 3000
retry_interval = 100.milliseconds
retries = (timeout / retry_interval).to_i

retries.times do
TCPSocket.open(host, port) { }
return
rescue IO::Error
sleep(retry_interval)
end

raise "Server at #{host}:#{port} did not start within #{timeout}"
end

def visit(path : String)
driver.visit("#{settings.base_uri}#{path}")
end
Expand Down
7 changes: 5 additions & 2 deletions src/lucky_flow/find_element.cr
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ class LuckyFlow::FindElement
private def find_matching_elements : Array(LuckyFlow::Element)
self.tries += 1
driver.find_css(selector).select do |element|
text_to_check_for = inner_text
if text_to_check_for
if text_to_check_for = inner_text
element.text.includes?(text_to_check_for)
else
true
end
end
rescue ex : ::Selenium::Error
raise ex unless ex.message.try(&.includes?("stale element"))

[] of LuckyFlow::Element
end

private def raise_element_not_found_error
Expand Down
38 changes: 26 additions & 12 deletions src/lucky_flow/selenium/driver.cr
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
abstract class LuckyFlow::Selenium::Driver < LuckyFlow::Driver
@retry_limit : Time = 2.seconds.from_now
SESSION_RETRY_LIMIT = 2.seconds

@driver : ::Selenium::Driver?
@capabilities : ::Selenium::Capabilities

Expand All @@ -15,6 +16,18 @@ abstract class LuckyFlow::Selenium::Driver < LuckyFlow::Driver

def visit(url : String)
session.navigate_to(url)
wait_for_ready
end

private def wait_for_ready
retry_interval = 10.milliseconds
retries = (LuckyFlow.settings.stop_retrying_after / retry_interval).to_i
retries.times do
ready = session.document_manager.execute_script("return document.readyState;")
return if ready == "complete"

sleep(retry_interval)
end
end

def window_size : NamedTuple(width: Int64?, height: Int64?)
Expand Down Expand Up @@ -69,7 +82,10 @@ abstract class LuckyFlow::Selenium::Driver < LuckyFlow::Driver
end

def reset : Nil
@session.try &.cookie_manager.delete_all_cookies
@session.try do |session|
session.navigate_to("about:blank")
session.cookie_manager.delete_all_cookies
end
end

def stop
Expand All @@ -82,18 +98,16 @@ abstract class LuckyFlow::Selenium::Driver < LuckyFlow::Driver
end

private def start_session : ::Selenium::Session
driver.create_session(@capabilities)
rescue e : IO::Error
retry_start_session(e)
end
retry_interval = 100.milliseconds
retries = (SESSION_RETRY_LIMIT / retry_interval).to_i

private def retry_start_session(e)
if Time.utc <= @retry_limit
sleep(100.milliseconds)
start_session
else
raise e
retries.times do
return driver.create_session(@capabilities)
rescue IO::Error
sleep(retry_interval)
end

driver.create_session(@capabilities)
end

private def find_elements(
Expand Down
Loading