mediawiki_selenium 1.0.0.pre.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +23 -1
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +1 -4
- data/UPGRADE.md +1 -1
- data/bin/mediawiki-selenium-init +1 -1
- data/lib/mediawiki_selenium/browser_factory/base.rb +8 -8
- data/lib/mediawiki_selenium/browser_factory/chrome.rb +1 -1
- data/lib/mediawiki_selenium/browser_factory/firefox.rb +4 -4
- data/lib/mediawiki_selenium/browser_factory/phantomjs.rb +2 -2
- data/lib/mediawiki_selenium/browser_factory.rb +5 -5
- data/lib/mediawiki_selenium/environment.rb +15 -14
- data/lib/mediawiki_selenium/initializer.rb +4 -4
- data/lib/mediawiki_selenium/page_factory.rb +1 -1
- data/lib/mediawiki_selenium/remote_browser_factory.rb +12 -8
- data/lib/mediawiki_selenium/step_definitions/login_steps.rb +0 -11
- data/lib/mediawiki_selenium/step_definitions/navigation_steps.rb +0 -11
- data/lib/mediawiki_selenium/step_definitions/preferences_steps.rb +0 -11
- data/lib/mediawiki_selenium/step_definitions/resource_loader_steps.rb +0 -11
- data/lib/mediawiki_selenium/step_definitions/upload_file_steps.rb +3 -3
- data/lib/mediawiki_selenium/step_definitions.rb +5 -5
- data/lib/mediawiki_selenium/support/env.rb +5 -16
- data/lib/mediawiki_selenium/support/hooks.rb +15 -26
- data/lib/mediawiki_selenium/support/modules/api_helper.rb +5 -7
- data/lib/mediawiki_selenium/support/pages/api_page.rb +6 -6
- data/lib/mediawiki_selenium/support/pages/login_page.rb +13 -12
- data/lib/mediawiki_selenium/support/pages/random_page.rb +2 -2
- data/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb +3 -3
- data/lib/mediawiki_selenium/support/pages.rb +4 -4
- data/lib/mediawiki_selenium/support/sauce.rb +14 -18
- data/lib/mediawiki_selenium/support.rb +4 -4
- data/lib/mediawiki_selenium/version.rb +1 -12
- data/lib/mediawiki_selenium/warnings_formatter.rb +15 -15
- data/lib/mediawiki_selenium.rb +8 -19
- data/mediawiki_selenium.gemspec +35 -28
- data/spec/api_helper_spec.rb +25 -25
- data/spec/browser_factory/base_spec.rb +50 -46
- data/spec/browser_factory/chrome_spec.rb +11 -11
- data/spec/browser_factory/firefox_spec.rb +17 -17
- data/spec/browser_factory/phantomjs_spec.rb +11 -11
- data/spec/environment_spec.rb +194 -159
- data/spec/page_factory_spec.rb +12 -12
- data/spec/remote_browser_factory_spec.rb +15 -15
- data/spec/spec_helper.rb +2 -2
- data/templates/tests/browser/features/support/env.rb +3 -3
- metadata +9 -9
- data/.rubocop_todo.yml +0 -160
@@ -1,25 +1,26 @@
|
|
1
|
-
require
|
1
|
+
require 'page-object'
|
2
2
|
|
3
3
|
class LoginPage
|
4
4
|
include PageObject
|
5
5
|
|
6
|
-
page_url
|
6
|
+
page_url 'Special:UserLogin'
|
7
7
|
|
8
|
-
div(:feedback, class:
|
9
|
-
button(:login, id:
|
10
|
-
li(:logout, id:
|
11
|
-
text_field(:password, id:
|
12
|
-
a(:password_strength, text:
|
13
|
-
a(:phishing, text:
|
14
|
-
text_field(:username, id:
|
8
|
+
div(:feedback, class: 'errorbox')
|
9
|
+
button(:login, id: 'wpLoginAttempt')
|
10
|
+
li(:logout, id: 'pt-logout')
|
11
|
+
text_field(:password, id: 'wpPassword1')
|
12
|
+
a(:password_strength, text: 'password strength')
|
13
|
+
a(:phishing, text: 'phishing')
|
14
|
+
text_field(:username, id: 'wpName1')
|
15
15
|
a(:username_displayed, title: /Your user page/)
|
16
16
|
|
17
17
|
def logged_in_as_element
|
18
|
-
@browser.div(id:
|
18
|
+
@browser.div(id: 'mw-content-text').p.b
|
19
19
|
end
|
20
|
+
|
20
21
|
def login_with(username, password, wait_for_logout_element = true)
|
21
|
-
|
22
|
-
|
22
|
+
username_element.when_present.send_keys(username)
|
23
|
+
password_element.when_present.send_keys(password)
|
23
24
|
login_element.when_present.click
|
24
25
|
logout_element.when_present(10) if wait_for_logout_element
|
25
26
|
end
|
@@ -1,9 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'page-object'
|
2
2
|
|
3
3
|
class ResetPreferencesPage
|
4
4
|
include PageObject
|
5
5
|
|
6
|
-
page_url
|
6
|
+
page_url 'Special:Preferences/reset'
|
7
7
|
|
8
|
-
button(:submit, class:
|
8
|
+
button(:submit, class: 'mw-htmlform-submit')
|
9
9
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'mediawiki_selenium/support/pages/api_page'
|
2
|
+
require 'mediawiki_selenium/support/pages/login_page'
|
3
|
+
require 'mediawiki_selenium/support/pages/random_page'
|
4
|
+
require 'mediawiki_selenium/support/pages/reset_preferences_page'
|
@@ -1,30 +1,26 @@
|
|
1
|
-
|
2
|
-
This file is subject to the license terms in the LICENSE file found in the
|
3
|
-
mediawiki_selenium top-level directory and at
|
4
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/LICENSE. No part of
|
5
|
-
mediawiki_selenium, including this file, may be copied, modified, propagated, or
|
6
|
-
distributed except according to the terms contained in the LICENSE file.
|
7
|
-
Copyright 2013 by the Mediawiki developers. See the CREDITS file in the
|
8
|
-
mediawiki_selenium top-level directory and at
|
9
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
|
10
|
-
=end
|
11
|
-
|
12
|
-
require "cucumber/formatter/junit"
|
1
|
+
require 'cucumber/formatter/junit'
|
13
2
|
|
14
3
|
module Cucumber::Formatter
|
15
4
|
class Sauce < Junit
|
16
5
|
|
6
|
+
class << self
|
7
|
+
attr_accessor :current_session_id
|
8
|
+
end
|
9
|
+
|
17
10
|
private
|
18
11
|
|
19
12
|
def format_exception(exception)
|
20
|
-
if ENV[
|
21
|
-
|
22
|
-
elsif
|
23
|
-
|
13
|
+
if ENV['HEADLESS'] == 'true'
|
14
|
+
job_url = ''
|
15
|
+
elsif self.class.current_session_id
|
16
|
+
job_url = "Sauce Labs job URL: http://saucelabs.com/jobs/#{self.class.current_session_id}\n"
|
24
17
|
else
|
25
|
-
|
18
|
+
job_url = 'Uh-oh. Could not find link to Sauce Labs job URL.'
|
26
19
|
end
|
27
|
-
|
20
|
+
|
21
|
+
msgs = [job_url] + ["#{exception.message} (#{exception.class})"] + exception.backtrace
|
22
|
+
|
23
|
+
msgs.join("\n")
|
28
24
|
end
|
29
25
|
end
|
30
26
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
1
|
+
require 'mediawiki_selenium/support/env'
|
2
|
+
require 'mediawiki_selenium/support/hooks'
|
3
|
+
require 'mediawiki_selenium/support/pages'
|
4
|
+
require 'mediawiki_selenium/support/sauce'
|
@@ -1,14 +1,3 @@
|
|
1
|
-
=begin
|
2
|
-
This file is subject to the license terms in the LICENSE file found in the
|
3
|
-
mediawiki_selenium top-level directory and at
|
4
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/LICENSE. No part of
|
5
|
-
mediawiki_selenium, including this file, may be copied, modified, propagated, or
|
6
|
-
distributed except according to the terms contained in the LICENSE file.
|
7
|
-
Copyright 2013 by the Mediawiki developers. See the CREDITS file in the
|
8
|
-
mediawiki_selenium top-level directory and at
|
9
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
|
10
|
-
=end
|
11
|
-
|
12
1
|
module MediawikiSelenium
|
13
|
-
VERSION =
|
2
|
+
VERSION = '1.0.0'
|
14
3
|
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require
|
1
|
+
require 'cucumber/formatter/console'
|
2
2
|
|
3
3
|
module MediawikiSelenium
|
4
4
|
class WarningsFormatter
|
5
5
|
include Cucumber::Formatter::Console
|
6
6
|
|
7
|
-
def initialize(
|
7
|
+
def initialize(_runtime, io, _options)
|
8
8
|
@io = io
|
9
9
|
@warning_counts = Hash.new(0)
|
10
10
|
end
|
11
11
|
|
12
12
|
def after_feature(feature)
|
13
|
-
|
14
|
-
feature.mw_warnings.each do |type, messages|
|
15
|
-
messages.each { |msg| @io.puts format_string(msg, :pending) }
|
16
|
-
@warning_counts[type] += messages.length
|
17
|
-
end
|
13
|
+
return unless feature.mw_warnings.any?
|
18
14
|
|
19
|
-
|
15
|
+
feature.mw_warnings.each do |type, messages|
|
16
|
+
messages.each { |msg| @io.puts format_string(msg, :pending) }
|
17
|
+
@warning_counts[type] += messages.length
|
20
18
|
end
|
19
|
+
|
20
|
+
@io.puts
|
21
21
|
end
|
22
22
|
|
23
|
-
def after_features(
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
23
|
+
def after_features(*)
|
24
|
+
return unless @warning_counts.any?
|
25
|
+
|
26
|
+
@warning_counts.each do |type, count|
|
27
|
+
message = "#{count} warning#{count > 1 ? "s" : ""}"
|
28
|
+
message += " due to #{type}" unless type == :default
|
29
|
+
@io.puts format_string(message, :pending)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
data/lib/mediawiki_selenium.rb
CHANGED
@@ -1,21 +1,10 @@
|
|
1
|
-
=begin
|
2
|
-
This file is subject to the license terms in the LICENSE file found in the
|
3
|
-
mediawiki_selenium top-level directory and at
|
4
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/LICENSE. No part of
|
5
|
-
mediawiki_selenium, including this file, may be copied, modified, propagated, or
|
6
|
-
distributed except according to the terms contained in the LICENSE file.
|
7
|
-
Copyright 2013 by the Mediawiki developers. See the CREDITS file in the
|
8
|
-
mediawiki_selenium top-level directory and at
|
9
|
-
https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
|
10
|
-
=end
|
11
|
-
|
12
1
|
module MediawikiSelenium
|
13
|
-
autoload :VERSION,
|
14
|
-
autoload :ApiHelper,
|
15
|
-
autoload :BrowserFactory,
|
16
|
-
autoload :ConfigurationError,
|
17
|
-
autoload :Environment,
|
18
|
-
autoload :Initializer,
|
19
|
-
autoload :PageFactory,
|
20
|
-
autoload :RemoteBrowserFactory,
|
2
|
+
autoload :VERSION, 'mediawiki_selenium/version'
|
3
|
+
autoload :ApiHelper, 'mediawiki_selenium/support/modules/api_helper'
|
4
|
+
autoload :BrowserFactory, 'mediawiki_selenium/browser_factory'
|
5
|
+
autoload :ConfigurationError, 'mediawiki_selenium/configuration_error'
|
6
|
+
autoload :Environment, 'mediawiki_selenium/environment'
|
7
|
+
autoload :Initializer, 'mediawiki_selenium/initializer'
|
8
|
+
autoload :PageFactory, 'mediawiki_selenium/page_factory'
|
9
|
+
autoload :RemoteBrowserFactory, 'mediawiki_selenium/remote_browser_factory'
|
21
10
|
end
|
data/mediawiki_selenium.gemspec
CHANGED
@@ -1,39 +1,46 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require 'mediawiki_selenium/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'mediawiki_selenium'
|
8
8
|
spec.version = MediawikiSelenium::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
|
11
|
-
spec.
|
12
|
-
|
13
|
-
|
14
|
-
spec.homepage = "https://gerrit.wikimedia.org/r/#/admin/projects/mediawiki/selenium"
|
15
|
-
spec.license = "GPL-2"
|
9
|
+
spec.authors = ['Chris McMahon', 'Dan Duvall', 'Jeff Hall', 'Nikolas Everett',
|
10
|
+
'Tobias Gritschacher', 'Željko Filipin']
|
11
|
+
spec.email = ['cmcmahon@wikimedia.org', 'dduvall@wikimedia.org', 'jhall@wikimedia.org',
|
12
|
+
'neverett@wikimedia.org', 'tobias.gritschacher@wikimedia.de',
|
13
|
+
'zeljko.filipin@gmail.com']
|
16
14
|
|
17
|
-
spec.
|
15
|
+
spec.description = (<<-end).split.join(' ')
|
16
|
+
Several MediaWiki extensions share code that makes it easy to run Selenium tests. This gem
|
17
|
+
makes it easy to update the shared code.
|
18
|
+
end
|
19
|
+
|
20
|
+
spec.summary = 'An easy way to run MediaWiki Selenium tests.'
|
21
|
+
spec.homepage = 'https://gerrit.wikimedia.org/r/#/admin/projects/mediawiki/selenium'
|
22
|
+
spec.license = 'GPL-2'
|
23
|
+
|
24
|
+
spec.bindir = 'bin'
|
18
25
|
spec.executables << 'mediawiki-selenium-init'
|
19
26
|
|
20
|
-
spec.files = `git ls-files`.split(
|
21
|
-
spec.require_paths = [
|
27
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
28
|
+
spec.require_paths = ['lib']
|
22
29
|
|
23
|
-
spec.add_runtime_dependency
|
24
|
-
spec.add_runtime_dependency
|
25
|
-
spec.add_runtime_dependency
|
26
|
-
spec.add_runtime_dependency
|
27
|
-
spec.add_runtime_dependency
|
28
|
-
spec.add_runtime_dependency
|
29
|
-
spec.add_runtime_dependency
|
30
|
-
spec.add_runtime_dependency
|
31
|
-
spec.add_runtime_dependency
|
30
|
+
spec.add_runtime_dependency 'cucumber', '~> 1.3', '>= 1.3.10'
|
31
|
+
spec.add_runtime_dependency 'headless', '~> 1.0', '>= 1.0.1'
|
32
|
+
spec.add_runtime_dependency 'json', '~> 1.8', '>= 1.8.1'
|
33
|
+
spec.add_runtime_dependency 'mediawiki_api', '~> 0.2', '>= 0.2.1'
|
34
|
+
spec.add_runtime_dependency 'page-object', '~> 1.0'
|
35
|
+
spec.add_runtime_dependency 'rest-client', '~> 1.6', '>= 1.6.7'
|
36
|
+
spec.add_runtime_dependency 'rspec-expectations', '~> 2.14', '>= 2.14.4'
|
37
|
+
spec.add_runtime_dependency 'syntax', '~> 1.2', '>= 1.2.0'
|
38
|
+
spec.add_runtime_dependency 'thor', '~> 0.19', '>= 0.19.1'
|
32
39
|
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
36
|
-
spec.add_development_dependency
|
37
|
-
spec.add_development_dependency
|
38
|
-
spec.add_development_dependency
|
40
|
+
spec.add_development_dependency 'bundler', '~> 1.6', '>= 1.6.3'
|
41
|
+
spec.add_development_dependency 'yard', '~> 0.8', '>= 0.8.7.4'
|
42
|
+
spec.add_development_dependency 'redcarpet', '~> 3.2', '>= 3.2.0'
|
43
|
+
spec.add_development_dependency 'rubocop', '~> 0.26', '>= 0.26.1'
|
44
|
+
spec.add_development_dependency 'rspec-core', '~> 2.14', '>= 2.14.4'
|
45
|
+
spec.add_development_dependency 'rspec-mocks', '~> 2.14', '>= 2.14.4'
|
39
46
|
end
|
data/spec/api_helper_spec.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module MediawikiSelenium
|
4
4
|
describe ApiHelper do
|
@@ -10,52 +10,52 @@ module MediawikiSelenium
|
|
10
10
|
mediawiki_url_b: alternative_wiki_url,
|
11
11
|
mediawiki_api_url: api_url,
|
12
12
|
mediawiki_api_url_b: alternative_api_url,
|
13
|
-
mediawiki_user:
|
14
|
-
mediawiki_password:
|
13
|
+
mediawiki_user: 'mw user',
|
14
|
+
mediawiki_password: 'mw password'
|
15
15
|
}
|
16
16
|
end
|
17
17
|
|
18
|
-
describe
|
18
|
+
describe '#api' do
|
19
19
|
subject { env.api }
|
20
20
|
|
21
|
-
let(:wiki_url) {
|
22
|
-
let(:api_url) {
|
23
|
-
let(:alternative_wiki_url) {
|
24
|
-
let(:alternative_api_url) {
|
21
|
+
let(:wiki_url) { 'http://an.example/wiki/' }
|
22
|
+
let(:api_url) { 'http://an.example/api' }
|
23
|
+
let(:alternative_wiki_url) { 'http://another.example/wiki/' }
|
24
|
+
let(:alternative_api_url) { '' }
|
25
25
|
|
26
26
|
let(:client) { double(MediawikiApi::Client) }
|
27
27
|
|
28
28
|
before do
|
29
29
|
expect(MediawikiApi::Client).to receive(:new).with(api_url).and_return(client)
|
30
|
-
expect(client).to receive(:log_in).with(
|
30
|
+
expect(client).to receive(:log_in).with('mw user', 'mw password')
|
31
31
|
end
|
32
32
|
|
33
|
-
context
|
34
|
-
it
|
33
|
+
context 'called for the first time' do
|
34
|
+
it 'returns a new client' do
|
35
35
|
expect(subject).to be(client)
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
context
|
39
|
+
context 'called subsequently' do
|
40
40
|
before do
|
41
41
|
env.api
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
44
|
+
it 'returns a cached client' do
|
45
45
|
expect(subject).to be(client)
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
50
|
-
describe
|
51
|
-
let(:wiki_url) {
|
52
|
-
let(:api_url) {
|
53
|
-
let(:alternative_wiki_url) {
|
50
|
+
describe '#on_wiki' do
|
51
|
+
let(:wiki_url) { 'http://an.example/wiki/' }
|
52
|
+
let(:api_url) { 'http://an.example/api' }
|
53
|
+
let(:alternative_wiki_url) { 'http://another.example/wiki/' }
|
54
54
|
|
55
|
-
context
|
56
|
-
let(:alternative_api_url) {
|
55
|
+
context 'and the given alternative API URL is configured' do
|
56
|
+
let(:alternative_api_url) { 'http://another.example/api' }
|
57
57
|
|
58
|
-
it
|
58
|
+
it 'executes in the new environment using the alternative wiki and API URL' do
|
59
59
|
expect { |block| env.on_wiki(:b, &block) }.
|
60
60
|
to yield_with_args(alternative_wiki_url, alternative_api_url)
|
61
61
|
|
@@ -66,16 +66,16 @@ module MediawikiSelenium
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
-
context
|
70
|
-
let(:alternative_api_url) {
|
69
|
+
context 'and no explicit API URL is configured for the wiki' do
|
70
|
+
let(:alternative_api_url) { '' }
|
71
71
|
|
72
|
-
it
|
72
|
+
it 'constructs one at /w/api.php relative to the wiki URL' do
|
73
73
|
expect { |block| env.on_wiki(:b, &block) }.
|
74
|
-
to yield_with_args(alternative_wiki_url,
|
74
|
+
to yield_with_args(alternative_wiki_url, 'http://another.example/w/api.php')
|
75
75
|
|
76
76
|
env.on_wiki(:b) do
|
77
77
|
expect(env[:mediawiki_url]).to eq(alternative_wiki_url)
|
78
|
-
expect(env[:mediawiki_api_url]).to eq(
|
78
|
+
expect(env[:mediawiki_api_url]).to eq('http://another.example/w/api.php')
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
module MediawikiSelenium::BrowserFactory
|
4
4
|
describe Base do
|
@@ -6,28 +6,28 @@ module MediawikiSelenium::BrowserFactory
|
|
6
6
|
let(:factory) { factory_class.new(browser_name) }
|
7
7
|
let(:browser_name) { :lynx }
|
8
8
|
|
9
|
-
describe
|
9
|
+
describe '.bind' do
|
10
10
|
subject { factory_class.bind(option_name, &block) }
|
11
11
|
|
12
12
|
let(:option_name) { :foo }
|
13
13
|
let(:block) { proc { } }
|
14
14
|
|
15
|
-
it
|
15
|
+
it 'adds a new default binding for the given option' do
|
16
16
|
subject
|
17
17
|
expect(factory_class.default_bindings).to include(option_name)
|
18
18
|
expect(factory_class.default_bindings[option_name]).to include(block)
|
19
19
|
end
|
20
20
|
|
21
|
-
context
|
21
|
+
context 'given no block' do
|
22
22
|
subject { factory_class.bind(option_name) }
|
23
23
|
|
24
|
-
it
|
24
|
+
it 'raises an ArgumentError' do
|
25
25
|
expect { subject }.to raise_error(ArgumentError)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
-
describe
|
30
|
+
describe '.bindings' do
|
31
31
|
subject { factory_class.bindings }
|
32
32
|
|
33
33
|
before do
|
@@ -38,59 +38,59 @@ module MediawikiSelenium::BrowserFactory
|
|
38
38
|
expect(subject).to include(Base.default_bindings)
|
39
39
|
end
|
40
40
|
|
41
|
-
it
|
41
|
+
it 'includes its own bindings' do
|
42
42
|
expect(subject).to include(factory_class.default_bindings)
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
-
describe
|
46
|
+
describe '.default_bindings' do
|
47
47
|
subject { factory_class.default_bindings }
|
48
48
|
|
49
49
|
it { is_expected.to be_a(Hash) }
|
50
50
|
|
51
|
-
context
|
51
|
+
context 'before any bindings are defined' do
|
52
52
|
it { is_expected.to be_empty }
|
53
53
|
end
|
54
54
|
|
55
|
-
context
|
55
|
+
context 'when bindings are defined' do
|
56
56
|
before do
|
57
57
|
factory_class.bind(:foo) {}
|
58
58
|
factory_class.bind(:bar) {}
|
59
59
|
factory_class.bind(:bar) {}
|
60
60
|
end
|
61
61
|
|
62
|
-
it
|
62
|
+
it 'includes all defined bindings' do
|
63
63
|
expect(subject).to include(:foo, :bar)
|
64
64
|
end
|
65
65
|
|
66
|
-
it
|
66
|
+
it 'includes all bindings for the same option name' do
|
67
67
|
expect(subject[:bar].length).to be(2)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
describe
|
72
|
+
describe '#bind' do
|
73
73
|
subject { factory.bind(option_name, &block) }
|
74
74
|
before { subject }
|
75
75
|
|
76
76
|
let(:option_name) { :foo }
|
77
77
|
let(:block) { proc { } }
|
78
78
|
|
79
|
-
it
|
79
|
+
it 'adds a new binding for the given option' do
|
80
80
|
expect(factory.bindings).to include(option_name)
|
81
81
|
expect(factory.bindings[option_name]).to include(block)
|
82
82
|
end
|
83
83
|
|
84
|
-
context
|
84
|
+
context 'given no block' do
|
85
85
|
subject { factory.bind(option_name) }
|
86
86
|
|
87
|
-
it
|
87
|
+
it 'will default to an empty block' do
|
88
88
|
expect(factory.bindings[option_name]).not_to include(nil)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
describe
|
93
|
+
describe '#bindings' do
|
94
94
|
subject { factory.bindings }
|
95
95
|
|
96
96
|
before do
|
@@ -98,19 +98,19 @@ module MediawikiSelenium::BrowserFactory
|
|
98
98
|
factory.bind(:bar)
|
99
99
|
end
|
100
100
|
|
101
|
-
it
|
101
|
+
it 'includes the class-level bindings' do
|
102
102
|
expect(subject).to include(factory_class.bindings)
|
103
103
|
end
|
104
104
|
|
105
|
-
it
|
105
|
+
it 'includes its own bindings' do
|
106
106
|
expect(subject).to include(:bar)
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
describe
|
110
|
+
describe '#browser_for' do
|
111
111
|
subject { factory.browser_for(config) }
|
112
112
|
|
113
|
-
let(:config) { { foo:
|
113
|
+
let(:config) { { foo: 'x' } }
|
114
114
|
|
115
115
|
let(:watir_browser) { double(Watir::Browser) }
|
116
116
|
let(:capabilities) { double(Selenium::WebDriver::Remote::Capabilities) }
|
@@ -122,27 +122,27 @@ module MediawikiSelenium::BrowserFactory
|
|
122
122
|
at_least(:once).and_return(browser_name)
|
123
123
|
end
|
124
124
|
|
125
|
-
it
|
125
|
+
it 'creates a new Watir::Browser' do
|
126
126
|
expect(Watir::Browser).to receive(:new).once.and_return(watir_browser)
|
127
127
|
expect(subject).to be(watir_browser)
|
128
128
|
end
|
129
129
|
|
130
|
-
context
|
130
|
+
context 'called more than once' do
|
131
131
|
let(:config1) { config }
|
132
132
|
|
133
|
-
context
|
133
|
+
context 'with the same configuration' do
|
134
134
|
let(:config2) { config }
|
135
135
|
|
136
|
-
it
|
136
|
+
it 'returns a cached browser' do
|
137
137
|
expect(Watir::Browser).to receive(:new).once.and_return(watir_browser)
|
138
138
|
expect(factory.browser_for(config1)).to be(factory.browser_for(config2))
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
-
context
|
143
|
-
let(:config2) { { foo:
|
142
|
+
context 'with different configuration' do
|
143
|
+
let(:config2) { { foo: 'y' } }
|
144
144
|
|
145
|
-
it
|
145
|
+
it 'returns two distinct browsers' do
|
146
146
|
expect(Watir::Browser).to receive(:new).twice
|
147
147
|
|
148
148
|
factory.browser_for(config1)
|
@@ -152,7 +152,7 @@ module MediawikiSelenium::BrowserFactory
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
-
describe
|
155
|
+
describe '#browser_options' do
|
156
156
|
subject { factory.browser_options(config) }
|
157
157
|
|
158
158
|
let(:config) { {} }
|
@@ -171,38 +171,42 @@ module MediawikiSelenium::BrowserFactory
|
|
171
171
|
it { is_expected.to be_a(Hash) }
|
172
172
|
it { is_expected.to include(desired_capabilities: capabilities, http_client: client) }
|
173
173
|
|
174
|
-
context
|
175
|
-
context
|
176
|
-
let(:config) { { foo:
|
174
|
+
context 'with a binding' do
|
175
|
+
context 'and corresponding configuration' do
|
176
|
+
let(:config) { { foo: 'x' } }
|
177
177
|
|
178
|
-
it
|
179
|
-
expect { |block| factory.bind(:foo, &block) && subject }.
|
178
|
+
it 'invokes the binding with the configured value' do
|
179
|
+
expect { |block| factory.bind(:foo, &block) && subject }.
|
180
|
+
to yield_with_args('x', options)
|
180
181
|
end
|
181
182
|
end
|
182
183
|
|
183
|
-
context
|
184
|
+
context 'but no configuration' do
|
184
185
|
let(:config) { {} }
|
185
186
|
|
186
|
-
it
|
187
|
-
expect { |block| factory.bind(:foo, &block) && subject }.
|
187
|
+
it 'never invokes the binding' do
|
188
|
+
expect { |block| factory.bind(:foo, &block) && subject }.
|
189
|
+
to_not yield_control
|
188
190
|
end
|
189
191
|
end
|
190
192
|
end
|
191
193
|
|
192
|
-
context
|
193
|
-
context
|
194
|
-
let(:config) { { foo:
|
194
|
+
context 'with a multi-option binding' do
|
195
|
+
context 'and complete configuration for all options' do
|
196
|
+
let(:config) { { foo: 'x', bar: 'y' } }
|
195
197
|
|
196
|
-
it
|
197
|
-
expect { |block| factory.bind(:foo, :bar, &block) && subject }.
|
198
|
+
it 'invokes the binding with the configured values' do
|
199
|
+
expect { |block| factory.bind(:foo, :bar, &block) && subject }.
|
200
|
+
to yield_with_args('x', 'y', options)
|
198
201
|
end
|
199
202
|
end
|
200
203
|
|
201
|
-
context
|
202
|
-
let(:config) { { foo:
|
204
|
+
context 'but incomplete configuration for all options' do
|
205
|
+
let(:config) { { foo: 'x' } }
|
203
206
|
|
204
|
-
it
|
205
|
-
expect { |block| factory.bind(:foo, :bar, &block) && subject }.
|
207
|
+
it 'never invokes the binding' do
|
208
|
+
expect { |block| factory.bind(:foo, :bar, &block) && subject }.
|
209
|
+
to_not yield_control
|
206
210
|
end
|
207
211
|
end
|
208
212
|
end
|