Dduvall has uploaded a new change for review.
https://gerrit.wikimedia.org/r/230261
Change subject: Basic RSpec support
......................................................................
Basic RSpec support
Implemented basic RSpec integration.
A `MediawikiSelenium::Environment` instance is created before each
example and exposed as a `mw` method. It looks for and loads an
`environments.yml` configuration in the current working directory.
All helpers except for `StrictPending` (which is Cucumber specific) are
supported.
See features/rspec.feature for what an RSpec based integration test
could look like.
Bug: T108273
Change-Id: I97a7522764fd535ef8f3510fd654df8976d70af0
---
M .rubocop.yml
A features/rspec.feature
A features/step_definitions/rspec_steps.rb
A lib/mediawiki_selenium/rspec.rb
A lib/mediawiki_selenium/rspec/environment.rb
A lib/mediawiki_selenium/rspec/features.rb
M mediawiki_selenium.gemspec
7 files changed, 203 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/selenium
refs/changes/61/230261/1
diff --git a/.rubocop.yml b/.rubocop.yml
index ef705cb..4e2a635 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,5 +1,10 @@
AllCops:
StyleGuideCopsOnly: true
+ Exclude:
+ # Features syntax is a vendor file imported from Capybara. Ignore it.
+ - 'lib/mediawiki_selenium/rspec/features.rb'
+ # Ignore anything left around in `tmp`
+ - 'tmp/**/*'
Metrics/LineLength:
Max: 100
diff --git a/features/rspec.feature b/features/rspec.feature
new file mode 100644
index 0000000..6cc5fbf
--- /dev/null
+++ b/features/rspec.feature
@@ -0,0 +1,49 @@
+@integration
+Feature: RSpec integration
+
+ As a developer, I want the option to use a test framework with less
+ indirection so that my tests are more straightforward to implement and
+ easier to reason about.
+
+ Background:
+ Given I have set up my `environments.yml`
+ And the following RSpec support file:
+ """
+ require 'bundler/setup'
+ require 'mediawiki_selenium/rspec'
+ """
+
+ Scenario: RSpec examples have access to the `Environment` via `#mw`
+ Given the following RSpec examples:
+ """
+ describe 'my feature' do
+ describe 'my component' do
+ it 'can access `mw` to implement its tests' do
+ expect(mw).to be_a(MediawikiSelenium::Environment)
+ end
+ end
+ end
+ """
+ When I run `rspec` against my examples
+ Then all my examples pass
+
+ Scenario: An alternative feature/scenario syntax is supported
+ Given the following RSpec examples:
+ """
+ feature 'my feature' do
+ background do
+ # do common stuff
+ @stuff = 'stuff'
+ end
+
+ scenario 'my scenario' do
+ expect(@stuff).to eq('stuff')
+ end
+
+ scenario 'my other scenario' do
+ expect(@stuff).to eq('stuff')
+ end
+ end
+ """
+ When I run `rspec` against my examples
+ Then all my examples pass
diff --git a/features/step_definitions/rspec_steps.rb
b/features/step_definitions/rspec_steps.rb
new file mode 100644
index 0000000..47dd13f
--- /dev/null
+++ b/features/step_definitions/rspec_steps.rb
@@ -0,0 +1,30 @@
+require 'yaml'
+
+Given(/^I have set up my `environments\.yml`$/) do
+ step 'the "tmp/rspec/spec" directory exists'
+ Pathname.new('tmp/rspec/environments.yml').write(YAML.dump({ 'default' => {}
}))
+end
+
+Given(/^the following RSpec support file:$/) do |content|
+ Pathname.new('tmp/rspec/spec/spec_helper.rb').write(content)
+end
+
+Given(/^the following RSpec examples:$/) do |content|
+ Pathname.new('tmp/rspec/spec/examples_spec.rb').write("require
'spec_helper'\n#{content}")
+end
+
+Given(/^$the following "(.+)" file for use with RSpec$/) do |path, content|
+ Pathname.new('tmp/rspec').join(path).write(content)
+end
+
+When(/^I run `rspec` against my examples$/) do
+ tail, head = IO.pipe
+ env = { 'MEDIAWIKI_ENVIRONMENT' => 'default' }
+
+ @rspec_passed = system(env, 'bundle exec rspec', chdir: 'tmp/rspec', err:
head, out: head)
+ @rspec_output = tail.read_nonblock(10_000)
+end
+
+Then(/^all my examples pass$/) do
+ expect(@rspec_passed).to be(true), "Examples did not pass. Output:
\n---\n#{@rspec_output}---\n"
+end
diff --git a/lib/mediawiki_selenium/rspec.rb b/lib/mediawiki_selenium/rspec.rb
new file mode 100644
index 0000000..2596f72
--- /dev/null
+++ b/lib/mediawiki_selenium/rspec.rb
@@ -0,0 +1,51 @@
+require 'rspec/core'
+require 'mediawiki_selenium'
+require 'mediawiki_selenium/rspec/features'
+
+module MediawikiSelenium
+ module RSpec
+ # Returns a name for the given example metadata, derived from its example
+ # groups and description.
+ #
+ # @param metadata [RSpec::Core::Metadata, Hash] Base or nested metadata.
+ #
+ # @return [String]
+ #
+ def self.example_name(metadata)
+ name = metadata[:example_group] ?
"#{example_name(metadata[:example_group])} " : ''
+ name += metadata[:description_args].first.to_s if
metadata[:description_args].any?
+ name
+ end
+
+ # Returns a status for the given RSpec example result.
+ #
+ # @param result [Object] Result of `example.run`.
+ #
+ # @return [:passed, :failed, :skipped]
+ #
+ def self.example_status(result)
+ case result
+ when Exception
+ :failed
+ when String
+ :skipped
+ else
+ :passed
+ end
+ end
+
+ autoload :Environment, 'mediawiki_selenium/rspec/environment'
+ end
+end
+
+RSpec.configure do |config|
+ config.include MediawikiSelenium::RSpec::Environment
+
+ config.around(:each) do |example|
+ name = MediawikiSelenium::RSpec.example_name(example.metadata)
+
+ mw.setup(name: name)
+ result = example.run
+ mw.teardown(name: name, status:
MediawikiSelenium::RSpec.example_status(result))
+ end
+end
diff --git a/lib/mediawiki_selenium/rspec/environment.rb
b/lib/mediawiki_selenium/rspec/environment.rb
new file mode 100644
index 0000000..f21d96f
--- /dev/null
+++ b/lib/mediawiki_selenium/rspec/environment.rb
@@ -0,0 +1,18 @@
+module MediawikiSelenium
+ module RSpec
+ module Environment
+ # Sets up and returns a new default environment.
+ #
+ # @return [Environment]
+ #
+ def mw
+ @_mw ||= MediawikiSelenium::Environment.load_default.extend(
+ MediawikiSelenium::ApiHelper,
+ MediawikiSelenium::PageFactory,
+ MediawikiSelenium::ScreenshotHelper,
+ MediawikiSelenium::UserFactoryHelper
+ )
+ end
+ end
+ end
+end
diff --git a/lib/mediawiki_selenium/rspec/features.rb
b/lib/mediawiki_selenium/rspec/features.rb
new file mode 100644
index 0000000..6cb9a21
--- /dev/null
+++ b/lib/mediawiki_selenium/rspec/features.rb
@@ -0,0 +1,49 @@
+# This was "derived" from Capybara's RSpec integration
+#
+#
https://github.com/jnicklas/capybara/blob/master/lib/capybara/rspec/features.rb
+#
+if RSpec::Core::Version::STRING.to_f >= 3.0
+ RSpec.shared_context "MW-Selenium Features", :mw_selenium_feature => true do
+ instance_eval do
+ alias background before
+ alias given let
+ alias given! let!
+ end
+ end
+
+ RSpec.configure do |config|
+ config.alias_example_group_to :feature, :mw_selenium_feature => true,
:type => :feature
+ config.alias_example_to :scenario
+ config.alias_example_to :xscenario, :skip => "Temporarily disabled with
xscenario"
+ config.alias_example_to :fscenario, :focus => true
+ end
+else
+ module MediawikiSelenium::RSpec
+ module Features
+ def self.included(base)
+ base.instance_eval do
+ alias :background :before
+ alias :scenario :it
+ alias :xscenario :xit
+ alias :given :let
+ alias :given! :let!
+ alias :feature :describe
+ end
+ end
+ end
+ end
+
+
+ def self.feature(*args, &block)
+ options = if args.last.is_a?(Hash) then args.pop else {} end
+ options[:mw_selenium_feature] = true
+ options[:type] = :feature
+ options[:caller] ||= caller
+ args.push(options)
+
+ #call describe on RSpec in case user has expose_dsl_globally set to false
+ RSpec.describe(*args, &block)
+ end
+
+ RSpec.configuration.include MediawikiSelenium::RSpec::Features,
:mw_selenium_feature => true
+end
diff --git a/mediawiki_selenium.gemspec b/mediawiki_selenium.gemspec
index a9f0127..6bb7269 100644
--- a/mediawiki_selenium.gemspec
+++ b/mediawiki_selenium.gemspec
@@ -33,6 +33,7 @@
spec.add_runtime_dependency 'mediawiki_api', '~> 0.4', '>= 0.4.1'
spec.add_runtime_dependency 'page-object', '~> 1.0'
spec.add_runtime_dependency 'rest-client', '~> 1.6', '>= 1.6.7'
+ spec.add_runtime_dependency 'rspec-core', '~> 2.14', '>= 2.14.4'
spec.add_runtime_dependency 'rspec-expectations', '~> 2.14', '>= 2.14.4'
spec.add_runtime_dependency 'syntax', '~> 1.2', '>= 1.2.0'
spec.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
@@ -41,6 +42,5 @@
spec.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7.4'
spec.add_development_dependency 'redcarpet', '~> 3.2', '>= 3.2.0'
spec.add_development_dependency 'rubocop', '~> 0.29.1'
- spec.add_development_dependency 'rspec-core', '~> 2.14', '>= 2.14.4'
spec.add_development_dependency 'rspec-mocks', '~> 2.14', '>= 2.14.4'
end
--
To view, visit https://gerrit.wikimedia.org/r/230261
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I97a7522764fd535ef8f3510fd654df8976d70af0
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