/
lucky_flow.cr
178 lines (145 loc) · 4.14 KB
/
lucky_flow.cr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
require "selenium"
require "habitat"
require "webdrivers"
require "webless"
require "html5"
class LuckyFlow; end
require "./lucky_flow/**"
require "file_utils"
require "./ext/spec/item"
class LuckyFlow
include LuckyFlow::Expectations
Habitat.create do
setting screenshot_directory : String = "./tmp/screenshots"
setting base_uri : String
setting retry_delay : Time::Span = 10.milliseconds
setting stop_retrying_after : Time::Span = 1.second
setting driver_path : String?
end
def self.default_driver=(value : String)
LuckyFlow::Registry.default_driver = value
end
def self.driver : LuckyFlow::Driver
LuckyFlow::Registry.current_driver ||= LuckyFlow::Registry.get_driver
end
def self.driver(name : String) : LuckyFlow::Driver
LuckyFlow::Registry.current_driver = LuckyFlow::Registry.get_driver(name)
end
def self.shutdown : Nil
LuckyFlow::Registry.shutdown_all
end
def self.use_default_driver
LuckyFlow::Registry.current_driver = nil
end
def self.reset : Nil
LuckyFlow::Registry.current_driver.try(&.reset)
end
def visit(path : String)
driver.visit("#{settings.base_uri}#{path}")
end
def open_screenshot(process = Process, time = Time.utc, fullsize = false) : Void
filename = generate_screenshot_filename(time)
take_screenshot(filename, fullsize)
process.new(command: "#{open_command(process)} #{filename}", shell: true)
end
def take_screenshot(filename : String = generate_screenshot_filename, fullsize : Bool = true)
if fullsize
with_fullsized_page { driver.screenshot(filename) }
else
driver.screenshot(filename)
end
end
private def generate_screenshot_filename(time : Time = Time.utc)
"#{settings.screenshot_directory}/#{time.to_unix}.png"
end
def expand_page_to_fullsize
driver.maximize_window
end
def with_fullsized_page(&)
original_size = driver.window_size
expand_page_to_fullsize
yield
ensure
driver.resize_window(**original_size) if original_size
end
private def open_command(process) : String
["open", "xdg-open", "kde-open", "gnome-open"].find do |command|
!!process.find_executable(command)
end || raise "Could not find a way to open the screenshot"
end
def click(css_selector : String)
el(css_selector).click
end
# Set the text of a form field, clearing any existing text
#
# ```
# fill("comment:body", with: "Lucky is great!")
# ```
def fill(name_attr : String, with value)
fill(field(name_attr), with: value)
end
def fill(element : Element, with value)
element.fill(value)
end
# Add text to the end of a field
#
# ```
# fill("comment:body", with: "Lucky is:")
#
# append("comment:body", " So much fun!")
# ```
def append(name_attr : String, with value : String)
field(name_attr).append(value)
end
# Select an option from a select element
#
# ```
# select("post:category", value: "rant")
# ```
#
# If given an Array(String), the select is assumed to have the 'multiple' attribute
# and will raise a `LuckyFlow::InvalidMultiSelectError` if it doesn't.
#
# ```
# select("post:tags", value: ["rant", "technology"])
# ```
#
def select(name_attr : String, value : Array(String) | String)
self.select(field(name_attr), value: value)
end
def select(element : Element, value : String)
element.select_option(value)
end
def select(element : Element, value : Array(String))
element.select_options(value)
end
def el(css_selector : String, text : String) : LuckyFlow::Element
LuckyFlow::FindElement.run(driver, css_selector, text)
end
def el(css_selector : String) : LuckyFlow::Element
LuckyFlow::FindElement.run(driver, css_selector)
end
def field(name_attr : String) : LuckyFlow::Element
el("[name='#{name_attr}']")
end
def html : String
driver.html
end
def current_path
url = driver.current_url
URI.parse(url).path
end
def accept_alert
driver.accept_alert
end
def dismiss_alert
driver.dismiss_alert
end
def pause
puts "\nPausing to debug... (press enter to continue)"
STDIN.gets
end
def driver : LuckyFlow::Driver
self.class.driver
end
end