unobtainium-cucumber 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +34 -0
- data/.gitignore +57 -0
- data/.rspec +2 -0
- data/.rubocop.yml +78 -0
- data/.travis.yml +11 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +106 -0
- data/LICENSE +30 -0
- data/README.md +150 -0
- data/Rakefile +29 -0
- data/config/config.yml +28 -0
- data/features/action.feature +12 -0
- data/features/action_support.feature +17 -0
- data/features/driver_reset.feature +17 -0
- data/features/extensions.feature +7 -0
- data/features/status_actions.feature +115 -0
- data/features/step_definitions/action.rb +61 -0
- data/features/step_definitions/action_support.rb +40 -0
- data/features/step_definitions/driver_reset.rb +85 -0
- data/features/step_definitions/extensions.rb +19 -0
- data/features/step_definitions/mocks/scenario.rb +18 -0
- data/features/step_definitions/status_actions.rb +358 -0
- data/features/support/env.rb +27 -0
- data/features/support/utils.rb +47 -0
- data/lib/unobtainium-cucumber/action/content.rb +40 -0
- data/lib/unobtainium-cucumber/action/screenshot.rb +37 -0
- data/lib/unobtainium-cucumber/action/support/naming.rb +44 -0
- data/lib/unobtainium-cucumber/driver_reset.rb +34 -0
- data/lib/unobtainium-cucumber/status_actions.rb +272 -0
- data/lib/unobtainium-cucumber/version.rb +14 -0
- data/lib/unobtainium-cucumber.rb +20 -0
- data/unobtainium-cucumber.gemspec +54 -0
- metadata +244 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
# Code coverage first
|
11
|
+
require 'simplecov'
|
12
|
+
SimpleCov.start do
|
13
|
+
add_filter 'features'
|
14
|
+
end
|
15
|
+
|
16
|
+
# Other requires after SimpleCov
|
17
|
+
require "unobtainium-cucumber"
|
18
|
+
|
19
|
+
# Extensions used for testing
|
20
|
+
module MyExtensions
|
21
|
+
def method_from_own_extension(*args, &block); end
|
22
|
+
end # module MyExtensions
|
23
|
+
|
24
|
+
World(MyExtensions)
|
25
|
+
|
26
|
+
# Utility code for testing
|
27
|
+
require_relative './utils'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
TIMESTAMP_REGEX ||= /\d{4}_\d{2}_\d{2}T\d{2}_\d{2}_\d{2}Z/
|
11
|
+
|
12
|
+
##
|
13
|
+
# Given a file name, extrat and convert timestamps
|
14
|
+
def timestamp_from_filename(filename)
|
15
|
+
# First, check if we can find the file name matching a timestamp
|
16
|
+
parts = File.split(filename)
|
17
|
+
parts = parts[-1].split('-')
|
18
|
+
timestamp = parts[0]
|
19
|
+
if not TIMESTAMP_REGEX.match(timestamp)
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
# Great, then fix the formatting...
|
24
|
+
timestamp[4] = '-'
|
25
|
+
timestamp[7] = '-'
|
26
|
+
timestamp[13] = ':'
|
27
|
+
timestamp[16] = ':'
|
28
|
+
|
29
|
+
return Time.parse(timestamp)
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Given a match pattern and optional timeout, finds files matching the pattern
|
34
|
+
# that have been created within the given timeout from now.
|
35
|
+
def timeout_match_files(pattern, timeout = 5)
|
36
|
+
now = Time.now.utc
|
37
|
+
|
38
|
+
Dir[pattern].each do |fname|
|
39
|
+
ts = timestamp_from_filename(fname)
|
40
|
+
if (now - ts).abs <= timeout
|
41
|
+
return fname
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
raise "No file matching '#{pattern}' with a timestamp in the last #{timeout} "\
|
46
|
+
"seconds was found!"
|
47
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/support/naming'
|
11
|
+
|
12
|
+
module Unobtainium
|
13
|
+
module Cucumber
|
14
|
+
|
15
|
+
##
|
16
|
+
# Namespace for built-in status actions
|
17
|
+
module Action
|
18
|
+
|
19
|
+
class << self
|
20
|
+
include Support
|
21
|
+
|
22
|
+
##
|
23
|
+
# Status action function that stores the page content (main page only)
|
24
|
+
def store_content(world, scenario)
|
25
|
+
# Make sure the content directory exists.
|
26
|
+
basedir = File.join(Dir.pwd, 'content')
|
27
|
+
FileUtils.mkdir_p(basedir)
|
28
|
+
|
29
|
+
# Store content. Note that not all drivers may support this.
|
30
|
+
filename = File.join(basedir, base_filename(scenario))
|
31
|
+
filename += '.txt'
|
32
|
+
|
33
|
+
File.open(filename, 'w') do |file|
|
34
|
+
file.write(world.driver.page_source)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end # class << self
|
38
|
+
end # module Action
|
39
|
+
end # module Cucumber
|
40
|
+
end # module Unobtainium
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/support/naming'
|
11
|
+
|
12
|
+
module Unobtainium
|
13
|
+
module Cucumber
|
14
|
+
|
15
|
+
##
|
16
|
+
# Namespace for built-in status actions
|
17
|
+
module Action
|
18
|
+
|
19
|
+
class << self
|
20
|
+
include Support
|
21
|
+
|
22
|
+
##
|
23
|
+
# Status action function that takes a screenshot.
|
24
|
+
def store_screenshot(world, scenario)
|
25
|
+
# Make sure the screenshots directory exists.
|
26
|
+
basedir = File.join(Dir.pwd, 'screenshots')
|
27
|
+
FileUtils.mkdir_p(basedir)
|
28
|
+
|
29
|
+
# Take screenshot.
|
30
|
+
filename = File.join(basedir, base_filename(scenario))
|
31
|
+
filename += '.png'
|
32
|
+
world.driver.save_screenshot(filename)
|
33
|
+
end
|
34
|
+
end # class << self
|
35
|
+
end # module Action
|
36
|
+
end # module Cucumber
|
37
|
+
end # module Unobtainium
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
module Unobtainium
|
10
|
+
module Cucumber
|
11
|
+
module Action
|
12
|
+
|
13
|
+
##
|
14
|
+
# Support functions for actions
|
15
|
+
module Support
|
16
|
+
|
17
|
+
##
|
18
|
+
# Given a cucumber scenario, this function returns a timestamped
|
19
|
+
# base filename (without extension) that reflects parts of the scenario
|
20
|
+
# name.
|
21
|
+
# Note that the optional tag is not related to cucumber tags. It's just
|
22
|
+
# a way to distinguish two filenames for the same scenario at the same
|
23
|
+
# timestamp.
|
24
|
+
# We use '_' as a replacement for unrenderable characters, and
|
25
|
+
# '-' as a separator between file name components.
|
26
|
+
def base_filename(scenario, tag = nil, timestamp = nil)
|
27
|
+
# Build base name from parameters
|
28
|
+
require 'time'
|
29
|
+
timestamp ||= Time.now.utc.iso8601
|
30
|
+
timestamp.tr!('-', '_')
|
31
|
+
scenario_name = scenario.name
|
32
|
+
base_name = [timestamp, tag, scenario_name].reject(&:nil?).join('-')
|
33
|
+
|
34
|
+
# Make base name filename safe
|
35
|
+
base_name.gsub!(/^.*(\\|\/)/, '')
|
36
|
+
base_name.gsub!(/[^0-9A-Za-z.\-]+/, '_')
|
37
|
+
|
38
|
+
return base_name
|
39
|
+
end
|
40
|
+
|
41
|
+
end # module Support
|
42
|
+
end # module Action
|
43
|
+
end # module Cucumber
|
44
|
+
end # module Unobtainium
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
After do |_|
|
11
|
+
if not driver.respond_to? :reset
|
12
|
+
next
|
13
|
+
end
|
14
|
+
|
15
|
+
# Covering this would require two separate test suites. I'm not sure I'm
|
16
|
+
# ready for that.
|
17
|
+
# :nocov:
|
18
|
+
if config['cucumber.driver_reset'] == false
|
19
|
+
next
|
20
|
+
end
|
21
|
+
# :nocov:
|
22
|
+
|
23
|
+
begin
|
24
|
+
driver.reset
|
25
|
+
rescue => error
|
26
|
+
# :nocov:
|
27
|
+
# If driver reset isn't possible, it doesn't make sense to continue
|
28
|
+
puts "DRIVER RESET WASN'T POSSIBLE DUE TO #{error} - BUT IS REQUIRED "\
|
29
|
+
"FOR BEFORE NEXT SCENARIO. WILL EXIT THE PROGRAM"
|
30
|
+
driver.quit
|
31
|
+
Kernel.exit(2)
|
32
|
+
# :nocov:
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,272 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium-cucumber/action/screenshot'
|
11
|
+
require 'unobtainium-cucumber/action/content'
|
12
|
+
|
13
|
+
module Unobtainium
|
14
|
+
module Cucumber
|
15
|
+
##
|
16
|
+
# The StatusActions module contains all functionality for registering
|
17
|
+
# actions to be run when a scenario or outline ended with a particular
|
18
|
+
# status.
|
19
|
+
module StatusActions
|
20
|
+
# Key for storing actions in unobtainium's runtime instance.
|
21
|
+
RUNTIME_KEY = 'unobtainium-cucumber-status-actions'.freeze
|
22
|
+
|
23
|
+
# Default status actions
|
24
|
+
DEFAULTS = {
|
25
|
+
failed?: [
|
26
|
+
'::Unobtainium::Cucumber::Action.store_screenshot',
|
27
|
+
]
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
##
|
31
|
+
# Register a action for a :passed? or :failed? scenario.
|
32
|
+
# The :type parameter may either be :scenario or :outline.
|
33
|
+
# The action will be passed the matching scenario. If no
|
34
|
+
# explicit action is given, a block is also acceptable.
|
35
|
+
def register_action(status, action = nil, options = nil, &block)
|
36
|
+
# If the action is a Hash, then the options should be nil. If that's
|
37
|
+
# the case, we have no action and instead got passed options.
|
38
|
+
if action.is_a? Hash
|
39
|
+
if not options.nil?
|
40
|
+
raise "Can't pass a Hash as an action!"
|
41
|
+
end
|
42
|
+
options = action
|
43
|
+
action = nil
|
44
|
+
end
|
45
|
+
|
46
|
+
# Parameter checks!
|
47
|
+
if not [:passed?, :failed?].include?(status)
|
48
|
+
raise "Status may be one of :passed? or :failed? only!"
|
49
|
+
end
|
50
|
+
|
51
|
+
options ||= {}
|
52
|
+
type = options[:type] || :scenario
|
53
|
+
if not [:scenario, :outline].include?(type)
|
54
|
+
raise "The :type option may be one of :scenario or :outline only!"
|
55
|
+
end
|
56
|
+
|
57
|
+
if action.nil? and block.nil?
|
58
|
+
raise "Must provide either an action method or a block!"
|
59
|
+
end
|
60
|
+
if not action.nil? and not block.nil?
|
61
|
+
raise "Cannot provide both an action method and a block!"
|
62
|
+
end
|
63
|
+
|
64
|
+
callback = action || block
|
65
|
+
|
66
|
+
# The key to store callbacks under is comprised of the status
|
67
|
+
# and the type. That way we can match precisely when actions are to
|
68
|
+
# be executed.
|
69
|
+
key = [status, type]
|
70
|
+
|
71
|
+
# Retrieve existing actions
|
72
|
+
actions = {}
|
73
|
+
if ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
74
|
+
actions = ::Unobtainium::Runtime.instance.fetch(RUNTIME_KEY)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Add the callback
|
78
|
+
actions[key] ||= []
|
79
|
+
actions[key] |= [callback]
|
80
|
+
|
81
|
+
# And store the callback actions again.
|
82
|
+
::Unobtainium::Runtime.instance.store(RUNTIME_KEY, actions)
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# For a given scenario, return the matching key for the actions.
|
87
|
+
def action_key(scenario)
|
88
|
+
return [
|
89
|
+
(scenario.passed? ? :passed? : :failed?),
|
90
|
+
(scenario.outline? ? :outline : :scenario)
|
91
|
+
]
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Automatically register all configured status actions.
|
96
|
+
# This is largely an internal function, run after the first scenario
|
97
|
+
# and before status actions are executed.
|
98
|
+
def register_config_actions(world)
|
99
|
+
to_register = world.config['cucumber.status_actions'] || DEFAULTS
|
100
|
+
|
101
|
+
[:passed?, :failed?].each do |status|
|
102
|
+
for_status = to_register[status]
|
103
|
+
if for_status.nil?
|
104
|
+
# :nocov:
|
105
|
+
next
|
106
|
+
# :nocov:
|
107
|
+
end
|
108
|
+
|
109
|
+
# If the entry for the status is an Array, it applies to scenarios
|
110
|
+
# and outlines equally. Otherwise we'll have to find a Hash with
|
111
|
+
# entries for either or both.
|
112
|
+
actions = {}
|
113
|
+
if for_status.is_a?(Array)
|
114
|
+
actions[:scenario] = for_status
|
115
|
+
actions[:outline] = for_status
|
116
|
+
elsif for_status.is_a?(Hash)
|
117
|
+
actions[:scenario] = for_status[:scenario] || []
|
118
|
+
actions[:outline] = for_status[:outline] || []
|
119
|
+
else
|
120
|
+
# :nocov:
|
121
|
+
raise "Cannot interpret status action configuration for status "\
|
122
|
+
"#{status}; it should be an Array or Hash, but instead it was"\
|
123
|
+
" this: #{for_status}"
|
124
|
+
# :nocov:
|
125
|
+
end
|
126
|
+
|
127
|
+
# Now we have actions for the statuses, we can register them.
|
128
|
+
[:scenario, :outline].each do |type|
|
129
|
+
actions[type].each do |action|
|
130
|
+
register_action(status, action, type: type)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
##
|
137
|
+
# Given an action and a scenario, execute the action. This includes
|
138
|
+
# late/lazy resolution of String or Symbol actions.
|
139
|
+
def execute_action(world, action, scenario)
|
140
|
+
# Simplest case first: the action is already callable.
|
141
|
+
if action.respond_to?(:call)
|
142
|
+
return action.call(world, scenario)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Symbols are almost as easy to handle: they must resolve to a
|
146
|
+
# method, either globally or on the world object.
|
147
|
+
if action.is_a? Symbol
|
148
|
+
meth = resolve_action(Object, world, action)
|
149
|
+
if meth.nil?
|
150
|
+
raise NoMethodError, "Symbol :#{action} could not be resolved "\
|
151
|
+
"either globally or as part of the cucumber World object, "\
|
152
|
+
"aborting!"
|
153
|
+
end
|
154
|
+
return meth.call(world, scenario)
|
155
|
+
end
|
156
|
+
|
157
|
+
# At this point, the action better be a String.
|
158
|
+
if not action.is_a? String
|
159
|
+
raise "Action '#{action}' is not callable, and not a method name. "\
|
160
|
+
"Aborting!"
|
161
|
+
end
|
162
|
+
|
163
|
+
# Split module and method name
|
164
|
+
module_name, method_name = split_string_action(action)
|
165
|
+
|
166
|
+
# If we have no discernable module, use Object instead.
|
167
|
+
the_module = Object
|
168
|
+
if not module_name.nil? and not module_name.empty?
|
169
|
+
the_module = Object.const_get(module_name)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Try the module we found (i.e. possibly Object) and world for
|
173
|
+
# resolving the method name.
|
174
|
+
meth = resolve_action(the_module, world, method_name)
|
175
|
+
if meth.nil?
|
176
|
+
raise NoMethodError, "Action '#{action}' could not be resolved!"
|
177
|
+
end
|
178
|
+
|
179
|
+
return meth.call(world, scenario)
|
180
|
+
end
|
181
|
+
|
182
|
+
##
|
183
|
+
# For a given status and type, return the registered actions.
|
184
|
+
def registered_actions(status, type)
|
185
|
+
if not ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
186
|
+
return []
|
187
|
+
end
|
188
|
+
|
189
|
+
actions = ::Unobtainium::Runtime.instance.fetch(RUNTIME_KEY)
|
190
|
+
return actions[[status, type]] || []
|
191
|
+
end
|
192
|
+
|
193
|
+
##
|
194
|
+
# Partially for testing purposes, clears the action registry.
|
195
|
+
def clear_actions
|
196
|
+
if not ::Unobtainium::Runtime.instance.has?(RUNTIME_KEY)
|
197
|
+
# :nocov:
|
198
|
+
return
|
199
|
+
# :nocov:
|
200
|
+
end
|
201
|
+
|
202
|
+
::Unobtainium::Runtime.instance.delete(RUNTIME_KEY)
|
203
|
+
end
|
204
|
+
|
205
|
+
##
|
206
|
+
# Resolves the given symbol in either of the given namespace or the
|
207
|
+
# world object. Returns nil if neither contained the symbol.
|
208
|
+
def resolve_action(namespace, world, method_name)
|
209
|
+
method_sym = method_name.to_sym
|
210
|
+
|
211
|
+
[namespace, world].each do |receiver|
|
212
|
+
begin
|
213
|
+
return receiver.method(method_sym)
|
214
|
+
rescue NameError
|
215
|
+
next
|
216
|
+
end
|
217
|
+
end
|
218
|
+
return nil
|
219
|
+
end
|
220
|
+
|
221
|
+
##
|
222
|
+
# Splits a string action into a module prefix and a method name
|
223
|
+
def split_string_action(action)
|
224
|
+
# Try to see whether we have a fully qualified name that requires us
|
225
|
+
# to query a particular module for the method.
|
226
|
+
split_action = action.split(/::/)
|
227
|
+
method_name = split_action.pop
|
228
|
+
|
229
|
+
# If the method name contains a dot, it uses 'Module.method' notation.
|
230
|
+
# rubocop:disable Lint/EmptyWhen
|
231
|
+
split_method = method_name.split(/\./)
|
232
|
+
case split_method.length
|
233
|
+
when 1
|
234
|
+
# Do nothing; the method name did not contain a dot
|
235
|
+
when 2
|
236
|
+
# We have a method name and a module part
|
237
|
+
split_action << split_method[0]
|
238
|
+
method_name = split_method[1]
|
239
|
+
else
|
240
|
+
raise "Too many dots in method name: #{method_name}"
|
241
|
+
end
|
242
|
+
# rubocop:enable Lint/EmptyWhen
|
243
|
+
|
244
|
+
# Re-join the module name
|
245
|
+
module_name = split_action.join('::')
|
246
|
+
|
247
|
+
return module_name, method_name
|
248
|
+
end
|
249
|
+
end # module StatusActions
|
250
|
+
end # module Cucumber
|
251
|
+
end # module Unobtainium
|
252
|
+
|
253
|
+
##
|
254
|
+
# In the Before hook, we register configured actions.
|
255
|
+
Before do |_|
|
256
|
+
# Register all configured actions.
|
257
|
+
register_config_actions(self)
|
258
|
+
end
|
259
|
+
|
260
|
+
##
|
261
|
+
# The After hook with cucumber defined here will execute all matching,
|
262
|
+
# registered actions.
|
263
|
+
After do |scenario|
|
264
|
+
# Fetch actions applying to this scenario
|
265
|
+
key = action_key(scenario)
|
266
|
+
applicable_actions = registered_actions(key[0], key[1])
|
267
|
+
|
268
|
+
# Execute all actions applying to this scenario
|
269
|
+
applicable_actions.each do |action|
|
270
|
+
execute_action(self, action, scenario)
|
271
|
+
end
|
272
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
module Unobtainium
|
10
|
+
module Cucumber
|
11
|
+
# The current release version
|
12
|
+
VERSION = "0.1.0".freeze
|
13
|
+
end # module Cucumber
|
14
|
+
end # module Unobtainium
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
require 'unobtainium'
|
11
|
+
require 'unobtainium-cucumber/version'
|
12
|
+
|
13
|
+
# First things first: extend the World. Otherwise nothing in this file will
|
14
|
+
# work.
|
15
|
+
World(Unobtainium::World)
|
16
|
+
|
17
|
+
require 'unobtainium-cucumber/driver_reset.rb'
|
18
|
+
require 'unobtainium-cucumber/status_actions.rb'
|
19
|
+
|
20
|
+
World(Unobtainium::Cucumber::StatusActions)
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
#
|
3
|
+
# unobtainium-cucumber
|
4
|
+
# https://github.com/jfinkhaeuser/unobtainium-cucumber
|
5
|
+
#
|
6
|
+
# Copyright (c) 2016 Jens Finkhaeuser and other unobtainium-cucumber
|
7
|
+
# contributors. All rights reserved.
|
8
|
+
#
|
9
|
+
|
10
|
+
lib = File.expand_path('../lib', __FILE__)
|
11
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
12
|
+
require 'unobtainium-cucumber/version'
|
13
|
+
|
14
|
+
# rubocop:disable Style/UnneededPercentQ, Style/ExtraSpacing
|
15
|
+
# rubocop:disable Style/SpaceAroundOperators
|
16
|
+
# rubocop:disable Metrics/BlockLength
|
17
|
+
Gem::Specification.new do |spec|
|
18
|
+
spec.name = "unobtainium-cucumber"
|
19
|
+
spec.version = Unobtainium::Cucumber::VERSION
|
20
|
+
spec.authors = ["Jens Finkhaeuser"]
|
21
|
+
spec.email = ["jens@finkhaeuser.de"]
|
22
|
+
spec.description = %q(
|
23
|
+
The unobtainium-cucucmber gem adds some convenient cucumber specific hooks
|
24
|
+
for use with unobtainium.
|
25
|
+
)
|
26
|
+
spec.summary = %q(
|
27
|
+
Cucumber hooks for unobtainium.
|
28
|
+
)
|
29
|
+
spec.homepage = "https://github.com/jfinkhaeuser/unobtainium-cucumber"
|
30
|
+
spec.license = "MITNFA"
|
31
|
+
|
32
|
+
spec.files = `git ls-files -z`.split("\x0")
|
33
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
34
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
35
|
+
spec.require_paths = ["lib"]
|
36
|
+
|
37
|
+
spec.required_ruby_version = '>= 2.0'
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
40
|
+
spec.add_development_dependency "rubocop", "~> 0.46"
|
41
|
+
spec.add_development_dependency "rake", "~> 11.2"
|
42
|
+
spec.add_development_dependency "simplecov", "~> 0.12"
|
43
|
+
spec.add_development_dependency "yard", "~> 0.9"
|
44
|
+
spec.add_development_dependency "appium_lib"
|
45
|
+
spec.add_development_dependency "selenium-webdriver"
|
46
|
+
spec.add_development_dependency "chromedriver-helper"
|
47
|
+
spec.add_development_dependency "phantomjs"
|
48
|
+
|
49
|
+
spec.add_dependency "unobtainium", "~> 0.10"
|
50
|
+
spec.add_dependency "cucumber", "~> 2.0"
|
51
|
+
end
|
52
|
+
# rubocop:enable Metrics/BlockLength
|
53
|
+
# rubocop:enable Style/SpaceAroundOperators
|
54
|
+
# rubocop:enable Style/UnneededPercentQ, Style/ExtraSpacing
|