testcentricity_web 3.2.23 → 4.0.1

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.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/Gemfile.lock +23 -23
  4. data/README.md +62 -29
  5. data/lib/testcentricity_web.rb +0 -10
  6. data/lib/testcentricity_web/browser_helper.rb +21 -13
  7. data/lib/testcentricity_web/data_objects/data_objects_helper.rb +34 -5
  8. data/lib/testcentricity_web/data_objects/environment.rb +70 -8
  9. data/lib/testcentricity_web/data_objects/excel_helper.rb +1 -25
  10. data/lib/testcentricity_web/utility_helpers.rb +4 -0
  11. data/lib/testcentricity_web/version.rb +1 -1
  12. data/lib/testcentricity_web/web_core/page_object.rb +1 -93
  13. data/lib/testcentricity_web/web_core/page_objects_helper.rb +1 -7
  14. data/lib/testcentricity_web/web_core/page_section.rb +0 -91
  15. data/lib/testcentricity_web/web_core/webdriver_helper.rb +127 -52
  16. data/lib/testcentricity_web/web_elements/checkbox.rb +1 -15
  17. data/lib/testcentricity_web/web_elements/file_field.rb +1 -1
  18. data/lib/testcentricity_web/web_elements/radio.rb +1 -1
  19. data/lib/testcentricity_web/web_elements/select_list.rb +0 -52
  20. data/lib/testcentricity_web/web_elements/ui_elements_helper.rb +5 -14
  21. data/lib/testcentricity_web/world_extensions.rb +1 -1
  22. metadata +2 -12
  23. data/lib/testcentricity_web/web_elements/cell_button.rb +0 -8
  24. data/lib/testcentricity_web/web_elements/cell_checkbox.rb +0 -38
  25. data/lib/testcentricity_web/web_elements/cell_element.rb +0 -69
  26. data/lib/testcentricity_web/web_elements/cell_image.rb +0 -8
  27. data/lib/testcentricity_web/web_elements/cell_radio.rb +0 -31
  28. data/lib/testcentricity_web/web_elements/list_button.rb +0 -8
  29. data/lib/testcentricity_web/web_elements/list_checkbox.rb +0 -38
  30. data/lib/testcentricity_web/web_elements/list_element.rb +0 -61
  31. data/lib/testcentricity_web/web_elements/list_radio.rb +0 -31
  32. data/lib/testcentricity_web/web_elements/siebel_open_ui_helper.rb +0 -15
@@ -1,21 +1,45 @@
1
1
  module TestCentricity
2
2
  class EnvironData < TestCentricity::ExcelDataSource
3
3
  attr_accessor :current
4
+ attr_accessor :generic_data
5
+ attr_accessor :environ_specific_data
4
6
 
5
- WKS_ENVIRONS ||= 'Environments'
6
-
7
- def find_environ(environ_name, source_type = :excel)
7
+ def self.find_environ(environ_name, source_type = :excel)
8
8
  data = case source_type
9
9
  when :excel
10
- ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, WKS_ENVIRONS, environ_name)
10
+ ExcelData.read_row_data(XL_PRIMARY_DATA_FILE, 'Environments', environ_name)
11
11
  when :yaml
12
- read_yaml_node_data('environments.yml', environ_name)
12
+ # read generic test data from data.yml file
13
+ @generic_data ||= YAML.load_file(YML_PRIMARY_DATA_FILE)
14
+ # read environment specific test data
15
+ data_file = "#{PRIMARY_DATA_PATH}#{environ_name}_data.yml"
16
+ @environ_specific_data ||= YAML.load_file(data_file)
17
+
18
+ read('Environments', environ_name)
13
19
  when :json
14
20
  read_json_node_data('environments.json', environ_name)
15
21
  end
16
22
  @current = Environ.new(data)
17
23
  Environ.current = @current
18
24
  end
25
+
26
+ def self.read(key_name, node_name)
27
+ if @environ_specific_data.key?(key_name) && @environ_specific_data[key_name].key?(node_name)
28
+ node_data = @environ_specific_data[key_name][node_name]
29
+ else
30
+ raise "No key named #{key_name} in generic and environment-specific data" unless @generic_data.key?(key_name)
31
+ raise "No node named #{node_name} in #{key_name} section of generic and environment-specific data" unless @generic_data[key_name].key?(node_name)
32
+
33
+ node_data = @generic_data[key_name][node_name]
34
+ end
35
+
36
+ if node_data.is_a?(Hash)
37
+ node_data.each do |key, value|
38
+ node_data[key] = calculate_dynamic_value(value) if value.to_s.start_with?('eval!')
39
+ end
40
+ end
41
+ node_data
42
+ end
19
43
  end
20
44
 
21
45
 
@@ -36,11 +60,14 @@ module TestCentricity
36
60
  attr_accessor :device_name
37
61
  attr_accessor :device_type
38
62
  attr_accessor :device_os
63
+ attr_accessor :device_os_version
39
64
  attr_accessor :device_orientation
40
65
  attr_accessor :platform
41
66
  attr_accessor :driver
42
67
  attr_accessor :grid
43
68
  attr_accessor :tunneling
69
+ attr_accessor :locale
70
+ attr_accessor :language
44
71
 
45
72
  attr_accessor :parallel
46
73
  attr_accessor :process_num
@@ -58,8 +85,12 @@ module TestCentricity
58
85
  attr_accessor :user_id
59
86
  attr_accessor :password
60
87
  attr_accessor :append
