mediawiki_selenium 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +6 -1
- data/UPGRADE.md +1 -1
- data/lib/mediawiki_selenium.rb +1 -0
- data/lib/mediawiki_selenium/environment.rb +1 -6
- data/lib/mediawiki_selenium/raita.rb +46 -0
- data/lib/mediawiki_selenium/raita/formatter.rb +21 -0
- data/lib/mediawiki_selenium/raita/logger.rb +114 -0
- data/lib/mediawiki_selenium/raita/null_io.rb +8 -0
- data/lib/mediawiki_selenium/support/hooks.rb +16 -0
- data/lib/mediawiki_selenium/version.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0037caf23b15c884315fe6a5c1b9980c5a090133
|
4
|
+
data.tar.gz: d4230eccd57eb777a52ceed3bd433cf75f3f624e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58be25747927e6719e1bb3bb04f3a195c24221aab7d357a2073667188f04bb3b696a76d959aaff2d109f6c4173ccdd73f678c7b866e91a65e588d526a404940f
|
7
|
+
data.tar.gz: ac660b1c962b03a8784c4de974395386b04d3f9d53695f97bbe1becfd0305ab4fd4f9dd0630c629d8e9c99f54afd3cf9e80f63b42e869808afe60068d8d2dc5a
|
data/README.md
CHANGED
@@ -37,7 +37,7 @@ Create a `Gemfile` in the root of your MediaWiki-related project that
|
|
37
37
|
specifies the version of `mediawiki_selenium` you wish to use (typically the
|
38
38
|
latest version).
|
39
39
|
|
40
|
-
gem 'mediawiki_selenium', '~> 1.0
|
40
|
+
gem 'mediawiki_selenium', '~> 1.2.0'
|
41
41
|
|
42
42
|
Install the gem and its dependencies by running `bundle install`. (If
|
43
43
|
[Bundler](http://bundler.io/) is not yet installed, install it with
|
@@ -199,6 +199,11 @@ See https://www.mediawiki.org/wiki/Gerrit
|
|
199
199
|
|
200
200
|
## Release notes
|
201
201
|
|
202
|
+
### 1.2.0 2015-05-28
|
203
|
+
* Support logging to a [Raita](http://git.wikimedia.org/summary/integration%2Fraita.git)
|
204
|
+
Elasticsearch database by setting `RAITA_URL`
|
205
|
+
* Removed deprecated support for `MEDIAWIKI_PASSWORD_VARIABLE`
|
206
|
+
|
202
207
|
### 1.1.0 2015-04-06
|
203
208
|
* Support for `browser_http_proxy` in Firefox, Chrome, and Phantomjs
|
204
209
|
* Renamed browser factory `bind` method to `configure`
|
data/UPGRADE.md
CHANGED
data/lib/mediawiki_selenium.rb
CHANGED
@@ -6,5 +6,6 @@ module MediawikiSelenium
|
|
6
6
|
autoload :Environment, 'mediawiki_selenium/environment'
|
7
7
|
autoload :Initializer, 'mediawiki_selenium/initializer'
|
8
8
|
autoload :PageFactory, 'mediawiki_selenium/page_factory'
|
9
|
+
autoload :Raita, 'mediawiki_selenium/raita'
|
9
10
|
autoload :RemoteBrowserFactory, 'mediawiki_selenium/remote_browser_factory'
|
10
11
|
end
|
@@ -317,7 +317,7 @@ module MediawikiSelenium
|
|
317
317
|
# @return [String]
|
318
318
|
#
|
319
319
|
def password(id = nil)
|
320
|
-
lookup(
|
320
|
+
lookup(:mediawiki_password, id: id)
|
321
321
|
end
|
322
322
|
|
323
323
|
# Whether this environment has been configured to use remote browser
|
@@ -476,11 +476,6 @@ module MediawikiSelenium
|
|
476
476
|
lookup_all(browser_factory.all_binding_keys, default: nil).reject { |_k, v| v.nil? }
|
477
477
|
end
|
478
478
|
|
479
|
-
def password_variable
|
480
|
-
name = lookup(:mediawiki_password_variable, default: '')
|
481
|
-
name.empty? ? :mediawiki_password : normalize_key(name)
|
482
|
-
end
|
483
|
-
|
484
479
|
def normalize_config(hash)
|
485
480
|
hash.each.with_object({}) { |(k, v), acc| acc[normalize_key(k)] = v }
|
486
481
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module MediawikiSelenium
|
2
|
+
# Supports logging to a Raita Elasticsearch index. Raita is a dashboard for
|
3
|
+
# visualizing and taking action on the results of Cucumber tests.
|
4
|
+
#
|
5
|
+
module Raita
|
6
|
+
# Mapping of environment configuration/variables to Raita build fields.
|
7
|
+
#
|
8
|
+
ENV_TO_BUILD_MAPPING = {
|
9
|
+
build_number: :number,
|
10
|
+
build_url: :url,
|
11
|
+
job_name: [:project, :name],
|
12
|
+
git_commit: [:project, :commit],
|
13
|
+
git_branch: [:project, :branch],
|
14
|
+
git_url: [:project, :repo],
|
15
|
+
mediawiki_environment: [:environment, :name],
|
16
|
+
mediawiki_url: [:environment, :url],
|
17
|
+
browser: [:browser, :name],
|
18
|
+
version: [:browser, :version],
|
19
|
+
platform: [:browser, :platform]
|
20
|
+
}
|
21
|
+
|
22
|
+
autoload :Formatter, 'mediawiki_selenium/raita/formatter'
|
23
|
+
autoload :Logger, 'mediawiki_selenium/raita/logger'
|
24
|
+
autoload :NullIO, 'mediawiki_selenium/raita/null_io'
|
25
|
+
|
26
|
+
# Returns a hash of relevant build information from the given {Environment}.
|
27
|
+
#
|
28
|
+
# @param env {Environment}
|
29
|
+
#
|
30
|
+
# @return {Hash} Raita build object.
|
31
|
+
#
|
32
|
+
def self.build_from(env)
|
33
|
+
ENV_TO_BUILD_MAPPING.each.with_object({}) do |(from, to), build|
|
34
|
+
value = env.lookup(from, default: nil)
|
35
|
+
|
36
|
+
case to
|
37
|
+
when Array
|
38
|
+
build[to.first] ||= {}
|
39
|
+
build[to.first][to.last] = value
|
40
|
+
else
|
41
|
+
build[to] = value
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'gherkin/formatter/json_formatter'
|
2
|
+
|
3
|
+
module MediawikiSelenium
|
4
|
+
module Raita
|
5
|
+
class Formatter < Gherkin::Formatter::JSONFormatter
|
6
|
+
attr_reader :feature_hashes
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super(NullIO.new)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Allows for simple embeddings without base64 encoding.
|
13
|
+
#
|
14
|
+
def embedding(mime_type, data)
|
15
|
+
return unless mime_type.start_with?('text/')
|
16
|
+
|
17
|
+
embeddings << { 'mime_type' => mime_type, 'data' => data }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'cucumber/formatter/gherkin_formatter_adapter'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module MediawikiSelenium
|
5
|
+
module Raita
|
6
|
+
class Logger < Cucumber::Formatter::GherkinFormatterAdapter
|
7
|
+
def initialize(_runtime, raita_options, options)
|
8
|
+
super(Formatter.new, false, options)
|
9
|
+
@db_url = URI.parse(raita_options[:url])
|
10
|
+
@build = raita_options[:build].merge(result: { status: 'passed', duration: 0 })
|
11
|
+
end
|
12
|
+
|
13
|
+
# Log everything at once to Raita's Elasticsearch DB.
|
14
|
+
#
|
15
|
+
def after_features(*)
|
16
|
+
@build_id = create('build', @build)['_id']
|
17
|
+
|
18
|
+
@gf.feature_hashes.each do |feature|
|
19
|
+
amend_feature(feature)
|
20
|
+
elements = feature.delete('elements')
|
21
|
+
|
22
|
+
feature_id = create('feature', feature, @build_id)['_id']
|
23
|
+
bulk('feature-element', elements, feature_id)
|
24
|
+
|
25
|
+
@build[:result][:status] = change_status(
|
26
|
+
@build[:result][:status],
|
27
|
+
feature['result']['status']
|
28
|
+
)
|
29
|
+
@build[:result][:duration] += feature['result']['duration']
|
30
|
+
end
|
31
|
+
|
32
|
+
update('build', @build_id, @build)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# Add status and duration at the feature and background/scenario level.
|
38
|
+
#
|
39
|
+
# @param feature {Hash}
|
40
|
+
#
|
41
|
+
def amend_feature(feature)
|
42
|
+
feature['result'] = { 'duration' => 0, 'status' => 'passed' }
|
43
|
+
|
44
|
+
feature['elements'].each do |element|
|
45
|
+
element['result'] = { 'duration' => 0, 'status' => 'passed' }
|
46
|
+
|
47
|
+
element['steps'].each do |step|
|
48
|
+
feature['result']['duration'] += step['result']['duration']
|
49
|
+
element['result']['duration'] += step['result']['duration']
|
50
|
+
|
51
|
+
element['result']['status'] = change_status(
|
52
|
+
element['result']['status'],
|
53
|
+
step['result']['status']
|
54
|
+
)
|
55
|
+
end
|
56
|
+
|
57
|
+
feature['result']['status'] = change_status(
|
58
|
+
feature['result']['status'],
|
59
|
+
element['result']['status']
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Calculates a new status given the current parent status and the next
|
65
|
+
# child status. A status can go from 'passed' to anything, 'skipped' to
|
66
|
+
# 'failed'.
|
67
|
+
#
|
68
|
+
def change_status(cur, new)
|
69
|
+
case cur.to_s
|
70
|
+
when 'passed'
|
71
|
+
new
|
72
|
+
when 'skipped'
|
73
|
+
new == 'failed' ? new : cur
|
74
|
+
else
|
75
|
+
cur
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def bulk(type, objects, parent = nil)
|
80
|
+
data = objects.reduce('') do |d, obj|
|
81
|
+
d << JSON.dump({ create: { _type: type, _parent: parent, _routing: @build_id } }) + "\n"
|
82
|
+
d << JSON.dump(obj) + "\n\n"
|
83
|
+
end
|
84
|
+
|
85
|
+
request(Net::HTTP::Post, ['_bulk'], data)
|
86
|
+
end
|
87
|
+
|
88
|
+
def create(type, object, parent = nil)
|
89
|
+
request(Net::HTTP::Post, [type], object, parent: parent, routing: @build_id)
|
90
|
+
end
|
91
|
+
|
92
|
+
def request(klass, paths, data, query = {})
|
93
|
+
query = query.reject { |_, v| v.nil? }
|
94
|
+
|
95
|
+
uri = @db_url.clone
|
96
|
+
uri.path = Pathname.new(uri.path).join(*paths.map(&:to_s)).to_s
|
97
|
+
uri.query = query.map { |pair| pair.join('=') unless pair.last.nil? }.compact.join('&')
|
98
|
+
|
99
|
+
data = JSON.dump(data) unless data.is_a?(String)
|
100
|
+
response = db.request(klass.new(uri), data)
|
101
|
+
|
102
|
+
JSON.parse(response.body)
|
103
|
+
end
|
104
|
+
|
105
|
+
def update(type, id, object)
|
106
|
+
request(Net::HTTP::Put, [type, id], object)
|
107
|
+
end
|
108
|
+
|
109
|
+
def db
|
110
|
+
Net::HTTP.new(@db_url.host, @db_url.port)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -7,6 +7,16 @@ AfterConfiguration do |config|
|
|
7
7
|
pretty_format, io = config.formats.find { |(format, _io)| format == 'pretty' }
|
8
8
|
config.formats << ['MediawikiSelenium::WarningsFormatter', io] if pretty_format
|
9
9
|
|
10
|
+
# Set up Raita logging if RAITA_DB_URL is set. Include any useful
|
11
|
+
# environment variables that Jenkins would have set.
|
12
|
+
env = MediawikiSelenium::Environment.load_default
|
13
|
+
raita_url = env.lookup(:raita_url, default: nil)
|
14
|
+
|
15
|
+
if raita_url
|
16
|
+
raita_build = MediawikiSelenium::Raita.build_from(env)
|
17
|
+
config.formats << ['MediawikiSelenium::Raita::Logger', { url: raita_url, build: raita_build }]
|
18
|
+
end
|
19
|
+
|
10
20
|
# Initiate headless mode
|
11
21
|
if ENV['HEADLESS'] == 'true' && ENV['BROWSER'] != 'phantomjs'
|
12
22
|
require 'headless'
|
@@ -73,6 +83,12 @@ After do |scenario|
|
|
73
83
|
require 'fileutils'
|
74
84
|
|
75
85
|
teardown(scenario.status) do |browser|
|
86
|
+
# Embed remote session URLs
|
87
|
+
if remote? && browser.driver.respond_to?(:session_id)
|
88
|
+
embed("http://saucelabs.com/jobs/#{browser.driver.session_id}", 'text/url')
|
89
|
+
end
|
90
|
+
|
91
|
+
# Take screenshots
|
76
92
|
if scenario.failed? && lookup(:screenshot_failures, default: false) == 'true'
|
77
93
|
screen_dir = lookup(:screenshot_failures_path, default: 'screenshots')
|
78
94
|
FileUtils.mkdir_p screen_dir
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mediawiki_selenium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris McMahon
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2015-
|
16
|
+
date: 2015-05-28 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: cucumber
|
@@ -340,6 +340,10 @@ files:
|
|
340
340
|
- lib/mediawiki_selenium/environment.rb
|
341
341
|
- lib/mediawiki_selenium/initializer.rb
|
342
342
|
- lib/mediawiki_selenium/page_factory.rb
|
343
|
+
- lib/mediawiki_selenium/raita.rb
|
344
|
+
- lib/mediawiki_selenium/raita/formatter.rb
|
345
|
+
- lib/mediawiki_selenium/raita/logger.rb
|
346
|
+
- lib/mediawiki_selenium/raita/null_io.rb
|
343
347
|
- lib/mediawiki_selenium/remote_browser_factory.rb
|
344
348
|
- lib/mediawiki_selenium/step_definitions.rb
|
345
349
|
- lib/mediawiki_selenium/step_definitions/login_steps.rb
|