ruby_raider 3.12.0 → 3.13.0

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/README.md +2 -0
  4. data/lib/commands/utility_commands.rb +16 -0
  5. data/lib/generators/automation/templates/page.tt +8 -3
  6. data/lib/generators/automation/templates/partials/initialize_selector.tt +3 -3
  7. data/lib/generators/automation/templates/partials/url_methods.tt +3 -2
  8. data/lib/generators/automation/templates/partials/visit_method.tt +5 -5
  9. data/lib/generators/cucumber/cucumber_generator.rb +1 -1
  10. data/lib/generators/cucumber/templates/env.tt +3 -3
  11. data/lib/generators/cucumber/templates/partials/selenium_env.tt +65 -1
  12. data/lib/generators/cucumber/templates/steps.tt +2 -2
  13. data/lib/generators/cucumber/templates/user_factory.tt +2 -0
  14. data/lib/generators/cucumber/templates/world.tt +5 -3
  15. data/lib/generators/generator.rb +25 -12
  16. data/lib/generators/helper_generator.rb +7 -0
  17. data/lib/generators/rspec/templates/accessibility_spec.tt +10 -10
  18. data/lib/generators/rspec/templates/spec.tt +2 -1
  19. data/lib/generators/templates/common/gemfile.tt +9 -9
  20. data/lib/generators/templates/common/partials/web_config.tt +7 -0
  21. data/lib/generators/templates/common/read_me.tt +45 -0
  22. data/lib/generators/templates/helpers/appium_helper.tt +17 -15
  23. data/lib/generators/templates/helpers/browser_helper.tt +1 -2
  24. data/lib/generators/templates/helpers/driver_helper.tt +22 -0
  25. data/lib/generators/templates/helpers/partials/appium_driver.tt +1 -1
  26. data/lib/generators/templates/helpers/partials/selenium_driver.tt +11 -1
  27. data/lib/generators/templates/helpers/raider_element.tt +4 -4
  28. data/lib/generators/templates/helpers/session_state.tt +1 -1
  29. data/lib/generators/templates/helpers/spec_helper.tt +20 -1
  30. data/lib/generators/templates/helpers/trace_helper.tt +1097 -0
  31. data/lib/generators/templates/helpers/wait_helper.tt +145 -4
  32. data/lib/ruby_raider.rb +9 -2
  33. data/lib/utilities/utilities.rb +7 -0
  34. data/lib/version +1 -1
  35. data/ruby_raider.gemspec +1 -0
  36. data/sig/commands/utility_commands.rbs +2 -0
  37. data/sig/generators/generator.rbs +6 -0
  38. data/sig/generators/helper_generator.rbs +1 -0
  39. data/sig/ruby_raider.rbs +1 -0
  40. data/sig/utilities/utilities.rbs +1 -0
  41. data/spec/commands/raider_commands_spec.rb +25 -1
  42. data/spec/fixtures/watir_master/cucumber_watir/features/step_definitions/login_steps.rb.snapshot +1 -1
  43. data/spec/fixtures/watir_master/cucumber_watir/page_objects/abstract/page.rb.snapshot +2 -4
  44. data/spec/fixtures/watir_master/rspec_watir/page_objects/abstract/page.rb.snapshot +2 -4
  45. data/spec/generators/fixtures/video_helper_stubs/selenium-webdriver.rb +11 -2
  46. data/spec/generators/trace_helper_spec.rb +945 -0
  47. data/spec/integration/content/config_content_spec.rb +20 -0
  48. data/spec/integration/content/content_helper.rb +1 -5
  49. data/spec/integration/content/cucumber_reporter_content_spec.rb +51 -0
  50. data/spec/integration/content/gemfile_content_spec.rb +2 -2
  51. data/spec/integration/content/helper_content_spec.rb +60 -1
  52. data/spec/integration/content/readme_content_spec.rb +46 -0
  53. data/spec/integration/content/rspec_reporter_content_spec.rb +2 -2
  54. data/spec/integration/content/rubocop_content_spec.rb +87 -0
  55. data/spec/integration/content/syntax_validation_spec.rb +31 -51
  56. data/spec/integration/content/test_content_spec.rb +5 -2
  57. data/spec/integration/end_to_end_spec.rb +415 -29
  58. data/spec/integration/frozen_string_literal_matcher.rb +13 -0
  59. data/spec/integration/generators/helpers_generator_spec.rb +26 -0
  60. data/spec/integration/generators/invoke_generators_spec.rb +60 -0
  61. data/spec/integration/helpers/wait_helper_spec.rb +183 -0
  62. data/spec/integration/scaffolding_e2e_spec.rb +1 -5
  63. data/spec/integration/trace_format_checker.rb +141 -0
  64. data/spec/integration/trace_page_server.rb +80 -0
  65. data/spec/utilities/trace_command_spec.rb +66 -0
  66. metadata +29 -2
