chemlab 0.4.0 → 0.7.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.
- checksums.yaml +4 -4
- data/Rakefile +8 -0
- data/bin/chemlab +10 -0
- data/bin/chemlab-suite +1 -0
- data/bin/chemlab-test +1 -0
- data/lib/chemlab.rb +27 -17
- data/lib/chemlab/attributable.rb +16 -10
- data/lib/chemlab/cli/fixtures/new_library/.gitignore +63 -0
- data/lib/chemlab/cli/fixtures/new_library/Gemfile +5 -0
- data/lib/chemlab/cli/fixtures/new_library/README.md.erb +1 -0
- data/lib/chemlab/cli/fixtures/new_library/lib/new_library.rb.erb +7 -0
- data/lib/chemlab/cli/fixtures/new_library/lib/page/sample.rb.erb +9 -0
- data/lib/chemlab/cli/fixtures/new_library/new_library.gemspec.erb +23 -0
- data/lib/chemlab/cli/fixtures/new_library/spec/integration/page/sample_spec.rb.erb +17 -0
- data/lib/chemlab/cli/fixtures/new_library/spec/unit/page/sample_spec.rb.erb +19 -0
- data/lib/chemlab/cli/generator.rb +46 -0
- data/lib/chemlab/cli/generator/templates/page.erb +3 -0
- data/lib/chemlab/cli/new_library.rb +62 -0
- data/lib/chemlab/cli/stub.erb +66 -0
- data/lib/chemlab/cli/stubber.rb +74 -0
- data/lib/chemlab/component.rb +78 -8
- data/lib/chemlab/configuration.rb +60 -12
- data/lib/chemlab/element.rb +4 -0
- data/lib/chemlab/page.rb +19 -1
- data/lib/chemlab/runtime/browser.rb +13 -18
- data/lib/chemlab/runtime/env.rb +13 -9
- data/lib/chemlab/runtime/logger.rb +16 -13
- data/lib/chemlab/version.rb +1 -1
- data/lib/tasks/generate.rake +22 -0
- data/lib/tasks/generate_stubs.rake +20 -0
- data/lib/tasks/help.rake +24 -0
- data/lib/tasks/new.rake +19 -0
- data/lib/tasks/version.rake +8 -0
- metadata +113 -57
- data/lib/chemlab/api_fabricator.rb +0 -134
- data/lib/chemlab/resource.rb +0 -169
- data/lib/chemlab/runtime/api_client.rb +0 -18
- data/lib/chemlab/support/api.rb +0 -71
- data/lib/chemlab/support/logging.rb +0 -176
- data/lib/chemlab/support/repeater.rb +0 -65
- data/lib/chemlab/support/waiter.rb +0 -39
@@ -1,134 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/object/deep_dup'
|
4
|
-
|
5
|
-
module Chemlab
|
6
|
-
# API Fabricator
|
7
|
-
module ApiFabricator
|
8
|
-
ResourceFabricationFailedError = Class.new(RuntimeError)
|
9
|
-
ResourceNotDeletedError = Class.new(RuntimeError)
|
10
|
-
ResourceNotFoundError = Class.new(RuntimeError)
|
11
|
-
ResourceQueryError = Class.new(RuntimeError)
|
12
|
-
ResourceUpdateFailedError = Class.new(RuntimeError)
|
13
|
-
ResourceURLMissingError = Class.new(RuntimeError)
|
14
|
-
InternalServerError = Class.new(RuntimeError)
|
15
|
-
|
16
|
-
attr_reader :api_resource, :api_response
|
17
|
-
attr_writer :api_client
|
18
|
-
attr_accessor :user
|
19
|
-
|
20
|
-
def api_support?
|
21
|
-
respond_to?(:api_get_path) &&
|
22
|
-
(respond_to?(:api_post_path) && respond_to?(:api_post_body)) ||
|
23
|
-
(respond_to?(:api_put_path) && respond_to?(:api_put_body))
|
24
|
-
end
|
25
|
-
|
26
|
-
def fabricate_via_api!
|
27
|
-
unless api_support?
|
28
|
-
raise NotImplementedError, "Resource #{self.class.name} does not support fabrication via the API!"
|
29
|
-
end
|
30
|
-
|
31
|
-
resource_web_url(api_post)
|
32
|
-
end
|
33
|
-
|
34
|
-
def reload!
|
35
|
-
api_get
|
36
|
-
|
37
|
-
self
|
38
|
-
end
|
39
|
-
|
40
|
-
def remove_via_api!
|
41
|
-
api_delete
|
42
|
-
end
|
43
|
-
|
44
|
-
def eager_load_api_client!
|
45
|
-
return unless api_client.nil?
|
46
|
-
|
47
|
-
api_client.tap do |client|
|
48
|
-
# Eager-load the API client so that the personal token creation isn't
|
49
|
-
# taken in account in the actual resource creation timing.
|
50
|
-
client.user = user
|
51
|
-
client.personal_access_token
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
include Support::API
|
56
|
-
|
57
|
-
attr_writer :api_resource, :api_response
|
58
|
-
|
59
|
-
def api_put(body = api_put_body)
|
60
|
-
response = put(
|
61
|
-
Runtime::API::Request.new(api_client, api_put_path).url,
|
62
|
-
body)
|
63
|
-
|
64
|
-
unless response.code == HTTP_STATUS_OK
|
65
|
-
raise ResourceFabricationFailedError, "Updating #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
|
66
|
-
end
|
67
|
-
|
68
|
-
process_api_response(parse_body(response))
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
def resource_web_url(resource)
|
74
|
-
resource.fetch(:web_url) do
|
75
|
-
raise ResourceURLMissingError, "API resource for #{self.class.name} does not expose a `web_url` property: `#{resource}`."
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def api_get
|
80
|
-
process_api_response(parse_body(api_get_from(api_get_path)))
|
81
|
-
end
|
82
|
-
|
83
|
-
def api_get_from(get_path)
|
84
|
-
url = Runtime::API::Request.new(api_client, get_path).url
|
85
|
-
response = get(url)
|
86
|
-
|
87
|
-
if response.code == HTTP_STATUS_SERVER_ERROR
|
88
|
-
raise InternalServerError, "Failed to GET #{url} - (#{response.code}): `#{response}`."
|
89
|
-
elsif response.code != HTTP_STATUS_OK
|
90
|
-
raise ResourceNotFoundError, "Resource at #{url} could not be found (#{response.code}): `#{response}`."
|
91
|
-
end
|
92
|
-
|
93
|
-
response
|
94
|
-
end
|
95
|
-
|
96
|
-
def api_post
|
97
|
-
response = post(
|
98
|
-
Runtime::API::Request.new(api_client, api_post_path).url,
|
99
|
-
api_post_body)
|
100
|
-
|
101
|
-
unless response.code == HTTP_STATUS_CREATED
|
102
|
-
raise ResourceFabricationFailedError, "Fabrication of #{self.class.name} using the API failed (#{response.code}) with `#{response}`."
|
103
|
-
end
|
104
|
-
|
105
|
-
process_api_response(parse_body(response))
|
106
|
-
end
|
107
|
-
|
108
|
-
def api_delete
|
109
|
-
url = Runtime::API::Request.new(api_client, api_delete_path).url
|
110
|
-
response = delete(url)
|
111
|
-
|
112
|
-
unless [HTTP_STATUS_NO_CONTENT, HTTP_STATUS_ACCEPTED].include? response.code
|
113
|
-
raise ResourceNotDeletedError, "Resource at #{url} could not be deleted (#{response.code}): `#{response}`."
|
114
|
-
end
|
115
|
-
|
116
|
-
response
|
117
|
-
end
|
118
|
-
|
119
|
-
def api_client
|
120
|
-
@api_client ||= begin
|
121
|
-
Runtime::API::Client.new(:gitlab, is_new_session: !current_url.start_with?('http'), user: user)
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
def process_api_response(parsed_response)
|
126
|
-
self.api_response = parsed_response
|
127
|
-
self.api_resource = transform_api_resource(parsed_response.deep_dup)
|
128
|
-
end
|
129
|
-
|
130
|
-
def transform_api_resource(api_resource)
|
131
|
-
api_resource
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
data/lib/chemlab/resource.rb
DELETED
@@ -1,169 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_support/core_ext/array/extract_options'
|
4
|
-
|
5
|
-
module Chemlab
|
6
|
-
class Resource
|
7
|
-
extend SingleForwardable
|
8
|
-
include ApiFabricator
|
9
|
-
|
10
|
-
NoValueError = Class.new(RuntimeError)
|
11
|
-
|
12
|
-
def_delegators :evaluator, :attribute
|
13
|
-
|
14
|
-
def initialize(api_client)
|
15
|
-
@api_client = api_client
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.fabricate!(*args, &prepare_block)
|
19
|
-
fabricate_via_api!(*args, &prepare_block)
|
20
|
-
rescue NotImplementedError
|
21
|
-
fabricate_via_browser_ui!(*args, &prepare_block)
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.fabricate_via_browser_ui!(*args, &prepare_block)
|
25
|
-
options = args.extract_options!
|
26
|
-
resource = options.fetch(:resource) { new }
|
27
|
-
parents = options.fetch(:parents) { [] }
|
28
|
-
|
29
|
-
do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
|
30
|
-
log_fabrication(:browser_ui, resource, parents, args) { resource.fabricate!(*args) }
|
31
|
-
|
32
|
-
current_url
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.fabricate_via_api!(*args, &prepare_block)
|
37
|
-
options = args.extract_options!
|
38
|
-
resource = options.fetch(:resource) { new }
|
39
|
-
parents = options.fetch(:parents) { [] }
|
40
|
-
|
41
|
-
raise NotImplementedError unless resource.api_support?
|
42
|
-
|
43
|
-
resource.eager_load_api_client!
|
44
|
-
|
45
|
-
do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
|
46
|
-
log_fabrication(:api, resource, parents, args) { resource.fabricate_via_api! }
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.remove_via_api!(*args, &prepare_block)
|
51
|
-
options = args.extract_options!
|
52
|
-
resource = options.fetch(:resource) { new }
|
53
|
-
parents = options.fetch(:parents) { [] }
|
54
|
-
|
55
|
-
resource.eager_load_api_client!
|
56
|
-
|
57
|
-
do_fabricate!(resource: resource, prepare_block: prepare_block, parents: parents) do
|
58
|
-
log_fabrication(:api, resource, parents, args) { resource.remove_via_api! }
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def fabricate!(*_args)
|
63
|
-
raise NotImplementedError
|
64
|
-
end
|
65
|
-
|
66
|
-
def visit!
|
67
|
-
Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"])
|
68
|
-
|
69
|
-
# Just in case an async action is not yet complete
|
70
|
-
Support::WaitForRequests.wait_for_requests
|
71
|
-
|
72
|
-
Support::Retrier.retry_until do
|
73
|
-
visit(web_url)
|
74
|
-
wait_until { current_url.include?(URI.parse(web_url).path.split('/').last || web_url) }
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def populate(*attributes)
|
79
|
-
attributes.each(&method(:public_send))
|
80
|
-
end
|
81
|
-
|
82
|
-
def wait_until(max_duration: 60, sleep_interval: 0.1)
|
83
|
-
Support::Waiter.wait_until(max_duration: max_duration, sleep_interval: sleep_interval) do
|
84
|
-
yield
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
private
|
89
|
-
|
90
|
-
def populate_attribute(name, block)
|
91
|
-
value = attribute_value(name, block)
|
92
|
-
|
93
|
-
raise NoValueError, "No value was computed for #{name} of #{self.class.name}." unless value
|
94
|
-
|
95
|
-
value
|
96
|
-
end
|
97
|
-
|
98
|
-
def attribute_value(name, block)
|
99
|
-
api_value = api_resource&.dig(name)
|
100
|
-
|
101
|
-
if api_value && block
|
102
|
-
log_having_both_api_result_and_block(name, api_value)
|
103
|
-
end
|
104
|
-
|
105
|
-
api_value || (block && instance_exec(&block))
|
106
|
-
end
|
107
|
-
|
108
|
-
def log_having_both_api_result_and_block(name, api_value)
|
109
|
-
QA::Runtime::Logger.info "<#{self.class}> Attribute #{name.inspect} has both API response `#{api_value}` and a block. API response will be picked. Block will be ignored."
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.do_fabricate!(resource:, prepare_block:, parents: [])
|
113
|
-
prepare_block.call(resource) if prepare_block
|
114
|
-
|
115
|
-
resource_web_url = yield
|
116
|
-
resource.web_url = resource_web_url
|
117
|
-
|
118
|
-
resource
|
119
|
-
end
|
120
|
-
|
121
|
-
private_class_method :do_fabricate!
|
122
|
-
|
123
|
-
def self.log_fabrication(method, resource, parents, args)
|
124
|
-
return yield unless Runtime::Env.debug?
|
125
|
-
|
126
|
-
start = Time.now
|
127
|
-
prefix = "==#{'=' * parents.size}>"
|
128
|
-
msg = [prefix]
|
129
|
-
msg << "Built a #{name}"
|
130
|
-
msg << "as a dependency of #{parents.last}" if parents.any?
|
131
|
-
msg << "via #{method}"
|
132
|
-
|
133
|
-
yield.tap do
|
134
|
-
msg << "in #{Time.now - start} seconds"
|
135
|
-
puts msg.join(' ')
|
136
|
-
puts if parents.empty?
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
private_class_method :log_fabrication
|
141
|
-
|
142
|
-
def self.evaluator
|
143
|
-
@evaluator ||= DSL.new(self)
|
144
|
-
end
|
145
|
-
|
146
|
-
private_class_method :evaluator
|
147
|
-
|
148
|
-
class DSL
|
149
|
-
def initialize(base)
|
150
|
-
@base = base
|
151
|
-
end
|
152
|
-
|
153
|
-
def attribute(name, &block)
|
154
|
-
@base.module_eval do
|
155
|
-
attr_writer(name)
|
156
|
-
|
157
|
-
define_method(name) do
|
158
|
-
instance_variable_get("@#{name}") ||
|
159
|
-
instance_variable_set(
|
160
|
-
"@#{name}",
|
161
|
-
populate_attribute(name, block))
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
attribute :web_url
|
168
|
-
end
|
169
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'airborne'
|
4
|
-
|
5
|
-
module Chemlab
|
6
|
-
module Runtime
|
7
|
-
module API
|
8
|
-
class Client
|
9
|
-
attr_reader :address, :user
|
10
|
-
|
11
|
-
def initialize(address = :gitlab, personal_access_token: nil, is_new_session: true, user: nil, ip_limits: false)
|
12
|
-
@address = address
|
13
|
-
@user = user
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
data/lib/chemlab/support/api.rb
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Chemlab
|
4
|
-
module Support
|
5
|
-
module API
|
6
|
-
HTTP_STATUS_OK = 200
|
7
|
-
HTTP_STATUS_CREATED = 201
|
8
|
-
HTTP_STATUS_NO_CONTENT = 204
|
9
|
-
HTTP_STATUS_ACCEPTED = 202
|
10
|
-
HTTP_STATUS_SERVER_ERROR = 500
|
11
|
-
|
12
|
-
def post(url, payload)
|
13
|
-
RestClient::Request.execute(
|
14
|
-
method: :post,
|
15
|
-
url: url,
|
16
|
-
payload: payload,
|
17
|
-
verify_ssl: false)
|
18
|
-
rescue RestClient::ExceptionWithResponse => e
|
19
|
-
return_response_or_raise(e)
|
20
|
-
end
|
21
|
-
|
22
|
-
def get(url, raw_response: false)
|
23
|
-
RestClient::Request.execute(
|
24
|
-
method: :get,
|
25
|
-
url: url,
|
26
|
-
verify_ssl: false,
|
27
|
-
raw_response: raw_response)
|
28
|
-
rescue RestClient::ExceptionWithResponse => e
|
29
|
-
return_response_or_raise(e)
|
30
|
-
end
|
31
|
-
|
32
|
-
def put(url, payload)
|
33
|
-
RestClient::Request.execute(
|
34
|
-
method: :put,
|
35
|
-
url: url,
|
36
|
-
payload: payload,
|
37
|
-
verify_ssl: false)
|
38
|
-
rescue RestClient::ExceptionWithResponse => e
|
39
|
-
return_response_or_raise(e)
|
40
|
-
end
|
41
|
-
|
42
|
-
def delete(url)
|
43
|
-
RestClient::Request.execute(
|
44
|
-
method: :delete,
|
45
|
-
url: url,
|
46
|
-
verify_ssl: false)
|
47
|
-
rescue RestClient::ExceptionWithResponse => e
|
48
|
-
return_response_or_raise(e)
|
49
|
-
end
|
50
|
-
|
51
|
-
def head(url)
|
52
|
-
RestClient::Request.execute(
|
53
|
-
method: :head,
|
54
|
-
url: url,
|
55
|
-
verify_ssl: false)
|
56
|
-
rescue RestClient::ExceptionWithResponse => e
|
57
|
-
return_response_or_raise(e)
|
58
|
-
end
|
59
|
-
|
60
|
-
def parse_body(response)
|
61
|
-
JSON.parse(response.body, symbolize_names: true)
|
62
|
-
end
|
63
|
-
|
64
|
-
def return_response_or_raise(error)
|
65
|
-
raise error unless error.respond_to?(:response) && error.response
|
66
|
-
|
67
|
-
error.response
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
@@ -1,176 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Chemlab
|
4
|
-
module Support
|
5
|
-
module Logging
|
6
|
-
def assert_no_element(name)
|
7
|
-
log("asserting no element :#{name}")
|
8
|
-
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def refresh
|
13
|
-
log("refreshing #{current_url}")
|
14
|
-
|
15
|
-
super
|
16
|
-
end
|
17
|
-
|
18
|
-
def scroll_to(selector, text: nil)
|
19
|
-
msg = "scrolling to :#{selector}"
|
20
|
-
msg += " with text: #{text}" if text
|
21
|
-
log(msg)
|
22
|
-
|
23
|
-
super
|
24
|
-
end
|
25
|
-
|
26
|
-
def asset_exists?(url)
|
27
|
-
exists = super
|
28
|
-
|
29
|
-
log("asset_exists? #{url} returned #{exists}")
|
30
|
-
|
31
|
-
exists
|
32
|
-
end
|
33
|
-
|
34
|
-
def find_element(name, **kwargs)
|
35
|
-
log("finding :#{name} with args #{kwargs}")
|
36
|
-
|
37
|
-
element = super
|
38
|
-
|
39
|
-
log("found :#{name}") if element
|
40
|
-
|
41
|
-
element
|
42
|
-
end
|
43
|
-
|
44
|
-
def all_elements(name, **kwargs)
|
45
|
-
log("finding all :#{name} with args #{kwargs}")
|
46
|
-
|
47
|
-
elements = super
|
48
|
-
|
49
|
-
log("found #{elements.size} :#{name}") if elements
|
50
|
-
|
51
|
-
elements
|
52
|
-
end
|
53
|
-
|
54
|
-
def check_element(name)
|
55
|
-
log("checking :#{name}")
|
56
|
-
|
57
|
-
super
|
58
|
-
end
|
59
|
-
|
60
|
-
def uncheck_element(name)
|
61
|
-
log("unchecking :#{name}")
|
62
|
-
|
63
|
-
super
|
64
|
-
end
|
65
|
-
|
66
|
-
def click_element(name, page = nil, **kwargs)
|
67
|
-
msg = ["clicking :#{name}"]
|
68
|
-
msg << ", expecting to be at #{page.class}" if page
|
69
|
-
msg << "with args #{kwargs}"
|
70
|
-
|
71
|
-
log(msg.compact.join(' '))
|
72
|
-
|
73
|
-
super
|
74
|
-
end
|
75
|
-
|
76
|
-
def fill_element(name, content)
|
77
|
-
masked_content = name.to_s.include?('password') ? '*****' : content
|
78
|
-
|
79
|
-
log(%Q(filling :#{name} with "#{masked_content}"))
|
80
|
-
|
81
|
-
super
|
82
|
-
end
|
83
|
-
|
84
|
-
def select_element(name, value)
|
85
|
-
log(%Q(selecting "#{value}" in :#{name}))
|
86
|
-
|
87
|
-
super
|
88
|
-
end
|
89
|
-
|
90
|
-
def has_element?(name, **kwargs)
|
91
|
-
found = super
|
92
|
-
|
93
|
-
log_has_element_or_not('has_element?', name, found, **kwargs)
|
94
|
-
|
95
|
-
found
|
96
|
-
end
|
97
|
-
|
98
|
-
def has_no_element?(name, **kwargs)
|
99
|
-
found = super
|
100
|
-
|
101
|
-
log_has_element_or_not('has_no_element?', name, found, **kwargs)
|
102
|
-
|
103
|
-
found
|
104
|
-
end
|
105
|
-
|
106
|
-
def has_text?(text, **kwargs)
|
107
|
-
found = super
|
108
|
-
|
109
|
-
log(%Q{has_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}})
|
110
|
-
|
111
|
-
found
|
112
|
-
end
|
113
|
-
|
114
|
-
def has_no_text?(text, **kwargs)
|
115
|
-
found = super
|
116
|
-
|
117
|
-
log(%Q{has_no_text?('#{text}', wait: #{kwargs[:wait] || Capybara.default_max_wait_time}) returned #{found}})
|
118
|
-
|
119
|
-
found
|
120
|
-
end
|
121
|
-
|
122
|
-
def finished_loading?
|
123
|
-
log('waiting for loading to complete...')
|
124
|
-
now = Time.now
|
125
|
-
|
126
|
-
loaded = super
|
127
|
-
|
128
|
-
log("loading complete after #{Time.now - now} seconds")
|
129
|
-
|
130
|
-
loaded
|
131
|
-
end
|
132
|
-
|
133
|
-
def wait_for_animated_element(name)
|
134
|
-
log("waiting for animated element: #{name}")
|
135
|
-
|
136
|
-
super
|
137
|
-
end
|
138
|
-
|
139
|
-
def within_element(name, text: nil)
|
140
|
-
log("within element :#{name}")
|
141
|
-
|
142
|
-
element = super
|
143
|
-
|
144
|
-
log("end within element :#{name}")
|
145
|
-
|
146
|
-
element
|
147
|
-
end
|
148
|
-
|
149
|
-
def within_element_by_index(name, index)
|
150
|
-
log("within elements :#{name} at index #{index}")
|
151
|
-
|
152
|
-
element = super
|
153
|
-
|
154
|
-
log("end within elements :#{name} at index #{index}")
|
155
|
-
|
156
|
-
element
|
157
|
-
end
|
158
|
-
|
159
|
-
private
|
160
|
-
|
161
|
-
def log(msg)
|
162
|
-
Runtime::Logger.debug(msg)
|
163
|
-
end
|
164
|
-
|
165
|
-
def log_has_element_or_not(method, name, found, **kwargs)
|
166
|
-
msg = ["#{method} :#{name}"]
|
167
|
-
msg << %Q(with text "#{kwargs[:text]}") if kwargs[:text]
|
168
|
-
msg << "class: #{kwargs[:class]}" if kwargs[:class]
|
169
|
-
msg << "(wait: #{kwargs[:wait] || Capybara.default_max_wait_time})"
|
170
|
-
msg << "returned: #{found}"
|
171
|
-
|
172
|
-
log(msg.compact.join(' '))
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|