bucky-core 0.9.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.
- checksums.yaml +7 -0
- data/.circleci/config.yml +66 -0
- data/.codeclimate.yml +48 -0
- data/.dockerignore +11 -0
- data/.gitignore +40 -0
- data/.rspec +3 -0
- data/.rubocop.yml +76 -0
- data/.rubocop_todo.yml +51 -0
- data/Dockerfile +38 -0
- data/Dockerfile.system-test +44 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +115 -0
- data/LICENSE +201 -0
- data/README.md +246 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/bucky-core.gemspec +47 -0
- data/docker-compose.dev-with-bm.yml +28 -0
- data/docker-compose.dev.yml +18 -0
- data/docker-compose.system-test.yml +21 -0
- data/docker/nginx/Dockerfile +7 -0
- data/docker/nginx/nginx.conf +22 -0
- data/docker/nginx/public/index.html +19 -0
- data/docker/nginx/public/test_page.html +12 -0
- data/exe/bucky +214 -0
- data/lib/bucky.rb +3 -0
- data/lib/bucky/core/database/db_connector.rb +29 -0
- data/lib/bucky/core/database/test_data_operator.rb +195 -0
- data/lib/bucky/core/exception/bucky_exception.rb +39 -0
- data/lib/bucky/core/report/screen_shot_generator.rb +24 -0
- data/lib/bucky/core/test_core/test_case_loader.rb +162 -0
- data/lib/bucky/core/test_core/test_class_generator.rb +129 -0
- data/lib/bucky/core/test_core/test_manager.rb +70 -0
- data/lib/bucky/core/test_core/test_result.rb +92 -0
- data/lib/bucky/test_equipment/evidence/evidence_generator.rb +36 -0
- data/lib/bucky/test_equipment/pageobject/base_pageobject.rb +55 -0
- data/lib/bucky/test_equipment/pageobject/pages.rb +61 -0
- data/lib/bucky/test_equipment/selenium_handler/webdriver_handler.rb +66 -0
- data/lib/bucky/test_equipment/test_case/abst_test_case.rb +49 -0
- data/lib/bucky/test_equipment/test_case/e2e_test_case.rb +70 -0
- data/lib/bucky/test_equipment/test_case/linkstatus_test_case.rb +28 -0
- data/lib/bucky/test_equipment/user_operation/user_operation_helper.rb +97 -0
- data/lib/bucky/test_equipment/user_operation/user_operation_logger.rb +15 -0
- data/lib/bucky/test_equipment/user_operation/user_operator.rb +61 -0
- data/lib/bucky/test_equipment/verifications/abst_verification.rb +13 -0
- data/lib/bucky/test_equipment/verifications/e2e_verification.rb +106 -0
- data/lib/bucky/test_equipment/verifications/js_error_checker.rb +23 -0
- data/lib/bucky/test_equipment/verifications/service_verifications.rb +62 -0
- data/lib/bucky/test_equipment/verifications/status_checker.rb +180 -0
- data/lib/bucky/tools/lint.rb +69 -0
- data/lib/bucky/utils/bucky_logger.rb +25 -0
- data/lib/bucky/utils/bucky_output.rb +23 -0
- data/lib/bucky/utils/config.rb +55 -0
- data/lib/bucky/utils/requests.rb +33 -0
- data/lib/bucky/utils/yaml_load.rb +24 -0
- data/lib/bucky/version.rb +7 -0
- data/system_testing/test_bucky_project/.bucky_home +2 -0
- data/system_testing/test_bucky_project/config/bucky_config.yml +6 -0
- data/system_testing/test_bucky_project/config/e2e_config.yml +15 -0
- data/system_testing/test_bucky_project/config/linkstatus_config.yml +3 -0
- data/system_testing/test_bucky_project/config/test_db_config.yml +8 -0
- data/system_testing/test_bucky_project/services/README.md +1 -0
- data/system_testing/test_bucky_project/services/service_a/pc/pageobject/index.rb +13 -0
- data/system_testing/test_bucky_project/services/service_a/pc/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/pc_e2e.yml +68 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_each_pc_e2e.yml +20 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/setup_teardown_each_pc_e2e.yml +35 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/e2e/teardown_each_pc_e2e.yml +20 -0
- data/system_testing/test_bucky_project/services/service_a/pc/scenarios/linkstatus/pc_link.yml +10 -0
- data/system_testing/test_bucky_project/services/service_a/sp/pageobject/index.rb +14 -0
- data/system_testing/test_bucky_project/services/service_a/sp/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/sp/scenarios/e2e/sp_e2e_test.yml +26 -0
- data/system_testing/test_bucky_project/services/service_a/sp/scenarios/linkstatus/sp_link.yml +10 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/pageobject/index.rb +14 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/parts/index.yml +6 -0
- data/system_testing/test_bucky_project/services/service_a/tablet/scenarios/e2e/tablet_e2e_test.yml +26 -0
- data/system_testing/test_bucky_project/system/evidences/README.md +1 -0
- data/system_testing/test_bucky_project/system/evidences/screen_shots/README.md +1 -0
- data/system_testing/test_bucky_project/system/logs/README.md +1 -0
- data/system_testing/test_specification.md +38 -0
- data/system_testing/testing_code/command.bats +42 -0
- data/system_testing/testing_code/e2e.bats +75 -0
- data/system_testing/testing_code/linkstatus.bats +24 -0
- data/template/make_page/pc/pageobject/sample_page.rb +23 -0
- data/template/make_page/pc/parts/sample_page.yml +9 -0
- data/template/make_page/sp/pageobject/sample_page.rb +24 -0
- data/template/make_page/sp/parts/sample_page.yml +9 -0
- data/template/make_page/tablet/pageobject/sample_page.rb +24 -0
- data/template/make_page/tablet/parts/sample_page.yml +9 -0
- data/template/new/.bucky_home +2 -0
- data/template/new/config/bucky_config.yml +6 -0
- data/template/new/config/e2e_config.yml +15 -0
- data/template/new/config/linkstatus_config.yml +3 -0
- data/template/new/config/test_db_config.yml +8 -0
- data/template/new/services/README.md +1 -0
- data/template/new/system/evidences/README.md +1 -0
- data/template/new/system/evidences/screen_shots/README.md +1 -0
- data/template/new/system/logs/README.md +1 -0
- metadata +415 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require_relative '../verifications/status_checker'
|
|
5
|
+
require_relative './abst_test_case'
|
|
6
|
+
|
|
7
|
+
module Bucky
|
|
8
|
+
module TestEquipment
|
|
9
|
+
module TestCase
|
|
10
|
+
class LinkstatusTestCase < Bucky::TestEquipment::TestCase::AbstTestCase
|
|
11
|
+
include Bucky::TestEquipment::Verifications::StatusChecker
|
|
12
|
+
|
|
13
|
+
class << self
|
|
14
|
+
def startup; end
|
|
15
|
+
|
|
16
|
+
def shutdown; end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def setup; end
|
|
20
|
+
|
|
21
|
+
def teardown
|
|
22
|
+
# Call abst_test_case.teardown to get elappsed time of every test case
|
|
23
|
+
super
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Bucky
|
|
4
|
+
module TestEquipment
|
|
5
|
+
module UserOperation
|
|
6
|
+
class UserOperationHelper
|
|
7
|
+
def initialize(args)
|
|
8
|
+
@app = args[:app]
|
|
9
|
+
@device = args[:device]
|
|
10
|
+
@driver = args[:driver]
|
|
11
|
+
@pages = args[:pages]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Open url
|
|
15
|
+
# @param [Hash]
|
|
16
|
+
def go(args)
|
|
17
|
+
@driver.navigate.to args[:url]
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def back(_)
|
|
21
|
+
@driver.navigate.back
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def input(args)
|
|
25
|
+
@pages.get_part(args).send_keys args[:word]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Clear textbox
|
|
29
|
+
def clear(args)
|
|
30
|
+
@pages.get_part(args).clear
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def click(args)
|
|
34
|
+
elem = @pages.get_part(args)
|
|
35
|
+
elem.location_once_scrolled_into_view
|
|
36
|
+
sleep 1
|
|
37
|
+
elem.click
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def refresh(_)
|
|
41
|
+
@driver.navigate.refresh
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def switch_next_window(_)
|
|
45
|
+
@driver.switch_to.window(@driver.window_handles.last)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def back_to_window(_)
|
|
49
|
+
@driver.switch_to.window(@driver.window_handles.first)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Close window
|
|
53
|
+
def close(_)
|
|
54
|
+
@driver.close
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def stop(_)
|
|
58
|
+
puts 'stop. please enter to continue'
|
|
59
|
+
gets
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def choose(args)
|
|
63
|
+
option = Selenium::WebDriver::Support::Select.new(@pages.get_part(args))
|
|
64
|
+
if args.key?(:text)
|
|
65
|
+
type = :text
|
|
66
|
+
selected = args[type].to_s
|
|
67
|
+
elsif args.key?(:value)
|
|
68
|
+
type = :value
|
|
69
|
+
selected = args[type].to_s
|
|
70
|
+
elsif args.key?(:index)
|
|
71
|
+
type = :index
|
|
72
|
+
selected = args[type].to_i
|
|
73
|
+
else
|
|
74
|
+
raise StandardError, "Included invalid key #{args.keys}"
|
|
75
|
+
end
|
|
76
|
+
option.select_by(type, selected)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Alert accept
|
|
80
|
+
def accept_alert(_)
|
|
81
|
+
a = @driver.switch_to.alert
|
|
82
|
+
a.accept
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def wait(args)
|
|
86
|
+
# Indent
|
|
87
|
+
print ' ' * 6
|
|
88
|
+
args[:sec].times do |count|
|
|
89
|
+
print "#{count + 1} "
|
|
90
|
+
sleep 1
|
|
91
|
+
end
|
|
92
|
+
puts ''
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../core/exception/bucky_exception'
|
|
4
|
+
require_relative './user_operation_helper'
|
|
5
|
+
require_relative '../../utils/bucky_logger'
|
|
6
|
+
|
|
7
|
+
module Bucky
|
|
8
|
+
module TestEquipment
|
|
9
|
+
module UserOperation
|
|
10
|
+
class UserOperator
|
|
11
|
+
include Bucky::Utils::BuckyLogger
|
|
12
|
+
|
|
13
|
+
def initialize(args)
|
|
14
|
+
@operation_helper = Bucky::TestEquipment::UserOperation::UserOperationHelper.new(args)
|
|
15
|
+
@pages = args[:pages]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Call user operation by argument
|
|
19
|
+
# @param [String] operation
|
|
20
|
+
# @param [String] test_case_name
|
|
21
|
+
# @param [Hash] args
|
|
22
|
+
def method_missing(operation, test_case_name, **args)
|
|
23
|
+
@operation = operation
|
|
24
|
+
@test_case_name = test_case_name
|
|
25
|
+
Bucky::Utils::BuckyLogger.write(test_case_name, args)
|
|
26
|
+
|
|
27
|
+
# Call method of UserOperationHelper
|
|
28
|
+
return @operation_helper.send(@operation, args) if @operation_helper.methods.include?(@operation)
|
|
29
|
+
|
|
30
|
+
# Call method of page object
|
|
31
|
+
# e.g) {page: 'top', operation: 'input_freeword', word: 'testing word'}
|
|
32
|
+
return page_method(args) if args.key?(:page) && !args.key?(:part)
|
|
33
|
+
|
|
34
|
+
# Call method of part
|
|
35
|
+
part_mothod(args) if args.key?(:part)
|
|
36
|
+
rescue StandardError => e
|
|
37
|
+
Bucky::Core::Exception::WebdriverException.handle(e)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def page_method(args)
|
|
43
|
+
@pages.send(args[:page]).send(@operation, args)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def part_mothod(args)
|
|
47
|
+
# Multiple parts is saved as hash
|
|
48
|
+
# e.g){page: 'top', part: {locate: 'rosen_tokyo', num: 1}, operate: 'click'}
|
|
49
|
+
if args[:part].class == Hash
|
|
50
|
+
part_name = args[:part][:locate]
|
|
51
|
+
num = args[:part][:num]
|
|
52
|
+
@pages.send(args[:page]).send(part_name)[num].send(@operation)
|
|
53
|
+
# e.g.){page: 'top', part: 'rosen_tokyo', operate: 'click'}
|
|
54
|
+
else
|
|
55
|
+
@pages.send(args[:page]).send(args[:part]).send(@operation)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../../utils/bucky_logger'
|
|
4
|
+
require_relative '../../utils/bucky_output'
|
|
5
|
+
require_relative './abst_verification'
|
|
6
|
+
require_relative '../evidence/evidence_generator'
|
|
7
|
+
|
|
8
|
+
module Bucky
|
|
9
|
+
module TestEquipment
|
|
10
|
+
module Verifications
|
|
11
|
+
class E2eVerification < Bucky::TestEquipment::Verifications::AbstVerification
|
|
12
|
+
include Bucky::Utils::BuckyLogger
|
|
13
|
+
include Bucky::Utils::BuckyOutput
|
|
14
|
+
using StringColorize
|
|
15
|
+
|
|
16
|
+
def initialize(driver, pages, test_case_name)
|
|
17
|
+
@driver = driver
|
|
18
|
+
@pages = pages
|
|
19
|
+
@evidence = Bucky::TestEquipment::Evidence::E2eEvidence.new(driver: driver, test_case: test_case_name)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def pages_getter
|
|
23
|
+
@pages
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Check whether title of web page matches expected value
|
|
27
|
+
# @param [Hash]
|
|
28
|
+
def assert_title(**args)
|
|
29
|
+
Bucky::Utils::BuckyLogger.write('assert_title', args)
|
|
30
|
+
verify_rescue { assert_equal(args[:expect]&.to_s, @driver.title, 'Not Expected Title.') }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Check whether text of web element matches expected value
|
|
34
|
+
# @param [Hash]
|
|
35
|
+
def assert_text(**args)
|
|
36
|
+
Bucky::Utils::BuckyLogger.write('assert_text', args)
|
|
37
|
+
part = @pages.get_part(args)
|
|
38
|
+
verify_rescue { assert_equal(args[:expect]&.to_s, part.text, 'Not Expected Text.') }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Check whether text of web element contains expected value
|
|
42
|
+
# @param [Hash]
|
|
43
|
+
def assert_contained_text(**args)
|
|
44
|
+
Bucky::Utils::BuckyLogger.write('assert_contained_text', args)
|
|
45
|
+
part = @pages.get_part(args)
|
|
46
|
+
verify_rescue { assert(part.text.include?(args[:expect]&.to_s), "Not Contain Expected Text.\nexpect: #{args[:expect].to_s.bg_green.black}\nactual: #{part.text.to_s.bg_red.black}") }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Check whether url contains excepted value
|
|
50
|
+
# @param [Hash]
|
|
51
|
+
def assert_contained_url(**args)
|
|
52
|
+
Bucky::Utils::BuckyLogger.write('assert_contained_url', args)
|
|
53
|
+
verify_rescue { assert(@driver.current_url.include?(args[:expect]&.to_s), "Not Contain Expected URL.\nexpect: #{args[:expect].to_s.bg_green.black}\nactual: #{@driver.current_url.to_s.bg_red.black}") }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Check whether attribute of web element contains excepted value.
|
|
57
|
+
# @param [Hash]
|
|
58
|
+
def assert_contained_attribute(**args)
|
|
59
|
+
Bucky::Utils::BuckyLogger.write('assert_contained_attribute', args)
|
|
60
|
+
part = @pages.get_part(args)
|
|
61
|
+
verify_rescue { assert(part[args[:attribute]].include?(args[:expect]&.to_s), "Not Contain Expected Attribute.\nexpect: #{args[:expect].to_s.bg_green.black}\nactual: #{part[args[:attribute]].to_s.bg_red.black}") }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Check whether text of part is number
|
|
65
|
+
# @param [Hash]
|
|
66
|
+
def assert_is_number(**args)
|
|
67
|
+
Bucky::Utils::BuckyLogger.write('assert is number', args)
|
|
68
|
+
text = @pages.get_part(args).text.sub(',', '')
|
|
69
|
+
verify_rescue { assert(text.to_i.to_s == text.to_s, "Not number.\nactual: #{text.bg_red.black}") }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Check whether style property includes display:block
|
|
73
|
+
# @param [Hash]
|
|
74
|
+
def assert_display(**args)
|
|
75
|
+
Bucky::Utils::BuckyLogger.write('assert display', args)
|
|
76
|
+
verify_rescue { assert_true(@pages.get_part(args).displayed?, "No display this parts.\nURL: #{@driver.current_url}\npage: #{args[:page]}\npart: #{args[:part]}") }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Check whether web element exists
|
|
80
|
+
# @param [Hash]
|
|
81
|
+
def assert_exist_part(**args)
|
|
82
|
+
Bucky::Utils::BuckyLogger.write('assert_exist_part', args)
|
|
83
|
+
verify_rescue { assert_true(@pages.part_exist?(args), "This part is not exist.\nURL: #{@driver.current_url}\npage: #{args[:page]}\npart: #{args[:part]}") }
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Check whether web element don't exist
|
|
87
|
+
# @param [Hash]
|
|
88
|
+
def assert_not_exist_part(**args)
|
|
89
|
+
Bucky::Utils::BuckyLogger.write('assert_not_exist_part', args)
|
|
90
|
+
verify_rescue { assert_false(@pages.part_exist?(args), "This part is exist.\nURL: #{@driver.current_url}\npage: #{args[:page]}\npart: #{args[:part]}") }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
# Common exception method
|
|
96
|
+
# @param [Method] &assert
|
|
97
|
+
def verify_rescue
|
|
98
|
+
yield
|
|
99
|
+
rescue StandardError => e
|
|
100
|
+
@evidence.save_evidence(e)
|
|
101
|
+
raise e
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
module Bucky
|
|
6
|
+
module TestEquipment
|
|
7
|
+
module Verifications
|
|
8
|
+
module JsErrorChecker
|
|
9
|
+
include Test::Unit::Assertions
|
|
10
|
+
|
|
11
|
+
# Check Javascript Error in page
|
|
12
|
+
# @param [Webdriver] driver
|
|
13
|
+
def assert_no_js_error(driver)
|
|
14
|
+
js_errors = driver.execute_script(
|
|
15
|
+
'return window.JSErrorCollector_errors ? window.JSErrorCollector_errors.pump() : []'
|
|
16
|
+
)
|
|
17
|
+
# Empty is ok
|
|
18
|
+
assert_empty(js_errors, '[JS Error]')
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative '../verifications/e2e_verification'
|
|
4
|
+
|
|
5
|
+
module Bucky
|
|
6
|
+
module TestEquipment
|
|
7
|
+
module Verifications
|
|
8
|
+
class ServiceVerifications
|
|
9
|
+
attr_reader :e2e_verification
|
|
10
|
+
|
|
11
|
+
# @param [String] @service
|
|
12
|
+
# @param [String] @device (pc, sp)
|
|
13
|
+
# @param [Selenium::WebDriver::Remote::Driver] @driver
|
|
14
|
+
# @param [Bucky::TestEquipment::PageObject::Pages] @pages
|
|
15
|
+
# @param [String] @test_case_name
|
|
16
|
+
def initialize(args)
|
|
17
|
+
@service = args[:service]
|
|
18
|
+
@device = args[:device]
|
|
19
|
+
@driver = args[:driver]
|
|
20
|
+
@pages = args[:pages]
|
|
21
|
+
@test_case_name = args[:method_name]
|
|
22
|
+
collect_verifications
|
|
23
|
+
@e2e_verification = Bucky::TestEquipment::Verifications::E2eVerification.new(@driver, @pages, @test_case_name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def method_missing(verification, **args)
|
|
27
|
+
if e2e_verification.respond_to? verification
|
|
28
|
+
puts " #{verification} is defined in E2eVerificationClass."
|
|
29
|
+
e2e_verification.send(verification, args)
|
|
30
|
+
elsif args.key?(:page)
|
|
31
|
+
send(args[:page]).send(verification, args)
|
|
32
|
+
else
|
|
33
|
+
raise StandardError, "Undefined verification method or invalid arguments. #{verification},#{args}"
|
|
34
|
+
end
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
raise e
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
# Load page and define page verification method
|
|
42
|
+
def collect_verifications
|
|
43
|
+
module_service_name = @service.split('_').map(&:capitalize).join
|
|
44
|
+
Dir.glob("#{$bucky_home_dir}/services/#{@service}/#{@device}/verifications/*.rb").each do |file|
|
|
45
|
+
require file
|
|
46
|
+
|
|
47
|
+
page_name = file.split('/')[-1].sub('.rb', '')
|
|
48
|
+
page_class_name = page_name.split('_').map(&:capitalize).join
|
|
49
|
+
|
|
50
|
+
# Get instance of page object
|
|
51
|
+
page_class = eval(format('Services::%<module_service_name>s::%<device>s::Verifications::%<page_class_name>s', module_service_name: module_service_name, device: @device.capitalize, page_class_name: page_class_name))
|
|
52
|
+
page_instance = page_class.new(@driver, @pages, @test_case_name)
|
|
53
|
+
|
|
54
|
+
self.class.class_eval do
|
|
55
|
+
define_method(page_name) { page_instance }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
require 'nokogiri'
|
|
5
|
+
require 'parallel'
|
|
6
|
+
require_relative '../../utils/requests'
|
|
7
|
+
require_relative '../../utils/config'
|
|
8
|
+
|
|
9
|
+
REDIRECT_LIMIT = 5
|
|
10
|
+
|
|
11
|
+
# Check http status code from response
|
|
12
|
+
# 2xx -> OK
|
|
13
|
+
# 3xx -> request again
|
|
14
|
+
# 4xx~5xx -> NG
|
|
15
|
+
|
|
16
|
+
module Bucky
|
|
17
|
+
module TestEquipment
|
|
18
|
+
module Verifications
|
|
19
|
+
module StatusChecker
|
|
20
|
+
include Test::Unit::Assertions
|
|
21
|
+
include Bucky::Utils::Requests
|
|
22
|
+
|
|
23
|
+
# Check http status code
|
|
24
|
+
# @param [String] url
|
|
25
|
+
# @return [String] message
|
|
26
|
+
def http_status_check(args)
|
|
27
|
+
url = args[:url]
|
|
28
|
+
device = args[:device]
|
|
29
|
+
link_check_max_times = args[:link_check_max_times]
|
|
30
|
+
url_log = args[:url_log]
|
|
31
|
+
redirect_count = args[:redirect_count]
|
|
32
|
+
redirect_url_list = args[:redirect_url_list]
|
|
33
|
+
|
|
34
|
+
# If number of requests is over redirect limit
|
|
35
|
+
return { error_message: "\n[Redirect Error] #{url} is redirected more than #{REDIRECT_LIMIT}" } if redirect_count > REDIRECT_LIMIT
|
|
36
|
+
|
|
37
|
+
check_result = check_log_and_get_response(url, device, link_check_max_times, url_log)
|
|
38
|
+
# If result include response continue to check, else return result
|
|
39
|
+
!check_result.key?(:response) ? (return check_result) : response = check_result[:response]
|
|
40
|
+
|
|
41
|
+
# Store original url
|
|
42
|
+
redirect_url_list << url
|
|
43
|
+
case response.code
|
|
44
|
+
when /2[0-9]{2}/
|
|
45
|
+
url_log[url][:entity] = response.entity
|
|
46
|
+
puts " #{url} ... [#{response.code}:OK]"
|
|
47
|
+
{ entity: response.entity }
|
|
48
|
+
when /3[0-9]{2}/
|
|
49
|
+
fqdn = url[%r{^(https?:\/\/([a-zA-Z0-9\-_.]+))}]
|
|
50
|
+
redirect_url = response['location']
|
|
51
|
+
# Add fqdn if location doesn't include fqdn
|
|
52
|
+
redirect_url = fqdn << redirect_url unless redirect_url.include?('http')
|
|
53
|
+
puts " #{url} ... redirect to #{redirect_url} [#{response.code}:RD]"
|
|
54
|
+
http_status_check_args = { url: redirect_url, device: device, link_check_max_times: link_check_max_times, url_log: url_log, redirect_count: redirect_count + 1, redirect_url_list: redirect_url_list }
|
|
55
|
+
http_status_check(http_status_check_args)
|
|
56
|
+
when /(4|5)[0-9]{2}/
|
|
57
|
+
url_log[url][:error_message] = "[Status Error] http status returned #{response.code}.\ncheck this url: #{redirect_url_list.join(' -> ')}"
|
|
58
|
+
puts " #{url} ... [#{response.code}:NG]"
|
|
59
|
+
{ error_message: url_log[url][:error_message] }
|
|
60
|
+
else
|
|
61
|
+
url_log[url][:error_message] = "[Status Code Invalid Error] Status Code is Invalid. \n Status:#{response.code}"
|
|
62
|
+
{ error_message: url_log[url][:error_message] }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def link_status_check(args)
|
|
67
|
+
url = args[:url]
|
|
68
|
+
device = args[:device]
|
|
69
|
+
exclude_urls = args[:exclude_urls]
|
|
70
|
+
link_check_max_times = args[:link_check_max_times]
|
|
71
|
+
url_log = args[:url_log]
|
|
72
|
+
only_same_fqdn = args[:only_same_fqdn] ||= true
|
|
73
|
+
|
|
74
|
+
# Extract base url and check if it is valid
|
|
75
|
+
url_reg = %r{^(https?://([a-zA-Z0-9\-_.]+))}
|
|
76
|
+
url_obj = url.match(url_reg)
|
|
77
|
+
raise "Invalid URL #{url}" unless url_obj
|
|
78
|
+
|
|
79
|
+
base_url = url_obj[1]
|
|
80
|
+
base_fqdn = url_obj[2]
|
|
81
|
+
|
|
82
|
+
# Check base url
|
|
83
|
+
http_status_check_args = { url: url, device: device, link_check_max_times: link_check_max_times, url_log: url_log, redirect_count: 0, redirect_url_list: [] }
|
|
84
|
+
base_response = http_status_check(http_status_check_args)
|
|
85
|
+
assert_nil(base_response[:error_message], "Response of base URL is incorrect.\n#{base_response[:error_message]}")
|
|
86
|
+
|
|
87
|
+
# Collect links
|
|
88
|
+
links_args = { base_url: base_url, base_fqdn: base_fqdn, url_reg: url_reg, only_same_fqdn: only_same_fqdn, entity: base_response[:entity] }
|
|
89
|
+
links = make_target_links(links_args)
|
|
90
|
+
links = exclude(links, exclude_urls) unless exclude_urls.nil?
|
|
91
|
+
|
|
92
|
+
errors = []
|
|
93
|
+
Parallel.each(links.uniq, in_threads: Bucky::Utils::Config.instance[:linkstatus_parallel_num]) do |link|
|
|
94
|
+
http_status_check_args[:url] = link
|
|
95
|
+
http_status_check_args[:redirect_url_list] = []
|
|
96
|
+
link_response = http_status_check(http_status_check_args)
|
|
97
|
+
errors << link_response[:error_message] if link_response[:error_message]
|
|
98
|
+
end
|
|
99
|
+
assert_empty(errors, errors.join("\n"))
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def make_target_links(args)
|
|
103
|
+
base_url = args[:base_url]
|
|
104
|
+
base_fqdn = args[:base_fqdn]
|
|
105
|
+
url_reg = args[:url_reg]
|
|
106
|
+
only_same_fqdn = args[:only_same_fqdn]
|
|
107
|
+
entity = args[:entity]
|
|
108
|
+
doc = Nokogiri::HTML.parse(entity)
|
|
109
|
+
links = []
|
|
110
|
+
doc.xpath('//a').each do |node|
|
|
111
|
+
href = node.attr('href')
|
|
112
|
+
next if exclude_href?(href)
|
|
113
|
+
|
|
114
|
+
# Add fqdn if href doesn't include fqdn
|
|
115
|
+
unless url_reg.match?(href)
|
|
116
|
+
links << base_url + href
|
|
117
|
+
next
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
href_fqdn = href.match(url_reg)[2]
|
|
121
|
+
if only_same_fqdn == false
|
|
122
|
+
links << href
|
|
123
|
+
elsif base_fqdn == href_fqdn
|
|
124
|
+
links << href
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
links
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Exclude non test target url
|
|
131
|
+
def exclude(links, exclude_urls)
|
|
132
|
+
excluded_links = links - exclude_urls
|
|
133
|
+
|
|
134
|
+
# Exclude url if it has "*" in the last of it
|
|
135
|
+
exclude_urls.each do |ex_url|
|
|
136
|
+
next unless ex_url.end_with?('*')
|
|
137
|
+
|
|
138
|
+
excluded_links.delete_if { |l| l.start_with?(ex_url.delete('*')) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
excluded_links
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def exclude_href?(href)
|
|
147
|
+
return true if href.nil?
|
|
148
|
+
|
|
149
|
+
exclude_regexps = [/^javascript.+/, /^tel:\d.+/, /^mailto:.+/]
|
|
150
|
+
exclude_regexps.keep_if { |reg| reg.match?(href) }
|
|
151
|
+
return true unless exclude_regexps.empty?
|
|
152
|
+
|
|
153
|
+
false
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Check result hash and submit request or return result.
|
|
157
|
+
# Return: 1.(if request submitted) respons 2. (code 2xx)entity 3. (reach max check times)error message
|
|
158
|
+
def check_log_and_get_response(url, device, link_check_max_times, url_log)
|
|
159
|
+
unless url_log.key?(url)
|
|
160
|
+
response = get_response(url, device, Bucky::Utils::Config.instance[:linkstatus_open_timeout], Bucky::Utils::Config.instance[:linkstatus_read_timeout])
|
|
161
|
+
url_log[url] = { code: response.code, entity: nil, error_message: nil, count: 1 }
|
|
162
|
+
return { response: response }
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
if url_log[url][:code].match?(/2[0-9]{2}/)
|
|
166
|
+
puts " #{url} is already [#{url_log[url][:code]}:OK]"
|
|
167
|
+
return { entity: url_log[url][:entity] }
|
|
168
|
+
elsif url_log[url][:count] >= link_check_max_times
|
|
169
|
+
puts " #{url} reach maximum check times [#{url_log[url][:code]}:NG]"
|
|
170
|
+
return { error_message: url_log[url][:error_message] }
|
|
171
|
+
else
|
|
172
|
+
response = get_response(url, device, Bucky::Utils::Config.instance[:linkstatus_open_timeout], Bucky::Utils::Config.instance[:linkstatus_read_timeout])
|
|
173
|
+
url_log[url][:count] += 1
|
|
174
|
+
return { response: response }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|