@@ -5,12 +5,34 @@ require 'yaml'
5
5
  require 'active_support/inflector'
6
6
  require 'selenium-webdriver'
7
7
  require_relative 'video_helper'
8
+ <%- if trace_helper? -%>
9
+ require_relative 'trace_helper'
10
+ <%- end -%>
8
11
  <%- else -%>
9
12
  require 'appium_lib'
10
13
  <%- end -%>
11
14
 
12
15
  module DriverHelper
13
16
  <%- if selenium_based? -%>
17
+ # Selenium takes one listener: this one hands every event on to the video and trace listeners.
18
+ class FanOutListener < Selenium::WebDriver::Support::AbstractEventListener
19
+ def self.for(listeners)
20
+ listeners.empty? ? nil : new(listeners)
21
+ end
22
+
23
+ def initialize(listeners)
24
+ super()
25
+ @listeners = listeners
26
+ end
27
+
28
+ Selenium::WebDriver::Support::AbstractEventListener.instance_methods(false).each do |event|
29
+ define_method(event) do |*args|
30
+ @listeners.each { |listener| listener.public_send(event, *args) if listener.respond_to?(event) }
31
+ nil
32
+ end
33
+ end
34
+ end
35
+
14
36
  def driver(*opts)
15
37
  @driver ||= create_driver(*opts)
16
38
  end
@@ -32,7 +32,7 @@
32
32
  end
33
33
  <%- end -%>
34
34
 
35
- <%= partial('browserstack_config', strip: true) %>
35
+ <%= partial('browserstack_config', strip: true) %>
36
36
 
37
37
  def configure_driver
38
38
  if browserstack?
@@ -2,11 +2,19 @@
2
2
  @config = YAML.load_file('config/config.yml')
3
3
  browser = @config['browser']
4
4
  arguments = { options: create_webdriver_options(*opts) }
5
- listener = VideoHelper.listener
5
+ listener = FanOutListener.for(listeners)
6
6
  arguments[:listener] = listener if listener
7
7
  Selenium::WebDriver.for(browser.to_sym, **arguments)
8
8
  end
9
9
 
10
+ # The helpers' Selenium listeners. Deleting video_helper.rb or trace_helper.rb needs only its require.
11
+ def listeners
12
+ listeners = []
13
+ listeners << VideoHelper.listener if defined?(VideoHelper)
14
+ listeners << TraceHelper.listener if defined?(TraceHelper)
15
+ listeners.compact
16
+ end
17
+
10
18
  def browser_arguments(*opts)
11
19
  args = opts.empty? ? @config['browser_arguments'][@config['browser']] : opts
12
20
  args += ['--headless'] if (ENV['HEADLESS'] || @config['headless']) && !args.include?('--headless')
@@ -18,5 +26,7 @@
18
26
  browser = load_browser == 'ie' ? load_browser.upcase : load_browser.capitalize
19
27
  options = "Selenium::WebDriver::#{browser}::Options".constantize.new
20
28
  browser_arguments(*opts).each { |arg| options.add_argument(arg) }
29
+ # WebDriver BiDi carries the trace's network and console (chrome, edge and firefox).
30
+ options.web_socket_url = true if defined?(TraceHelper) && TraceHelper.bidi?(load_browser)
21
31
  options
22
32
  end
@@ -65,13 +65,13 @@ class RaiderElement
65
65
  end
66
66
 
67
67
  def send_keys(*keys, timeout: nil)
68
- perform(:send_keys, timeout) { |element| element.send_keys(*keys) }
68
+ perform(:send_keys, timeout, args: keys) { |element| element.send_keys(*keys) }
69
69
  self
