cucumber_helper 0.0.5
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,114 @@
|
|
1
|
+
module CucumberHelper
|
2
|
+
module Support
|
3
|
+
# create random report path and set the ENV['REPORT_PATH']
|
4
|
+
def create_report_path
|
5
|
+
report_root = File.absolute_path('./report')
|
6
|
+
|
7
|
+
if ENV['REPORT_PATH'].nil? || ENV['REPORT_PATH'] == ''
|
8
|
+
# clear report files
|
9
|
+
# this is same purpose with rake:clear_report on rakefile but run locally
|
10
|
+
puts '=====:: Delete report directory via env.rb'
|
11
|
+
FileUtils.rm_rf(report_root, secure: true)
|
12
|
+
FileUtils.mkdir_p report_root
|
13
|
+
|
14
|
+
# init report files
|
15
|
+
# this is same purpose with rake:init_report on rakefile but run locally
|
16
|
+
ENV['REPORT_PATH'] = Faker::Number.number(digits: 8).to_s
|
17
|
+
puts "=====:: about to create report #{ENV['REPORT_PATH']} via env.rb"
|
18
|
+
end
|
19
|
+
|
20
|
+
path = report_root.to_s
|
21
|
+
FileUtils.mkdir_p path
|
22
|
+
path
|
23
|
+
end
|
24
|
+
|
25
|
+
# create the browser and screenshot data to Path argument
|
26
|
+
# ENV['BROWSER'] = chrome_headless should make the chrome in headless mode
|
27
|
+
def create_browser(path)
|
28
|
+
browser_profile = Selenium::WebDriver::Chrome::Profile.new
|
29
|
+
browser_options = Selenium::WebDriver::Chrome::Options.new profile: browser_profile
|
30
|
+
|
31
|
+
setup_options(browser_options)
|
32
|
+
register_driver(browser_options)
|
33
|
+
setup_browser_screenshot(path)
|
34
|
+
setup_host
|
35
|
+
end
|
36
|
+
|
37
|
+
def headless(browser_options)
|
38
|
+
browser_options.add_argument('--headless=new')
|
39
|
+
browser_options.add_argument('--no-sandbox')
|
40
|
+
browser_options.add_argument('--disable-gpu')
|
41
|
+
browser_options.add_argument('--disable-dev-shm-usage')
|
42
|
+
browser_options.add_argument('--enable-features=NetworkService,NetworkServiceInProcess')
|
43
|
+
end
|
44
|
+
|
45
|
+
def setup_options(browser_options)
|
46
|
+
headless(browser_options) if ENV['BROWSER'].eql?('chrome_headless')
|
47
|
+
browser_options.add_preference('download.default_directory', File.absolute_path('./features/data/downloaded'))
|
48
|
+
browser_options.add_preference(:download, default_directory: File.absolute_path('./features/data/downloaded'))
|
49
|
+
browser_options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
|
50
|
+
browser_options.add_preference('plugins.always_open_pdf_externally', true)
|
51
|
+
browser_options.add_preference(:plugins, always_open_pdf_externally: true)
|
52
|
+
browser_options.add_preference('profile.geolocation.default_content_setting', 1)
|
53
|
+
browser_options.add_preference('profile.default_content_setting_values.geolocation', 1)
|
54
|
+
end
|
55
|
+
|
56
|
+
def register_driver(browser_options)
|
57
|
+
Capybara.register_driver :chrome do |app|
|
58
|
+
browser_options.add_argument('--window-size=1440,877')
|
59
|
+
browser_options.add_argument('--user-agent=selenium')
|
60
|
+
|
61
|
+
client = Selenium::WebDriver::Remote::Http::Default.new
|
62
|
+
client.open_timeout = 60
|
63
|
+
client.read_timeout = 300
|
64
|
+
|
65
|
+
Capybara::Selenium::Driver.new(
|
66
|
+
app,
|
67
|
+
browser: :chrome,
|
68
|
+
options: browser_options,
|
69
|
+
http_client: client
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
Capybara.default_driver = ENV['CI'] == 'true' ? :selenium : :chrome
|
74
|
+
end
|
75
|
+
|
76
|
+
# config rspec
|
77
|
+
def config_rspec
|
78
|
+
# try to add this to fix net::readtimeout but still no luck
|
79
|
+
RSpec.configure do |config|
|
80
|
+
# show retry status in spec process
|
81
|
+
config.verbose_retry = true
|
82
|
+
# Try twice (retry once)
|
83
|
+
config.default_retry_count = 2
|
84
|
+
# Only retry when Selenium raises Net::ReadTimeout
|
85
|
+
config.exceptions_to_retry = [Net::ReadTimeout]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# setup the how the browser take screenshot and its saved path
|
90
|
+
def setup_browser_screenshot(path)
|
91
|
+
Capybara::Screenshot.register_driver(:chrome) do |driver, dir|
|
92
|
+
driver.browser.save_screenshot dir
|
93
|
+
end
|
94
|
+
Capybara::Screenshot.autosave_on_failure = true
|
95
|
+
Capybara::Screenshot.prune_strategy = { keep: 50 }
|
96
|
+
Capybara::Screenshot.append_timestamp = true
|
97
|
+
Capybara::Screenshot.webkit_options = {
|
98
|
+
width: 1440,
|
99
|
+
height: 877
|
100
|
+
}
|
101
|
+
Capybara.save_path = "#{path}/screenshots"
|
102
|
+
end
|
103
|
+
|
104
|
+
# setup the browser base url and the timeout
|
105
|
+
def setup_host
|
106
|
+
# we use this when call .load function
|
107
|
+
Capybara.app_host = ENV['BASE_URL']
|
108
|
+
Capybara.default_max_wait_time = DEFAULT_TIMEOUT
|
109
|
+
Capybara.javascript_driver = :chrome
|
110
|
+
Selenium::WebDriver.logger.level = :debug
|
111
|
+
Selenium::WebDriver.logger.output = 'selenium.log'
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module CucumberHelper
|
2
|
+
module Support
|
3
|
+
# get the scenario tags into array of tags
|
4
|
+
def scn_tags(scenario)
|
5
|
+
scenario.source_tag_names
|
6
|
+
end
|
7
|
+
|
8
|
+
# capture screenshot if the scenario failed
|
9
|
+
def capture_screenshot(scenario)
|
10
|
+
return unless scenario.failed?
|
11
|
+
|
12
|
+
p 'test failed!'
|
13
|
+
p "Getting screen shoot in session #{Capybara.session_name}"
|
14
|
+
Capybara.using_session_with_screenshot(Capybara.session_name.to_s) do
|
15
|
+
# screenshots will work and use the correct session
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# make scenario with @continue tag didn't delete its cookies/cache data
|
20
|
+
def handle_continue(scenario)
|
21
|
+
Capybara.session_name = :default
|
22
|
+
|
23
|
+
# if the scenario consist @continue tag, the session wont deleted
|
24
|
+
if scn_tags(scenario).include? '@continue'
|
25
|
+
Capybara.current_session.instance_variable_set(:@touched, false)
|
26
|
+
else
|
27
|
+
Capybara.current_session.driver.browser.manage.delete_all_cookies
|
28
|
+
Capybara.current_session.driver.browser.execute_script('localStorage.clear()')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# delete all downloaded file at ./features/data/downloaded
|
33
|
+
def delete_downloaded_file
|
34
|
+
return unless @downloaded_file.nil?
|
35
|
+
|
36
|
+
file = "#{File.absolute_path('./features/data/downloaded')}/#{@downloaded_file}"
|
37
|
+
File.delete(file) if File.file?(file)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# rubocop:disable Lint/UselessAssignment, /Lint/RescueException
|
4
|
+
def update_result_in_test_rail(test_rail_url, user_name, access_key, run_id, case_ids, status)
|
5
|
+
b_flag = true
|
6
|
+
if test_rail_url.to_s.strip.empty? || user_name.to_s.strip.empty? || access_key.to_s.strip.empty? || run_id.to_s.strip.empty? || case_ids.to_s.strip.empty? || status.to_s.strip.empty?
|
7
|
+
puts 'Specified parameters is not correct, please re-check !'
|
8
|
+
puts "Specified Test Rail URL : #{test_rail_url}"
|
9
|
+
puts "Specified Test Rail User Name : #{user_name}"
|
10
|
+
puts "Specified Test Rail Access Key : #{access_key}"
|
11
|
+
puts "Specified Test Rail Run Id : #{run_id}"
|
12
|
+
puts "Specified Test Rail Case Id : #{case_ids}"
|
13
|
+
puts "Specified Test Rail Status : #{status}"
|
14
|
+
else
|
15
|
+
obj_test_rail = TestRail::APIClient.new(test_rail_url)
|
16
|
+
obj_test_rail.user = user_name
|
17
|
+
obj_test_rail.password = access_key
|
18
|
+
coll_case_ids = case_ids.split(',')
|
19
|
+
if status.casecmp('passed').zero?
|
20
|
+
result = { status_id: 1, comment: 'This scenarios marked as PASSED by DEADPOOL' }
|
21
|
+
elsif status.casecmp('failed').zero?
|
22
|
+
result = { status_id: 5, comment: 'This scenarios marked as FAILED by DEADPOOL' }
|
23
|
+
end
|
24
|
+
puts "Updating test run id #{run_id}"
|
25
|
+
coll_case_ids.each do |id|
|
26
|
+
add_results_uri = "add_result_for_case/#{run_id}/#{id}"
|
27
|
+
obj_test_rail.send_post(add_results_uri, result)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
rescue Exception => e
|
31
|
+
b_flag = false
|
32
|
+
puts "Error Occured In Uploading The results in Test Rail, Error is : #{e.message}"
|
33
|
+
b_flag
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_rail_integration(arg_run_id, arg_case_ids, arg_status)
|
37
|
+
file_name = "#{Dir.pwd}/features/config/test_rail.yml"
|
38
|
+
test_rail_file = YAML.load_file(file_name)
|
39
|
+
url = test_rail_file['url']
|
40
|
+
user_name = test_rail_file['user_name']
|
41
|
+
access_key = test_rail_file['access_key']
|
42
|
+
if arg_status.empty? || arg_status.nil?
|
43
|
+
puts 'No result retrieved'
|
44
|
+
elsif update_result_in_test_rail(url, user_name, access_key, arg_run_id, arg_case_ids, arg_status)
|
45
|
+
puts "Result uploaded in Test Rail with case id #{arg_case_ids} Successfully!"
|
46
|
+
else
|
47
|
+
puts "Result uploaded in Test Rail with case id #{arg_case_ids} Failed!"
|
48
|
+
end
|
49
|
+
rescue Exception => e
|
50
|
+
puts "Error Occured in Test Rail Integration, Error Desc is : #{e.message}"
|
51
|
+
end
|
52
|
+
# rubocop:enable Lint/UselessAssignment
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'net/http'
|
4
|
+
require 'net/https'
|
5
|
+
require 'uri'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
module TestRail
|
9
|
+
class APIClient
|
10
|
+
@url = ''
|
11
|
+
@user = ''
|
12
|
+
@password = ''
|
13
|
+
|
14
|
+
attr_accessor :user, :password
|
15
|
+
|
16
|
+
def initialize(base_url)
|
17
|
+
base_url += '/' unless base_url =~ %r{/$}
|
18
|
+
@url = "#{base_url}index.php?/api/v2/"
|
19
|
+
end
|
20
|
+
|
21
|
+
def send_get(uri, data = nil)
|
22
|
+
_send_request('GET', uri, data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def send_post(uri, data)
|
26
|
+
_send_request('POST', uri, data)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def _send_request(method, uri, data)
|
32
|
+
url = URI.parse(@url + uri)
|
33
|
+
if method == 'POST'
|
34
|
+
request = Net::HTTP::Post.new("#{url.path}?#{url.query}")
|
35
|
+
if uri.start_with?('add_attachment')
|
36
|
+
# SOURCE: https://yukimotopress.github.io/http
|
37
|
+
boundary = 'TestRailAPIAttachmentBoundary'
|
38
|
+
post_body = []
|
39
|
+
post_body << "--#{boundary}\r\n"
|
40
|
+
post_body << "Content-Disposition: form-data; name=\"attachment\"; filename=\"#{File.basename(data)}\"\r\n"
|
41
|
+
post_body << "\r\n"
|
42
|
+
post_body << File.read(data)
|
43
|
+
post_body << "\r\n--#{boundary}--\r\n"
|
44
|
+
|
45
|
+
request.body = post_body.join
|
46
|
+
request['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
|
47
|
+
else
|
48
|
+
request['Content-Type'] = 'application/json'
|
49
|
+
request.body = JSON.dump(data)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
request = Net::HTTP::Get.new("#{url.path}?#{url.query}")
|
53
|
+
request['Content-Type'] = 'application/json'
|
54
|
+
end
|
55
|
+
request.basic_auth(@user, @password)
|
56
|
+
|
57
|
+
conn = Net::HTTP.new(url.host, url.port)
|
58
|
+
if url.scheme == 'https'
|
59
|
+
conn.use_ssl = true
|
60
|
+
conn.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
61
|
+
end
|
62
|
+
response = conn.request(request)
|
63
|
+
|
64
|
+
if response.body && !response.body.empty? && (response.code == '200')
|
65
|
+
if uri.start_with?('get_attachment/')
|
66
|
+
File.write(data, response.body)
|
67
|
+
result = data
|
68
|
+
else
|
69
|
+
result = JSON.parse(response.body)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
result = {}
|
73
|
+
end
|
74
|
+
|
75
|
+
if response.code != '200'
|
76
|
+
error = if result.key?('error')
|
77
|
+
"\"#{result['error']}\""
|
78
|
+
else
|
79
|
+
'No additional error message received'
|
80
|
+
end
|
81
|
+
raise APIError, format('TestRail API returned HTTP %<code>s (%<error>s)', { code: response.code, error: error })
|
82
|
+
end
|
83
|
+
result
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class APIError < StandardError; end
|
88
|
+
end
|