mediawiki_selenium 0.4.3 → 1.0.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitreview +1 -1
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/Gemfile +1 -1
- data/README.md +108 -55
- data/bin/mediawiki-selenium-init +5 -0
- data/lib/mediawiki_selenium.rb +10 -19
- data/lib/mediawiki_selenium/browser_factory.rb +24 -0
- data/lib/mediawiki_selenium/browser_factory/base.rb +212 -0
- data/lib/mediawiki_selenium/browser_factory/chrome.rb +27 -0
- data/lib/mediawiki_selenium/browser_factory/firefox.rb +34 -0
- data/lib/mediawiki_selenium/browser_factory/phantomjs.rb +21 -0
- data/lib/mediawiki_selenium/configuration_error.rb +4 -0
- data/lib/mediawiki_selenium/environment.rb +494 -0
- data/lib/mediawiki_selenium/initializer.rb +19 -0
- data/lib/mediawiki_selenium/page_factory.rb +38 -0
- data/lib/mediawiki_selenium/remote_browser_factory.rb +87 -0
- data/lib/mediawiki_selenium/step_definitions.rb +5 -0
- data/lib/mediawiki_selenium/support.rb +3 -0
- data/lib/mediawiki_selenium/support/env.rb +3 -127
- data/lib/mediawiki_selenium/support/hooks.rb +23 -34
- data/lib/mediawiki_selenium/support/modules/api_helper.rb +44 -5
- data/lib/mediawiki_selenium/support/pages.rb +4 -0
- data/lib/mediawiki_selenium/support/pages/api_page.rb +1 -0
- data/lib/mediawiki_selenium/support/pages/login_page.rb +3 -12
- data/lib/mediawiki_selenium/support/pages/random_page.rb +2 -12
- data/lib/mediawiki_selenium/support/pages/reset_preferences_page.rb +3 -12
- data/lib/mediawiki_selenium/version.rb +1 -1
- data/mediawiki_selenium.gemspec +9 -3
- data/spec/api_helper_spec.rb +84 -0
- data/spec/browser_factory/base_spec.rb +211 -0
- data/spec/browser_factory/chrome_spec.rb +36 -0
- data/spec/browser_factory/firefox_spec.rb +60 -0
- data/spec/browser_factory/phantomjs_spec.rb +38 -0
- data/spec/environment_spec.rb +474 -0
- data/spec/page_factory_spec.rb +61 -0
- data/spec/remote_browser_factory_spec.rb +50 -0
- data/spec/spec_helper.rb +4 -0
- data/templates/tests/browser/environments.yml +35 -0
- data/templates/tests/browser/features/support/env.rb +6 -0
- metadata +122 -20
- data/lib/mediawiki_selenium/support/modules/sauce_helper.rb +0 -13
- data/lib/mediawiki_selenium/support/modules/url_module.rb +0 -21
- data/spec/README +0 -2
@@ -0,0 +1,19 @@
|
|
1
|
+
require "thor"
|
2
|
+
|
3
|
+
module MediawikiSelenium
|
4
|
+
# Creates the directory structure and configuration for a brand new
|
5
|
+
# MediaWiki related test suite.
|
6
|
+
#
|
7
|
+
class Initializer < Thor
|
8
|
+
include Thor::Actions
|
9
|
+
|
10
|
+
def self.source_root
|
11
|
+
File.expand_path("../../../templates", __FILE__)
|
12
|
+
end
|
13
|
+
|
14
|
+
desc "install", "Creates tests/browser directory structure and default configuration"
|
15
|
+
def install
|
16
|
+
directory("tests")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "page-object"
|
2
|
+
|
3
|
+
module MediawikiSelenium
|
4
|
+
# Handles on-demand browser instantiation and assignment of the `@browser`
|
5
|
+
# instance variable before delegating to `PageObject::PageFactory` methods.
|
6
|
+
#
|
7
|
+
module PageFactory
|
8
|
+
include ::PageObject::PageFactory
|
9
|
+
|
10
|
+
# Instantiates a new browser before delegating to
|
11
|
+
# `PageObject::PageFactory#on_page`. All page URLs are also qualified
|
12
|
+
# using {Environment#wiki_url}.
|
13
|
+
#
|
14
|
+
# @see http://www.rubydoc.info/github/cheezy/page-object
|
15
|
+
#
|
16
|
+
def on_page(page_class, params = { using_params: {} }, visit = false)
|
17
|
+
@browser = browser if visit
|
18
|
+
|
19
|
+
super(page_class, params, false).tap do |page|
|
20
|
+
if page.respond_to?(:goto)
|
21
|
+
wiki_url = method(:wiki_url)
|
22
|
+
|
23
|
+
page.define_singleton_method(:page_url_value) do
|
24
|
+
wiki_url.call(super())
|
25
|
+
end
|
26
|
+
|
27
|
+
page.goto if visit
|
28
|
+
end
|
29
|
+
|
30
|
+
yield page if block_given?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# @see #on_page
|
35
|
+
alias on on_page
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require "rest_client"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
module MediawikiSelenium
|
5
|
+
# Constructs remote browser sessions to be run via Sauce Labs. Adds the
|
6
|
+
# following configuration bindings to the factory.
|
7
|
+
#
|
8
|
+
# - sauce_ondemand_username
|
9
|
+
# - sauce_ondemand_access_key
|
10
|
+
# - platform
|
11
|
+
# - version
|
12
|
+
#
|
13
|
+
module RemoteBrowserFactory
|
14
|
+
REQUIRED_CONFIG = [:sauce_ondemand_username, :sauce_ondemand_access_key]
|
15
|
+
URL = "http://ondemand.saucelabs.com/wd/hub"
|
16
|
+
|
17
|
+
class << self
|
18
|
+
def extend_object(factory)
|
19
|
+
return if factory.is_a?(self)
|
20
|
+
|
21
|
+
super
|
22
|
+
|
23
|
+
factory.bind(:sauce_ondemand_username, :sauce_ondemand_access_key) do |user, key, options|
|
24
|
+
options[:url] = URI.parse(URL)
|
25
|
+
|
26
|
+
options[:url].user = user
|
27
|
+
options[:url].password = key
|
28
|
+
end
|
29
|
+
|
30
|
+
factory.bind(:platform) do |platform, options|
|
31
|
+
options[:desired_capabilities].platform = platform
|
32
|
+
end
|
33
|
+
|
34
|
+
factory.bind(:version) do |version, options|
|
35
|
+
options[:desired_capabilities].version = version
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Submits status and Jenkins build info to Sauce Labs.
|
41
|
+
#
|
42
|
+
def teardown(env, status)
|
43
|
+
each do |browser|
|
44
|
+
sid = browser.driver.session_id
|
45
|
+
url = browser.driver.send(:bridge).http.send(:server_url)
|
46
|
+
username = url.user
|
47
|
+
key = url.password
|
48
|
+
|
49
|
+
RestClient::Request.execute(
|
50
|
+
method: :put,
|
51
|
+
url: "https://saucelabs.com/rest/v1/#{username}/jobs/#{sid}",
|
52
|
+
user: username,
|
53
|
+
password: key,
|
54
|
+
headers: { content_type: "application/json" },
|
55
|
+
payload: {
|
56
|
+
public: true,
|
57
|
+
passed: status == :passed,
|
58
|
+
build: env.lookup(:build_number, default: nil),
|
59
|
+
}.to_json
|
60
|
+
)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
def finalize_options!(options)
|
67
|
+
case @browser_name
|
68
|
+
when :firefox
|
69
|
+
options[:desired_capabilities][:firefox_profile] = options.delete(:profile)
|
70
|
+
when :chrome
|
71
|
+
options[:desired_capabilities]["chromeOptions"] ||= {}
|
72
|
+
options[:desired_capabilities]["chromeOptions"]["prefs"] = options.delete(:prefs)
|
73
|
+
options[:desired_capabilities]["chromeOptions"]["args"] = options.delete(:args)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def new_browser(options)
|
78
|
+
Watir::Browser.new(:remote, options).tap do |browser|
|
79
|
+
browser.driver.file_detector = lambda do |args|
|
80
|
+
# args => ["/path/to/file"]
|
81
|
+
str = args.first.to_s
|
82
|
+
str if File.exist?(str)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
require "mediawiki_selenium/step_definitions/login_steps"
|
2
|
+
require "mediawiki_selenium/step_definitions/navigation_steps"
|
3
|
+
require "mediawiki_selenium/step_definitions/preferences_steps"
|
4
|
+
require "mediawiki_selenium/step_definitions/resource_loader_steps"
|
5
|
+
require "mediawiki_selenium/step_definitions/upload_file_steps"
|
@@ -11,138 +11,14 @@ https://git.wikimedia.org/blob/mediawiki%2Fselenium/HEAD/CREDITS.
|
|
11
11
|
|
12
12
|
# before all
|
13
13
|
require "bundler/setup"
|
14
|
-
require "page-object"
|
15
14
|
require "page-object/page_factory"
|
16
|
-
require "rest_client"
|
17
15
|
require "watir-webdriver"
|
18
16
|
|
19
17
|
require "mediawiki_selenium/support/modules/api_helper"
|
20
|
-
require "mediawiki_selenium/support/modules/sauce_helper"
|
21
18
|
require "mediawiki_selenium/support/modules/strict_pending"
|
22
19
|
|
23
|
-
World
|
20
|
+
World { MediawikiSelenium::Environment.load_default }
|
21
|
+
|
24
22
|
World(MediawikiSelenium::ApiHelper)
|
25
|
-
World(MediawikiSelenium::
|
23
|
+
World(MediawikiSelenium::PageFactory)
|
26
24
|
World(MediawikiSelenium::StrictPending)
|
27
|
-
|
28
|
-
def browser(test_name, configuration = nil)
|
29
|
-
if environment == :saucelabs
|
30
|
-
sauce_browser(test_name, configuration)
|
31
|
-
else
|
32
|
-
local_browser(configuration)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
def browser_name
|
36
|
-
if ENV["BROWSER"]
|
37
|
-
ENV["BROWSER"].to_sym
|
38
|
-
else
|
39
|
-
:firefox
|
40
|
-
end
|
41
|
-
end
|
42
|
-
def environment
|
43
|
-
if ENV["SAUCE_ONDEMAND_USERNAME"] and ENV["SAUCE_ONDEMAND_ACCESS_KEY"] and ENV["BROWSER"] != "phantomjs" and ENV["HEADLESS"] != "true"
|
44
|
-
:saucelabs
|
45
|
-
else
|
46
|
-
:local
|
47
|
-
end
|
48
|
-
end
|
49
|
-
def local_browser(configuration)
|
50
|
-
if ENV["BROWSER_TIMEOUT"] && browser_name == :firefox
|
51
|
-
timeout = ENV["BROWSER_TIMEOUT"].to_i
|
52
|
-
|
53
|
-
client = Selenium::WebDriver::Remote::Http::Default.new
|
54
|
-
client.timeout = timeout
|
55
|
-
|
56
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
57
|
-
profile["dom.max_script_run_time"] = timeout
|
58
|
-
profile["dom.max_chrome_script_run_time"] = timeout
|
59
|
-
browser = Watir::Browser.new browser_name, :http_client => client, :profile => profile
|
60
|
-
elsif configuration && configuration[:language] && browser_name == :firefox
|
61
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
62
|
-
profile["intl.accept_languages"] = configuration[:language]
|
63
|
-
browser = Watir::Browser.new browser_name, profile: profile
|
64
|
-
elsif configuration && configuration[:language] && browser_name == :chrome
|
65
|
-
prefs = {intl: {accept_languages: configuration[:language]}}
|
66
|
-
browser = Watir::Browser.new browser_name, prefs: prefs
|
67
|
-
elsif configuration && configuration[:language] && browser_name == :phantomjs
|
68
|
-
capabilities = Selenium::WebDriver::Remote::Capabilities.phantomjs
|
69
|
-
capabilities["phantomjs.page.customHeaders.Accept-Language"] = configuration[:language]
|
70
|
-
browser = Watir::Browser.new browser_name, desired_capabilities: capabilities
|
71
|
-
elsif configuration && configuration[:user_agent] && browser_name == :firefox
|
72
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
73
|
-
profile["general.useragent.override"] = configuration[:user_agent]
|
74
|
-
browser = Watir::Browser.new browser_name, profile: profile
|
75
|
-
else
|
76
|
-
browser = Watir::Browser.new browser_name
|
77
|
-
end
|
78
|
-
|
79
|
-
browser.window.resize_to 1280, 1024
|
80
|
-
set_cookie(browser)
|
81
|
-
browser
|
82
|
-
end
|
83
|
-
def sauce_api(json, session_id)
|
84
|
-
RestClient::Request.execute(
|
85
|
-
:method => :put,
|
86
|
-
:url => "https://saucelabs.com/rest/v1/#{ENV['SAUCE_ONDEMAND_USERNAME']}/jobs/#{session_id}",
|
87
|
-
:user => ENV["SAUCE_ONDEMAND_USERNAME"],
|
88
|
-
:password => ENV["SAUCE_ONDEMAND_ACCESS_KEY"],
|
89
|
-
:headers => {:content_type => "application/json"},
|
90
|
-
:payload => json
|
91
|
-
)
|
92
|
-
end
|
93
|
-
def sauce_browser(test_name, configuration)
|
94
|
-
abort "Environment variables BROWSER, PLATFORM and VERSION have to be set" if (ENV["BROWSER"] == nil) or (ENV["PLATFORM"] == nil) or (ENV["VERSION"] == nil)
|
95
|
-
|
96
|
-
client = Selenium::WebDriver::Remote::Http::Default.new
|
97
|
-
|
98
|
-
if ENV["BROWSER_TIMEOUT"] && ENV["BROWSER"] == "firefox"
|
99
|
-
timeout = ENV["BROWSER_TIMEOUT"].to_i
|
100
|
-
client.timeout = timeout
|
101
|
-
|
102
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
103
|
-
profile["dom.max_script_run_time"] = timeout
|
104
|
-
profile["dom.max_chrome_script_run_time"] = timeout
|
105
|
-
caps = Selenium::WebDriver::Remote::Capabilities.firefox(:firefox_profile => profile)
|
106
|
-
elsif configuration && configuration[:language] && ENV["BROWSER"] == "firefox"
|
107
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
108
|
-
profile["intl.accept_languages"] = configuration[:language]
|
109
|
-
caps = Selenium::WebDriver::Remote::Capabilities.firefox(:firefox_profile => profile)
|
110
|
-
elsif configuration && configuration[:language] && ENV["BROWSER"] == "chrome"
|
111
|
-
profile = Selenium::WebDriver::Chrome::Profile.new
|
112
|
-
profile["intl.accept_languages"] = configuration[:language]
|
113
|
-
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chrome.profile" => profile.as_json["zip"])
|
114
|
-
elsif configuration && configuration[:user_agent] && ENV["BROWSER"] == "firefox"
|
115
|
-
profile = Selenium::WebDriver::Firefox::Profile.new
|
116
|
-
profile["general.useragent.override"] = configuration[:user_agent]
|
117
|
-
caps = Selenium::WebDriver::Remote::Capabilities.firefox(:firefox_profile => profile)
|
118
|
-
else
|
119
|
-
caps = Selenium::WebDriver::Remote::Capabilities.send(ENV["BROWSER"])
|
120
|
-
end
|
121
|
-
|
122
|
-
caps.platform = ENV["PLATFORM"]
|
123
|
-
caps.version = ENV["VERSION"]
|
124
|
-
caps[:name] = "#{test_name} #{ENV['JOB_NAME']}##{ENV['BUILD_NUMBER']}"
|
125
|
-
|
126
|
-
browser = Watir::Browser.new(
|
127
|
-
:remote,
|
128
|
-
http_client: client,
|
129
|
-
url: "http://#{ENV['SAUCE_ONDEMAND_USERNAME']}:#{ENV['SAUCE_ONDEMAND_ACCESS_KEY']}@ondemand.saucelabs.com:80/wd/hub",
|
130
|
-
desired_capabilities: caps)
|
131
|
-
browser.wd.file_detector = lambda do |args|
|
132
|
-
# args => ["/path/to/file"]
|
133
|
-
str = args.first.to_s
|
134
|
-
str if File.exist?(str)
|
135
|
-
end
|
136
|
-
|
137
|
-
browser
|
138
|
-
end
|
139
|
-
def set_cookie(browser)
|
140
|
-
# implement this method in env.rb of the repository where it is needed
|
141
|
-
end
|
142
|
-
def test_name(scenario)
|
143
|
-
if scenario.respond_to? :feature
|
144
|
-
"#{scenario.feature.title}: #{scenario.title}"
|
145
|
-
elsif scenario.respond_to? :scenario_outline
|
146
|
-
"#{scenario.scenario_outline.feature.title}: #{scenario.scenario_outline.title}: #{scenario.name}"
|
147
|
-
end
|
148
|
-
end
|
@@ -13,12 +13,6 @@ Before("@custom-browser") do |scenario|
|
|
13
13
|
@scenario = scenario
|
14
14
|
end
|
15
15
|
|
16
|
-
Before("@login") do
|
17
|
-
ENV["MEDIAWIKI_PASSWORD"] = ENV[ENV["MEDIAWIKI_PASSWORD_VARIABLE"]] if ENV["MEDIAWIKI_PASSWORD_VARIABLE"]
|
18
|
-
puts "MEDIAWIKI_USER environment variable is not defined! Please export a value for that variable before proceeding." unless ENV["MEDIAWIKI_USER"]
|
19
|
-
puts "MEDIAWIKI_PASSWORD environment variable is not defined! Please export a value for that variable before proceeding." unless ENV["MEDIAWIKI_PASSWORD"]
|
20
|
-
end
|
21
|
-
|
22
16
|
AfterConfiguration do |config|
|
23
17
|
# Install a formatter that can be used to show feature-related warnings
|
24
18
|
pretty_format, io = config.formats.find { |(format, io)| format == "pretty" }
|
@@ -68,44 +62,39 @@ Before do |scenario|
|
|
68
62
|
end
|
69
63
|
|
70
64
|
Before do |scenario|
|
65
|
+
# Create a unique random string for this scenario
|
71
66
|
@random_string = Random.new.rand.to_s
|
72
67
|
|
73
|
-
#
|
74
|
-
|
75
|
-
|
76
|
-
elsif scenario.source_tag_names.include? "@custom-browser"
|
77
|
-
# browser will be started in Cucumber step
|
78
|
-
else
|
79
|
-
@browser = browser(test_name(scenario))
|
80
|
-
$browser = @browser # CirrusSearch and VisualEditor need this
|
68
|
+
# Annotate sessions with the scenario name and Jenkins build info
|
69
|
+
browser_factory.bind do |options|
|
70
|
+
options[:desired_capabilities][:name] = test_name(scenario)
|
81
71
|
end
|
82
72
|
|
83
|
-
|
73
|
+
browser_factory.bind(:job_name) do |job, options|
|
74
|
+
options[:desired_capabilities][:name] += " #{job}"
|
75
|
+
end
|
76
|
+
|
77
|
+
browser_factory.bind(:build_number) do |build, options|
|
78
|
+
options[:desired_capabilities][:name] += "##{build}"
|
79
|
+
end
|
84
80
|
end
|
85
81
|
|
86
82
|
After do |scenario|
|
87
|
-
if
|
83
|
+
if scenario.respond_to?(:status)
|
88
84
|
require "fileutils"
|
89
|
-
screen_dir = ENV["SCREENSHOT_FAILURES_PATH"] || "screenshots"
|
90
|
-
FileUtils.mkdir_p screen_dir
|
91
|
-
name = test_name(scenario).gsub(/ /, '_')
|
92
|
-
path = "#{screen_dir}/#{name}.png"
|
93
|
-
@browser.screenshot.save path
|
94
|
-
embed path, "image/png"
|
95
|
-
end
|
96
85
|
|
97
|
-
|
98
|
-
|
86
|
+
teardown(scenario.status) do |browser|
|
87
|
+
if scenario.failed? && lookup(:screenshot_failures, default: false) == "true"
|
88
|
+
screen_dir = lookup(:screenshot_failures_path, default: "screenshots")
|
89
|
+
FileUtils.mkdir_p screen_dir
|
90
|
+
name = test_name(scenario).gsub(/ /, '_')
|
91
|
+
path = "#{screen_dir}/#{name}.png"
|
92
|
+
browser.screenshot.save path
|
93
|
+
embed path, "image/png"
|
94
|
+
end
|
99
95
|
|
100
|
-
unless sid.nil?
|
101
|
-
sauce_api(%Q{{"passed": #{scenario.passed?}}}, sid)
|
102
|
-
sauce_api(%Q{{"public": true}}, sid)
|
103
|
-
sauce_api(%Q{{"build": #{ENV["BUILD_NUMBER"]}}}, sid) if ENV["BUILD_NUMBER"]
|
104
96
|
end
|
105
|
-
|
106
|
-
|
107
|
-
if @browser
|
108
|
-
# CirrusSearch and VisualEditor need this
|
109
|
-
@browser.close unless ENV["KEEP_BROWSER_OPEN"] == "true" || ENV["REUSE_BROWSER"] == "true"
|
97
|
+
else
|
98
|
+
teardown
|
110
99
|
end
|
111
100
|
end
|
@@ -5,16 +5,55 @@ module MediawikiSelenium
|
|
5
5
|
# definitions.
|
6
6
|
#
|
7
7
|
module ApiHelper
|
8
|
-
#
|
8
|
+
# An authenticated MediaWiki API client.
|
9
9
|
#
|
10
10
|
# @return [MediawikiApi::Client]
|
11
11
|
#
|
12
12
|
def api
|
13
|
-
|
13
|
+
@_api_cache ||= {}
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
@
|
15
|
+
url = lookup(:mediawiki_api_url, default: api_url_from(lookup(:mediawiki_url)))
|
16
|
+
|
17
|
+
@_api_cache[[url, user]] ||= MediawikiApi::Client.new(url).tap do |client|
|
18
|
+
client.log_in(user, password)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Ensures the given alternative account exists by attempting to create it
|
23
|
+
# via the API. Any errors related to the account already existing are
|
24
|
+
# swallowed.
|
25
|
+
#
|
26
|
+
# @param id [Symbol] ID of alternative user.
|
27
|
+
#
|
28
|
+
def ensure_account(id)
|
29
|
+
begin
|
30
|
+
api.create_account(user(id), password(id))
|
31
|
+
rescue MediawikiApi::ApiError => e
|
32
|
+
raise e unless e.code == "userexists"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Extends parent implementation to also override the API URL. If no API
|
37
|
+
# URL is explicitly defined for the given alternative, one is constructed
|
38
|
+
# relative to the wiki URL.
|
39
|
+
#
|
40
|
+
# @yield [wiki_url, api_url]
|
41
|
+
# @yieldparam wiki_url [String] Alternative wiki URL.
|
42
|
+
# @yieldparam api_url [String] Alternative API URL.
|
43
|
+
#
|
44
|
+
# @see Environment#on_wiki
|
45
|
+
#
|
46
|
+
def on_wiki(id, &blk)
|
47
|
+
super(id) do |wiki_url|
|
48
|
+
api_url = lookup(:mediawiki_api_url, id: id, default: -> { api_url_from(wiki_url) })
|
49
|
+
return with(mediawiki_url: wiki_url, mediawiki_api_url: api_url, &blk)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def api_url_from(wiki_url)
|
56
|
+
URI.parse(wiki_url).merge("/w/api.php").to_s
|
18
57
|
end
|
19
58
|
end
|
20
59
|
end
|