70
70
  end
71
71
 
72
72
  <%- unless mobile? -%>
73
73
  def select_by(how, what, timeout: nil)
74
- perform(:select_by, timeout) { |element| Selenium::WebDriver::Support::Select.new(element).select_by(how, what) }
74
+ perform(:select_by, timeout, args: [how, what]) { |element| Selenium::WebDriver::Support::Select.new(element).select_by(how, what) }
75
75
  self
76
76
  end
77
77
 
@@ -143,8 +143,8 @@ class RaiderElement
143
143
  WaitHelper::Lookup.for(@driver, locator, by, scope: @lookup)
144
144
  end
145
145
 
146
- def perform(action, timeout, &block)
147
- waiter(timeout).perform_action(action, @lookup, WaitHelper::Waiter::CHECKS.fetch(action), &block)
146
+ def perform(action, timeout, args: nil, &block)
147
+ waiter(timeout).perform_action(action, @lookup, WaitHelper::Waiter::CHECKS.fetch(action), args: args, &block)
148
148
  end
149
149
 
150
150
  def method_missing(name, *args, **options, &block)
@@ -17,7 +17,7 @@ require 'yaml'
17
17
  class SessionState
18
18
  FORMAT = 1
19
19
  DEFAULT_MAX_AGE = 3600
20
- NAME_PATTERN = /\A[a-z0-9_-]+\z/.freeze
20
+ NAME_PATTERN = Regexp.new('\A[a-z0-9_-]+\z').freeze
21
21
  DIR = File.join('.raider', 'auth')
22
22
  READ_STORAGE = 'return Object.assign({}, window[arguments[0]]);'
23
23
  WRITE_STORAGE = 'var s = window[arguments[0]]; s.clear(); var d = arguments[1]; ' \
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- <%- if axe_addon? %>
3
+ <%- if axe_addon? -%>
4
4
  require 'axe-rspec'
5
5
  <%- end -%>
6
6
  require 'rspec'
@@ -62,6 +62,10 @@ module SpecHelper
62
62
  <%- end -%>
63
63
  @video_recorder = VideoHelper.recorder_for(<%= watir? ? 'browser' : 'driver' %>)
64
64
  @video_recorder.start
65
+ <%- if trace_helper? -%>
66
+ @trace_recorder = TraceHelper.recorder_for(driver) if defined?(TraceHelper)
67
+ @trace_recorder&.start
68
+ <%- end -%>
65
69
  end
66
70
  <%- if web? && examples? -%>
67
71
 
@@ -80,6 +84,15 @@ module SpecHelper
80
84
 
81
85
  config.after(:each) do |example|
82
86
  example_name = example.description
87
+ <%- if trace_helper? -%>
88
+ if defined?(TraceHelper)
89
+ attempt = example.metadata[:retry_attempts].to_i + 1
90
+ keep_trace = TraceHelper.keep_all? || (example.exception && (defined?(VideoHelper) ? VideoHelper.final_attempt?(example) : true))
91
+ trace_test = { identifier: example.id.delete_prefix('./'), full_name: example.full_description,
92
+ status: example.exception ? 'failed' : 'passed', attempt: attempt, error: example.exception }
93
+ trace_path = @trace_recorder&.stop(keep: keep_trace, test: trace_test)
94
+ end
95
+ <%- end -%>
83
96
  keep_video = example.exception ? VideoHelper.final_attempt?(example) : false
84
97
  video_path = @video_recorder&.stop(keep: keep_video)
85
98
  if example.exception
@@ -91,7 +104,13 @@ module SpecHelper
91
104
  end
92
105
  end
93
106
  RaiderReporter.attach('video', video_path, type: <%= mobile? ? ':mp4' : ':webm' %>) if video_path
107
+ <%- if trace_helper? -%>
108
+ RaiderReporter.attach('trace', trace_path, type: :trace, attempt: attempt) if trace_path
109
+ <%- end -%>
94
110
  ensure
111
+ <%- if trace_helper? -%>
112
+ @trace_recorder&.cleanup
113
+ <%- end -%>
95
114
  @video_recorder&.cleanup
96
115
  <%= partial('quit_driver', strip: true) %>
97
116
  end