Dduvall has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/159644

Change subject: WIP Environment abstraction layer
......................................................................

WIP Environment abstraction layer

This is a very early WIP of an environment abstraction layer that
binds environment configuration to browser instantiation and
provides switching between different wiki, user, and other contexts.

Change-Id: I1a3aa64b8fdca73aff2778ec12143a8789e4843f
---
A .rspec
M Gemfile
M lib/mediawiki_selenium.rb
A lib/mediawiki_selenium/browser_factory.rb
A lib/mediawiki_selenium/browser_factory/base.rb
A lib/mediawiki_selenium/browser_factory/chrome.rb
A lib/mediawiki_selenium/browser_factory/firefox.rb
A lib/mediawiki_selenium/browser_factory/phantomjs.rb
A lib/mediawiki_selenium/environment.rb
A lib/mediawiki_selenium/step_definitions.rb
A lib/mediawiki_selenium/support.rb
M lib/mediawiki_selenium/support/env.rb
A lib/mediawiki_selenium/support/pages.rb
M lib/mediawiki_selenium/support/pages/api_page.rb
M lib/mediawiki_selenium/support/pages/login_page.rb
M lib/mediawiki_selenium/support/pages/random_page.rb
M lib/mediawiki_selenium/support/pages/reset_preferences_page.rb
M mediawiki_selenium.gemspec
A spec/environment_spec.rb
A spec/spec_helper.rb
20 files changed, 560 insertions(+), 20 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/selenium 
refs/changes/44/159644/1

diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..4e1e0d2
--- /dev/null
+++ b/.rspec
@@ -0,0 +1 @@
+--color
diff --git a/Gemfile b/Gemfile
index 6fa2b49..fb7bcfb 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,3 +4,7 @@
 source "https://rubygems.org";
 
 gemspec
+
+group :development do
+  gem "pry-byebug"
+end
diff --git a/lib/mediawiki_selenium.rb b/lib/mediawiki_selenium.rb
index 612105f..2b59a4a 100644
--- a/lib/mediawiki_selenium.rb
+++ b/lib/mediawiki_selenium.rb
@@ -9,22 +9,9 @@
 https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
 =end
 
-require "mediawiki_selenium/version"
-
-require "mediawiki_selenium/support/env"
-require "mediawiki_selenium/support/hooks"
-require "mediawiki_selenium/support/sauce"
-
-require "mediawiki_selenium/step_definitions/login_steps"
-require "mediawiki_selenium/step_definitions/navigation_steps"
-require "mediawiki_selenium/step_definitions/preferences_steps"
-require "mediawiki_selenium/step_definitions/resource_loader_steps"
-require "mediawiki_selenium/step_definitions/upload_file_steps"
-
-require "mediawiki_selenium/support/modules/api_helper"
-require "mediawiki_selenium/support/modules/url_module"
-
-require "mediawiki_selenium/support/pages/api_page"
-require "mediawiki_selenium/support/pages/login_page"
-require "mediawiki_selenium/support/pages/random_page"
-require "mediawiki_selenium/support/pages/reset_preferences_page"
+module MediawikiSelenium
+  autoload :VERSION, "mediawiki_selenium/version"
+  autoload :ApiHelper, "mediawiki_selenium/support/modules/api_helper"
+  autoload :BrowserFactory, "mediawiki_selenium/browser_factory"
+  autoload :Environment, "mediawiki_selenium/environment"
+end
diff --git a/lib/mediawiki_selenium/browser_factory.rb 
b/lib/mediawiki_selenium/browser_factory.rb
new file mode 100644
index 0000000..cc58f58
--- /dev/null
+++ b/lib/mediawiki_selenium/browser_factory.rb
@@ -0,0 +1,22 @@
+module MediawikiSelenium
+  # Browser factory.
+  #
+  module BrowserFactory
+    autoload :Base, "mediawiki_selenium/browser_factory/base"
+    autoload :Firefox, "mediawiki_selenium/browser_factory/firefox"
+    autoload :Chrome, "mediawiki_selenium/browser_factory/chrome"
+    autoload :Phantomjs, "mediawiki_selenium/browser_factory/phantomjs"
+
+    # Resolves a new factory for the given browser name.
+    #
+    # @param name [Symbol] Browser name.
+    # @param options [Hash] Browser options.
+    #
+    # @return [BrowserFactory::Base]
+    #
+    def self.new(name, options)
+      factory_class = 
const_get(name.to_s.split('_').map(&:capitalize).join(''))
+      factory_class.new(name, options)
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/browser_factory/base.rb 
b/lib/mediawiki_selenium/browser_factory/base.rb
new file mode 100644
index 0000000..b6e321c
--- /dev/null
+++ b/lib/mediawiki_selenium/browser_factory/base.rb
@@ -0,0 +1,46 @@
+require "watir-webdriver"
+
+module MediawikiSelenium
+  module BrowserFactory
+    class Base
+      attr_reader :name
+
+      def initialize(name, options)
+        @name = name
+        @options = options
+      end
+
+      def browser
+        Watir::Browser.new(name, options)
+      end
+
+      def capabilities
+        {}
+      end
+
+      def desired_capabilities
+        if Selenium::WebDriver::Remote::Capabilities.respond_to?(@name)
+          Selenium::WebDriver::Remote::Capabilities.send(@name, capabilities)
+        end
+      end
+
+      def options
+        { http_client: http_client, desired_capabilities: desired_capabilities 
}
+      end
+
+      def http_client
+        Selenium::WebDriver::Remote::Http::Default.new.tap do |client|
+          client.timeout = @options[:browser_timeout]
+        end
+      end
+
+      protected
+
+      def bind(option)
+        unless @options[option].nil? || @options[option].to_s.empty?
+          yield @options[option]
+        end
+      end
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/browser_factory/chrome.rb 
b/lib/mediawiki_selenium/browser_factory/chrome.rb
new file mode 100644
index 0000000..b81429a
--- /dev/null
+++ b/lib/mediawiki_selenium/browser_factory/chrome.rb
@@ -0,0 +1,28 @@
+module MediawikiSelenium
+  module BrowserFactory
+    class Chrome < Base
+      def arguments
+        [].tap do |args|
+          bind(:browser_user_agent) do |user_agent|
+            args << "--user-agent=#{user_agent}"
+          end
+        end
+      end
+
+      def capabilities
+        super.merge(
+          "chrome.profile" => profile.as_json["zip"],
+          "chromeOptions" => { "args" => arguments },
+        )
+      end
+
+      def profile
+        Selenium::WebDriver::Chrome::Profile.new.tap do |profile|
+          bind(:browser_language) do |language|
+            profile["intl.accept_languages"] = language
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/browser_factory/firefox.rb 
b/lib/mediawiki_selenium/browser_factory/firefox.rb
new file mode 100644
index 0000000..c1d5a90
--- /dev/null
+++ b/lib/mediawiki_selenium/browser_factory/firefox.rb
@@ -0,0 +1,26 @@
+module MediawikiSelenium
+  module BrowserFactory
+    class Firefox < Base
+      def capabilities
+        super.merge(firefox_profile: profile)
+      end
+
+      def profile
+        Selenium::WebDriver::Firefox::Profile.new.tap do |profile|
+          bind(:browser_timeout) do |timeout|
+            profile["dom.max_script_run_time"] = timeout
+            profile["dom.max_chrome_script_run_time"] = timeout
+          end
+
+          bind(:browser_language) do |language|
+            profile["intl.accept_languages"] = language
+          end
+
+          bind(:browser_user_agent) do |user_agent|
+            profile["general.useragent.override"] = user_agent
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/browser_factory/phantomjs.rb 
b/lib/mediawiki_selenium/browser_factory/phantomjs.rb
new file mode 100644
index 0000000..5a8309b
--- /dev/null
+++ b/lib/mediawiki_selenium/browser_factory/phantomjs.rb
@@ -0,0 +1,17 @@
+module MediawikiSelenium
+  module BrowserFactory
+    class Phantomjs < Base
+      def capabilities
+        super.tap do |capabilities|
+          bind(:browser_language) do |language|
+            capabilities["phantomjs.page.customHeaders.Accept-Language"] = 
language
+          end
+
+          bind(:browser_user_agent) do |user_agent|
+            capabilities["phantomjs.page.settings.userAgent"] = user_agent
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/environment.rb 
b/lib/mediawiki_selenium/environment.rb
new file mode 100644
index 0000000..325b5d6
--- /dev/null
+++ b/lib/mediawiki_selenium/environment.rb
@@ -0,0 +1,172 @@
+module MediawikiSelenium
+  # Provides an abstraction layer between the environmental configuration and
+  # step definitions.
+  #
+  class Environment
+    include Comparable
+
+    class ConfigurationError < StandardError
+      attr_reader :name
+
+      def initialize(name)
+        @name = name
+      end
+
+      def to_s
+        "missing configuration for #{name}"
+      end
+    end
+
+    BROWSER_OPTIONS = [
+      :browser,
+      :browser_language,
+      :browser_timeout,
+      :browser_user_agent,
+      :mediawiki_url,
+      :mediawiki_user,
+    ]
+
+    REQUIRED_CONFIG = [
+      :browser,
+      :mediawiki_api_url,
+      :mediawiki_password,
+      :mediawiki_url,
+      :mediawiki_user,
+    ]
+
+    attr_reader :config
+
+    def initialize(config, browsers = {})
+      @config = normalize_config(config)
+      @browsers = browsers
+    end
+
+    # Two environments are considered equal if they have identical
+    # configuration.
+    #
+    def ==(other)
+      @config == other.config
+    end
+
+    # Executes the given block within the context of an environment that's
+    # using the given alternative user and its password.
+    #
+    # @param id [Symbol] Alternative user ID.
+    #
+    # @yield [env]
+    # @yieldparam env [Environment] Environment
+    #
+    # @return [Environment]
+    #
+    def as_user(id, &blk)
+      with_alternative([:mediawiki_user, :mediawiki_password], id, &blk)
+    end
+
+    # Browser with which to drive tests.
+    #
+    # @return [Watir::Browser]
+    #
+    def browser
+      options = browser_options
+      @browsers[options] ||= BrowserFactory.new(browser_name, options).browser
+    end
+
+    # Name of the browser we're using.
+    #
+    # @return [Symbol]
+    #
+    def browser_name
+      lookup(:browser).downcase.to_sym
+    end
+
+    # Options to use when instantiating a new browser.
+    #
+    # @return [Hash]
+    #
+    def browser_options
+      @browser_options ||= lookup_all(BROWSER_OPTIONS)
+    end
+
+    # Executes the given block within the context of an environment that's
+    # using the given alternative wiki URL and its corresponding API endpoint.
+    #
+    # @param id [Symbol] Alternative wiki ID.
+    #
+    # @yield [env]
+    # @yieldparam env [Environment] Environment
+    #
+    # @return [Environment]
+    #
+    def on_wiki(id, &blk)
+      with_alternative([:mediawiki_url, :mediawiki_api_url], id, &blk)
+    end
+
+    # Yields a new environment using the alternative versions of the given
+    # configuration options. The alternative values are resolved by looking up
+    # options that correspond to the given ones but have the given ID
+    # appended.
+    #
+    # @example Overwrite :option with the value from :option_b
+    #   # given an environment with { option: "x", option_b: "y", ... }
+    #   env.with_alternative(:option, :b) do |env|
+    #     env # => { option: "y", ... }
+    #   end
+    #
+    # @example Overwrite both :option and :other with :option_b and :other_b
+    #   # given { option: "x", option_b: "y", other: "w", other_b: "z" }
+    #   env.with_alternative([:option, :other], :b) do |env|
+    #     env # => { option: "y", other: "z", ... }
+    #   end
+    #
+    # @param names [Array|Symbol] Configuration option or options.
+    # @param id [Symbol] Alternative user ID.
+    #
+    # @yield [env]
+    # @yieldparam env [Environment] The modified environment.
+    #
+    # @return [Environment] The modified environment.
+    #
+    def with_alternative(names, id, &blk)
+      with(lookup_all(Array(names), id), &blk)
+    end
+
+    private
+
+    def lookup_all(keys, id = nil)
+      keys.each.with_object({}) do |key, hash|
+        value = lookup(key, id)
+        hash[key] = value unless value.nil?
+      end
+    end
+
+    def lookup(key, id = nil)
+      key = "#{key}_#{id}" unless id.nil?
+      key = key.to_sym
+      value = @config[key]
+
+      if value.nil? || value.to_s.empty?
+        if id.nil?
+          if REQUIRED_CONFIG.include?(key)
+            raise ConfigurationError, key
+          else
+            nil
+          end
+        else
+          lookup(key)
+        end
+      else
+        value
+      end
+    end
+
+    def normalize_config(hash)
+      hash.each.with_object({}) { |(k, v), acc| acc[k.to_s.downcase.to_sym] = 
v }
+    end
+
+    def with(overrides = {})
+      config = self.class.new(@config.merge(normalize_config(overrides)), 
@browsers)
+      yield config
+      config
+    end
+  end
+end
diff --git a/lib/mediawiki_selenium/step_definitions.rb 
b/lib/mediawiki_selenium/step_definitions.rb
new file mode 100644
index 0000000..b8608f6
--- /dev/null
+++ b/lib/mediawiki_selenium/step_definitions.rb
@@ -0,0 +1,5 @@
+require "mediawiki_selenium/step_definitions/login_steps"
+require "mediawiki_selenium/step_definitions/navigation_steps"
+require "mediawiki_selenium/step_definitions/preferences_steps"
+require "mediawiki_selenium/step_definitions/resource_loader_steps"
+require "mediawiki_selenium/step_definitions/upload_file_steps"
diff --git a/lib/mediawiki_selenium/support.rb 
b/lib/mediawiki_selenium/support.rb
new file mode 100644
index 0000000..f5a6cb6
--- /dev/null
+++ b/lib/mediawiki_selenium/support.rb
@@ -0,0 +1,3 @@
+require "mediawiki_selenium/support/env"
+require "mediawiki_selenium/support/hooks"
+require "mediawiki_selenium/support/sauce"
diff --git a/lib/mediawiki_selenium/support/env.rb 
b/lib/mediawiki_selenium/support/env.rb
index bb7f751..418b24f 100644
--- a/lib/mediawiki_selenium/support/env.rb
+++ b/lib/mediawiki_selenium/support/env.rb
@@ -11,7 +11,6 @@
 
 # before all
 require "bundler/setup"
-require "page-object"
 require "page-object/page_factory"
 require "rest_client"
 require "watir-webdriver"
@@ -21,6 +20,8 @@
 World(PageObject::PageFactory)
 World(MediawikiSelenium::ApiHelper)
 
+World { MediawikiSelenium::Environment.new(ENV) }
+
 def browser(test_name, configuration = nil)
   if environment == :saucelabs
     sauce_browser(test_name, configuration)
diff --git a/lib/mediawiki_selenium/support/pages.rb 
b/lib/mediawiki_selenium/support/pages.rb
new file mode 100644
index 0000000..f316bcf
--- /dev/null
+++ b/lib/mediawiki_selenium/support/pages.rb
@@ -0,0 +1,4 @@
+require "mediawiki_selenium/support/pages/api_page"
+require "mediawiki_selenium/support/pages/login_page"
+require "mediawiki_selenium/support/pages/random_page"
+require "mediawiki_selenium/support/pages/reset_preferences_page"
diff --git a/lib/mediawiki_selenium/support/pages/api_page.rb 
b/lib/mediawiki_selenium/support/pages/api_page.rb
index ba2ef39..53da9ee 100644
--- a/lib/mediawiki_selenium/support/pages/api_page.rb
+++ b/lib/mediawiki_selenium/support/pages/api_page.rb
@@ -1,3 +1,4 @@
+require "page-object"
 require "mediawiki_api"
 
 class APIPage
diff --git a/lib/mediawiki_selenium/support/pages/login_page.rb 
b/lib/mediawiki_selenium/support/pages/login_page.rb
index 89857bf..44fbf78 100644
--- a/lib/mediawiki_selenium/support/pages/login_page.rb
+++ b/lib/mediawiki_selenium/support/pages/login_page.rb
@@ -8,6 +8,8 @@
 mediawiki_selenium top-level directory and at
 https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
 =end
+require "page-object"
+require "mediawiki_selenium/support/modules/url_module"
 
 class LoginPage
   include PageObject
diff --git a/lib/mediawiki_selenium/support/pages/random_page.rb 
b/lib/mediawiki_selenium/support/pages/random_page.rb
index c181ea3..40e33cd 100644
--- a/lib/mediawiki_selenium/support/pages/random_page.rb
+++ b/lib/mediawiki_selenium/support/pages/random_page.rb
@@ -8,6 +8,8 @@
 mediawiki_selenium top-level directory and at
 https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
 =end
+require "page-object"
+require "mediawiki_selenium/support/modules/url_module"
 
 class RandomPage
   include PageObject
diff --git a/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb 
b/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb
index 255c772..76f2281 100644
--- a/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb
+++ b/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb
@@ -8,6 +8,8 @@
 mediawiki_selenium top-level directory and at
 https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
 =end
+require "page-object"
+require "mediawiki_selenium/support/modules/url_module"
 
 class ResetPreferencesPage
   include PageObject
diff --git a/mediawiki_selenium.gemspec b/mediawiki_selenium.gemspec
index 2028545..0979d1a 100644
--- a/mediawiki_selenium.gemspec
+++ b/mediawiki_selenium.gemspec
@@ -25,4 +25,8 @@
   spec.add_runtime_dependency "rest-client", "~> 1.6", ">= 1.6.7"
   spec.add_runtime_dependency "rspec-expectations", "~> 2.14", ">= 2.14.4"
   spec.add_runtime_dependency "syntax", "~> 1.2", ">= 1.2.0"
+
+  spec.add_development_dependency "bundler", "~> 1.6", ">= 1.6.3"
+  spec.add_development_dependency "rspec-core", "~> 2.14", ">= 2.14.4"
+  spec.add_development_dependency "rspec-mocks", "~> 2.14", ">= 2.14.4"
 end
diff --git a/spec/environment_spec.rb b/spec/environment_spec.rb
new file mode 100644
index 0000000..2094c33
--- /dev/null
+++ b/spec/environment_spec.rb
@@ -0,0 +1,209 @@
+require "spec_helper"
+
+module MediawikiSelenium
+  describe Environment do
+    subject { env }
+
+    let(:env) { Environment.new(config) }
+    let(:config) { minimum_config }
+
+    let(:minimum_config) do 
+      {
+        browser: browser,
+        mediawiki_api_url: mediawiki_api_url,
+        mediawiki_url: mediawiki_url,
+        mediawiki_user: mediawiki_user,
+        mediawiki_password: mediawiki_password,
+      }
+    end
+
+    let(:full_config) do
+      minimum_config.merge({
+        browser_language: browser_language,
+        browser_timeout: browser_timeout,
+        browser_user_agent: browser_user_agent,
+      })
+    end
+
+    let(:browser) { "firefox" }
+    let(:mediawiki_api_url) { "http://an.example/wiki/api.php"; }
+    let(:mediawiki_url) { "http://an.example/wiki/"; }
+    let(:mediawiki_user) { "mw user" }
+    let(:mediawiki_password) { "mw password" }
+
+    let(:browser_language) { "en-US" }
+    let(:browser_timeout) { 60 }
+    let(:browser_user_agent) { "Lynx/1.0" }
+
+    describe "#==" do
+      subject { env == other }
+
+      context "given an environment with the same configuration" do
+        let(:other) { Environment.new(env.config) }
+
+        it "considers them equal" do
+          expect(subject).to be(true)
+        end
+      end
+
+      context "given an environment with different configuration" do
+        let(:other) { Environment.new(env.config.merge(some: "extra")) }
+
+        it "considers them not equal" do
+          expect(subject).to be(false)
+        end
+      end
+    end
+
+    describe "#as_user" do
+      let(:config) do
+        {
+          mediawiki_user: "user",
+          mediawiki_password: "pass",
+          mediawiki_user_b: "user b",
+          mediawiki_password_b: "pass b",
+        }
+      end
+
+      it "yields a new environment for the alternative user and its password" 
do
+        expected_env = Environment.new(config.merge(
+          mediawiki_user: "user b",
+          mediawiki_password: "pass b",
+        ))
+        expect { |block| env.as_user(:b, &block) }.to 
yield_with_args(expected_env)
+      end
+    end
+
+    describe "#browser" do
+      subject { env.browser }
+
+      it "should create a browser through the right factory" do
+        factory = double(BrowserFactory::Firefox)
+
+        expect(BrowserFactory).to receive(:new).
+          with(env.browser_name, env.browser_options).
+          and_return(factory)
+        expect(factory).to receive(:browser)
+
+        subject
+      end
+
+      context "where the options are the same as before" do
+        it "should return a cached browser instance" do
+          factory = double(BrowserFactory::Firefox)
+          browser = double(Watir::Browser)
+
+          expect(BrowserFactory).to receive(:new).once.
+            with(env.browser_name, env.browser_options).
+            and_return(factory)
+          expect(factory).to receive(:browser).and_return(browser)
+
+          browsers = 2.times.collect { env.browser }
+          expect(browsers.first).to be(browsers.last)
+        end
+      end
+    end
+
+    describe "#browser_name" do
+      subject { env.browser_name }
+
+      let(:browser) { "Firefox" }
+
+      it "is always a lowercase symbol" do
+        expect(subject).to be(:firefox)
+      end
+
+      context "missing browser configuration" do
+        let(:browser) { nil }
+
+        it "raises a ConfigurationError" do
+          expect { subject }.to raise_error(Environment::ConfigurationError)
+        end
+      end
+    end
+
+    describe "#browser_options" do
+      subject { env.browser_options }
+
+      context "minimum configuration" do
+        let(:config) { minimum_config }
+
+        it "contains just :browser, :mediawiki_url, and :mediawiki_user" do
+          expect(subject.keys).to match_array([:browser, :mediawiki_url, 
:mediawiki_user])
+        end
+      end
+
+      context "full configuration" do
+        let(:config) { full_config }
+
+        it "also contains :browser_language, :browser_timeout, and 
:browser_user_agent" do
+          expect(subject.keys).to match_array([
+            :browser, :mediawiki_url, :mediawiki_user,
+            :browser_language, :browser_timeout, :browser_user_agent
+          ])
+        end
+      end
+
+      context "missing some required configuration (e.g. :browser)" do
+        let(:browser) { nil }
+
+        it "raises a ConfigurationError" do
+          expect { subject }.to raise_error(Environment::ConfigurationError)
+        end
+      end
+    end
+
+    describe "#on_wiki" do
+      let(:config) do
+        {
+          mediawiki_url: "http://an.example/wiki";,
+          mediawiki_url_b: "http://alt.example/wiki";,
+          mediawiki_api_url: "http://an.example/api";,
+          mediawiki_api_url_b: "http://alt.example/api";,
+        }
+      end
+
+      it "yields a new environment for the alternative wiki and API urls" do
+        expected_env = Environment.new(config.merge(
+          mediawiki_url: "http://alt.example/wiki";,
+          mediawiki_api_url: "http://alt.example/api";,
+        ))
+        expect { |block| env.on_wiki(:b, &block) }.to 
yield_with_args(expected_env)
+      end
+    end
+
+    describe "#with_alternative" do
+      let(:config) do
+        {
+          mediawiki_url: "http://an.example/wiki";,
+          mediawiki_url_b: "http://alt.example/wiki";,
+          mediawiki_api_url: "http://an.example/api";,
+          mediawiki_api_url_b: "http://alt.example/api";,
+        }
+      end
+
+      context "given one option name and an ID" do
+        let(:names) { :mediawiki_url }
+
+        it "yields an environment that substitutes it using the alternative" do
+          expected_env = Environment.new(config.merge(
+            mediawiki_url: "http://alt.example/wiki";,
+          ))
+          expect { |block| env.with_alternative(names, :b, &block) }.to 
yield_with_args(expected_env)
+        end
+      end
+
+      context "given multiple option names and an ID" do
+        let(:names) { [:mediawiki_url, :mediawiki_api_url] }
+
+        it "yields an environment that substitutes both using the 
alternatives" do
+          expected_env = Environment.new(config.merge(
+            mediawiki_url: "http://alt.example/wiki";,
+            mediawiki_api_url: "http://alt.example/api";,
+          ))
+          expect { |block| env.with_alternative(names, :b, &block) }.to 
yield_with_args(expected_env)
+        end
+      end
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..f92911d
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,4 @@
+require "bundler/setup"
+require "mediawiki_selenium"
+
+Bundler.require(:development)

-- 
To view, visit https://gerrit.wikimedia.org/r/159644
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1a3aa64b8fdca73aff2778ec12143a8789e4843f
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/selenium
Gerrit-Branch: master
Gerrit-Owner: Dduvall <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to