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.
Class Method Summary collapse
-
.load(name, extra = {}) ⇒ Object
Instantiates a new environment using the given set of default configuration from
environments.ymlin the current working directory, and the additional hash of environment variables. -
.load_default ⇒ Object
Instantiates a new environment from the values of
ENVand the default configuration corresponding toENV["MEDIAWIKI_ENVIRONMENT"], if one is defined.
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.
-
#env ⇒ self
A reference to this environment.
-
#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 = {}) ⇒ Array<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_passwordor the value for the given alternative. -
#remote? ⇒ Boolean
Whether this environment has been configured to use remote browser sessions.
-
#teardown(status = :passed) {|browser| ... } ⇒ Object
Executes teardown tasks including instructing all browser factories to close any open browsers and perform their own teardown tasks.
-
#test_name(scenario) ⇒ String
Returns a name from the given scenario.
-
#user(id = nil) ⇒ String
Returns the current value for
:mediawiki_useror 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) {|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.
103 104 105 106 |
# File 'lib/mediawiki_selenium/environment.rb', line 103 def initialize(*configs) @_config = configs.map { |config| normalize_config(config) }.reduce(:merge) @_factory_cache = {} 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 |
Class Method Details
.load(name, extra = {}) ⇒ 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.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/mediawiki_selenium/environment.rb', line 75 def load(name, extra = {}) name = name.to_s configs = [] unless name.empty? envs = YAML.load_file(default_configuration) raise ConfigurationError, "unknown environment `#{name}`" unless envs.include?(name) configs << envs[name] end configs << extra new(*configs) end |
.load_default ⇒ Object
Instantiates a new environment from the values of ENV and the
default configuration corresponding to ENV["MEDIAWIKI_ENVIRONMENT"],
if one is defined.
96 97 98 |
# File 'lib/mediawiki_selenium/environment.rb', line 96 def load_default load(ENV['MEDIAWIKI_ENVIRONMENT'] || 'default', ENV) 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.
115 116 117 |
# File 'lib/mediawiki_selenium/environment.rb', line 115 def ==(other) config == other.config end |
#[](key) ⇒ String
Returns the configured value for the given env variable name.
127 128 129 |
# File 'lib/mediawiki_selenium/environment.rb', line 127 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.
145 146 147 148 149 150 |
# File 'lib/mediawiki_selenium/environment.rb', line 145 def as_user(id, &blk) user = lookup(:mediawiki_user, id: id) password = lookup(:mediawiki_password, id: id, default: -> { lookup(:mediawiki_password) }) with(mediawiki_user: user, mediawiki_password: password, &blk) end |
#browser ⇒ Watir::Browser
Browser with which to drive tests.
156 157 158 |
# File 'lib/mediawiki_selenium/environment.rb', line 156 def browser browser_factory.browser_for(browser_config) end |
#browser_factory(browser = browser_name) ⇒ BrowserFactory::Base
Factory used to instantiate and open new browsers.
166 167 168 169 170 171 172 173 |
# File 'lib/mediawiki_selenium/environment.rb', line 166 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.
179 180 181 |
# File 'lib/mediawiki_selenium/environment.rb', line 179 def browser_name lookup(:browser, default: 'firefox').downcase.to_sym 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.
194 195 196 |
# File 'lib/mediawiki_selenium/environment.rb', line 194 def env self 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.
228 229 230 231 232 233 234 |
# File 'lib/mediawiki_selenium/environment.rb', line 228 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.
238 239 240 |
# File 'lib/mediawiki_selenium/environment.rb', line 238 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.
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/mediawiki_selenium/environment.rb', line 260 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 = {}) ⇒ Array<String>
Returns the configured values for the given env variable names.
288 289 290 291 292 |
# File 'lib/mediawiki_selenium/environment.rb', line 288 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.
308 309 310 |
# File 'lib/mediawiki_selenium/environment.rb', line 308 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.
319 320 321 |
# File 'lib/mediawiki_selenium/environment.rb', line 319 def password(id = nil) lookup(:mediawiki_password, id: id) end |
#remote? ⇒ Boolean
Whether this environment has been configured to use remote browser sessions.
328 329 330 |
# File 'lib/mediawiki_selenium/environment.rb', line 328 def remote? RemoteBrowserFactory::REQUIRED_CONFIG.all? { |name| lookup(name, default: false) } end |
#teardown(status = :passed) {|browser| ... } ⇒ Object
Executes teardown tasks including instructing all browser factories to close any open browsers and perform their own teardown tasks.
345 346 347 348 349 350 351 352 353 354 |
# File 'lib/mediawiki_selenium/environment.rb', line 345 def teardown(status = :passed) @_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.teardown(self, status) end end |
#test_name(scenario) ⇒ String
Returns a name from the given scenario.
362 363 364 365 366 367 368 369 370 371 |
# File 'lib/mediawiki_selenium/environment.rb', line 362 def test_name(scenario) if scenario.respond_to? :feature "#{scenario.feature.title}: #{scenario.title}" elsif scenario.respond_to? :scenario_outline outline = scenario.scenario_outline "#{outline.feature.title}: #{outline.title}: #{scenario.name}" else scenario.name end end |
#user(id = nil) ⇒ String
Returns the current value for :mediawiki_user or the value for the
given alternative.
380 381 382 |
# File 'lib/mediawiki_selenium/environment.rb', line 380 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 " ".
391 392 393 |
# File 'lib/mediawiki_selenium/environment.rb', line 391 def user_label(id = nil) user(id).gsub('_', ' ') end |
#visit_wiki(id) {|url| ... } ⇒ Object
Navigates the current browser to the given wiki.
402 403 404 405 406 407 |
# File 'lib/mediawiki_selenium/environment.rb', line 402 def visit_wiki(id) 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.
420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 |
# File 'lib/mediawiki_selenium/environment.rb', line 420 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.
463 464 465 |
# File 'lib/mediawiki_selenium/environment.rb', line 463 def with_alternative(names, id, &blk) with(lookup_all(Array(names), id: id), &blk) end |