cucumber_helper 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +320 -0
- data/lib/cucumber_helper/api/helpers.rb +32 -0
- data/lib/cucumber_helper/api/hooks.rb +3 -0
- data/lib/cucumber_helper/api/response.rb +155 -0
- data/lib/cucumber_helper/api.rb +17 -0
- data/lib/cucumber_helper/commons/command_helpers.rb +28 -0
- data/lib/cucumber_helper/commons/test_data_helper.rb +27 -0
- data/lib/cucumber_helper/commons/user_data_helper.rb +19 -0
- data/lib/cucumber_helper/commons.rb +6 -0
- data/lib/cucumber_helper/support/env_helper.rb +114 -0
- data/lib/cucumber_helper/support/hooks_helper.rb +40 -0
- data/lib/cucumber_helper/support.rb +4 -0
- data/lib/cucumber_helper/testrail/test_rail_integration.rb +52 -0
- data/lib/cucumber_helper/testrail/testrail.rb +88 -0
- data/lib/cucumber_helper/version.rb +5 -0
- data/lib/cucumber_helper/web/helpers.rb +772 -0
- data/lib/cucumber_helper/web/hooks.rb +4 -0
- data/lib/cucumber_helper/web/table_helper.rb +50 -0
- data/lib/cucumber_helper/web.rb +18 -0
- data/lib/cucumber_helper.rb +5 -0
- metadata +66 -0
@@ -0,0 +1,772 @@
|
|
1
|
+
# rubocop: disable Metrics/ModuleLength
|
2
|
+
module CucumberHelper
|
3
|
+
module Web
|
4
|
+
module Helpers
|
5
|
+
def short_wait(time_out = SHORT_TIMEOUT)
|
6
|
+
Selenium::WebDriver::Wait.new(
|
7
|
+
timeout: time_out,
|
8
|
+
interval: 0.2,
|
9
|
+
ignore: Selenium::WebDriver::Error::NoSuchElementError,
|
10
|
+
message: "element not found on the current screen after waiting #{time_out} seconds"
|
11
|
+
)
|
12
|
+
end
|
13
|
+
|
14
|
+
def waiting_for_page_ready
|
15
|
+
sleep 1
|
16
|
+
wait_for_ajax
|
17
|
+
end
|
18
|
+
|
19
|
+
def wait_for_ajax
|
20
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
21
|
+
sleep 1 while finished_all_ajax_requests?.eql? false
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def finished_all_ajax_requests?
|
26
|
+
page.evaluate_script(<<~SCRIPT
|
27
|
+
((typeof window.jQuery === 'undefined')
|
28
|
+
|| (typeof window.jQuery.active === 'undefined')
|
29
|
+
|| (window.jQuery.active === 0))
|
30
|
+
&& ((typeof window.injectedJQueryFromNode === 'undefined')
|
31
|
+
|| (typeof window.injectedJQueryFromNode.active === 'undefined')
|
32
|
+
|| (window.injectedJQueryFromNode.active === 0))
|
33
|
+
&& (document.readyState === 'complete')
|
34
|
+
&& ((typeof window.httpClients === 'undefined')
|
35
|
+
|| (window.httpClients.every(function (client) { return (client.activeRequestCount === 0); })))
|
36
|
+
SCRIPT
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def wait_for_download
|
41
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
42
|
+
sleep 1 until downloaded?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# wait for request made
|
47
|
+
def inject_xhr_listener
|
48
|
+
page.evaluate_script(<<~SCRIPT
|
49
|
+
(function() {
|
50
|
+
var oldOpen = XMLHttpRequest.prototype.open;
|
51
|
+
window.openHTTPs = 0;
|
52
|
+
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
|
53
|
+
window.openHTTPs++;
|
54
|
+
this.addEventListener("readystatechange", function() {
|
55
|
+
if(this.readyState == 4) {
|
56
|
+
window.openHTTPs--;
|
57
|
+
}
|
58
|
+
}, false);
|
59
|
+
oldOpen.call(this, method, url, async, user, pass);
|
60
|
+
}
|
61
|
+
})(XMLHttpRequest);
|
62
|
+
SCRIPT
|
63
|
+
)
|
64
|
+
sleep 0.5
|
65
|
+
true
|
66
|
+
end
|
67
|
+
|
68
|
+
def any_xhr_request?
|
69
|
+
page.evaluate_script('window.openHTTPs').positive?
|
70
|
+
end
|
71
|
+
|
72
|
+
# check the request already finished
|
73
|
+
def finished_xhr_request?
|
74
|
+
page.evaluate_script('window.openHTTPs').zero?
|
75
|
+
end
|
76
|
+
|
77
|
+
def waiting_for_xhr_complete
|
78
|
+
@script_injected ||= inject_xhr_listener
|
79
|
+
wait_xhr_request_made
|
80
|
+
wait_xhr_finished
|
81
|
+
rescue Timeout::Error
|
82
|
+
p 'either xhr finished before or no xhr'
|
83
|
+
end
|
84
|
+
|
85
|
+
def wait_xhr_finished
|
86
|
+
Timeout.timeout(Capybara.default_max_wait_time) do
|
87
|
+
sleep 1 while finished_xhr_request?.eql? false
|
88
|
+
end
|
89
|
+
# give time for page to update the data
|
90
|
+
sleep 1
|
91
|
+
end
|
92
|
+
|
93
|
+
def wait_xhr_request_made
|
94
|
+
Timeout.timeout(2) do
|
95
|
+
sleep 1 while any_xhr_request?.eql? false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def downloaded_location
|
100
|
+
Dir[File.absolute_path('./features/data/downloaded/*')]
|
101
|
+
end
|
102
|
+
|
103
|
+
def downloaded?
|
104
|
+
short_wait.until { !Dir[File.absolute_path('./features/data/downloaded/*')].empty? }
|
105
|
+
short_wait.until { (Dir[File.absolute_path('./features/data/downloaded/*')].any? { |x| x.include? '.crdownload' }).eql? false }
|
106
|
+
end
|
107
|
+
|
108
|
+
# round to up eg: 10.8 = 11
|
109
|
+
# convert number
|
110
|
+
# increase number before comma to + 1 if number after comma bigger than 5
|
111
|
+
# 5.6 = 6
|
112
|
+
# 5.4 = 5
|
113
|
+
def adjust_comma_number(number)
|
114
|
+
number_array = number.to_s.split('.')
|
115
|
+
|
116
|
+
if number_array[1][0].to_i > 4
|
117
|
+
number_array[0].to_i + 1
|
118
|
+
else
|
119
|
+
number_array[0].to_i
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# round to down eg: 10.8 = 10
|
124
|
+
def adjust_comma_number_down(number)
|
125
|
+
number_array = number.to_s.split('.')
|
126
|
+
|
127
|
+
number_array[0].to_i
|
128
|
+
end
|
129
|
+
|
130
|
+
# convert string to d/m/y format
|
131
|
+
def date_conversion_ddmmyyyy_with_slash(date)
|
132
|
+
if date.nil? || date == ''
|
133
|
+
nil
|
134
|
+
elsif date == 'yesterday'
|
135
|
+
(Time.new.to_date - 1).strftime('%d/%m/%Y')
|
136
|
+
elsif date == 'today'
|
137
|
+
Time.new.to_date.strftime('%d/%m/%Y')
|
138
|
+
elsif date == 'tomorrow'
|
139
|
+
(Time.new.to_date + 1).strftime('%d/%m/%Y')
|
140
|
+
elsif date == 'one_month_before_today'
|
141
|
+
(Time.new.to_date - 31).strftime('%d/%m/%Y')
|
142
|
+
elsif date == 'one_month_from_tomorrow'
|
143
|
+
(Time.new.to_date + 31).strftime('%d/%m/%Y')
|
144
|
+
elsif date == 'two_month_from_tomorrow'
|
145
|
+
(Time.new.to_date + 60).strftime('%d/%m/%Y')
|
146
|
+
elsif date.include? 'day_after_today'
|
147
|
+
expected_date = date.split('_')
|
148
|
+
(Time.new.to_date + expected_date[0].to_i).strftime('%d/%m/%Y')
|
149
|
+
elsif date == 'day_before_today_not_weekend'
|
150
|
+
case Time.new.to_date.wday
|
151
|
+
when 1
|
152
|
+
# if today is monday set to past friday
|
153
|
+
(Time.new.to_date - 3).strftime('%d/%m/%Y')
|
154
|
+
else
|
155
|
+
# if today is not sunday and monday set to before yesterday
|
156
|
+
(Time.new.to_date - 2).strftime('%d/%m/%Y')
|
157
|
+
end
|
158
|
+
elsif date.include? 'date_on_same_month'
|
159
|
+
expected_date = date.split('_')
|
160
|
+
expected_date = format('%02d', expected_date[0])
|
161
|
+
Time.new.to_date.strftime("#{expected_date}/%m/%Y")
|
162
|
+
else
|
163
|
+
date.to_date.strftime('%d/%m/%Y')
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
# convert to 20 March, 2020
|
168
|
+
def date_conversion_output(date)
|
169
|
+
date.to_date.strftime('%d %B, %Y')
|
170
|
+
end
|
171
|
+
|
172
|
+
# convert to 2020-05-20
|
173
|
+
def date_conversion_output_yyyymmdd_with_dash(date)
|
174
|
+
date.to_date.strftime('%Y-%m-%d')
|
175
|
+
end
|
176
|
+
|
177
|
+
# convert to 20-05-2020
|
178
|
+
def date_conversion_output_ddmmyyyy_with_dash(date)
|
179
|
+
date.to_date.strftime('%d-%m-%Y')
|
180
|
+
end
|
181
|
+
|
182
|
+
def fetch_weekend_date(date)
|
183
|
+
d = date.to_date
|
184
|
+
d += 1 until d.sunday?
|
185
|
+
d.strftime('%d/%m/%Y')
|
186
|
+
end
|
187
|
+
|
188
|
+
def convert_second_to_time_in_words(from, to)
|
189
|
+
distance_in_days = to.to_date - from.to_date
|
190
|
+
# using dotiw library
|
191
|
+
# 86400 is total second in 1 day
|
192
|
+
distance_of_time(distance_in_days * 86_400)
|
193
|
+
end
|
194
|
+
|
195
|
+
def currency_trimmer(currency)
|
196
|
+
number = if currency.include? 'Rp'
|
197
|
+
if currency.include? 'Rp.'
|
198
|
+
currency.gsub(/[Rp. ]/, '').tr('.', '').tr(',', '.')
|
199
|
+
else
|
200
|
+
currency.gsub(/[Rp ]/, '').tr('.', '')
|
201
|
+
end
|
202
|
+
elsif currency.include? '$'
|
203
|
+
currency.gsub(/[ABCGHKNSTUZ$ ()]/, '').tr('.', '').tr(',', '.')
|
204
|
+
else
|
205
|
+
currency.gsub(/ /, '').tr('.', '').tr(',', '.')
|
206
|
+
end
|
207
|
+
number = if (number =~ /([0-9])/).nil?
|
208
|
+
number.tr('(', '').tr(')', '')
|
209
|
+
else
|
210
|
+
number.tr('(', '-').tr(')', '')
|
211
|
+
end
|
212
|
+
number.strip.to_f
|
213
|
+
end
|
214
|
+
|
215
|
+
# to convert 50000 to 50.000
|
216
|
+
def add_dot_to_interger(string_number)
|
217
|
+
string_number.to_s.reverse.scan(/\d{3}|.+/).join('.').reverse
|
218
|
+
end
|
219
|
+
|
220
|
+
# to convert 50000 to 50,000
|
221
|
+
def add_comma_to_interger(string_number)
|
222
|
+
string_number.to_s.reverse.scan(/\d{3}|.+/).join(',').reverse
|
223
|
+
end
|
224
|
+
|
225
|
+
def scroll_to(element)
|
226
|
+
script = <<-JS
|
227
|
+
arguments[0].scrollIntoView(true);
|
228
|
+
JS
|
229
|
+
expected = element =~ /^(xpath|css)/
|
230
|
+
type_of_element = element_mapper(element) unless expected.nil?
|
231
|
+
locator = if expected.nil? || type_of_element[:element_type].eql?('xpath')
|
232
|
+
find_xpath(element.path)
|
233
|
+
else
|
234
|
+
find_css(type_of_element[:element_locator])
|
235
|
+
end
|
236
|
+
Capybara.current_session.driver.browser.execute_script(script, locator.native)
|
237
|
+
sleep 2
|
238
|
+
end
|
239
|
+
|
240
|
+
def element_mapper(element)
|
241
|
+
element_map = element.partition(':')
|
242
|
+
type = element_map.first
|
243
|
+
locator = element_map.last
|
244
|
+
{ element_type: type, element_locator: locator }
|
245
|
+
end
|
246
|
+
|
247
|
+
def find_xpath(locator, timeout = 3)
|
248
|
+
short_wait.until { find(:xpath, locator, wait: timeout) }
|
249
|
+
end
|
250
|
+
|
251
|
+
def find_css(locator, timeout = 3)
|
252
|
+
short_wait.until { find(:css, locator, wait: timeout) }
|
253
|
+
end
|
254
|
+
|
255
|
+
def select_date_clear(input_element, date_element)
|
256
|
+
retries ||= 0
|
257
|
+
begin
|
258
|
+
p "Try #{retries + 1}"
|
259
|
+
input_element.click
|
260
|
+
short_wait.until { page.has_css?('.picker--opened', wait: 1) }
|
261
|
+
rescue Exception => e
|
262
|
+
p e.message
|
263
|
+
retry if (retries += 1) < 3
|
264
|
+
raise e.message if retries == 3
|
265
|
+
end
|
266
|
+
|
267
|
+
clear_button = "#{date_element.path}//button[contains(@class,'btn-flat picker__clear')]"
|
268
|
+
scroll_to(find_xpath(clear_button))
|
269
|
+
|
270
|
+
find_xpath(clear_button).click while page.has_css?('.picker--opened', wait: 1)
|
271
|
+
|
272
|
+
short_wait.until { page.has_css?('.picker--opened', wait: 1).eql? false }
|
273
|
+
end
|
274
|
+
|
275
|
+
def select_date(input_element, date_element, date)
|
276
|
+
retries ||= 0
|
277
|
+
begin
|
278
|
+
p "Try select date #{retries + 1}"
|
279
|
+
input_element.click
|
280
|
+
page.has_css?('.picker--opened', wait: 2)
|
281
|
+
find(:css, '.picker--opened', wait: 2)
|
282
|
+
rescue Exception => e
|
283
|
+
p e.message
|
284
|
+
retry if (retries += 1) < 5
|
285
|
+
raise e.message if retries == 5
|
286
|
+
end
|
287
|
+
|
288
|
+
date = date_conversion_ddmmyyyy_with_slash(date)
|
289
|
+
|
290
|
+
expected_date = date.split('/')
|
291
|
+
expected_day = expected_date[0].to_i
|
292
|
+
expected_month = Date::MONTHNAMES[expected_date[1].to_i]
|
293
|
+
expected_year = expected_date[2].to_s
|
294
|
+
|
295
|
+
month_element = "#{date_element.path}//select[contains(@class,'picker__select--month browser-default')]"
|
296
|
+
year_element = "#{date_element.path}//select[contains(@class,'picker__select--year browser-default')]"
|
297
|
+
day_element = "#{date_element.path}//table[contains(@class,'picker__table')]"
|
298
|
+
select_button = "#{date_element.path}//button[contains(@class,'btn-flat picker__close')]"
|
299
|
+
|
300
|
+
# select year
|
301
|
+
find_xpath(year_element).find(:option, expected_year).select_option
|
302
|
+
# select month
|
303
|
+
find_xpath(month_element).find(:option, expected_month).select_option
|
304
|
+
# select day
|
305
|
+
find_xpath(day_element).find('tbody tr td', text: expected_day, exact_text: true).click
|
306
|
+
|
307
|
+
scroll_to(find_xpath(select_button))
|
308
|
+
find_xpath(select_button).click
|
309
|
+
short_wait.until { page.has_css?('.picker--opened', wait: 1).eql? false }
|
310
|
+
end
|
311
|
+
|
312
|
+
def select_date_new(input_element, date)
|
313
|
+
retries ||= 0
|
314
|
+
begin
|
315
|
+
p "Try #{retries + 1}"
|
316
|
+
input_element.click
|
317
|
+
page.has_css?('div.datepicker', wait: 2)
|
318
|
+
find(:css, 'div.datepicker', wait: 2)
|
319
|
+
rescue Exception => e
|
320
|
+
p e.message
|
321
|
+
retry if (retries += 1) < 5
|
322
|
+
raise e.message if retries == 5
|
323
|
+
end
|
324
|
+
|
325
|
+
date = date_conversion_ddmmyyyy_with_slash(date)
|
326
|
+
|
327
|
+
expected_date = date.split('/')
|
328
|
+
expected_day = expected_date[0].to_i
|
329
|
+
expected_month_abbr = Date::ABBR_MONTHNAMES[expected_date[1].to_i]
|
330
|
+
expected_year = expected_date[2].to_s
|
331
|
+
|
332
|
+
# date element
|
333
|
+
switch_days_prev_button = find(:css, 'div.datepicker div.datepicker-days th.prev')
|
334
|
+
switch_days_next_button = find(:css, 'div.datepicker div.datepicker-days th.next')
|
335
|
+
switch_days_to_month = find(:css, 'div.datepicker div.datepicker-days th.datepicker-switch')
|
336
|
+
|
337
|
+
# select year
|
338
|
+
if expected_year != switch_days_to_month.text.split[1]
|
339
|
+
switch_days_to_month.click
|
340
|
+
waiting_for_page_ready
|
341
|
+
|
342
|
+
switch_month_prev_button = find(:css, 'div.datepicker div.datepicker-months th.prev')
|
343
|
+
switch_month_next_button = find(:css, 'div.datepicker div.datepicker-months th.next')
|
344
|
+
switch_month_to_year = find(:css, 'div.datepicker div.datepicker-months th.datepicker-switch')
|
345
|
+
|
346
|
+
if expected_year.to_i < switch_month_to_year.text.to_i
|
347
|
+
while expected_year != switch_month_to_year.text
|
348
|
+
switch_month_prev_button.click
|
349
|
+
waiting_for_page_ready
|
350
|
+
end
|
351
|
+
elsif expected_year.to_i > switch_month_to_year.text.to_i
|
352
|
+
while expected_year != switch_month_to_year.text
|
353
|
+
switch_month_next_button.click
|
354
|
+
waiting_for_page_ready
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
# select month
|
359
|
+
find(:css, 'div.datepicker div.datepicker-months table tbody tr td span', text: expected_month_abbr).click
|
360
|
+
waiting_for_page_ready
|
361
|
+
end
|
362
|
+
sleep 1
|
363
|
+
|
364
|
+
# select day
|
365
|
+
if expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
366
|
+
if expected_date[1].to_i < Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
367
|
+
while expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
368
|
+
switch_days_prev_button.click
|
369
|
+
waiting_for_page_ready
|
370
|
+
end
|
371
|
+
elsif expected_date[1].to_i > Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
372
|
+
while expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
373
|
+
switch_days_next_button.click
|
374
|
+
waiting_for_page_ready
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
sleep 1
|
379
|
+
|
380
|
+
find(:xpath, "//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-days')]//table//tbody//tr//td[not(contains(@class,'old')) and not(contains(@class,'new'))]", exact_text: expected_day.to_s).click
|
381
|
+
waiting_for_page_ready
|
382
|
+
|
383
|
+
expect(input_element.value.nil?).to eq false
|
384
|
+
end
|
385
|
+
|
386
|
+
def select_date_new2(input_element, date)
|
387
|
+
retries ||= 0
|
388
|
+
begin
|
389
|
+
p "Try select date #{retries + 1}"
|
390
|
+
input_element.click
|
391
|
+
page.has_css?('div.date-picker-calendar-view', wait: 2)
|
392
|
+
find(:css, 'div.date-picker-calendar-view', wait: 2)
|
393
|
+
rescue Exception => e
|
394
|
+
p e.message
|
395
|
+
retry if (retries += 1) < 5
|
396
|
+
raise e.message if retries == 5
|
397
|
+
end
|
398
|
+
|
399
|
+
date = date_conversion_ddmmyyyy_with_slash(date)
|
400
|
+
|
401
|
+
expected_date = date.split('/')
|
402
|
+
expected_day = expected_date[0].to_i
|
403
|
+
expected_month_abbr = Date::ABBR_MONTHNAMES[expected_date[1].to_i]
|
404
|
+
expected_year = expected_date[2].to_s
|
405
|
+
|
406
|
+
# date element
|
407
|
+
switch_days_prev_button = find(:css, 'div.date-picker-header div.date-picker-previous-button i')
|
408
|
+
switch_days_next_button = find(:css, 'div.date-picker-header div.date-picker-next-button i')
|
409
|
+
switch_days_to_month = find(:css, 'div.date-picker-header div.date-picker-header-title')
|
410
|
+
|
411
|
+
# select year
|
412
|
+
if expected_year != switch_days_to_month.text.split[1]
|
413
|
+
switch_days_to_month.click
|
414
|
+
waiting_for_page_ready
|
415
|
+
|
416
|
+
switch_month_prev_button = find(:css, 'div.date-picker-header div.date-picker-previous-button i')
|
417
|
+
switch_month_next_button = find(:css, 'div.date-picker-header div.date-picker-next-button i')
|
418
|
+
switch_month_to_year = find(:css, 'div.date-picker-header div.date-picker-header-title')
|
419
|
+
|
420
|
+
if expected_year.to_i < switch_month_to_year.text.to_i
|
421
|
+
while expected_year != switch_month_to_year.text
|
422
|
+
switch_month_prev_button.click
|
423
|
+
waiting_for_page_ready
|
424
|
+
end
|
425
|
+
elsif expected_year.to_i > switch_month_to_year.text.to_i
|
426
|
+
while expected_year != switch_month_to_year.text
|
427
|
+
switch_month_next_button.click
|
428
|
+
waiting_for_page_ready
|
429
|
+
end
|
430
|
+
end
|
431
|
+
# select month
|
432
|
+
find(:css, 'div.date-picker-body div.date-picker-month-cell', text: expected_month_abbr).click
|
433
|
+
waiting_for_page_ready
|
434
|
+
end
|
435
|
+
sleep 1
|
436
|
+
|
437
|
+
# select day
|
438
|
+
if expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
439
|
+
if expected_date[1].to_i < Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
440
|
+
while expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
441
|
+
switch_days_prev_button.click
|
442
|
+
waiting_for_page_ready
|
443
|
+
end
|
444
|
+
elsif expected_date[1].to_i > Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
445
|
+
while expected_date[1].to_i != Date::MONTHNAMES.index(switch_days_to_month.text.split[0])
|
446
|
+
switch_days_next_button.click
|
447
|
+
waiting_for_page_ready
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
sleep 1
|
452
|
+
|
453
|
+
find(:xpath, "//div[contains(@class,'date-picker-body')]//div[contains(@class,'date-picker-cell')]//div[not(contains(@class,'date-picker-date-cell text-muted'))]", exact_text: expected_day.to_s).click
|
454
|
+
waiting_for_page_ready
|
455
|
+
|
456
|
+
expect(input_element.value.nil?).to eq false
|
457
|
+
end
|
458
|
+
|
459
|
+
def select_date_new3(input_element, date)
|
460
|
+
retries ||= 0
|
461
|
+
begin
|
462
|
+
p "Try select date #{retries + 1}"
|
463
|
+
input_element.click
|
464
|
+
page.has_css?('div.datepicker-calendar.vdp-datepicker__calendar', wait: 2)
|
465
|
+
find(:css, 'div.datepicker-calendar.vdp-datepicker__calendar', wait: 2)
|
466
|
+
rescue Exception => e
|
467
|
+
p e.message
|
468
|
+
retry if (retries += 1) < 5
|
469
|
+
raise e.message if retries == 5
|
470
|
+
end
|
471
|
+
|
472
|
+
date = date.strftime('%d/%m/%Y') if date.is_a?(Date)
|
473
|
+
date = date_conversion_ddmmyyyy_with_slash(date) unless date.is_a?(Date)
|
474
|
+
|
475
|
+
expected_date = date.split('/')
|
476
|
+
expected_day = expected_date[0].to_i
|
477
|
+
expected_month_abbr = Date::ABBR_MONTHNAMES[expected_date[1].to_i]
|
478
|
+
expected_year = expected_date[2].to_s
|
479
|
+
|
480
|
+
# date element
|
481
|
+
switch_prev_button = find(:css, 'div.datepicker-calendar.vdp-datepicker__calendar span.prev')
|
482
|
+
switch_next_button = find(:css, 'div.datepicker-calendar.vdp-datepicker__calendar span.next')
|
483
|
+
switch_days_to_month = find(:css, 'span.day__month_btn')
|
484
|
+
|
485
|
+
# select year
|
486
|
+
if expected_year != switch_days_to_month.text.split[1]
|
487
|
+
switch_days_to_month.click
|
488
|
+
waiting_for_page_ready
|
489
|
+
|
490
|
+
switch_month_to_year = find(:css, 'span.month__year_btn')
|
491
|
+
|
492
|
+
if expected_year.to_i < switch_month_to_year.text.to_i
|
493
|
+
while expected_year != switch_month_to_year.text
|
494
|
+
switch_prev_button.click
|
495
|
+
waiting_for_page_ready
|
496
|
+
end
|
497
|
+
elsif expected_year.to_i > switch_month_to_year.text.to_i
|
498
|
+
while expected_year != switch_month_to_year.text
|
499
|
+
switch_next_button.click
|
500
|
+
waiting_for_page_ready
|
501
|
+
end
|
502
|
+
end
|
503
|
+
# select month
|
504
|
+
find(:css, 'span.cell.month', text: expected_month_abbr).click
|
505
|
+
waiting_for_page_ready
|
506
|
+
end
|
507
|
+
sleep 1
|
508
|
+
|
509
|
+
# select day
|
510
|
+
if expected_date[1].to_i != switch_days_to_month.text.to_date.month
|
511
|
+
if expected_date[1].to_i < switch_days_to_month.text.to_date.month
|
512
|
+
while expected_date[1].to_i != switch_days_to_month.text.to_date.month
|
513
|
+
switch_prev_button.click
|
514
|
+
waiting_for_page_ready
|
515
|
+
end
|
516
|
+
elsif expected_date[1].to_i > switch_days_to_month.text.to_date.month
|
517
|
+
while expected_date[1].to_i != switch_days_to_month.text.to_date.month
|
518
|
+
switch_next_button.click
|
519
|
+
waiting_for_page_ready
|
520
|
+
end
|
521
|
+
end
|
522
|
+
end
|
523
|
+
sleep 1
|
524
|
+
|
525
|
+
find('span.cell.day', exact_text: expected_day.to_s).click
|
526
|
+
waiting_for_page_ready
|
527
|
+
|
528
|
+
expect(input_element.value.nil?).to eq false
|
529
|
+
end
|
530
|
+
|
531
|
+
def select_only_year_month_date_new(input_element, date)
|
532
|
+
retries ||= 0
|
533
|
+
begin
|
534
|
+
p "Try #{retries + 1}"
|
535
|
+
input_element.click
|
536
|
+
short_wait.until { page.has_css?('div.datepicker', wait: 1) }
|
537
|
+
find(:css, 'div.datepicker')
|
538
|
+
rescue Exception => e
|
539
|
+
p e.message
|
540
|
+
retry if (retries += 1) < 5
|
541
|
+
raise e.message if retries == 5
|
542
|
+
end
|
543
|
+
|
544
|
+
date = date_conversion_ddmmyyyy_with_slash(date)
|
545
|
+
|
546
|
+
expected_date = date.split('/')
|
547
|
+
expected_month_abbr = Date::ABBR_MONTHNAMES[expected_date[1].to_i]
|
548
|
+
expected_year = expected_date[2].to_s
|
549
|
+
|
550
|
+
# date element
|
551
|
+
switch_month_prev_button = find(:css, 'div.datepicker div.datepicker-months th.prev')
|
552
|
+
switch_month_next_button = find(:css, 'div.datepicker div.datepicker-months th.next')
|
553
|
+
switch_month_to_year = find(:css, 'div.datepicker div.datepicker-months th.datepicker-switch')
|
554
|
+
|
555
|
+
# select year
|
556
|
+
if expected_year.to_i < switch_month_to_year.text.to_i
|
557
|
+
while expected_year != switch_month_to_year.text
|
558
|
+
switch_month_prev_button.click
|
559
|
+
waiting_for_page_ready
|
560
|
+
end
|
561
|
+
elsif expected_year.to_i > switch_month_to_year.text.to_i
|
562
|
+
while expected_year != switch_month_to_year.text
|
563
|
+
switch_month_next_button.click
|
564
|
+
waiting_for_page_ready
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
# select month
|
569
|
+
find(:css, 'div.datepicker div.datepicker-months table tbody tr td span', text: expected_month_abbr).click
|
570
|
+
waiting_for_page_ready
|
571
|
+
sleep 1
|
572
|
+
|
573
|
+
expect(input_element.value.nil?).to eq false
|
574
|
+
end
|
575
|
+
|
576
|
+
def select_only_year_date_new(input_element, year)
|
577
|
+
retries ||= 0
|
578
|
+
begin
|
579
|
+
p "Try #{retries + 1}"
|
580
|
+
input_element.click
|
581
|
+
short_wait.until { page.has_css?('div.datepicker', wait: 1) }
|
582
|
+
find(:css, 'div.datepicker')
|
583
|
+
rescue Exception => e
|
584
|
+
p e.message
|
585
|
+
retry if (retries += 1) < 5
|
586
|
+
raise e.message if retries == 5
|
587
|
+
end
|
588
|
+
|
589
|
+
# set css so the whole datepicker panel become visible
|
590
|
+
page.execute_script('$(".datepicker-orient-bottom").css({"top":"0px"})')
|
591
|
+
|
592
|
+
list_year_element = find_all(:xpath, "//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//tbody//tr//td//span")
|
593
|
+
prev_year_button = find(:xpath, "//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//thead//tr[2]//th[@class='prev']")
|
594
|
+
next_year_button = find(:xpath, "//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//thead//tr[2]//th[@class='next']")
|
595
|
+
|
596
|
+
if list_year_element.first.text.to_i > year.to_i
|
597
|
+
# if first display year greater than selected year
|
598
|
+
prev_year_button.click until has_xpath?("//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//tbody//tr//td//span[contains(text(),\"#{year}\")]", wait: 2)
|
599
|
+
elsif list_year_element.last.text.to_i < year.to_i
|
600
|
+
# if last display year lower than selected year
|
601
|
+
next_year_button.click until has_xpath?("//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//tbody//tr//td//span[contains(text(),\"#{year}\")]", wait: 2)
|
602
|
+
end
|
603
|
+
|
604
|
+
find(:xpath, "//div[contains(@class,'datepicker')]//div[contains(@class,'datepicker-years')]//table//tbody//tr//td//span[contains(text(),\"#{year}\")]", wait: 2).click
|
605
|
+
end
|
606
|
+
|
607
|
+
def close_new_select_date
|
608
|
+
# close date dropdown
|
609
|
+
find(:css, '.tl-footer').click
|
610
|
+
|
611
|
+
short_wait.until { page.has_no_css?('div.datepicker', wait: 1) }
|
612
|
+
end
|
613
|
+
|
614
|
+
def select_date_new_with_close_date(input_element, date)
|
615
|
+
select_date_new input_element, date
|
616
|
+
close_new_select_date
|
617
|
+
end
|
618
|
+
|
619
|
+
def select_date_new_without_close_date(input_element, date)
|
620
|
+
select_date_new input_element, date
|
621
|
+
end
|
622
|
+
|
623
|
+
def fetch_selected_text(selector)
|
624
|
+
value = selector.value
|
625
|
+
selector.find("option[value='#{value}']").text
|
626
|
+
end
|
627
|
+
|
628
|
+
def set_default_value_to_excel_file(default_column_value, filename)
|
629
|
+
# read xlsx file
|
630
|
+
workbook = RubyXL::Parser.parse(File.absolute_path("./features/data/excel/#{filename}"))
|
631
|
+
worksheet = workbook.first
|
632
|
+
|
633
|
+
# reset excel data with default value
|
634
|
+
(0...default_column_value.size).each do |x|
|
635
|
+
(0...worksheet[0].size).each do |y|
|
636
|
+
next unless worksheet[0][y].value.eql? default_column_value[x]['column_name']
|
637
|
+
|
638
|
+
(1...worksheet.sheet_data.rows.size).each do |z|
|
639
|
+
# update data on all column_name with data
|
640
|
+
worksheet.add_cell(z, y, default_column_value[x]['value'])
|
641
|
+
end
|
642
|
+
break
|
643
|
+
end
|
644
|
+
end
|
645
|
+
|
646
|
+
# update xlsx file
|
647
|
+
workbook.write(File.absolute_path("./features/data/excel/#{filename}"))
|
648
|
+
end
|
649
|
+
|
650
|
+
def make_invalid_value_to_excel_file(filename)
|
651
|
+
# read xlsx file
|
652
|
+
workbook = RubyXL::Parser.parse(File.absolute_path("./features/data/excel/#{filename}"))
|
653
|
+
workbook.first
|
654
|
+
|
655
|
+
# update xlsx file
|
656
|
+
workbook.write(File.absolute_path("./features/data/excel/#{filename}"))
|
657
|
+
end
|
658
|
+
|
659
|
+
def mail_account
|
660
|
+
if ENV['BASE_URL'].include? 'talenta.co'
|
661
|
+
MailHelper.new(@data_login['email'])
|
662
|
+
else
|
663
|
+
# use mailtrap credential for staging
|
664
|
+
@data_login = @load_data.login.load_secret_details('user_mailtrap').with_indifferent_access
|
665
|
+
MailHelperMailtrap.new(@data_login['email'], @data_login['inboxes_id'], @data_login['apikey_staging'])
|
666
|
+
end
|
667
|
+
end
|
668
|
+
|
669
|
+
def validate_json(response)
|
670
|
+
JSON.parse(response)
|
671
|
+
true
|
672
|
+
rescue JSON::ParserError, TypeError
|
673
|
+
false
|
674
|
+
end
|
675
|
+
|
676
|
+
def reset_excel_data_to_default(default_column_value, workbook, worksheet, filename)
|
677
|
+
(0...default_column_value.size).each do |x|
|
678
|
+
(0...worksheet[0].size).each do |y|
|
679
|
+
next unless worksheet[0][y].value.eql? default_column_value[x]['column_name']
|
680
|
+
|
681
|
+
(1...worksheet.sheet_data.rows.size).each do |z|
|
682
|
+
# update data on all column_name with data
|
683
|
+
worksheet.add_cell(z, y, default_column_value[x]['value'])
|
684
|
+
end
|
685
|
+
break
|
686
|
+
end
|
687
|
+
end
|
688
|
+
|
689
|
+
# update xlsx file
|
690
|
+
workbook.write(File.absolute_path("./features/data/excel/#{filename}"))
|
691
|
+
end
|
692
|
+
|
693
|
+
def resolve(url)
|
694
|
+
url.gsub!(/\{([a-zA-Z0-9_]+)\}/) do |s|
|
695
|
+
s.gsub!(/[{}]/, '')
|
696
|
+
raise "Did you forget to \"grab\" #{s}?" unless instance_variable_defined?("@#{s}")
|
697
|
+
|
698
|
+
CGI.escape instance_variable_get("@#{s}").to_s
|
699
|
+
end
|
700
|
+
url
|
701
|
+
end
|
702
|
+
|
703
|
+
def parse_rp(angka)
|
704
|
+
if angka.respond_to? :to_ary
|
705
|
+
angka.map { |s| s.gsub(/[^\d,]/, '').to_i }
|
706
|
+
else
|
707
|
+
angka.gsub(/[^\d,]/, '').to_i
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
def parse_rp_with_coma(angka)
|
712
|
+
angka.gsub(/\D/, '').to_i
|
713
|
+
end
|
714
|
+
|
715
|
+
def chrome_session(retries = 2)
|
716
|
+
# check if window crashed?
|
717
|
+
begin
|
718
|
+
empty = windows.empty?
|
719
|
+
rescue NoMethodError
|
720
|
+
empty = true
|
721
|
+
end
|
722
|
+
|
723
|
+
# create new window if neccessary
|
724
|
+
if empty
|
725
|
+
begin
|
726
|
+
page = Capybara::Session.new(:chrome)
|
727
|
+
page.open_new_window
|
728
|
+
rescue Selenium::WebDriver::Error::UnknownError
|
729
|
+
raise if windows.empty?
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
begin
|
734
|
+
switch_to_window(windows[0])
|
735
|
+
rescue NoMethodError => e
|
736
|
+
page = Capybara::Session.new(:chrome)
|
737
|
+
page.open_new_window
|
738
|
+
chrome_session(retries - 1) unless retries.zero?
|
739
|
+
raise e.message
|
740
|
+
end
|
741
|
+
page
|
742
|
+
rescue NoMethodError => e
|
743
|
+
page = Capybara::Session.new(:chrome)
|
744
|
+
page.open_new_window
|
745
|
+
chrome_session(retries - 1) unless retries.zero?
|
746
|
+
raise e.message
|
747
|
+
end
|
748
|
+
|
749
|
+
def close_broken_session
|
750
|
+
begin
|
751
|
+
empty = windows.empty?
|
752
|
+
rescue NoMethodError
|
753
|
+
empty = true
|
754
|
+
end
|
755
|
+
|
756
|
+
return if empty
|
757
|
+
|
758
|
+
broken = !page.current_url.include?('https')
|
759
|
+
return unless broken
|
760
|
+
|
761
|
+
begin
|
762
|
+
windows.first.close
|
763
|
+
rescue Exception
|
764
|
+
page = Capybara::Session.new(:chrome)
|
765
|
+
page.open_new_window
|
766
|
+
end
|
767
|
+
end
|
768
|
+
end
|
769
|
+
end
|
770
|
+
end
|
771
|
+
# rubocop:enable Metrics/ModuleLength
|
772
|
+
World(CucumberHelper::Web::Helpers)
|