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. (See Environment.load and
Environment.load_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.
94 95 96 97 |
# File 'lib/mediawiki_selenium/environment.rb', line 94 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.
57 58 59 |
# File 'lib/mediawiki_selenium/environment.rb', line 57 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.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/mediawiki_selenium/environment.rb', line 66 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.
87 88 89 |
# File 'lib/mediawiki_selenium/environment.rb', line 87 def load_default load(ENV['MEDIAWIKI_ENVIRONMENT'], 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.
106 107 108 |
# File 'lib/mediawiki_selenium/environment.rb', line 106 def ==(other) config == other.config end |
#[](key) ⇒ String
Returns the configured value for the given env variable name.
118 119 120 |
# File 'lib/mediawiki_selenium/environment.rb', line 118 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.
136 137 138 139 140 141 |
# File 'lib/mediawiki_selenium/environment.rb', line 136 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.
147 148 149 |
# File 'lib/mediawiki_selenium/environment.rb', line 147 def browser browser_factory.browser_for(browser_config) end |
#browser_factory(browser = browser_name) ⇒ BrowserFactory::Base
Factory used to instantiate and open new browsers.
157 158 159 160 161 162 163 164 |
# File 'lib/mediawiki_selenium/environment.rb', line 157 def browser_factory(browser = browser_name) browser = browser.to_s.downcase.to_sym @_factory_cache[[remote?, browser]] ||= BrowserFactory.new(browser).tap do |factory| factory.bind(:_browser_session) factory.extend(RemoteBrowserFactory) if remote? end end |
#browser_name ⇒ Symbol
Name of the browser we're using.
170 171 172 |
# File 'lib/mediawiki_selenium/environment.rb', line 170 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.
185 186 187 |
# File 'lib/mediawiki_selenium/environment.rb', line 185 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.
219 220 221 222 223 224 225 |
# File 'lib/mediawiki_selenium/environment.rb', line 219 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.
229 230 231 |
# File 'lib/mediawiki_selenium/environment.rb', line 229 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.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 |
# File 'lib/mediawiki_selenium/environment.rb', line 251 def lookup(key, = {}) key = "#{key}_#{options[: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.
279 280 281 282 283 |
# File 'lib/mediawiki_selenium/environment.rb', line 279 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.
299 300 301 |
# File 'lib/mediawiki_selenium/environment.rb', line 299 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.
310 311 312 |
# File 'lib/mediawiki_selenium/environment.rb', line 310 def password(id = nil) lookup(password_variable, id: id) end |
#remote? ⇒ Boolean
Whether this environment has been configured to use remote browser sessions.
319 320 321 |
# File 'lib/mediawiki_selenium/environment.rb', line 319 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.
336 337 338 339 340 341 342 343 344 345 |
# File 'lib/mediawiki_selenium/environment.rb', line 336 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.
353 354 355 356 357 358 359 360 361 362 |
# File 'lib/mediawiki_selenium/environment.rb', line 353 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.
371 372 373 |
# File 'lib/mediawiki_selenium/environment.rb', line 371 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 " ".
382 383 384 |
# File 'lib/mediawiki_selenium/environment.rb', line 382 def user_label(id = nil) user(id).gsub('_', ' ') end |
#visit_wiki(id) {|url| ... } ⇒ Object
Navigates the current browser to the given wiki.
393 394 395 396 397 398 |
# File 'lib/mediawiki_selenium/environment.rb', line 393 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.
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 |
# File 'lib/mediawiki_selenium/environment.rb', line 411 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.
454 455 456 |
# File 'lib/mediawiki_selenium/environment.rb', line 454 def with_alternative(names, id, &blk) with(lookup_all(Array(names), id: id), &blk) end |