jenkins-bot has submitted this change and it was merged. Change subject: Add browser tests. ......................................................................
Add browser tests. All but one of them passes against my sandbox at the moment. Change-Id: I7f33fdbae404244649605849c55dd4115036958a --- M README A tests/browser/.gitignore A tests/browser/.ruby-gemset A tests/browser/.ruby-version A tests/browser/Gemfile A tests/browser/README A tests/browser/config/config.yml A tests/browser/config/cucumber.yml A tests/browser/features/full_text.feature A tests/browser/features/prefix.feature A tests/browser/features/step_definitions/general_steps.rb A tests/browser/features/step_definitions/page_steps.rb A tests/browser/features/step_definitions/search_steps.rb A tests/browser/features/support/build_pages.rb A tests/browser/features/support/env.rb A tests/browser/features/support/modules/url_module.rb A tests/browser/features/support/pages/article_page.rb A tests/browser/features/support/pages/delete_page.rb A tests/browser/features/support/pages/edit_page.rb A tests/browser/features/support/pages/login_page.rb A tests/browser/features/support/pages/random_page.rb A tests/browser/features/support/pages/search_page.rb A tests/browser/features/support/pages/search_results_page.rb A tests/browser/features/support/sauce.rb A tests/browser/features/updates.feature 25 files changed, 715 insertions(+), 1 deletion(-) Approvals: Manybubbles: Looks good to me, approved jenkins-bot: Verified diff --git a/README b/README index 9d938a8..4dc5d3f 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ MediaWiki extension: CirrusSearch -------------------------------- +--------------------------------- Installation diff --git a/tests/browser/.gitignore b/tests/browser/.gitignore new file mode 100644 index 0000000..1af12b1 --- /dev/null +++ b/tests/browser/.gitignore @@ -0,0 +1,2 @@ +Gemfile.lock +reports/ diff --git a/tests/browser/.ruby-gemset b/tests/browser/.ruby-gemset new file mode 100644 index 0000000..7e1ee64 --- /dev/null +++ b/tests/browser/.ruby-gemset @@ -0,0 +1 @@ +CirrusSearch diff --git a/tests/browser/.ruby-version b/tests/browser/.ruby-version new file mode 100644 index 0000000..abf2cce --- /dev/null +++ b/tests/browser/.ruby-version @@ -0,0 +1 @@ +ruby-2.0.0-p247 diff --git a/tests/browser/Gemfile b/tests/browser/Gemfile new file mode 100644 index 0000000..1285565 --- /dev/null +++ b/tests/browser/Gemfile @@ -0,0 +1,8 @@ +source 'https://rubygems.org' + +gem 'cucumber' +gem 'json' +gem 'net-http-persistent' +gem 'page-object' +gem 'rspec-expectations' +gem 'syntax' diff --git a/tests/browser/README b/tests/browser/README new file mode 100644 index 0000000..08fec7b --- /dev/null +++ b/tests/browser/README @@ -0,0 +1,57 @@ +Browser Tests for Search +------------------------ +Setup +----- + +These are browser based tests for search written using the ruby page-object gem. +To run them you should first install rvm from rvm.io. Go through the whole +setup including the gnome-terminal instructions if you are using Linux and +gnome-terminal. + +Then you must install the dependencies: + cd <this directory> + gem update --system + gem install bundler + bundle install + +Some tests have to log in. The simplest way to get this working is to setup a +user named 'Selenium_user' with password 'selenium123' in your wiki and give +them all all permissions. You can do this by running this script from your +mediawiki directory: + php maintenance/createAndPromote.php --force --sysop Selenium_user selenium123 + +You can override the password by creating /private/wmf/secret.yml in the format: + mediawiki_password: new_password +or just changing it in config/config.yml. If you change it in config.yml +remember not to push it. + + +Running +------- +If you want to run tests against anything other than +en.wikipedia.beta.wmflabs.org first do this: + export MEDIAWIKI_URL=http://your-mediawiki/wiki/ + +To run all tests: + bundle exec cucumber +To run all tests in a file: + bundle exec cucumber path/to/file.feature +To run one test in a file: + bundle exec cucumber path/to/file.feature:LINE_NUMBER + +By default, the browser will close itself at the end of every scenario. If you +want the browser to stay open after each scenario: + export KEEP_BROWSER_OPEN=true + +You can also use one browser for all tests like this: + export REUSE_BROWSER=true +but doing so cause previous tests to effect one another. Do this at your own +risk but this should be safe for search tests and is much faster and it doesn't +cause the browser to keep stealing your focus. + + +Want to Contribute Some Tests? +------------------------------ +Interested? Read more at [How to contribute] +(http://www.mediawiki.org/wiki/QA/Browser_testing#How_to_contribute) section of +Browser testing page. diff --git a/tests/browser/config/config.yml b/tests/browser/config/config.yml new file mode 100644 index 0000000..f0fb67a --- /dev/null +++ b/tests/browser/config/config.yml @@ -0,0 +1,54 @@ +# mediawiki_username: Selenium_user +# mediawiki_password: selenium123 +mediawiki_username: NEverett (WMF) +mediawiki_password: 'H/a=O>_10lYz' + +android: + name: android + platform: Linux + version: 4 + +chrome: + name: chrome + platform: Linux + version: + +firefox: + name: firefox + platform: Linux + version: 21 + +internet_explorer_6: + name: internet_explorer + platform: Windows 2003 + version: 6 + +internet_explorer_7: + name: internet_explorer + platform: Windows 2003 + version: 7 + +internet_explorer_8: + name: internet_explorer + platform: Windows 2003 + version: 8 + +internet_explorer_9: + name: internet_explorer + platform: Windows 2008 + version: 9 + +internet_explorer_10: + name: internet_explorer + platform: Windows 2012 + version: 10 + +ipad: + name: ipad + platform: Mac 10.8 + version: 6 + +iphone: + name: iphone + platform: Mac 10.8 + version: 6 diff --git a/tests/browser/config/cucumber.yml b/tests/browser/config/cucumber.yml new file mode 100644 index 0000000..addebea --- /dev/null +++ b/tests/browser/config/cucumber.yml @@ -0,0 +1,2 @@ +ci: --format Cucumber::Formatter::Sauce --out reports/junit --format html --out reports/cucumber<%= ENV['TEST_ENV_NUMBER'] %>.html +default: --format pretty diff --git a/tests/browser/features/full_text.feature b/tests/browser/features/full_text.feature new file mode 100644 index 0000000..8776062 --- /dev/null +++ b/tests/browser/features/full_text.feature @@ -0,0 +1,90 @@ +Feature: Full text search + @setup_main + Scenario Outline: Query string search + Given I am at a random page + When I search for <term> + Then I am on a page titled Search results + And <first_result> the first search result + But Two Words is <two_words_is_in> the search results + Examples: + | term | first_result | two_words_is_in | + | catapult | Catapult is in | in | + | pickles | Two Words is | in | + | catapul* | Catapult is in | in | + | rdir | Two Words (redirect is in | not in | + | intitle:catapult | Catapult is in | not in | + | intitle:catapul* | Catapult is in | not in | + | intitle:catapult amazing | Amazing Catapult is | not in | + | intitle:catapul* amaz* | Amazing Catapult is | not in | + | incategory:weaponry | Catapult is in | not in | + | incategory:weaponry amazing | Amazing Catapult is | not in | + | incategory:weaponry intitle:catapult | Catapult is in | not in | + | incategory:alpha incategory:beta | AlphaBeta is | not in | + | incategory:twowords catapult | Two Words is | in | + | incategory:twowords intitle:catapult | none is | not in | + | talk:catapult | Talk:Two Words is | not in | + | talk:intitle:words | Talk:Two Words is | not in | + | template:pickles | Template:Template Test is | not in | + | pickles/ | Two Words is | in | + | catapult/pickles | Two Words is | in | + + @setup_main + Scenario Outline: Searching for empty-string like values + Given I am at a random page + When I search for <term> + Then I am on a page titled <title> + And there are no search results + Examples: + | term | title | + | the empty string | Search | + | ♙ | Search results | + + @setup_main + @setup_namespaces + Scenario Outline: Main search with non-advanced clicky features + Given I am at the search results page + When I click the <filter> link + And I search for <term> + Then I am on a page titled Search results + And <first_result> is the first search result + Examples: + | filter | term | first_result | + | Content pages | catapult | Catapult | + | Content pages | smoosh | none | + | Content pages | nothingasdf | none | + | Help and Project pages | catapult | none | + | Help and Project pages | smoosh | Help:Smoosh | + | Help and Project pages | nothingasdf | none | + | Multimedia | catapult | none | + | Multimedia | smoosh | none | + | Multimedia | nothingasdf | File:Nothingasdf | + | Everything | catapult | Catapult | + | Everything | smoosh | Help:Smoosh | + | Everything | nothingasdf | File:Nothingasdf | + + @setup_main + @setup_namespaces + Scenario Outline: Main search with advanced clicky features + Given I am at the search results page + When I click the Advanced link + And I click the (Main) or (Article) label + And I click the <filters> labels + And I search for <term> + Then I am on a page titled Search results + And <first_result> the first search result + Examples: + | filters | term | first_result | + | Talk, Help | catapult | Talk:Two Words is | + | Help, Help talk | catapult | none is | + | (Main) or (Article) | catapult | Catapult is in | + | List redirects | rdir | none is | + + @setup_suggestions + Scenario Outline: Suggestions + Given I am at a random page + When I search for <term> + Then <suggestion> is suggested + Examples: + | term | suggestion | + | popular culatur | popular culture | + | noble prize | nobel prize | diff --git a/tests/browser/features/prefix.feature b/tests/browser/features/prefix.feature new file mode 100644 index 0000000..ae0fbf7 --- /dev/null +++ b/tests/browser/features/prefix.feature @@ -0,0 +1,18 @@ +Feature: Prefix search + @setup_main + Scenario Outline: Search suggestions + Given I am at a random page + When I type <term> into the search box + Then suggestions should appear + And <first_result> is the first suggestion + And I should be offered to search for <term> + When I hit enter in the search box + Then I am on a page titled <title> + Examples: + | term | first_result | title | + | catapult | Catapult | Catapult | + | two words | Two Words | Two Words | + | ~catapult | none | Search results | + | África | África | África | +# Hitting enter in a search for Africa should pull up África but that bug is beyond me. + | Africa | África | Search results | diff --git a/tests/browser/features/step_definitions/general_steps.rb b/tests/browser/features/step_definitions/general_steps.rb new file mode 100644 index 0000000..8715168 --- /dev/null +++ b/tests/browser/features/step_definitions/general_steps.rb @@ -0,0 +1,6 @@ +Given(/^I am logged in$/) do + visit(LoginPage).login_with(@mediawiki_username, @mediawiki_password) +end +Given(/^I am at a random page.*$/) do + visit RandomPage +end diff --git a/tests/browser/features/step_definitions/page_steps.rb b/tests/browser/features/step_definitions/page_steps.rb new file mode 100644 index 0000000..770cfa4 --- /dev/null +++ b/tests/browser/features/step_definitions/page_steps.rb @@ -0,0 +1,38 @@ +Given(/^a page named (.*) exists with contents (.*)$/) do |title, text| + edit_page(title, text, false) +end + +When(/^I delete (.+)$/) do |title| + visit(DeletePage, using_params: {page_name: title}) do |page| + page.delete + end +end +When(/^I edit (.+) to add (.+)$/) do |title, text| + edit_page(title, text, true) +end + +def edit_page(title, text, add) + visit(EditPage, using_params: {page_name: title}) do |page| + if (!page.article_text? and page.login?) then + # Looks like we're not being given the article text probably because we're + # trying to edit an article that requires us to be logged in. Lets try + # logging in. + step 'I am logged in' + visit(EditPage, using_params: {page_name: title}) + end + if (page.article_text.strip != text.strip) then + if (!page.save? and page.login?) then + # Looks like I'm at a page I don't have permission to change and I'm not + # logged in. Lets log in and try again. + step 'I am logged in' + visit(EditPage, using_params: {page_name: title}) + end + if (add) then + page.article_text += text + else + page.article_text = text + end + page.save + end + end +end \ No newline at end of file diff --git a/tests/browser/features/step_definitions/search_steps.rb b/tests/browser/features/step_definitions/search_steps.rb new file mode 100644 index 0000000..d72a88b --- /dev/null +++ b/tests/browser/features/step_definitions/search_steps.rb @@ -0,0 +1,145 @@ +Given(/^I am at the search results page$/) do + visit SearchResultsPage +end + +When(/^I type (.+) into the search box$/) do |search_term| + on(SearchPage).search_input = search_term +end +When(/^I click the Search button$/) do + on(RandomPage) do |page| + if page.search_button? then + page.search_button + else + page.simple_search_button + end + end +end +When(/^I hit enter in the search box$/) do + on(SearchPage).search_input += "\n" +end +When(/^I search for (.+)$/) do |text| + #If I'm on the search page then I actually want to search in that box not the + #one in the upper right. + page_type = RandomPage + if ['Search', 'Search results'].include?(on(ArticlePage).title) then + page_type = SearchResultsPage + end + on(page_type) do |page| + if text == 'the empty string' then + page.search_input = '' + if page.simple_search_button? then + page.simple_search_button + else + page.search_button + end + else + page.search_input = text + if page.simple_search_button? then + page.simple_search_button + else + #Since there isn't a simple search button on this page we're going to have + #to use the "containing..." drop down.... + on(SearchPage).search_special_element.when_present.should exist + on(SearchPage).search_special_element.click + end + end + end +end +When(/^I click the (.*) link$/) do |text| + @browser.link(:text => text).click +end +When(/^I click the (.*) label(?:s)?$/) do |text| + text.split(',').each do |link_text| + link_text.strip! + if link_text.include? " or " then + found = false + link_text.split(" or ").each do |or_text| + or_text.strip! + label = @browser.label(:text => or_text) + if label.exists? then + found = true + label.click + end + end + if !found then + fail "none of \"" + link_text + "\" could be found" + end + else + @browser.label(:text => link_text).click + end + end +end + +Then(/^suggestions should appear$/) do + on(SearchPage).search_results_element.when_present.should exist +end +Then(/^(.+) is the first suggestion$/) do |title| + if (title == 'none') then + on(SearchPage).one_result_element.should_not exist + else + on(SearchPage).one_result.should == title + end +end +Then(/^I should be offered to search for (.+)$/) do |term| + on(SearchPage).search_special.should == "containing...\n" + term +end +Then(/^I am on a page titled (.*)$/) do |title| + on(ArticlePage).title.should == title +end +Then(/^(.*) is( in)? the first search result$/) do |title, in_ok| + on(SearchResultsPage) do |page| + if title == 'none' then + page.first_result_element.should_not exist + else + page.first_result_element.should exist + if in_ok then + page.first_result.should include title + else + page.first_result.should == title + end + end + end +end +Then(/^(.+) is( not)? in the search results$/) do |title, not_searching| + found = false + on(SearchResultsPage).results.each do |result| + if result.text == title then + found = true + end + end + if not_searching then + found.should == false + else + found.should == true + end +end +Then(/^there are no search results$/) do + on(SearchResultsPage).first_result_element.should_not exist +end +Then(/^within (\d+) seconds searching for (.*) yields (.*) as the first result$/) do |seconds, term, title| + within(seconds) do + step('I search for ' + term) + step("#{title} is the first search result") + end +end +Then(/^within (\d+) seconds typing (.*) into the search box yields (.*) as the first suggestion$/) do |seconds, term, title| + within(seconds) do + step("I type #{term} into the search box") + step('suggestions should appear') + step("#{title} is the first suggestion") + end +end + +def within(seconds) + end_time = Time.new + Integer(seconds) + begin + yield + rescue => e + if Time.new > end_time then + raise e + else + @browser.refresh + retry + end + end +end \ No newline at end of file diff --git a/tests/browser/features/support/build_pages.rb b/tests/browser/features/support/build_pages.rb new file mode 100644 index 0000000..7dab7ab --- /dev/null +++ b/tests/browser/features/support/build_pages.rb @@ -0,0 +1,40 @@ +# encoding: utf-8 + +Before('@setup_main') do + if !$newsearch_setup_main + steps %Q{ + And a page named Template:Template Test exists with contents pickles + And a page named Catapult exists with contents ♙ asdf [[Category:Weaponry]] + And a page named Amazing Catapult exists with contents test [[Category:Weaponry]] + And a page named Two Words exists with contents catapult {{Template_Test}} [[Category:TwoWords]] + And a page named África exists with contents for testing + And a page named Rdir exists with contents #REDIRECT [[Two Words]] + And a page named AlphaBeta exists with contents [[Category:Alpha]] [[Category:Beta]] + } + $newsearch_setup_main = true + end +end + +Before('@setup_namespaces') do + if !$newsearch_setup_namespaces + steps %Q{ + And a page named Talk:Two Words exists with contents why is this page about catapults? + And a page named Help:Smoosh exists with contents test + And a page named File:Nothingasdf exists with contents nothingasdf + } + $newsearch_setup_namespaces = true + end +end + +Before('@setup_suggestions') do + if !$newsearch_setup_namespaces + steps %Q{ + And a page named Popular Culture exists with contents popular culture + And a page named Nobel Prize exists with contents nobel prize + And a page named Noble Gasses exists with contents noble gasses + And a page named Noble Somethingelse exists with contents noble somethingelse + And a page named Template:Noble Pipe exists with contents pipes are so noble + } + $newsearch_setup_namespaces = true + end +end diff --git a/tests/browser/features/support/env.rb b/tests/browser/features/support/env.rb new file mode 100644 index 0000000..b1f2ef3 --- /dev/null +++ b/tests/browser/features/support/env.rb @@ -0,0 +1,133 @@ +# before all +require 'bundler/setup' +require 'page-object' +require 'page-object/page_factory' +require 'watir-webdriver' +require 'yaml' + +World(PageObject::PageFactory) + +def browser(environment, test_name, saucelabs_username, saucelabs_key, language) + if environment == :cloudbees + sauce_browser(test_name, saucelabs_username, saucelabs_key, language) + else + local_browser(language) + end +end +def environment + if ENV['ENVIRONMENT'] == 'cloudbees' + :cloudbees + else + :local + end +end +def local_browser(language) + if ENV['BROWSER_LABEL'] + browser_label = ENV['BROWSER_LABEL'].to_sym + else + browser_label = :firefox + end + + if language == 'default' + Watir::Browser.new browser_label + else + if browser_label == :firefox + profile = Selenium::WebDriver::Firefox::Profile.new + elsif browser_label == :chrome + profile = Selenium::WebDriver::Chrome::Profile.new + else + raise "Changing default language is currently supported only for Firefox and Chrome!" + end + profile['intl.accept_languages'] = language + Watir::Browser.new browser_label, :profile => profile + end +end +def sauce_api(json, saucelabs_username, saucelabs_key) + %x{curl -H 'Content-Type:text/json' -s -X PUT -d '#{json}' http://#{saucelabs_username}:#{saucelabs_key}@saucelabs.com/rest/v1/#{saucelabs_username}/jobs/#{$session_id}} +end +def sauce_browser(test_name, saucelabs_username, saucelabs_key, language) + config = YAML.load_file('config/config.yml') + browser_label = config[ENV['BROWSER_LABEL']] + + if language == 'default' + caps = Selenium::WebDriver::Remote::Capabilities.send(browser_label['name']) + elsif browser_label['name'] == 'firefox' + profile = Selenium::WebDriver::Firefox::Profile.new + profile['intl.accept_languages'] = language + caps = Selenium::WebDriver::Remote::Capabilities.firefox(:firefox_profile => profile) + elsif browser_label['name'] == 'chrome' + profile = Selenium::WebDriver::Chrome::Profile.new + profile['intl.accept_languages'] = language + caps = Selenium::WebDriver::Remote::Capabilities.chrome('chrome.profile' => profile.as_json['zip']) + end + + caps.platform = browser_label['platform'] + caps.version = browser_label['version'] + caps[:name] = "#{test_name} #{ENV['JOB_NAME']}##{ENV['BUILD_NUMBER']}" + + require 'selenium/webdriver/remote/http/persistent' # http_client + browser = Watir::Browser.new( + :remote, + http_client: Selenium::WebDriver::Remote::Http::Persistent.new, + url: "http://#{saucelabs_username}:#{saucelabs_key}@ondemand.saucelabs.com:80/wd/hub", + desired_capabilities: caps) + + browser.wd.file_detector = lambda do |args| + # args => ['/path/to/file'] + str = args.first.to_s + str if File.exist?(str) + end + + browser +end +def secret_yml_location + secret_yml_locations = ['/private/wmf/secret.yml', 'config/config.yml'] + secret_yml_locations.each do |secret_yml_location| + return secret_yml_location if File.exists?("#{secret_yml_location}") + end + nil +end +def test_name(scenario) + if scenario.respond_to? :feature + "#{scenario.feature.name}: #{scenario.name}" + elsif scenario.respond_to? :scenario_outline + "#{scenario.scenario_outline.feature.name}: #{scenario.scenario_outline.name}: #{scenario.name}" + end +end + +config = YAML.load_file('config/config.yml') +mediawiki_username = config['mediawiki_username'] + +secret = YAML.load_file("#{secret_yml_location}") +mediawiki_password = secret['mediawiki_password'] + +if ENV['ENVIRONMENT'] == 'cloudbees' + saucelabs_username = secret['saucelabs_username'] + saucelabs_key = secret['saucelabs_key'] +end + +Before do |scenario| + @config = config + @does_not_exist_page_name = Random.new.rand.to_s + @mediawiki_username = mediawiki_username + @mediawiki_password = mediawiki_password + if ENV['REUSE_BROWSER'] == 'true' and $browser then + @browser = $browser + else + @browser = browser(environment, test_name(scenario), saucelabs_username, saucelabs_key, 'default') + $browser = @browser + end + $session_id = @browser.driver.instance_variable_get(:@bridge).session_id +end + +After do |scenario| + if environment == :cloudbees + sauce_api(%Q{{"passed": #{scenario.passed?}}}, saucelabs_username, saucelabs_key) + sauce_api(%Q{{"public": true}}, saucelabs_username, saucelabs_key) + end + @browser.close unless ENV['KEEP_BROWSER_OPEN'] == 'true' or ENV['REUSE_BROWSER'] == 'true' +end + +at_exit do + $browser.close unless ENV['KEEP_BROWSER_OPEN'] == 'true' +end diff --git a/tests/browser/features/support/modules/url_module.rb b/tests/browser/features/support/modules/url_module.rb new file mode 100644 index 0000000..6268546 --- /dev/null +++ b/tests/browser/features/support/modules/url_module.rb @@ -0,0 +1,10 @@ +module URL + def self.url(name) + if ENV['MEDIAWIKI_URL'] + mediawiki_url = ENV['MEDIAWIKI_URL'] + else + mediawiki_url = 'http://en.wikipedia.beta.wmflabs.org/wiki/' + end + "#{mediawiki_url}#{name}" + end +end diff --git a/tests/browser/features/support/pages/article_page.rb b/tests/browser/features/support/pages/article_page.rb new file mode 100644 index 0000000..1402806 --- /dev/null +++ b/tests/browser/features/support/pages/article_page.rb @@ -0,0 +1,7 @@ +class ArticlePage + include PageObject + + page_url URL.url('<%=params[:page_name]%>') + + h1(:title, id: 'firstHeading') +end diff --git a/tests/browser/features/support/pages/delete_page.rb b/tests/browser/features/support/pages/delete_page.rb new file mode 100644 index 0000000..465476f --- /dev/null +++ b/tests/browser/features/support/pages/delete_page.rb @@ -0,0 +1,7 @@ +class DeletePage + include PageObject + + page_url URL.url('../w/index.php?title=<%=params[:page_name]%>&action=delete') + + button(:delete, :value => 'Delete page') +end diff --git a/tests/browser/features/support/pages/edit_page.rb b/tests/browser/features/support/pages/edit_page.rb new file mode 100644 index 0000000..66abe60 --- /dev/null +++ b/tests/browser/features/support/pages/edit_page.rb @@ -0,0 +1,9 @@ +class EditPage + include PageObject + + page_url URL.url('../w/index.php?title=<%=params[:page_name]%>&action=edit') + + text_area(:article_text, id: 'wpTextbox1') + button(:save, id: 'wpSave') + a(:login, text: 'Log in') +end diff --git a/tests/browser/features/support/pages/login_page.rb b/tests/browser/features/support/pages/login_page.rb new file mode 100644 index 0000000..839670c --- /dev/null +++ b/tests/browser/features/support/pages/login_page.rb @@ -0,0 +1,15 @@ +class LoginPage + include PageObject + + page_url URL.url('Special:UserLogin') + + button(:login, id: 'wpLoginAttempt') + text_field(:password, id: 'wpPassword1') + text_field(:username, id: 'wpName1') + + def login_with(username, password) + self.username = username + self.password = password + login + end +end diff --git a/tests/browser/features/support/pages/random_page.rb b/tests/browser/features/support/pages/random_page.rb new file mode 100644 index 0000000..ca51ab2 --- /dev/null +++ b/tests/browser/features/support/pages/random_page.rb @@ -0,0 +1,13 @@ +class RandomPage + include PageObject + + page_url URL.url('Special:Random') + + # Unfortunately some wikis don't have a button at searchButton and some put it + # at mw-searchButton so we make both and use whichever one we can. Yet worse, + # the searchButton actually works like hitting enter in the search box, going + # directly to the top prefix suggestion which we don't always want. + button(:search_button, id: 'searchButton') + button(:simple_search_button, id: 'mw-searchButton') + text_field(:search_input, id: 'searchInput') +end diff --git a/tests/browser/features/support/pages/search_page.rb b/tests/browser/features/support/pages/search_page.rb new file mode 100644 index 0000000..42c1163 --- /dev/null +++ b/tests/browser/features/support/pages/search_page.rb @@ -0,0 +1,9 @@ +class SearchPage + include PageObject + + div(:one_result, class: 'suggestions-result') + button(:search_button, id: 'searchButton') + text_field(:search_input, id: 'searchInput') + div(:search_results, class: 'suggestions-results') + div(:search_special, class: 'suggestions-special') +end diff --git a/tests/browser/features/support/pages/search_results_page.rb b/tests/browser/features/support/pages/search_results_page.rb new file mode 100644 index 0000000..21e4399 --- /dev/null +++ b/tests/browser/features/support/pages/search_results_page.rb @@ -0,0 +1,18 @@ +class SearchResultsPage + include PageObject + + page_url URL.url('/w/index.php?search') + + text_field(:search, id: 'searchText') + h1(:title, id: 'firstHeading') + div(:first_result, :class => 'mw-search-result-heading') + button(:simple_search_button, value: 'Search') + text_field(:search_input, name: 'search') + div(:suggestion_wrapper, class: 'searchdidyoumean') + def suggestion + suggestion_wrapper_element.link_element.text + end + def results + @browser.divs(:class => 'mw-search-result-heading') + end +end diff --git a/tests/browser/features/support/sauce.rb b/tests/browser/features/support/sauce.rb new file mode 100644 index 0000000..63eaeaa --- /dev/null +++ b/tests/browser/features/support/sauce.rb @@ -0,0 +1,10 @@ +require 'cucumber/formatter/junit' + +module Cucumber::Formatter + class Sauce < Junit + def format_exception(exception) + sauce_job_page = "Sauce Labs job URL: http://saucelabs.com/jobs/#{$session_id}\n" + ([sauce_job_page] + ["#{exception.message} (#{exception.class})"] + exception.backtrace).join("\n") + end + end +end diff --git a/tests/browser/features/updates.feature b/tests/browser/features/updates.feature new file mode 100644 index 0000000..4e5fa0a --- /dev/null +++ b/tests/browser/features/updates.feature @@ -0,0 +1,21 @@ +Feature: Search backend updates + Scenario: Deleted pages are removed from the index + Given I am logged in + And a page named DeleteMe exists with contents deleteme + When I delete DeleteMe + And I am at a random page so I can reload it if I need to + # Sometimes deletes take a second or two to kick in + And within 3 seconds typing deleteme into the search box yields none as the first suggestion + + Scenario: Altered pages are updated in the index + Given a page named ChangeMe exists with contents foo + When I edit ChangeMe to add superduperchangedme + And I search for superduperchangedme + Then ChangeMe is the first search result + + Scenario: Pages containing altered template are updated in the index + And a page named Template:ChangeMe exists with contents foo + And a page named ChangeMyTemplate exists with contents {{Template:ChangeMe}} + When I edit Template:ChangeMe to add superduperultrachangedme + # Updating a template uses the job queue and that can take quite a while to complete in beta + Then within 75 seconds searching for superduperultrachangedme yields ChangeMyTemplate as the first result -- To view, visit https://gerrit.wikimedia.org/r/78118 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I7f33fdbae404244649605849c55dd4115036958a Gerrit-PatchSet: 3 Gerrit-Project: mediawiki/extensions/CirrusSearch Gerrit-Branch: master Gerrit-Owner: Manybubbles <never...@wikimedia.org> Gerrit-Reviewer: Demon <ch...@wikimedia.org> Gerrit-Reviewer: Manybubbles <never...@wikimedia.org> Gerrit-Reviewer: Reedy <re...@wikimedia.org> Gerrit-Reviewer: Zfilipin <zfili...@wikimedia.org> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits