testcentricity_web 3.2.23 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
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