Class: MediawikiSelenium::Environment
- Inherits:
-
Object
- Object
- MediawikiSelenium::Environment
- Includes:
- Comparable
- Defined in:
- lib/mediawiki_selenium/environment.rb
Overview
Provides an interface that unifies environmental configuration, page objects, and browser setup. Additionally, it provides a DSL for switching between user/wiki/browser contexts in ways that help to decouple test implementation from the target wikis.
Default configuration for various resources (wiki URLs, users, etc.) is
typically loaded from an environments.yml
YAML file in the current
working directory. It should contain defaults for each environment in
which the tests are expected to run, indexed by environment name.
beta:
mediawiki_url: http://en.wikipedia.beta.wmflabs.org/wiki/
mediawiki_user: Selenium_user
test2:
mediawiki_url: http://test2.wikipedia.org/wiki/
mediawiki_user: Selenium_user
Which default set to use is determined by the value of the
MEDIAWIKI_ENVIRONMENT
environment variable, or an entry called "default"
if none is set. (See Environment.load and Environment.load_default.) The easiest way to
designate such a default set is to use a YAML anchor like so.
beta: &default
mediawiki_url: http://en.wikipedia.beta.wmflabs.org/wiki/
mediawiki_user: Selenium_user
test2:
mediawiki_url: http://test2.wikipedia.org/wiki/
mediawiki_user: Selenium_user
default: *default
Any additional configuration specified via environment variables overrides
what is specified in the YAML file. For example, the following would use
the default configuration as specified under beta
in the YAML file but
define mediawiki_user
as Other_user
instead of Selenium_user
.
export MEDIAWIKI_ENVIRONMENT=beta MEDIAWIKI_USER=Other_user
bundle exec cucumber ...
There are various methods that allow you to perform actions in the context
of some alternative resource, for example as a different user using
#as_user, or on different wiki using #on_wiki. Instead of referencing
the exact user names or URLs for these resources, you reference them by an
ID which corresponds to configuration made in environments.yml
.
# environments.yml:
beta:
# ...
mediawiki_user_b: Selenium_user2
# step definition:
Given(/^user B has linked to a page I created$/) do
as_user(:b) { api.create_page(...) }
end
This level of abstraction is intended to reduce coupling between tests and test environments, and should promote step definitions that are more readable and congruent with the natural-language steps they implement.
Class Attribute Summary collapse
-
.default_configuration ⇒ Object
Returns the value of attribute default_configuration.
-
.default_test_directory ⇒ Object
Returns the value of attribute default_test_directory.
Class Method Summary collapse
-
.load(name, extra = {}, test_dir = nil) ⇒ Object
Instantiates a new environment using the given set of default configuration from
environments.yml
in the current working directory, and the additional hash of environment variables. -
.load_default(test_dir = nil) ⇒ Object
Instantiates a new environment from the values of
ENV
and the default configuration corresponding toENV["MEDIAWIKI_ENVIRONMENT"]
, if one is defined. -
.search_for_configuration(path) ⇒ String
Searches for
environments.yml
in the given path.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Whether the given environment is equal to this one.
-
#[](key) ⇒ String
Returns the configured value for the given env variable name.
-
#as_user(id) {|user, password| ... } ⇒ Object
Executes the given block within the context of an environment that's using the given alternative user and its password.
-
#browser ⇒ Watir::Browser
Browser with which to drive tests.
-
#browser_factory(browser = browser_name) ⇒ BrowserFactory::Base
Factory used to instantiate and open new browsers.
-
#browser_name ⇒ Symbol
Name of the browser we're using.
-
#browser_tags ⇒ Array<String>
Tag names that can be used to filter test scenarios for a specific browser and/or version.
-
#browser_version ⇒ String
Version of the browser we're using.
-
#current_alternative(key) ⇒ Object
Returns the current alternate ID for the given configuration key.
-
#env ⇒ self
A reference to this environment.
-
#headless? ⇒ true, false
Whether this environment is configured to run in headless mode (using Xvfb via the headless gem).
-
#in_browser(id, overrides = {}) {|*args| ... } ⇒ Object
Executes the given block within the context of an environment that uses a unique browser session and possibly different configuration.
-
#initialize(*configs) ⇒ Environment
constructor
A new instance of Environment.
-
#keep_browser_open? ⇒ Boolean
Whether browsers should be left open after each scenario completes.
-
#lookup(key, options = {}) ⇒ String
Returns the configured value for the given env variable name.
-
#lookup_all(keys, options = {}) ⇒ Hash{Symbol => String}
Returns the configured values for the given env variable names.
-
#on_wiki(id) {|wiki_url| ... } ⇒ Object
Executes the given block within the context of an environment that's using the given alternative wiki URL and its corresponding API endpoint.
-
#password(id = nil) ⇒ String
Returns the current value for
:mediawiki_password
or the value for the given alternative. -
#remote? ⇒ Boolean
Whether this environment has been configured to use remote browser sessions.
-
#setup(info = {}) ⇒ Object
Executes setup tasks, annotating the Selenium session with any configured
job_name
andbuild_number
. -
#teardown(info = {}) {|browser| ... } ⇒ Hash{String => String}
Executes teardown tasks including instructing all browser factories to close any open browsers and perform their own teardown tasks.
-
#user(id = nil) ⇒ String
Returns the current value for
:mediawiki_user
or the value for the given alternative. -
#user_label(id = nil) ⇒ String
Returns the current user, or the one for the given alternative, with all "_" replaced with " ".
-
#visit_wiki(id = nil) {|url| ... } ⇒ Object
Navigates the current browser to the given wiki.
-
#wiki_url(path = nil) ⇒ Object
Qualifies any given relative path using the configured
:mediawiki_url
. -
#with_alternative(names, id) {|*args| ... } ⇒ Object
Executes the given block within the context of a new environment configured using the alternative versions of the given options.
Constructor Details
#initialize(*configs) ⇒ Environment
Returns a new instance of Environment.
123 124 125 126 127 128 129 |
# File 'lib/mediawiki_selenium/environment.rb', line 123 def initialize(*configs) @_config = configs.map { |config| normalize_config(config) }.reduce(:merge) @_factory_cache = {} @_current_alternatives = {} extend(HeadlessHelper) if headless? end |
Class Attribute Details
.default_configuration ⇒ Object
Returns the value of attribute default_configuration.
66 67 68 |
# File 'lib/mediawiki_selenium/environment.rb', line 66 def default_configuration @default_configuration end |
.default_test_directory ⇒ Object
Returns the value of attribute default_test_directory.
66 67 68 |
# File 'lib/mediawiki_selenium/environment.rb', line 66 def default_test_directory @default_test_directory end |
Class Method Details
.load(name, extra = {}, test_dir = nil) ⇒ Object
Instantiates a new environment using the given set of default
configuration from environments.yml
in the current working
directory, and the additional hash of environment variables.
environments.yml
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/mediawiki_selenium/environment.rb', line 77 def load(name, extra = {}, test_dir = nil) name = name.to_s configs = [] unless name.empty? envs = YAML.load_file(search_for_configuration(test_dir || default_test_directory)) raise ConfigurationError, "unknown environment `#{name}`" unless envs.include?(name) configs << envs[name] end configs << extra env = new(*configs) env end |
.load_default(test_dir = nil) ⇒ Object
Instantiates a new environment from the values of ENV
and the
default configuration corresponding to ENV["MEDIAWIKI_ENVIRONMENT"]
,
if one is defined.
99 100 101 |
# File 'lib/mediawiki_selenium/environment.rb', line 99 def load_default(test_dir = nil) load(ENV['MEDIAWIKI_ENVIRONMENT'] || 'default', ENV, test_dir) end |
.search_for_configuration(path) ⇒ String
Searches for environments.yml
in the given path. If it isn't found,
the search continues upward in the directory hierarchy.
110 111 112 113 114 115 116 117 |
# File 'lib/mediawiki_selenium/environment.rb', line 110 def search_for_configuration(path) return default_configuration if path.nil? || path.empty? || path == '.' file_path = File.join(path, default_configuration) return file_path if File.exist?(file_path) search_for_configuration(File.dirname(path)) end |
Instance Method Details
#==(other) ⇒ Boolean
Whether the given environment is equal to this one. Two environments are considered equal if they have identical configuration.
138 139 140 |
# File 'lib/mediawiki_selenium/environment.rb', line 138 def ==(other) config == other.config end |
#[](key) ⇒ String
Returns the configured value for the given env variable name.
150 151 152 |
# File 'lib/mediawiki_selenium/environment.rb', line 150 def [](key) lookup(key) end |
#as_user(id) {|user, password| ... } ⇒ Object
Executes the given block within the context of an environment that's using the given alternative user and its password.
168 169 170 171 172 |
# File 'lib/mediawiki_selenium/environment.rb', line 168 def as_user(id, &blk) record_alternatives([:mediawiki_user, :mediawiki_password], id) do with(mediawiki_user: user(id), mediawiki_password: password(id), &blk) end end |
#browser ⇒ Watir::Browser
Browser with which to drive tests.
178 179 180 |
# File 'lib/mediawiki_selenium/environment.rb', line 178 def browser browser_factory.browser_for(browser_config) end |
#browser_factory(browser = browser_name) ⇒ BrowserFactory::Base
Factory used to instantiate and open new browsers.
188 189 190 191 192 193 194 195 |
# File 'lib/mediawiki_selenium/environment.rb', line 188 def browser_factory(browser = browser_name) browser = browser.to_s.downcase.to_sym @_factory_cache[[remote?, browser]] ||= BrowserFactory.new(browser).tap do |factory| factory.configure(:_browser_session) factory.extend(RemoteBrowserFactory) if remote? end end |
#browser_name ⇒ Symbol
Name of the browser we're using. If the :browser
configuration
contains a version at the end, only the name is returned.
206 207 208 |
# File 'lib/mediawiki_selenium/environment.rb', line 206 def browser_name browser_spec[0].to_sym end |
#browser_tags ⇒ Array<String>
Tag names that can be used to filter test scenarios for a specific browser and/or version.
215 216 217 218 219 220 221 222 |
# File 'lib/mediawiki_selenium/environment.rb', line 215 def = [browser_name.to_s] version = browser_version << "#{browser_name}_#{version}" if version end |
#browser_version ⇒ String
Version of the browser we're using. If a :version
configuration
is provided, that value is returned. Otherwise a version is searched for
in the :browser
configuration.
230 231 232 |
# File 'lib/mediawiki_selenium/environment.rb', line 230 def browser_version lookup(:version, default: browser_spec[1]) end |
#current_alternative(key) ⇒ Object
Returns the current alternate ID for the given configuration key.
238 239 240 |
# File 'lib/mediawiki_selenium/environment.rb', line 238 def current_alternative(key) @_current_alternatives[key] end |
#env ⇒ self
A reference to this environment. Can be used in conjunction with #[]
for syntactic sugar in looking up environment configuration where self
would otherwise seem ambiguous.
253 254 255 |
# File 'lib/mediawiki_selenium/environment.rb', line 253 def env self end |
#headless? ⇒ true, false
Whether this environment is configured to run in headless mode (using Xvfb via the headless gem).
262 263 264 |
# File 'lib/mediawiki_selenium/environment.rb', line 262 def headless? lookup(:headless, default: 'false').to_s == 'true' end |
#in_browser(id, overrides = {}) {|*args| ... } ⇒ Object
Executes the given block within the context of an environment that uses
a unique browser session and possibly different configuration. Note that
any given configuration overrides are scoped with a :browser_
prefix.
296 297 298 299 300 301 302 |
# File 'lib/mediawiki_selenium/environment.rb', line 296 def in_browser(id, overrides = {}, &blk) overrides = overrides.each.with_object({}) do |(name, value), hash| hash["browser_#{name}".to_sym] = value end with(overrides.merge(_browser_session: id), &blk) end |
#keep_browser_open? ⇒ Boolean
Whether browsers should be left open after each scenario completes.
306 307 308 |
# File 'lib/mediawiki_selenium/environment.rb', line 306 def keep_browser_open? lookup(:keep_browser_open, default: 'false') == 'true' end |
#lookup(key, options = {}) ⇒ String
Returns the configured value for the given env variable name.
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 |
# File 'lib/mediawiki_selenium/environment.rb', line 328 def lookup(key, = {}) key = "#{key}_#{[:id]}" if .fetch(:id, nil) key = normalize_key(key) value = config[key] if value.nil? || value.to_s.empty? if .include?(:default) [:default].is_a?(Proc) ? [:default].call : [:default] else raise ConfigurationError, "missing configuration for `#{key}`" end else value end end |
#lookup_all(keys, options = {}) ⇒ Hash{Symbol => String}
Returns the configured values for the given env variable names.
356 357 358 359 360 |
# File 'lib/mediawiki_selenium/environment.rb', line 356 def lookup_all(keys, = {}) keys.each.with_object({}) do |key, hash| hash[key] = lookup(key, ) end end |
#on_wiki(id) {|wiki_url| ... } ⇒ Object
Executes the given block within the context of an environment that's using the given alternative wiki URL and its corresponding API endpoint.
If no API URL is explicitly defined for the given alternative, one is constructed relative to the wiki URL.
376 377 378 |
# File 'lib/mediawiki_selenium/environment.rb', line 376 def on_wiki(id, &blk) with_alternative(:mediawiki_url, id, &blk) end |
#password(id = nil) ⇒ String
Returns the current value for :mediawiki_password
or the value for the
given alternative.
387 388 389 |
# File 'lib/mediawiki_selenium/environment.rb', line 387 def password(id = nil) lookup(:mediawiki_password, id: id, default: -> { lookup(:mediawiki_password) }) end |
#remote? ⇒ Boolean
Whether this environment has been configured to use remote browser sessions.
396 397 398 |
# File 'lib/mediawiki_selenium/environment.rb', line 396 def remote? RemoteBrowserFactory::REQUIRED_CONFIG.all? { |name| lookup(name, default: false) } end |
#setup(info = {}) ⇒ Object
Executes setup tasks, annotating the Selenium session with any
configured job_name
and build_number
.
Additional helpers may perform their own tasks by implementing this method.
413 414 415 416 417 418 419 420 421 422 423 424 425 |
# File 'lib/mediawiki_selenium/environment.rb', line 413 def setup(info = {}) browser_factory.configure do || [:desired_capabilities][:name] = info[:name] || 'scenario' end browser_factory.configure(:job_name) do |job, | [:desired_capabilities][:name] += " #{job}" end browser_factory.configure(:build_number) do |build, | [:desired_capabilities][:name] += "##{build}" end end |
#teardown(info = {}) {|browser| ... } ⇒ Hash{String => String}
Executes teardown tasks including instructing all browser factories to close any open browsers and perform their own teardown tasks.
Teardown tasks may produce artifacts, which will be returned in the form
{ path => mime_type }
.
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/mediawiki_selenium/environment.rb', line 446 def teardown(info = {}) artifacts = {} @_factory_cache.each do |(_, browser_name), factory| factory.each do |browser| yield browser if block_given? browser.close unless keep_browser_open? && browser_name != :phantomjs end factory_artifacts = factory.teardown(self, info[:status] || :passed) artifacts.merge!(factory_artifacts) if factory_artifacts.is_a?(Hash) end artifacts end |
#user(id = nil) ⇒ String
Returns the current value for :mediawiki_user
or the value for the
given alternative.
469 470 471 |
# File 'lib/mediawiki_selenium/environment.rb', line 469 def user(id = nil) lookup(:mediawiki_user, id: id) end |
#user_label(id = nil) ⇒ String
Returns the current user, or the one for the given alternative, with all "_" replaced with " ".
480 481 482 |
# File 'lib/mediawiki_selenium/environment.rb', line 480 def user_label(id = nil) user(id).gsub('_', ' ') end |
#visit_wiki(id = nil) {|url| ... } ⇒ Object
Navigates the current browser to the given wiki.
491 492 493 494 495 496 |
# File 'lib/mediawiki_selenium/environment.rb', line 491 def visit_wiki(id = nil) on_wiki(id) do |url| browser.goto url yield url if block_given? end end |
#wiki_url(path = nil) ⇒ Object
Qualifies any given relative path using the configured :mediawiki_url
.
Absolute URLs are left untouched.
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
# File 'lib/mediawiki_selenium/environment.rb', line 509 def wiki_url(path = nil) url = lookup(:mediawiki_url) if path # Prefixing relative paths with an explicit "./" guarantees proper # parsing of paths like "Special:Page" that would otherwise be # confused for URI schemes. if path.include?(':') path_uri = URI.parse(path) path = "./#{path}" if path_uri.class == URI::Generic && !path.start_with?('/') end url = URI.parse(url).merge(path).to_s end url end |
#with_alternative(names, id) {|*args| ... } ⇒ Object
Executes the given block within the context of a new environment configured using the alternative versions of the given options. The alternative configuration values are resolved using the given ID and passed to the block as arguments.
552 553 554 555 |
# File 'lib/mediawiki_selenium/environment.rb', line 552 def with_alternative(names, id, &blk) names = Array(names) record_alternatives(names, id) { with(lookup_all(names, id: id), &blk) } end |