88
+ attr_accessor :app_id
89
+ attr_accessor :api_key
61
90
  attr_accessor :option1
62
91
  attr_accessor :option2
92
+ attr_accessor :option3
93
+ attr_accessor :option4
63
94
  attr_accessor :dns
64
95
  attr_accessor :db_username
65
96
  attr_accessor :db_password
@@ -71,12 +102,18 @@ module TestCentricity
71
102
  @user_id = data['USER_ID']
72
103
  @password = data['PASSWORD']
73
104
  @append = data['APPEND']
105
+ @app_id = data['APP_ID']
106
+ @api_key = data['API_KEY']
74
107
  @option1 = data['OPTIONAL_1']
75
108
  @option2 = data['OPTIONAL_2']
109
+ @option3 = data['OPTIONAL_3']
110
+ @option4 = data['OPTIONAL_4']
76
111
  @dns = data['DNS']
77
112
  @db_username = data['DB_USERNAME']
78
113
  @db_password = data['DB_PASSWORD']
79
114
  @a11y_standard = ENV['ACCESSIBILITY_STANDARD'] || 'best-practice'
115
+ @locale = ENV['LOCALE'] || 'en'
116
+ @language = ENV['LANGUAGE'] || 'English'
80
117
 
81
118
  super
82
119
  end
@@ -205,6 +242,14 @@ module TestCentricity
205
242
  @device_os
206
243
  end
207
244
 
245
+ def self.device_os_version=(version)
246
+ @device_os_version = version
247
+ end
248
+
249
+ def self.device_os_version
250
+ @device_os_version
251
+ end
252
+
208
253
  def self.is_ios?
209
254
  @device_os == :ios
210
255
  end
@@ -245,6 +290,22 @@ module TestCentricity
245
290
  @tunneling
246
291
  end
247
292
 
293
+ def self.language=(language)
294
+ @language = language
295
+ end
296
+
297
+ def self.language
298
+ @language
299
+ end
300
+
301
+ def self.locale=(locale)
302
+ @locale = locale
303
+ end
304
+
305
+ def self.locale
306
+ @locale
307
+ end
308
+
248
309
  def self.platform=(platform)
249
310
  @platform = platform
250
311
  end
@@ -305,16 +366,17 @@ module TestCentricity
305
366
  report_header = "\n<b><u>TEST ENVIRONMENT</u>:</b> #{ENV['TEST_ENVIRONMENT']}\n"\
306
367
  " <b>Browser:</b>\t #{Environ.browser.capitalize}\n"
307
368
  report_header = "#{report_header} <b>Device:</b>\t\t #{Environ.device_name}\n" if Environ.device_name
308
- report_header = "#{report_header} <b>Device OS:</b>\t #{Environ.device_os}\n" if Environ.device_os
369
+ report_header = "#{report_header} <b>Device OS:</b>\t #{Environ.device_os} #{Environ.device_os_version}\n" if Environ.device_os
309
370
  report_header = "#{report_header} <b>Device type:</b>\t #{Environ.device_type}\n" if Environ.device_type
310
371
  report_header = "#{report_header} <b>Driver:</b>\t\t #{Environ.driver}\n" if Environ.driver
311
372
  report_header = "#{report_header} <b>Grid:</b>\t\t #{Environ.grid}\n" if Environ.grid
312
373
  report_header = "#{report_header} <b>OS:</b>\t\t\t #{Environ.os}\n" if Environ.os
313
- report_header = "#{report_header} <b>Locale:</b>\t\t #{ENV['LOCALE']}\n" if ENV['LOCALE']
314
- report_header = "#{report_header} <b>Language:</b>\t #{ENV['LANGUAGE']}\n" if ENV['LANGUAGE']
374
+ report_header = "#{report_header} <b>Locale:</b>\t\t #{Environ.locale}\n" if Environ.locale
375
+ report_header = "#{report_header} <b>Language:</b>\t #{Environ.language}\n" if Environ.language
315
376
  report_header = "#{report_header} <b>Country:</b>\t #{ENV['COUNTRY']}\n" if ENV['COUNTRY']
316
377
  report_header = "#{report_header} <b>WCAG Accessibility Standard:</b>\t #{ENV['ACCESSIBILITY_STANDARD']}\n" if ENV['ACCESSIBILITY_STANDARD']
317
378
  "#{report_header}\n\n"
318
379
  end
319
380
  end
320
381
  end
382
+
@@ -1,6 +1,3 @@
1
- require 'time'
2
- require 'chronic'
3
- require 'faker'
4
1
  require 'spreadsheet'
5
2
 
6
3
 
@@ -273,27 +270,6 @@ module TestCentricity
273
270
  # rename new Excel document, replacing the original
274
271
  File.rename(outfile, file)
275
272
  end
276
-
277
- private
278
-
279
- def self.calculate_dynamic_value(value)
280
- test_value = value.split('!', 2)
281
- parameter = test_value[1].split('.', 2)
282
- case parameter[0]
283
- when 'Date'
284
- result = eval("Chronic.parse('#{parameter[1]}')")
285
- when 'FormattedDate', 'FormatDate'
286
- date_time_params = parameter[1].split(' format! ', 2)
287
- date_time = eval("Chronic.parse('#{date_time_params[0].strip}')")
288
- result = date_time.to_s.format_date_time("#{date_time_params[1].strip}")
289
- else
290
- result = if Faker.constants.include?(parameter[0].to_sym)
291
- eval("Faker::#{parameter[0]}.#{parameter[1]}")
292
- else
293
- eval(test_value[1])
294
- end
295
- end
296
- result.to_s
297
- end
298
273
  end
