lapis_lazuli 0.6.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 +7 -0
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +42 -0
- data/LICENSE +30 -0
- data/README.md +74 -0
- data/Rakefile +1 -0
- data/bin/lapis_lazuli +3 -0
- data/lapis_lazuli.gemspec +32 -0
- data/lib/lapis_lazuli/api.rb +52 -0
- data/lib/lapis_lazuli/argparse.rb +128 -0
- data/lib/lapis_lazuli/ast.rb +160 -0
- data/lib/lapis_lazuli/browser/error.rb +93 -0
- data/lib/lapis_lazuli/browser/find.rb +500 -0
- data/lib/lapis_lazuli/browser/interaction.rb +91 -0
- data/lib/lapis_lazuli/browser/screenshots.rb +70 -0
- data/lib/lapis_lazuli/browser/wait.rb +158 -0
- data/lib/lapis_lazuli/browser.rb +246 -0
- data/lib/lapis_lazuli/cli.rb +110 -0
- data/lib/lapis_lazuli/cucumber.rb +25 -0
- data/lib/lapis_lazuli/generators/cucumber/template/.gitignore +6 -0
- data/lib/lapis_lazuli/generators/cucumber/template/Gemfile +37 -0
- data/lib/lapis_lazuli/generators/cucumber/template/README.md +27 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/config.yml +29 -0
- data/lib/lapis_lazuli/generators/cucumber/template/config/cucumber.yml +34 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/example.feature +11 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/interaction_steps.rb +20 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/step_definitions/validation_steps.rb +21 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/env.rb +12 -0
- data/lib/lapis_lazuli/generators/cucumber/template/features/support/transition.rb +12 -0
- data/lib/lapis_lazuli/generators/cucumber.rb +128 -0
- data/lib/lapis_lazuli/generic/xpath.rb +49 -0
- data/lib/lapis_lazuli/options.rb +28 -0
- data/lib/lapis_lazuli/placeholders.rb +36 -0
- data/lib/lapis_lazuli/proxy.rb +179 -0
- data/lib/lapis_lazuli/runtime.rb +88 -0
- data/lib/lapis_lazuli/scenario.rb +88 -0
- data/lib/lapis_lazuli/storage.rb +59 -0
- data/lib/lapis_lazuli/version.rb +10 -0
- data/lib/lapis_lazuli/versions.rb +40 -0
- data/lib/lapis_lazuli/world/annotate.rb +45 -0
- data/lib/lapis_lazuli/world/api.rb +35 -0
- data/lib/lapis_lazuli/world/browser.rb +75 -0
- data/lib/lapis_lazuli/world/config.rb +292 -0
- data/lib/lapis_lazuli/world/error.rb +141 -0
- data/lib/lapis_lazuli/world/hooks.rb +109 -0
- data/lib/lapis_lazuli/world/logging.rb +53 -0
- data/lib/lapis_lazuli/world/proxy.rb +59 -0
- data/lib/lapis_lazuli/world/variable.rb +139 -0
- data/lib/lapis_lazuli.rb +75 -0
- data/test/.gitignore +8 -0
- data/test/Gemfile +42 -0
- data/test/README.md +35 -0
- data/test/config/config.yml +37 -0
- data/test/config/cucumber.yml +37 -0
- data/test/features/annotation.feature +23 -0
- data/test/features/browser.feature +10 -0
- data/test/features/button.feature +38 -0
- data/test/features/click.feature +35 -0
- data/test/features/error.feature +30 -0
- data/test/features/find.feature +92 -0
- data/test/features/har.feature +9 -0
- data/test/features/modules.feature +14 -0
- data/test/features/step_definitions/interaction_steps.rb +154 -0
- data/test/features/step_definitions/validation_steps.rb +350 -0
- data/test/features/support/env.rb +21 -0
- data/test/features/text_field.feature +32 -0
- data/test/features/timing.feature +47 -0
- data/test/features/variable.feature +11 -0
- data/test/features/xpath.feature +41 -0
- data/test/server/start.rb +17 -0
- data/test/server/www/button.html +22 -0
- data/test/server/www/error_html.html +9 -0
- data/test/server/www/find.html +66 -0
- data/test/server/www/javascript_error.html +12 -0
- data/test/server/www/text_fields.html +15 -0
- data/test/server/www/timing.html +32 -0
- data/test/server/www/xpath.html +22 -0
- metadata +295 -0
@@ -0,0 +1,158 @@
|
|
1
|
+
#
|
2
|
+
# LapisLazuli
|
3
|
+
# https://github.com/spriteCloud/lapis-lazuli
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2015 spriteCloud B.V. and other LapisLazuli contributors.
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'test/unit/assertions'
|
10
|
+
require 'lapis_lazuli/argparse'
|
11
|
+
|
12
|
+
module LapisLazuli
|
13
|
+
module BrowserModule
|
14
|
+
|
15
|
+
##
|
16
|
+
# Wait functionality for Browser
|
17
|
+
module Wait
|
18
|
+
include LapisLazuli::ArgParse
|
19
|
+
|
20
|
+
##
|
21
|
+
# Same arguments as for the find functions, but a few more options are valid:
|
22
|
+
#
|
23
|
+
# :timeout - specifies the timeout to wait for, defaulting to 10 seconds
|
24
|
+
# :condition - specifies the condition to wait for, either of :while or
|
25
|
+
# :until. The default is :until.
|
26
|
+
# :screenshot - boolean flag determining whether a screenshot should be made
|
27
|
+
# if the function produces an error. The default is false.
|
28
|
+
def multi_wait_all(*args)
|
29
|
+
return internal_wait(:multi_find_all, *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def wait_all(*args)
|
33
|
+
return internal_wait(:find_all, *args)
|
34
|
+
end
|
35
|
+
|
36
|
+
def multi_wait(*args)
|
37
|
+
return internal_wait(:multi_find, *args)
|
38
|
+
end
|
39
|
+
|
40
|
+
def wait(*args)
|
41
|
+
return internal_wait(:find, *args)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
##
|
47
|
+
# Internal wait function; public functions differ only in which of the find
|
48
|
+
# functions they use.
|
49
|
+
def internal_wait(find_func, *args)
|
50
|
+
options = parse_wait_options(*args)
|
51
|
+
|
52
|
+
# Extract our own options
|
53
|
+
timeout = options[:timeout]
|
54
|
+
options.delete(:timeout)
|
55
|
+
|
56
|
+
retries = options[:stale_retries] + 1 # Add first attempt!
|
57
|
+
options.delete(:stale_retries)
|
58
|
+
|
59
|
+
condition = options[:condition]
|
60
|
+
options.delete(:condition)
|
61
|
+
|
62
|
+
# The easiest way to deal with find's new :throw policy is to set it to
|
63
|
+
# false.
|
64
|
+
options[:throw] = false
|
65
|
+
|
66
|
+
# pp "got options: #{options}"
|
67
|
+
|
68
|
+
# The proc we're waiting for invokes the find_func
|
69
|
+
results = []
|
70
|
+
has_single = false
|
71
|
+
find_proc = lambda { |dummy|
|
72
|
+
res = false
|
73
|
+
err = nil
|
74
|
+
retries.times do
|
75
|
+
begin
|
76
|
+
opts = Marshal.load(Marshal.dump(options))
|
77
|
+
results = send(find_func.to_sym, opts)
|
78
|
+
if results.respond_to? :length
|
79
|
+
res = (results.length > 0)
|
80
|
+
else
|
81
|
+
has_single = true
|
82
|
+
results = [results]
|
83
|
+
res = !!results[0]
|
84
|
+
end
|
85
|
+
break # don't need to retry
|
86
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError => e
|
87
|
+
err = e
|
88
|
+
end
|
89
|
+
# Retry
|
90
|
+
end
|
91
|
+
|
92
|
+
# Raise the error if the retries didn't suffice
|
93
|
+
if not err.nil? and not res
|
94
|
+
raise err, "Tried #{retries} times, but got: #{err.message}", err.backtrace
|
95
|
+
end
|
96
|
+
|
97
|
+
# Return the results!
|
98
|
+
res
|
99
|
+
}
|
100
|
+
|
101
|
+
# Call the appropriate condition function.
|
102
|
+
err = nil
|
103
|
+
begin
|
104
|
+
res = Watir::Wait.send(condition, timeout, &find_proc)
|
105
|
+
rescue Watir::Wait::TimeoutError => e
|
106
|
+
@world.log.debug("Caught timeout: #{e}")
|
107
|
+
err = e
|
108
|
+
end
|
109
|
+
|
110
|
+
# Filter out any nil results
|
111
|
+
filter_results = results.select {|i| not i.nil?}
|
112
|
+
# Error handling
|
113
|
+
if not err.nil? and filter_results.empty?
|
114
|
+
options[:exception] = err
|
115
|
+
@world.error(options)
|
116
|
+
end
|
117
|
+
|
118
|
+
# Set if the underlying find function returns single results
|
119
|
+
if has_single
|
120
|
+
return results[0]
|
121
|
+
end
|
122
|
+
return results
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
##
|
128
|
+
# Parses wait options, using parse_args
|
129
|
+
def parse_wait_options(*args)
|
130
|
+
options = {
|
131
|
+
:timeout => 10,
|
132
|
+
:stale_retries => 3,
|
133
|
+
:condition => :until,
|
134
|
+
:screenshot => false,
|
135
|
+
}
|
136
|
+
options = ERROR_OPTIONS.merge options
|
137
|
+
options = parse_args(options, :selectors, *args)
|
138
|
+
|
139
|
+
# Validate options
|
140
|
+
options[:timeout] = options[:timeout].to_i
|
141
|
+
options[:screenshot] = !!options[:screenshot]
|
142
|
+
|
143
|
+
options[:condition] = options[:condition].to_sym
|
144
|
+
assert [:while, :until].include?(options[:condition]), ":condition must be one of :while, :until"
|
145
|
+
|
146
|
+
# For all selectors that don't have the filter_by set, default it to
|
147
|
+
# present?
|
148
|
+
options[:selectors].each do |sel|
|
149
|
+
if not sel.has_key? :filter_by
|
150
|
+
sel[:filter_by] = :present?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
return options
|
155
|
+
end
|
156
|
+
end # module Wait
|
157
|
+
end # module BrowserModule
|
158
|
+
end # module LapisLazuli
|
@@ -0,0 +1,246 @@
|
|
1
|
+
#
|
2
|
+
# LapisLazuli
|
3
|
+
# https://github.com/spriteCloud/lapis-lazuli
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2015 spriteCloud B.V. and other LapisLazuli contributors.
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
|
9
|
+
require 'selenium-webdriver'
|
10
|
+
require 'watir-webdriver'
|
11
|
+
require "watir-webdriver/extensions/alerts"
|
12
|
+
require 'test/unit/assertions'
|
13
|
+
|
14
|
+
require "lapis_lazuli/ast"
|
15
|
+
|
16
|
+
# Modules
|
17
|
+
require "lapis_lazuli/browser/error"
|
18
|
+
require 'lapis_lazuli/browser/find'
|
19
|
+
require "lapis_lazuli/browser/wait"
|
20
|
+
require "lapis_lazuli/browser/screenshots"
|
21
|
+
require "lapis_lazuli/browser/interaction"
|
22
|
+
require 'lapis_lazuli/generic/xpath'
|
23
|
+
|
24
|
+
module LapisLazuli
|
25
|
+
##
|
26
|
+
# Extension to the Watir browser
|
27
|
+
#
|
28
|
+
# This class handles initialization, for the most part. BrowserModules
|
29
|
+
# included here can rely on @world being set to the current cucumber world
|
30
|
+
# object, and for some WorldModules to exist in it (see assertions in
|
31
|
+
# constructor).
|
32
|
+
class Browser
|
33
|
+
include Test::Unit::Assertions
|
34
|
+
|
35
|
+
include LapisLazuli::Ast
|
36
|
+
|
37
|
+
include LapisLazuli::BrowserModule::Error
|
38
|
+
include LapisLazuli::BrowserModule::Find
|
39
|
+
include LapisLazuli::BrowserModule::Wait
|
40
|
+
include LapisLazuli::BrowserModule::Screenshots
|
41
|
+
include LapisLazuli::BrowserModule::Interaction
|
42
|
+
include LapisLazuli::GenericModule::XPath
|
43
|
+
|
44
|
+
@world
|
45
|
+
@browser
|
46
|
+
@cached_browser_wanted
|
47
|
+
@cached_optional_data
|
48
|
+
|
49
|
+
@browser_name
|
50
|
+
attr_reader :browser_name
|
51
|
+
|
52
|
+
def initialize(world, *args)
|
53
|
+
# The class only works with some modules loaded; they're loaded by the
|
54
|
+
# Browser module, but we can't be sure that's been used.
|
55
|
+
assert world.respond_to?(:config), "Need to include LapisLazuli::WorldModule::Config in your cucumber world."
|
56
|
+
assert world.respond_to?(:log), "Need to include LapisLazuli::WorldModule::Logging in your cucumber world."
|
57
|
+
assert world.respond_to?(:error), "Need to include LapisLazuli::WorldModule::Error in your cucumber world."
|
58
|
+
assert world.respond_to?(:has_proxy?), "Need to include LapisLazuli::WorldModule::Proxy in your cucumber world."
|
59
|
+
|
60
|
+
@world = world
|
61
|
+
|
62
|
+
# Create a new browser with optional arguments
|
63
|
+
@browser = self.init(*args)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# The main browser window for testing
|
68
|
+
def init(browser_wanted=(no_browser_wanted=true;nil), optional_data=(no_optional_data=true;nil))
|
69
|
+
# Store the optional data so on restart of the browser it still has the
|
70
|
+
# correct configuration
|
71
|
+
if no_optional_data and optional_data.nil? and @cached_optional_data
|
72
|
+
optional_data = @cached_optional_data
|
73
|
+
elsif optional_data.nil?
|
74
|
+
optional_data = {}
|
75
|
+
else
|
76
|
+
# Duplicate the data as Webdriver modifies it
|
77
|
+
@cached_optional_data = optional_data.dup
|
78
|
+
end
|
79
|
+
|
80
|
+
# Do the same caching stuff for the browser
|
81
|
+
if no_browser_wanted and browser_wanted.nil? and @cached_browser_wanted
|
82
|
+
browser_wanted = @cached_browser_wanted
|
83
|
+
else
|
84
|
+
@cached_browser_wanted = browser_wanted
|
85
|
+
end
|
86
|
+
|
87
|
+
# Create the browser
|
88
|
+
self.create(browser_wanted, optional_data)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Create a new browser depending on settings
|
93
|
+
# Always cached the supplied arguments
|
94
|
+
def create(browser_wanted=nil, optional_data=nil)
|
95
|
+
# No browser? Does the config have a browser? Default to firefox
|
96
|
+
if browser_wanted.nil?
|
97
|
+
browser_wanted = @world.env_or_config('browser', 'firefox')
|
98
|
+
end
|
99
|
+
|
100
|
+
# Select the correct browser
|
101
|
+
case browser_wanted.to_s.downcase
|
102
|
+
when 'chrome'
|
103
|
+
# Check Platform running script
|
104
|
+
browser = :chrome
|
105
|
+
when 'safari'
|
106
|
+
browser = :safari
|
107
|
+
when 'ie'
|
108
|
+
require 'rbconfig'
|
109
|
+
if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
|
110
|
+
browser = :ie
|
111
|
+
else
|
112
|
+
@world.error("You can't run IE tests on non-Windows machine")
|
113
|
+
end
|
114
|
+
when 'ios'
|
115
|
+
if RUBY_PLATFORM.downcase.include?("darwin")
|
116
|
+
browser = :iphone
|
117
|
+
else
|
118
|
+
@world.error("You can't run IOS tests on non-mac machine")
|
119
|
+
end
|
120
|
+
else
|
121
|
+
browser = :firefox
|
122
|
+
end
|
123
|
+
|
124
|
+
args = [browser]
|
125
|
+
@browser_name = browser.to_s
|
126
|
+
if not optional_data.nil? and not optional_data.empty?
|
127
|
+
@world.log.debug("Got optional data: #{optional_data}")
|
128
|
+
args.push(optional_data)
|
129
|
+
elsif @world.has_proxy?
|
130
|
+
# Create a session if needed
|
131
|
+
if !@world.proxy.has_session?
|
132
|
+
@world.proxy.create()
|
133
|
+
end
|
134
|
+
|
135
|
+
proxy_url = "#{@world.proxy.ip}:#{@world.proxy.port}"
|
136
|
+
if browser == :firefox
|
137
|
+
@world.log.debug("Configuring Firefox proxy: #{proxy_url}")
|
138
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
139
|
+
profile.proxy = Selenium::WebDriver::Proxy.new :http => proxy_url, :ssl => proxy_url
|
140
|
+
args.push({:profile => profile})
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
browser_instance = Watir::Browser.new(*args)
|
145
|
+
return browser_instance
|
146
|
+
end
|
147
|
+
|
148
|
+
##
|
149
|
+
# Return if the browser is open
|
150
|
+
def is_open?
|
151
|
+
return !@browser.nil?
|
152
|
+
end
|
153
|
+
|
154
|
+
##
|
155
|
+
# Start the browser if it's not yet open.
|
156
|
+
def start
|
157
|
+
if @browser.nil?
|
158
|
+
@browser = self.init
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# Close and create a new browser
|
164
|
+
def restart
|
165
|
+
@world.log.debug "Restarting browser"
|
166
|
+
@browser.close
|
167
|
+
self.start
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Closes the browser and updates LL so that it will open a new one if needed
|
172
|
+
def close(reason = nil)
|
173
|
+
if not @browser.nil?
|
174
|
+
if not reason.nil?
|
175
|
+
reason = " after #{reason}"
|
176
|
+
else
|
177
|
+
reason = ""
|
178
|
+
end
|
179
|
+
|
180
|
+
@world.log.debug "Closing browser#{reason}: #{@browser}"
|
181
|
+
@browser.close
|
182
|
+
@browser = nil
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
##
|
187
|
+
# Same as close
|
188
|
+
def quit
|
189
|
+
self.close
|
190
|
+
end
|
191
|
+
|
192
|
+
##
|
193
|
+
# Close after scenario will close the browser depending on the close_browser_after
|
194
|
+
# configuration
|
195
|
+
#
|
196
|
+
# Valid config options: feature, scenario, end, never
|
197
|
+
# Default: feature
|
198
|
+
def close_after_scenario(scenario)
|
199
|
+
# Determine the config
|
200
|
+
close_browser_after = @world.env_or_config("close_browser_after")
|
201
|
+
|
202
|
+
case close_browser_after
|
203
|
+
when "scenario"
|
204
|
+
# We always close it
|
205
|
+
self.close close_browser_after
|
206
|
+
when "never"
|
207
|
+
# Do nothing: party time, excellent!
|
208
|
+
when "end"
|
209
|
+
# Also ignored here - this is handled in World.browser_destroy
|
210
|
+
else
|
211
|
+
if is_last_scenario?(scenario)
|
212
|
+
# Close it
|
213
|
+
self.close close_browser_after
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
##
|
219
|
+
# Map any missing method to the browser object
|
220
|
+
# Example
|
221
|
+
# ll.browser.goto "http://www.spritecloud.com"
|
222
|
+
def respond_to?(meth)
|
223
|
+
if !@browser.nil? and @browser.respond_to? meth
|
224
|
+
return true
|
225
|
+
end
|
226
|
+
return super
|
227
|
+
end
|
228
|
+
|
229
|
+
def method_missing(meth, *args, &block)
|
230
|
+
if !@browser.nil? and @browser.respond_to? meth
|
231
|
+
return @browser.send(meth.to_s, *args, &block)
|
232
|
+
end
|
233
|
+
return super
|
234
|
+
end
|
235
|
+
|
236
|
+
def destroy(world)
|
237
|
+
if "end" == world.env_or_config("close_browser_after")
|
238
|
+
begin
|
239
|
+
self.close "end"
|
240
|
+
rescue
|
241
|
+
world.log.debug("Failed to close the browser, probably chrome")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
#
|
2
|
+
# LapisLazuli
|
3
|
+
# https://github.com/spriteCloud/lapis-lazuli
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 spriteCloud B.V. and other LapisLazuli contributors.
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
require 'thor'
|
9
|
+
|
10
|
+
require 'lapis_lazuli/generators/cucumber'
|
11
|
+
require 'lapis_lazuli/options'
|
12
|
+
require 'lapis_lazuli/placeholders'
|
13
|
+
|
14
|
+
module LapisLazuli
|
15
|
+
class CLI < Thor
|
16
|
+
class_option :verbose, :aliases => "-v", :type => :boolean, :default => false, :desc => "Be verbose."
|
17
|
+
|
18
|
+
long_desc <<-LONGDESC
|
19
|
+
Creates/updates a cucumber test script directory pre-seeded with common
|
20
|
+
step definitions, environment and configuratin support, and all the bells
|
21
|
+
and whistles of a proper spriteCloud test setup.
|
22
|
+
|
23
|
+
The default behaviour is to reference the release gem of the Lapis Lazuli
|
24
|
+
version you are using as a dependency of the created/updated project.
|
25
|
+
|
26
|
+
By specifying a github branch, you will instead use that branch of Lapis
|
27
|
+
Lazuli as a dependency.
|
28
|
+
LONGDESC
|
29
|
+
|
30
|
+
option :branch, :aliases => "-b", :type => :string, :default => nil, :desc => "Specify the github branch of Lapis Lazuli a created/updated project is to use."
|
31
|
+
register(LapisLazuli::Generators::Cucumber, "create", "create PROJECT", "Creates a cucumber project with some common step definitions.")
|
32
|
+
register(LapisLazuli::Generators::Cucumber, "update", "update PROJECT", "Updates a project. Alias for 'create'.")
|
33
|
+
|
34
|
+
|
35
|
+
desc "config", "Describe how LapisLazuli configuration works."
|
36
|
+
def config
|
37
|
+
STDOUT.write <<-INTRO
|
38
|
+
LapisLazuli searches for configuration files in the `config' subdirectory of
|
39
|
+
the current working directory, taking the stated test environment into
|
40
|
+
consideration.
|
41
|
+
|
42
|
+
Example:
|
43
|
+
ENV['TEST_ENV'] = 'production'
|
44
|
+
load_config("config/config.yml")
|
45
|
+
|
46
|
+
Will try to load the following files, in order:
|
47
|
+
- config/config-production.yml
|
48
|
+
- config/config-debug.yml
|
49
|
+
- config/config-test.yml
|
50
|
+
- config/config-local.yml
|
51
|
+
- config/config.yml
|
52
|
+
|
53
|
+
The first configuration file in the list that is found will be loaded, and its
|
54
|
+
contents become available via the configuraiton functions.
|
55
|
+
|
56
|
+
Supported configuration formats and file name extensions are:
|
57
|
+
.yml - YAML file
|
58
|
+
.json - JSON file
|
59
|
+
|
60
|
+
In addition to environment-specific configuration files, LapisLazuli supports
|
61
|
+
the concept of test environments within a single file, where environments are
|
62
|
+
just top-level keys, e.g.:
|
63
|
+
|
64
|
+
production:
|
65
|
+
- config for the production environment
|
66
|
+
|
67
|
+
development:
|
68
|
+
- config for the development environment
|
69
|
+
|
70
|
+
The configuration files can contain any configuration options, but a few are
|
71
|
+
interpreted by LapisLazuli. Note that instead of specifying these supported
|
72
|
+
options in the configuraiton file, you may also provide them in the environment
|
73
|
+
(convert option name to upper case). Environment variables override the
|
74
|
+
configuration file contents.
|
75
|
+
|
76
|
+
INTRO
|
77
|
+
STDOUT.flush
|
78
|
+
|
79
|
+
LapisLazuli::CONFIG_OPTIONS.each do |option, value|
|
80
|
+
printf "%22s\n", option
|
81
|
+
|
82
|
+
display_default = value[0]
|
83
|
+
if display_default.nil?
|
84
|
+
display_default = "No default."
|
85
|
+
else
|
86
|
+
display_default = "Defaults to '#{display_default}'."
|
87
|
+
end
|
88
|
+
printf " #{display_default}\n"
|
89
|
+
printf " #{value[1]}\n\n"
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
desc "placeholders", "Display placeholders managed by WorldModule::Variable."
|
97
|
+
def placeholders
|
98
|
+
STDOUT.write <<-INTRO
|
99
|
+
The following are placeholders to use with WorldModule::Variable's functions
|
100
|
+
as managed by this version of LapisLazuli.
|
101
|
+
|
102
|
+
INTRO
|
103
|
+
STDOUT.flush
|
104
|
+
|
105
|
+
LapisLazuli::PLACEHOLDERS.each do |option, value|
|
106
|
+
printf "%22s - %s\n", option, value[1]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#
|
2
|
+
# LapisLazuli
|
3
|
+
# https://github.com/spriteCloud/lapis-lazuli
|
4
|
+
#
|
5
|
+
# Copyright (c) 2013-2014 spriteCloud B.V. and other LapisLazuli contributors.
|
6
|
+
# All rights reserved.
|
7
|
+
#
|
8
|
+
|
9
|
+
Before do |scenario|
|
10
|
+
if respond_to? :before_scenario_hook
|
11
|
+
before_scenario_hook(scenario)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
After do |scenario|
|
16
|
+
if respond_to? :after_scenario_hook
|
17
|
+
after_scenario_hook(scenario)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Can be used for debug purposes
|
22
|
+
AfterStep('@pause') do |scenario|
|
23
|
+
print "Press Return to continue"
|
24
|
+
STDIN.getc
|
25
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
source 'http://rubygems.org'
|
2
|
+
|
3
|
+
|
4
|
+
# Add following two lines to your ~/.gemrc or /etc/gemrc:
|
5
|
+
# install: --no-rdoc --no-ri
|
6
|
+
# update: --no-rdoc --no-ri
|
7
|
+
|
8
|
+
# Install helper libraries
|
9
|
+
gem 'rspec'
|
10
|
+
gem 'gherkin'
|
11
|
+
gem 'xml-simple'
|
12
|
+
gem 'mechanize'
|
13
|
+
|
14
|
+
# Debuggers
|
15
|
+
platforms :ruby_18, :ruby_19 do
|
16
|
+
gem 'debugger'
|
17
|
+
end
|
18
|
+
platforms :ruby_20, :ruby_21 do
|
19
|
+
gem 'byebug'
|
20
|
+
gem 'rb-readline'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Windows specific
|
24
|
+
platforms :mswin, :mingw do
|
25
|
+
gem 'win32console'
|
26
|
+
gem 'term-ansicolor'
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Install all the webdriver gems and cucumber
|
31
|
+
gem 'watir-webdriver'
|
32
|
+
gem 'watir-webdriver-performance'
|
33
|
+
gem 'watir-scroll'
|
34
|
+
gem 'cucumber'
|
35
|
+
|
36
|
+
# LapisLazul itself
|
37
|
+
gem 'lapis_lazuli', <%= config[:lapis_lazuli][:dependency] %>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Tests for <%= config[:project][:name] %>
|
2
|
+
|
3
|
+
Author: "<%= config[:user] %>" <<%= config[:email] %>>
|
4
|
+
|
5
|
+
# Setup
|
6
|
+
|
7
|
+
## General
|
8
|
+
|
9
|
+
- Make sure you have ruby 1.9 or later installed.
|
10
|
+
- Make sure you have firefox and/or chrome installed
|
11
|
+
- Install the bundler gem:
|
12
|
+
|
13
|
+
$ gem install bundler
|
14
|
+
|
15
|
+
- Install all of the required gems defined in the gemfile:
|
16
|
+
|
17
|
+
$ bundle install
|
18
|
+
|
19
|
+
- Run cucumber or regressinator through bundler:
|
20
|
+
|
21
|
+
$ bundle exec cucumber
|
22
|
+
$ bundle exec regressinator legacy cucumber
|
23
|
+
|
24
|
+
# Contributing
|
25
|
+
|
26
|
+
If you create new utility functions and want to contribute them to the Lapis
|
27
|
+
Lazuli project, see https://github.com/spriteCloud/lapis-lazuli
|
@@ -0,0 +1,29 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright <%= config[:year] %> spriteCloud B.V. All rights reserved.
|
3
|
+
# Generated by LapisLazuli, version <%= config[:lapis_lazuli][:version] %>
|
4
|
+
# Author: "<%= config[:user] %>" <<%= config[:email] %>>
|
5
|
+
#
|
6
|
+
# Config file for the test automation
|
7
|
+
# When a config_local.yml exists, that will then be loaded instead of this default config file
|
8
|
+
|
9
|
+
################################################################################
|
10
|
+
# Set the global variables
|
11
|
+
default_env: production # defines the environment
|
12
|
+
|
13
|
+
################################################################################
|
14
|
+
# List of error strings. Step will fail if one of these strings is detected.
|
15
|
+
error_strings:
|
16
|
+
[
|
17
|
+
"Server Error",
|
18
|
+
"Error: Page Not Found"
|
19
|
+
]
|
20
|
+
|
21
|
+
################################################################################
|
22
|
+
# Environment specific variables
|
23
|
+
test:
|
24
|
+
|
25
|
+
uat:
|
26
|
+
|
27
|
+
production:
|
28
|
+
google:
|
29
|
+
english: http://www.google.com/ncr
|
@@ -0,0 +1,34 @@
|
|
1
|
+
################################################################################
|
2
|
+
# Copyright <%= config[:year] %> spriteCloud B.V. All rights reserved.
|
3
|
+
# Generated by LapisLazuli, version <%= config[:lapis_lazuli][:version] %>
|
4
|
+
# Author: "<%= config[:user] %>" <<%= config[:email] %>>
|
5
|
+
#
|
6
|
+
# Ask developer of testsuite to add profiles where desired.
|
7
|
+
# This file defines predefined profiles that can be used.
|
8
|
+
# Example > Cucumber -t @homepage -p default -p localhost
|
9
|
+
|
10
|
+
<%% timestamp = Time.now.strftime("%Y%m%d_%H%M") %>
|
11
|
+
|
12
|
+
################################################################################
|
13
|
+
# Type of testrun
|
14
|
+
default: -f pretty -x
|
15
|
+
debug: -f pretty BREAKPOINT_ON_FAILURE=1
|
16
|
+
html_report: -f pretty -f html --out=results/<%%=timestamp%>_report.html
|
17
|
+
junit_report: -f pretty -f junit --out=results
|
18
|
+
|
19
|
+
################################################################################
|
20
|
+
# Supported browsers (default = firefox)
|
21
|
+
ff: BROWSER=firefox
|
22
|
+
firefox: BROWSER=firefox
|
23
|
+
chrome: BROWSER=chrome
|
24
|
+
ie: BROWSER=ie
|
25
|
+
safari: BROWSER=safari
|
26
|
+
|
27
|
+
|
28
|
+
################################################################################
|
29
|
+
# Listed environments (default is set in config.yml)
|
30
|
+
t: TEST_ENV=test -t @t,@test
|
31
|
+
test: TEST_ENV=test -t @t,@test
|
32
|
+
|
33
|
+
p: TEST_ENV=production -t @p,@prod
|
34
|
+
production: TEST_ENV=production -t @p,@prod
|
@@ -0,0 +1,11 @@
|
|
1
|
+
@example @p
|
2
|
+
Feature: Example Feature
|
3
|
+
When I want to learn how to make test cases
|
4
|
+
As a user of the test automation tool
|
5
|
+
I want to run and adjust the tests below
|
6
|
+
|
7
|
+
@example01
|
8
|
+
Scenario: example01 - Google Search
|
9
|
+
Given I navigate to Google in english
|
10
|
+
And I search for "spriteCloud"
|
11
|
+
Then I see "www.spriteCloud.com" on the page
|