299
274
  end
275
+
@@ -34,6 +34,10 @@ class String
34
34
  end
35
35
  end
36
36
 
37
+ def titlecase
38
+ "#{self.split.each{ |text| text.capitalize! }.join(' ')}"
39
+ end
40
+
37
41
  def is_int?
38
42
  Integer(self) && true rescue false
39
43
  end
@@ -1,3 +1,3 @@
1
1
  module TestCentricityWeb
2
- VERSION = '3.2.23'
2
+ VERSION = '4.0.1'
3
3
  end
@@ -5,8 +5,7 @@ module TestCentricity
5
5
  # @param element_name [Symbol] name of UI object (as a symbol)
6
6
  # @param locator [String] CSS selector or XPath expression that uniquely identifies object
7
7
  # @example
8
- # element :siebel_view, 'div#_sweview'
9
- # element :siebel_busy, "//html[contains(@class, 'siebui-busy')]"
8
+ # element :settings_item, 'a#userPreferencesTrigger'
10
9
  #
11
10
  def self.element(element_name, locator)
12
11
  define_page_element(element_name, TestCentricity::UIElement, locator)
@@ -288,97 +287,6 @@ module TestCentricity
288
287
  element_hash.each(&method(:filefield))
289
288
  end
290
289
 
291
- # Declare and instantiate a cell button in a table column on this page object.
292
- #
293
- # @param element_name [Symbol] name of cell button object (as a symbol)
294
- # @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
295
- # @param table [Symbol] Name (as a symbol) of parent table object
296
- # @param column [Integer] 1-based index of table column that contains the cell button object
297
- # @example
298
- # cell_button :show_button, "a[@class='show']", :data_table, 5
299
- # cell_button :edit_button, "a[@class='edit']", :data_table, 5
300
- #
301
- def self.cell_button(element_name, locator, table, column)
302
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
303
- end
304
-
305
- # Declare and instantiate a cell checkbox in a table column on this page object.
306
- #
307
- # @param element_name [Symbol] name of cell checkbox object (as a symbol)
308
- # @param locator [String] XPath expression that uniquely identifies cell checkbox within row and column of parent table object
309
- # @param table [Symbol] Name (as a symbol) of parent table object
310
- # @param column [Integer] 1-based index of table column that contains the cell checkbox object
311
- # @example
312
- # cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
313
- #
314
- def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
315
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
316
- end
317
-
318
- # Declare and instantiate a cell radio in a table column on this page object.
319
- #
320
- # @param element_name [Symbol] name of cell radio object (as a symbol)
321
- # @param locator [String] XPath expression that uniquely identifies cell radio within row and column of parent table object
322
- # @param table [Symbol] Name (as a symbol) of parent table object
323
- # @param column [Integer] 1-based index of table column that contains the cell radio object
324
- # @example
325
- # cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
326
- #
327
- def self.cell_radio(element_name, locator, table, column, proxy = nil)
328
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column}, #{proxy});end))
329
- end
330
-
331
- # Declare and instantiate a cell image in a table column on this page object.
332
- #
333
- # @param element_name [Symbol] name of cell image object (as a symbol)
334
- # @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
335
- # @param table [Symbol] Name (as a symbol) of parent table object
336
- # @param column [Integer] 1-based index of table column that contains the cell image object
337
- # @example
338
- # cell_image :ready_icon, "img[@class='ready']", :data_table, 3
339
- # cell_image :send_icon, "img[@class='send']", :data_table, 3
340
- #
341
- def self.cell_image(element_name, locator, table, column)
342
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :page, #{table}, #{column});end))
343
- end
344
-
345
- # Declare and instantiate a list button in a row of a list object on this page object.
346
- #
347
- # @param element_name [Symbol] name of list button object (as a symbol)
348
- # @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
349
- # @param list [Symbol] Name (as a symbol) of parent list object
350
- # @example
351
- # list_button :delete_button, "a[@class='delete']", :icon_list
352
- # list_button :edit_button, "a[@class='edit']", :icon_list
353
- #
354
- def self.list_button(element_name, locator, list)
355
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :page, #{list});end))
356
- end
357
-
358
- # Declare and instantiate a list checkbox in a row of a list object on this page object.
359
- #
360
- # @param element_name [Symbol] name of list checkbox object (as a symbol)
361
- # @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
362
- # @param list [Symbol] Name (as a symbol) of parent list object
363
- # @example
364
- # list_checkbox :is_registered_check, "a[@class='registered']", :data_list
365
- #
366
- def self.list_checkbox(element_name, locator, list, proxy = nil)
367
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
368
- end
369
-
370
- # Declare and instantiate a list radio in a row of a list object on this page object.
371
- #
372
- # @param element_name [Symbol] name of list radio object (as a symbol)
373
- # @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
374
- # @param list [Symbol] Name (as a symbol) of parent list object
375
- # @example
376
- # list_radio :sharing_radio, "a[@class='sharing']", :data_list
377
- #
378
- def self.list_radio(element_name, locator, list, proxy = nil)
379
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListRadio.new("#{element_name}", self, "#{locator}", :page, #{list}, #{proxy});end))
380
- end
381
-
382
290
  # Instantiate a single PageSection object for this page object.
383
291
  #
384
292
  # @param section_name [Symbol] name of PageSection object (as a symbol)
@@ -137,8 +137,6 @@ module TestCentricity
137
137
  ui_object.count(visible = true)
138
138
  when :count_all
139
139
  ui_object.count(visible = :all)
140
- when :siebel_options
141
- ui_object.get_siebel_options
142
140
  when :style
143
141
  ui_object.style
144
142
  when :href
@@ -282,11 +280,7 @@ module TestCentricity
282
280
  check_state = data_param.is_a?(String) ? data_param.to_bool : data_param
283
281
  data_field.set_checkbox_state(check_state)
284
282
  when :selectlist
285
- if data_field.get_siebel_object_type == 'JComboBox'
286
- data_field.set("#{data_param}\t")
287
- else
288
- data_field.choose_option(data_param)
289
- end
283
+ data_field.choose_option(data_param)
290
284
  when :radio
291
285
  check_state = data_param.is_a?(String) ? data_param.to_bool : data_param
292
286
  data_field.set_selected_state(check_state)
@@ -407,97 +407,6 @@ module TestCentricity
407
407
  element_hash.each(&method(:filefield))
408
408
  end
409
409
 
410
- # Declare and instantiate a cell button in a table column on this page section.
411
- #
412
- # @param element_name [Symbol] name of cell button object (as a symbol)
413
- # @param locator [String] XPath expression that uniquely identifies cell button within row and column of parent table object
414
- # @param table [Symbol] Name (as a symbol) of parent table object
415
- # @param column [Integer] 1-based index of table column that contains the cell button object
416
- # @example
417
- # cell_button :show_button, "a[@class='show']", :data_table, 5
418
- # cell_button :edit_button, "a[@class='edit']", :data_table, 5
419
- #
420
- def self.cell_button(element_name, locator, table, column)
421
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellButton.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column});end))
422
- end
423
-
424
- # Declare and instantiate a cell checkbox in a table column on this page section.
425
- #
426
- # @param element_name [Symbol] name of cell checkbox object (as a symbol)
427
- # @param locator [String] XPath expression that uniquely identifies cell checkbox within row and column of parent table object
428
- # @param table [Symbol] Name (as a symbol) of parent table object
429
- # @param column [Integer] 1-based index of table column that contains the cell checkbox object
430
- # @example
431
- # cell_checkbox :is_registered_check, "a[@class='registered']", :data_table, 4
432
- #
433
- def self.cell_checkbox(element_name, locator, table, column, proxy = nil)
434
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellCheckBox.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column}, #{proxy});end))
435
- end
436
-
437
- # Declare and instantiate a cell radio in a table column on this page section.
438
- #
439
- # @param element_name [Symbol] name of cell radio object (as a symbol)
440
- # @param locator [String] XPath expression that uniquely identifies cell radio within row and column of parent table object
441
- # @param table [Symbol] Name (as a symbol) of parent table object
442
- # @param column [Integer] 1-based index of table column that contains the cell radio object
443
- # @example
444
- # cell_radio :track_a_radio, "a[@class='track_a']", :data_table, 8
445
- #
446
- def self.cell_radio(element_name, locator, table, column, proxy = nil)
447
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column}, #{proxy});end))
448
- end
449
-
450
- # Declare and instantiate a cell image in a table column on this page object.
451
- #
452
- # @param element_name [Symbol] name of cell image object (as a symbol)
453
- # @param locator [String] XPath expression that uniquely identifies cell image within row and column of parent table object
454
- # @param table [Symbol] Name (as a symbol) of parent table object
455
- # @param column [Integer] 1-based index of table column that contains the cell image object
456
- # @example
457
- # cell_image :ready_icon, "img[@class='ready']", :data_table, 3
458
- # cell_image :send_icon, "img[@class='send']", :data_table, 3
459
- #
460
- def self.cell_image(element_name, locator, table, column)
461
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellImage.new("#{element_name}", self, "#{locator}", :section, #{table}, #{column});end))
462
- end
463
-
464
- # Declare and instantiate a list button in a row of a list object on this section object.
465
- #
466
- # @param element_name [Symbol] name of list button object (as a symbol)
467
- # @param locator [String] XPath expression that uniquely identifies list button within row of parent list object
468
- # @param list [Symbol] Name (as a symbol) of parent list object
469
- # @example
470
- # list_button :delete_button, "a[@class='delete']", :icon_list
471
- # list_button :edit_button, "a[@class='edit']", :icon_list
472
- #
473
- def self.list_button(element_name, locator, list)
474
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListButton.new("#{element_name}", self, "#{locator}", :section, #{list});end))
475
- end
476
-
477
- # Declare and instantiate a list checkbox in a row of a list object on this section object.
478
- #
479
- # @param element_name [Symbol] name of list checkbox object (as a symbol)
480
- # @param locator [String] XPath expression that uniquely identifies list checkbox within row of parent list object
481
- # @param list [Symbol] Name (as a symbol) of parent list object
482
- # @example
483
- # list_checkbox :is_registered_check, "a[@class='registered']", :data_list
484
- #
485
- def self.list_checkbox(element_name, locator, list, proxy = nil)
486
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::ListCheckBox.new("#{element_name}", self, "#{locator}", :section, #{list}, #{proxy});end))
487
- end
488
-
489
- # Declare and instantiate a list radio in a row of a list object on this section object.
490
- #
491
- # @param element_name [Symbol] name of list radio object (as a symbol)
492
- # @param locator [String] XPath expression that uniquely identifies list radio within row of parent list object
493
- # @param list [Symbol] Name (as a symbol) of parent list object
494
- # @example
495
- # list_radio :sharing_radio, "a[@class='sharing']", :data_list
496
- #
497
- def self.list_radio(element_name, locator, list, proxy = nil)
498
- class_eval(%(def #{element_name};@#{element_name} ||= TestCentricity::CellRadio.new("#{element_name}", self, "#{locator}", :section, #{list}, #{proxy});end))
499
- end
500
-
501
410
  # Instantiate a single PageSection object within this PageSection object.
502
411
  #
503
412
  # @param section_name [Symbol] name of PageSection object (as a symbol)
@@ -6,14 +6,23 @@ require 'fileutils'
6
6
 
7
7
 
8
8
  module TestCentricity
9
- module WebDriverConnect
9
+ class WebDriverConnect
10
10
  include Capybara::DSL
11
11
 
12
12
  attr_accessor :bs_local
13
13
  attr_accessor :downloads_path
14
14
 
15
- def self.initialize_web_driver(app_host = nil)
16
- Capybara.app_host = app_host unless app_host.nil?
15
+ def self.initialize_web_driver(options = nil)
16
+ desired_caps = nil
17
+ merge_caps = nil
18
+ if options.is_a?(String)
19
+ Capybara.app_host = options
20
+ elsif options.is_a?(Hash)
21
+ Capybara.app_host = options[:app_host] if options.key?(:app_host)
22
+ desired_caps = options[:desired_capabilities] if options.key?(:desired_capabilities)
23
+ merge_caps = options[:merge_capabilities] if options.key?(:merge_capabilities)
24
+ end
25
+
17
26
  browser = ENV['WEB_BROWSER']
18
27
  # set downloads folder path
19
28
  @downloads_path = "#{Dir.pwd}/downloads"
@@ -37,25 +46,25 @@ module TestCentricity
37
46
 
38
47
  context = case browser.downcase.to_sym
39
48
  when :appium
40
- initialize_appium
49
+ initialize_appium(desired_caps, merge_caps)
41
50
  'mobile device emulator'
42
51
  when :browserstack
43
- initialize_browserstack
52
+ initialize_browserstack(desired_caps, merge_caps)
44
53
  'Browserstack cloud service'
45
54
  when :crossbrowser
46
- initialize_crossbrowser
55
+ initialize_crossbrowser(desired_caps, merge_caps)
47
56
  'CrossBrowserTesting cloud service'
48
57
  when :gridlastic
49
- initialize_gridlastic
58
+ initialize_gridlastic(desired_caps, merge_caps)
50
59
  'Gridlastic cloud service'
51
60
  when :lambdatest
52
- initialize_lambdatest
61
+ initialize_lambdatest(desired_caps, merge_caps)
53
62
  'LambdaTest cloud service'
54
63
  when :saucelabs
55
- initialize_saucelabs
64
+ initialize_saucelabs(desired_caps, merge_caps)
56
65
  'Sauce Labs cloud service'
57
66
  when :testingbot
58
- initialize_testingbot
67
+ initialize_testingbot(desired_caps, merge_caps)
59
68
  'TestingBot cloud service'
60
69
  else
61
70
  if ENV['SELENIUM'] == 'remote'
@@ -124,21 +133,22 @@ module TestCentricity
124
133
 
125
134
  private
126
135
 
127
- def self.initialize_appium
136
+ def self.initialize_appium(desired_caps = nil, merge_caps = false)
128
137
  Environ.platform = :mobile
129
138
  Environ.device_name = ENV['APP_DEVICE']
130
- Environ.device_os = ENV['APP_PLATFORM_NAME']
139
+ Environ.device_os = ENV['APP_PLATFORM_NAME'].downcase.to_sym
131
140
  Environ.device_type = ENV['DEVICE_TYPE'] if ENV['DEVICE_TYPE']
141
+ Environ.device_os_version = ENV['APP_VERSION']
132
142
  Environ.device_orientation = ENV['ORIENTATION'] if ENV['ORIENTATION']
133
143
  Capybara.default_driver = :appium
134
144
  endpoint = 'http://localhost:4723/wd/hub'
135
145
  desired_capabilities = {
136
- platformName: ENV['APP_PLATFORM_NAME'],
137
- platformVersion: ENV['APP_VERSION'],
146
+ platformName: Environ.device_os,
147
+ platformVersion: Environ.device_os_version,
138
148
  browserName: ENV['APP_BROWSER'],
139
- deviceName: ENV['APP_DEVICE']
149
+ deviceName: Environ.device_name
140
150
  }
141
- desired_capabilities[:avd] = ENV['APP_DEVICE'] if ENV['APP_PLATFORM_NAME'].downcase.to_sym == :android
151
+ desired_capabilities[:avd] = ENV['APP_DEVICE'] if Environ.device_os == :android
142
152
  desired_capabilities[:automationName] = ENV['AUTOMATION_ENGINE'] if ENV['AUTOMATION_ENGINE']
143
153
  if ENV['UDID']
144
154
  Environ.device = :device
@@ -148,30 +158,49 @@ module TestCentricity
148
158
  desired_capabilities[:xcodeSigningId] = ENV['TEAM_NAME'] if ENV['TEAM_NAME']
149
159
  else
150
160
  Environ.device = :simulator
151
- desired_capabilities[:orientation] = ENV['ORIENTATION'].upcase if ENV['ORIENTATION']
161
+ desired_capabilities[:orientation] = Environ.device_orientation.upcase if Environ.device_orientation
152
162
  if Environ.device_os == :ios
153
- desired_capabilities[:language] = ENV['LANGUAGE'] if ENV['LANGUAGE']
154
- desired_capabilities[:locale] = ENV['LOCALE'].gsub('-', '_') if ENV['LOCALE']
163
+ desired_capabilities[:language] = Environ.language if Environ.language
164
+ desired_capabilities[:locale] = Environ.locale.gsub('-', '_') if Environ.locale
155
165
  end
156
166
  end
157
167
  desired_capabilities[:safariIgnoreFraudWarning] = ENV['APP_IGNORE_FRAUD_WARNING'] if ENV['APP_IGNORE_FRAUD_WARNING']
158
168
  desired_capabilities[:safariInitialUrl] = ENV['APP_INITIAL_URL'] if ENV['APP_INITIAL_URL']
159
169
  desired_capabilities[:safariAllowPopups] = ENV['APP_ALLOW_POPUPS'] if ENV['APP_ALLOW_POPUPS']
170
+
171
+ desired_capabilities[:autoAcceptAlerts] = ENV['AUTO_ACCEPT_ALERTS'] if ENV['AUTO_ACCEPT_ALERTS']
172
+ desired_capabilities[:autoDismissAlerts] = ENV['AUTO_DISMISS_ALERTS'] if ENV['AUTO_DISMISS_ALERTS']
173
+ desired_capabilities[:isHeadless] = ENV['HEADLESS'] if ENV['HEADLESS']
174
+
160
175
  desired_capabilities[:newCommandTimeout] = ENV['NEW_COMMAND_TIMEOUT'] if ENV['NEW_COMMAND_TIMEOUT']
161
176
  desired_capabilities[:noReset] = ENV['APP_NO_RESET'] if ENV['APP_NO_RESET']
162
177
  desired_capabilities[:fullReset] = ENV['APP_FULL_RESET'] if ENV['APP_FULL_RESET']
163
178
  desired_capabilities[:webkitDebugProxyPort] = ENV['WEBKIT_DEBUG_PROXY_PORT'] if ENV['WEBKIT_DEBUG_PROXY_PORT']
164
179
  desired_capabilities[:webDriverAgentUrl] = ENV['WEBDRIVER_AGENT_URL'] if ENV['WEBDRIVER_AGENT_URL']
165
- desired_capabilities[:wdaLocalPort] = ENV['WDA_LOCAL_PORT'] if ENV['WDA_LOCAL_PORT']
166
180
  desired_capabilities[:usePrebuiltWDA] = ENV['USE_PREBUILT_WDA'] if ENV['USE_PREBUILT_WDA']
167
181
  desired_capabilities[:useNewWDA] = ENV['USE_NEW_WDA'] if ENV['USE_NEW_WDA']
168
182
  desired_capabilities[:chromedriverExecutable] = ENV['CHROMEDRIVER_EXECUTABLE'] if ENV['CHROMEDRIVER_EXECUTABLE']
183
+ # set wdaLocalPort (iOS) or systemPort (Android) if PARALLEL_PORT is true
184
+ if ENV['PARALLEL'] && ENV['PARALLEL_PORT']
185
+ if Environ.device_os == :ios
186
+ desired_capabilities[:wdaLocalPort] = 8100 + ENV['TEST_ENV_NUMBER'].to_i
187
+ else
188
+ desired_capabilities[:systemPort] = 8200 + ENV['TEST_ENV_NUMBER'].to_i
189
+ end
190
+ else
191
+ desired_capabilities[:wdaLocalPort] = ENV['WDA_LOCAL_PORT'] if ENV['WDA_LOCAL_PORT']
192
+ desired_capabilities[:systemPort] = ENV['SYSTEM_PORT'] if ENV['SYSTEM_PORT']
193
+ end
194
+
195
+ unless desired_caps.nil?
196
+ desired_capabilities = merge_caps ? desired_capabilities.merge(desired_caps) : desired_caps
197
+ end
169
198
 
170
199
  Capybara.register_driver :appium do |app|
171
200
  appium_lib_options = { server_url: endpoint }
172
201
  all_options = {
173
- appium_lib: appium_lib_options,
174
- caps: desired_capabilities
202
+ appium_lib: appium_lib_options,
203
+ caps: desired_capabilities
175
204
  }
176
205
  Appium::Capybara::Driver.new app, all_options
177
206
  end
@@ -182,6 +211,8 @@ module TestCentricity
182
211
  'OS X'
183
212
  elsif OS.windows?
184
213
  'Windows'
214
+ elsif OS.linux?
215
+ 'Linux'
185
216
  end
186
217
 
187
218
  browser = ENV['WEB_BROWSER'].downcase.to_sym
@@ -200,8 +231,8 @@ module TestCentricity
200
231
  Capybara.register_driver :selenium do |app|
201
232
  case browser
202
233
  when :safari
203
- desired_caps = Selenium::WebDriver::Remote::Capabilities.safari(cleanSession: true)
204
- Capybara::Selenium::Driver.new(app, browser: browser, desired_capabilities: desired_caps)
234
+ caps = Selenium::WebDriver::Remote::Capabilities.safari(cleanSession: true)
235
+ Capybara::Selenium::Driver.new(app, browser: browser, desired_capabilities: caps)
205
236
  when :ie, :edge
206
237
  Capybara::Selenium::Driver.new(app, browser: browser)
207
238
  when :firefox, :firefox_headless
@@ -224,25 +255,29 @@ module TestCentricity
224
255
  options.args << '--headless' if browser == :firefox_headless
225
256
  Capybara::Selenium::Driver.new(app, browser: :firefox, options: options)
226
257
  when :chrome, :chrome_headless
227
- if browser == :chrome
228
- options = Selenium::WebDriver::Chrome::Options.new
229
- prefs = {
230
- prompt_for_download: false,
231
- directory_upgrade: true,
232
- default_directory: @downloads_path
233
- }
234
- options.add_preference(:download, prefs)
235
- else
236
- options = Selenium::WebDriver::Chrome::Options.new(args: %w[headless disable-gpu no-sandbox])
237
- end
258
+ options = Selenium::WebDriver::Chrome::Options.new
259
+ prefs = {
260
+ prompt_for_download: false,
261
+ directory_upgrade: true,
262
+ default_directory: @downloads_path
263
+ }
264
+ options.add_preference(:download, prefs)
238
265
  options.add_argument('--disable-infobars')
266
+ options.add_argument('--disable-dev-shm-usage')
239
267
  options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
268
+ if browser == :chrome_headless
269
+ options.add_argument('--headless')
270
+ options.add_argument('--disable-gpu')
271
+ options.add_argument('--no-sandbox')
272
+ end
273
+
240
274
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
241
275
  else
242
276
  if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
243
277
  user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
244
278
  options = Selenium::WebDriver::Chrome::Options.new
245
279
  options.add_argument('--disable-infobars')
280
+ options.add_argument('--disable-dev-shm-usage')
246
281
  options.add_argument("--user-agent='#{user_agent}'")
247
282
  options.add_argument("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
248
283
  Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
@@ -254,7 +289,7 @@ module TestCentricity
254
289
  Capybara.default_driver = :selenium
255
290
  end
256
291
 
257
- def self.initialize_browserstack
292
+ def self.initialize_browserstack(desired_caps = nil, merge_caps = false)
258
293
  browser = ENV['BS_BROWSER']
259
294
  Environ.grid = :browserstack
260
295
 
@@ -266,19 +301,22 @@ module TestCentricity
266
301
  elsif ENV['BS_OS']
267
302
  Environ.os = "#{ENV['BS_OS']} #{ENV['BS_OS_VERSION']}"
268
303
  end
304
+ Environ.device = if ENV['BS_REAL_MOBILE']
305
+ :device
306
+ elsif ENV['BS_PLATFORM']
307
+ :simulator
308
+ end
269
309
 
270
310
  endpoint = "http://#{ENV['BS_USERNAME']}:#{ENV['BS_AUTHKEY']}@hub-cloud.browserstack.com/wd/hub"
271
311
  Capybara.register_driver :browserstack do |app|
272
312
  capabilities = Selenium::WebDriver::Remote::Capabilities.new
273
313
 
274
314
  if ENV['BS_REAL_MOBILE']
275
- Environ.device = :device
276
315
  capabilities['device'] = ENV['BS_DEVICE']
277
316
  capabilities['realMobile'] = true
278
317
  capabilities['os_version'] = ENV['BS_OS_VERSION']
279
318
 
280
319
  elsif ENV['BS_PLATFORM']
281
- Environ.device = :simulator
282
320
  capabilities[:platform] = ENV['BS_PLATFORM']
283
321
  capabilities[:browserName] = browser
284
322
  capabilities['device'] = ENV['BS_DEVICE'] if ENV['BS_DEVICE']
@@ -340,6 +378,10 @@ module TestCentricity
340
378
  capabilities['cleanSession'] = 'true'
341
379
  end
342
380
 
381
+ unless desired_caps.nil?
382
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
383
+ end
384
+
343
385
  if ENV['TUNNELING']
344
386
  @bs_local = BrowserStack::Local.new
345
387
  bs_local_args = {'key' => "#{ENV['BS_AUTHKEY']}"}
@@ -368,7 +410,7 @@ module TestCentricity
368
410
  end
369
411
  end
370
412
 
371
- def self.initialize_crossbrowser
413
+ def self.initialize_crossbrowser(desired_caps = nil, merge_caps = false)
372
414
  browser = ENV['CB_BROWSER']
373
415
  Environ.grid = :crossbrowser
374
416
 
@@ -395,6 +437,11 @@ module TestCentricity
395
437
  elsif ENV['CB_PLATFORM']
396
438
  capabilities['os_api_name'] = ENV['CB_PLATFORM']
397
439
  end
440
+
441
+ unless desired_caps.nil?
442
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
443
+ end
444
+
398
445
  Capybara::Selenium::Driver.new(app, browser: :remote, url: endpoint, desired_capabilities: capabilities)
399
446
  end
400
447
 
@@ -410,12 +457,11 @@ module TestCentricity
410
457
  end
411
458
  end
412
459
 
413
- def self.initialize_gridlastic
460
+ def self.initialize_gridlastic(desired_caps = nil, merge_caps = false)
414
461
  browser = ENV['GL_BROWSER']
415
462
  Environ.grid = :gridlastic
416
463
  Environ.os = ENV['GL_OS']
417
464
  endpoint = "http://#{ENV['GL_USERNAME']}:#{ENV['GL_AUTHKEY']}@#{ENV['GL_SUBDOMAIN']}.gridlastic.com:80/wd/hub"
418
-
419
465
  capabilities = Selenium::WebDriver::Remote::Capabilities.new
420
466
  capabilities['browserName'] = browser
421
467
  capabilities['version'] = ENV['GL_VERSION'] if ENV['GL_VERSION']
@@ -423,6 +469,10 @@ module TestCentricity
423
469
  capabilities['platformName'] = ENV['GL_PLATFORM']
424
470
  capabilities['video'] = ENV['RECORD_VIDEO'].capitalize if ENV['RECORD_VIDEO']
425
471
 
472
+ unless desired_caps.nil?
473
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
474
+ end
475
+
426
476
  Capybara.register_driver :selenium do |app|
427
477
  client = Selenium::WebDriver::Remote::Http::Default.new
428
478
  client.timeout = 1200
@@ -446,7 +496,7 @@ module TestCentricity
446
496
  end
447
497
  end
448
498
 
449
- def self.initialize_lambdatest
499
+ def self.initialize_lambdatest(desired_caps = nil, merge_caps = false)
450
500
  browser = ENV['LT_BROWSER']
451
501
  Environ.grid = :lambdatest
452
502
  Environ.os = ENV['LT_OS']
@@ -485,6 +535,10 @@ module TestCentricity
485
535
  end
486
536
  capabilities['build'] = context_message
487
537
 
538
+ unless desired_caps.nil?
539
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
540
+ end
541
+
488
542
  Capybara::Selenium::Driver.new(app, browser: :remote, url: endpoint, desired_capabilities: capabilities)
489
543
  end
490
544
 
@@ -509,13 +563,23 @@ module TestCentricity
509
563
  when :firefox, :safari, :ie, :edge
510
564
  capabilities = Selenium::WebDriver::Remote::Capabilities.send(browser)
511
565
  when :chrome, :chrome_headless
512
- options = browser == :chrome ? %w[--disable-infobars] : %w[headless disable-gpu no-sandbox --disable-infobars]
566
+ options = %w[--disable-infobars]
567
+ options.push('--disable-dev-shm-usage')
513
568
  options.push("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
569
+ if browser == :chrome_headless
570
+ Environ.headless = true
571
+ options.push('--headless')
572
+ options.push('--disable-gpu')
573
+ options.push('--no-sandbox')
574
+ end
514
575
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome('goog:chromeOptions' => { args: options })
515
576
  else
516
577
  if ENV['HOST_BROWSER'] && ENV['HOST_BROWSER'].downcase.to_sym == :chrome
578
+ Environ.platform = :mobile
579
+ Environ.device_name = Browsers.mobile_device_name(ENV['WEB_BROWSER'])
517
580
  user_agent = Browsers.mobile_device_agent(ENV['WEB_BROWSER'])
518
581
  options = %w[--disable-infobars]
582
+ options.push('--disable-dev-shm-usage')
519
583
  options.push("--user-agent='#{user_agent}'")
520
584
  options.push("--lang=#{ENV['LOCALE']}") if ENV['LOCALE']
521
585
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome('goog:chromeOptions' => { args: options })
@@ -523,19 +587,22 @@ module TestCentricity
523
587
  raise "Requested browser '#{browser}' is not supported on Selenium Grid"
524
588
  end
525
589
  end
526
- Capybara::Selenium::Driver.new(app, browser: :remote, url: endpoint, desired_capabilities: capabilities)
590
+ Capybara::Selenium::Driver.new(app,
591
+ browser: :remote,
592
+ url: endpoint,
593
+ desired_capabilities: capabilities).tap do |driver|
594
+ # configure file_detector for remote uploads
595
+ driver.browser.file_detector = lambda do |args|
596
+ str = args.first.to_s
597
+ str if File.exist?(str)
598
+ end
599
+ end
527
600
  end
528
601
  Capybara.current_driver = :remote_browser
529
602
  Capybara.default_driver = :remote_browser
530
- # configure file_detector for remote uploads
531
- selenium = Capybara.page.driver.browser
532
- selenium.file_detector = lambda do |args|
533
- str = args.first.to_s
534
- str if File.exist?(str)
535
- end
536
603
  end
537
604
 
538
- def self.initialize_saucelabs
605
+ def self.initialize_saucelabs(desired_caps = nil, merge_caps = false)
539
606
  browser = ENV['SL_BROWSER']
540
607
  Environ.grid = :saucelabs
541
608
 
@@ -565,6 +632,10 @@ module TestCentricity
565
632
  capabilities['deviceOrientation'] = ENV['ORIENTATION'] if ENV['ORIENTATION']
566
633
  end
567
634
 
635
+ unless desired_caps.nil?
636
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
637
+ end
638
+
568
639
  Capybara::Selenium::Driver.new(app, browser: :remote, url: endpoint, desired_capabilities: capabilities)
569
640
  end
570
641
 
@@ -580,7 +651,7 @@ module TestCentricity
580
651
  end
581
652
  end
582
653
 
583
- def self.initialize_testingbot
654
+ def self.initialize_testingbot(desired_caps = nil, merge_caps = false)
584
655
  browser = ENV['TB_BROWSER']
585
656
  Environ.grid = :testingbot
586
657
 
@@ -613,6 +684,10 @@ module TestCentricity
613
684
  capabilities['deviceName'] = ENV['TB_DEVICE']
614
685
  end
615
686
 
687
+ unless desired_caps.nil?
688
+ capabilities = merge_caps ? capabilities.merge(desired_caps) : desired_caps
689
+ end
690
+
616
691
  Capybara::Selenium::Driver.new(app, browser: :remote, url: endpoint, desired_capabilities: capabilities)
617
692
  end
618
693