Jdlrobson has uploaded a new change for review. https://gerrit.wikimedia.org/r/233764
Change subject: QA: My extensions first browser test ...................................................................... QA: My extensions first browser test Bug: T110198 Change-Id: I38b27161dd8ad2651bb32c00150e3c76f2ae7b30 --- A Gemfile A Gemfile.lock A tests/browser/.gitignore A tests/browser/LocalSettings.php A tests/browser/README.mediawiki A tests/browser/environments.yml A tests/browser/features/internal_survey.feature A tests/browser/features/step_definitions/common_article_steps.rb A tests/browser/features/step_definitions/common_steps.rb A tests/browser/features/step_definitions/create_account_failure_messages_steps.rb A tests/browser/features/step_definitions/create_page_api_steps.rb A tests/browser/features/step_definitions/diff_steps.rb A tests/browser/features/step_definitions/editor_steps.rb A tests/browser/features/step_definitions/editor_ve_steps.rb A tests/browser/features/step_definitions/issues_steps.rb A tests/browser/features/step_definitions/language_steps.rb A tests/browser/features/step_definitions/mainmenu_steps.rb A tests/browser/features/step_definitions/messages_steps.rb A tests/browser/features/step_definitions/nearby_steps.rb A tests/browser/features/step_definitions/notification_steps.rb A tests/browser/features/step_definitions/pageactions_steps.rb A tests/browser/features/step_definitions/references_steps.rb A tests/browser/features/step_definitions/search_steps.rb A tests/browser/features/step_definitions/special_contributions_steps.rb A tests/browser/features/step_definitions/special_history_steps.rb A tests/browser/features/step_definitions/special_userlogin_steps.rb A tests/browser/features/step_definitions/special_userprofile_steps.rb A tests/browser/features/step_definitions/special_watchlist_steps.rb A tests/browser/features/step_definitions/talk_steps.rb A tests/browser/features/step_definitions/toc_steps.rb A tests/browser/features/step_definitions/toggling_steps.rb A tests/browser/features/step_definitions/ui_links_steps.rb A tests/browser/features/step_definitions/watchstar_steps.rb A tests/browser/features/support/common_steps.rb A tests/browser/features/support/env.rb A tests/browser/features/support/hooks.rb A tests/browser/features/support/pages/article_page.rb A tests/browser/features/support/permissions.sqlite 38 files changed, 1,103 insertions(+), 0 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/QuickSurveys refs/changes/64/233764/1 diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..06d966a --- /dev/null +++ b/Gemfile @@ -0,0 +1,9 @@ +# ruby=ruby-2.1.1 +# ruby-gemset=MobileFrontend + +source 'https://rubygems.org' + +gem 'chunky_png' +gem 'jsduck' +gem 'mediawiki_selenium', '~> 1.5.0' +gem 'rubocop', require: false diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..1c3e4ab --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,112 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.0.0) + astrolabe (1.3.0) + parser (>= 2.2.0.pre.3, < 3.0) + builder (3.2.2) + childprocess (0.5.6) + ffi (~> 1.0, >= 1.0.11) + chunky_png (1.3.4) + cucumber (1.3.20) + builder (>= 2.1.2) + diff-lcs (>= 1.1.3) + gherkin (~> 2.12) + multi_json (>= 1.7.5, < 2.0) + multi_test (>= 0.1.2) + data_magic (0.21) + faker (>= 1.1.2) + yml_reader (>= 0.4) + diff-lcs (1.2.5) + dimensions (1.2.0) + domain_name (0.5.24) + unf (>= 0.0.5, < 1.0.0) + faker (1.4.3) + i18n (~> 0.5) + faraday (0.9.1) + multipart-post (>= 1.2, < 3) + faraday-cookie_jar (0.0.6) + faraday (>= 0.7.4) + http-cookie (~> 1.0.0) + ffi (1.9.10) + gherkin (2.12.2) + multi_json (~> 1.3) + headless (2.1.0) + http-cookie (1.0.2) + domain_name (~> 0.5) + i18n (0.7.0) + jsduck (5.3.4) + dimensions (~> 1.2.0) + json (~> 1.8.0) + parallel (~> 0.7.1) + rdiscount (~> 2.1.6) + rkelly-remix (~> 0.0.4) + json (1.8.2) + mediawiki_api (0.4.1) + faraday (~> 0.9, >= 0.9.0) + faraday-cookie_jar (~> 0.0, >= 0.0.6) + mediawiki_selenium (1.5.0) + cucumber (~> 1.3, >= 1.3.20) + headless (~> 2.0, >= 2.1.0) + json (~> 1.8, >= 1.8.1) + mediawiki_api (~> 0.4, >= 0.4.1) + page-object (~> 1.0) + rest-client (~> 1.6, >= 1.6.7) + rspec-expectations (~> 2.14, >= 2.14.4) + syntax (~> 1.2, >= 1.2.0) + thor (~> 0.19, >= 0.19.1) + mime-types (2.6.1) + multi_json (1.11.2) + multi_test (0.1.2) + multipart-post (2.0.0) + netrc (0.10.3) + page-object (1.1.0) + page_navigation (>= 0.9) + selenium-webdriver (>= 2.44.0) + watir-webdriver (>= 0.6.11) + page_navigation (0.9) + data_magic (>= 0.14) + parallel (0.7.1) + parser (2.2.0.3) + ast (>= 1.1, < 3.0) + powerpack (0.1.0) + rainbow (2.0.0) + rdiscount (2.1.8) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + rkelly-remix (0.0.7) + rspec-expectations (2.99.2) + diff-lcs (>= 1.1.3, < 2.0) + rubocop (0.29.1) + astrolabe (~> 1.3) + parser (>= 2.2.0.1, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.4) + ruby-progressbar (1.7.1) + rubyzip (1.1.7) + selenium-webdriver (2.46.2) + childprocess (~> 0.5) + multi_json (~> 1.0) + rubyzip (~> 1.0) + websocket (~> 1.0) + syntax (1.2.0) + thor (0.19.1) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.1) + watir-webdriver (0.8.0) + selenium-webdriver (>= 2.46.2) + websocket (1.2.2) + yml_reader (0.5) + +PLATFORMS + ruby + +DEPENDENCIES + chunky_png + jsduck + mediawiki_selenium (~> 1.5.0) + rubocop diff --git a/tests/browser/.gitignore b/tests/browser/.gitignore new file mode 100644 index 0000000..5509614 --- /dev/null +++ b/tests/browser/.gitignore @@ -0,0 +1,5 @@ +# Puppet-managed dependencies for browser tests +.bundle +.gem +.ruby-version +screenshots diff --git a/tests/browser/LocalSettings.php b/tests/browser/LocalSettings.php new file mode 100644 index 0000000..49e04a9 --- /dev/null +++ b/tests/browser/LocalSettings.php @@ -0,0 +1,21 @@ +<?php +$wgQuickSurveysConfig = array( + array( + "name" => "internal example survey", + "type" => "internal", + "question" => "ext-quicksurveys-example-internal-survey-question", + "answers" => array( + "positive" => "ext-quicksurveys-example-internal-survey-answer-positive", + "neutral" => "ext-quicksurveys-example-internal-survey-answer-neutral", + "negative"=> "ext-quicksurveys-example-internal-survey-answer-negative" + ), + "schema" => "QuickSurveysResponse", + "enabled" => false, + "coverage" => "100", + "description" => "yo", + "platform" => array( + "desktop" => array( "stable" ), + "mobile" => array( "stable", "beta", "alpha" ), + ), + ) +); \ No newline at end of file diff --git a/tests/browser/README.mediawiki b/tests/browser/README.mediawiki new file mode 100644 index 0000000..afa2982 --- /dev/null +++ b/tests/browser/README.mediawiki @@ -0,0 +1,2 @@ += Setup = +Please include the LocalSettings.php file in your MediaWiki instance. diff --git a/tests/browser/environments.yml b/tests/browser/environments.yml new file mode 100644 index 0000000..b6e4d95 --- /dev/null +++ b/tests/browser/environments.yml @@ -0,0 +1,45 @@ +# Customize this configuration as necessary to provide defaults for various +# test environments. +# +# The set of defaults to use is determined by the MEDIAWIKI_ENVIRONMENT +# environment variable. +# +# export MEDIAWIKI_ENVIRONMENT=mw-vagrant-host +# bundle exec cucumber +# +# Additional variables set by the environment will override the corresponding +# defaults defined here. +# +# export MEDIAWIKI_ENVIRONMENT=mw-vagrant-host +# export MEDIAWIKI_USER=Selenium_user2 +# bundle exec cucumber +# +mw-vagrant-host: &default + mediawiki_url: http://127.0.0.1:8080/wiki/ + user_factory: true + +barry: + browser: phantomjs + user_factory: false + # mediawiki_url: Will be set manually + +mw-vagrant-guest: + mediawiki_url: http://127.0.0.1/wiki/ + user_factory: true + +beta: + mediawiki_url: http://en.m.wikipedia.beta.wmflabs.org/wiki/ + mediawiki_user: Selenium_user + # mediawiki_password: SET THIS IN THE ENVIRONMENT! + +test2: + mediawiki_url: http://test2.wikipedia.org/wiki/ + mediawiki_user: Selenium_user + # mediawiki_password: SET THIS IN THE ENVIRONMENT! + +integration: + browser: chrome + user_factory: true + # mediawiki_url: JENKINS WILL SET THIS + +default: *default diff --git a/tests/browser/features/internal_survey.feature b/tests/browser/features/internal_survey.feature new file mode 100644 index 0000000..1247ec2 --- /dev/null +++ b/tests/browser/features/internal_survey.feature @@ -0,0 +1,8 @@ +@chrome @en.m.wikipedia.beta.wmflabs.org @firefox @test2.m.wikipedia.org @vagrant +Feature: Create failure messages + Background: + Given the quick survey test pages are installed + And I am on the "Quick survey test 1" page with the quick survey flag enabled + + Scenario: Internal survey is visible + Then I should see the survey diff --git a/tests/browser/features/step_definitions/common_article_steps.rb b/tests/browser/features/step_definitions/common_article_steps.rb new file mode 100644 index 0000000..c685eba --- /dev/null +++ b/tests/browser/features/step_definitions/common_article_steps.rb @@ -0,0 +1,68 @@ +Given(/^I click continue$/) do + on(ArticlePage).continue_button_element.when_present.click +end + +Given(/^I click submit$/) do + on(ArticlePage) do |page| + page.spinner_loading_element.when_not_present + page.submit_button_element.when_present.click + end +end + +Given(/^I click the escape button$/) do + on(ArticlePage).escape_button_element.when_present.click +end + +Given(/^I switch to desktop$/) do + on(ArticlePage).desktop_link_element.click +end + +When(/^I click on the history link in the last modified bar$/) do + on(ArticlePage).last_modified_bar_history_link_element.when_present.click + expect(on(SpecialHistoryPage).side_list_element.when_present(10)).to be_visible +end + +When(/^I click on the page$/) do + on(ArticlePage).content_wrapper_element.click +end + +When(/^I click the unwatch star$/) do + on(ArticlePage).unwatch_star_element.when_present.click +end + +When(/^I click the watch star$/) do + on(ArticlePage).watch_star_element.when_present.click +end + +Then(/^I should see a toast notification$/) do + expect(on(ArticlePage).toast_element.when_present(10)).to be_visible +end + +Then(/^I should see a toast error$/) do + expect(on(ArticlePage).toast_element.when_present.class_name).to match 'error' +end + +Then /^I should see a drawer with message "(.+)"$/ do |text| + expect(on(ArticlePage).drawer_element.when_present.text).to match text +end + +Then(/^I should see the error box message "(.+)"$/) do |error_message| + expect(on(ArticlePage).error_message).to match (error_message) +end + +Then(/^the text of the first heading should be "(.*)"$/) do |title| + on(ArticlePage) do |page| + page.wait_until do + page.first_heading_element.when_present.text.include? title + end + expect(page.first_heading_element.when_present.text).to match title + end +end + +Then /^the watch star should be selected$/ do + expect(on(ArticlePage).unwatch_star_element).to be_visible +end + +Then /^the watch star should not be selected$/ do + expect(on(ArticlePage).watch_star_element).to be_visible +end diff --git a/tests/browser/features/step_definitions/common_steps.rb b/tests/browser/features/step_definitions/common_steps.rb new file mode 100644 index 0000000..e460af6 --- /dev/null +++ b/tests/browser/features/step_definitions/common_steps.rb @@ -0,0 +1,109 @@ +Given /^I am in beta mode$/ do + visit(MainPage) do |page| + page_uri = URI.parse(page.page_url_value) + + # A domain is explicitly given to avoid a bug in earlier versions of Chrome + domain = page_uri.host == 'localhost' ? nil : page_uri.host + browser.cookies.add 'mf_useformat', 'true', domain: domain + browser.cookies.add 'optin', 'beta', domain: domain + + page.refresh + end +end + +Given /^I am logged in as a new user$/ do + step 'I am on the "Main Page" page' + step 'I click on "Log in" in the main navigation menu' + # FIXME: Actually create a new user instead of using an existing one + on(SpecialUserLoginPage).login_with('Selenium_newuser', password) +end + +Given(/^I am logged in as a user with a > (\d+) edit count$/) do |count| + api.meta(:userinfo, uiprop: 'editcount').data['editcount'].upto(count.to_i) do |n| + api.create_page("Ensure #{user} edit count - #{n + 1}", 'foo') + end + + visit(SpecialUserLoginPage).login_with(user, password) +end + +Given(/^I am logged into the mobile website$/) do + step 'I am using the mobile site' + visit(LoginPage).login_with(user, password, false) + # avoids login failing (see https://phabricator.wikimedia.org/T109593) + expect(on(ArticlePage).is_authenticated_element.when_present(20)).to exist +end + +Given(/^I am on a page that does not exist$/) do + name = 'NewPage' + Time.now.to_i.to_s + visit(ArticlePage, using_params: { article_name: name }) +end + +Given(/^I am on the random page$/) do + visit(ArticlePage, using_params: { article_name: @random_string }) +end + +Given(/^I am on the sign-up page$/) do + visit(SpecialUserLoginPage).create_account_link_element.when_present.click +end + +Given(/^I am on the "(.+)" page$/) do |article| + # Ensure we do not cause a redirect + article = article.gsub(/ /, '_') + visit(ArticlePage, using_params: { article_name: article }) +end + +Given(/^I am using the mobile site$/) do + visit(MainPage) do |page| + page_uri = URI.parse(page.page_url_value) + + domain = page_uri.host == 'localhost' ? nil : page_uri.host + browser.cookies.add 'mf_useformat', 'true', domain: domain + + page.refresh + end +end + +Given(/^I am viewing the site in mobile mode$/) do + browser.window.resize_to(320, 480) +end + +Given(/^I am viewing the site in tablet mode$/) do + # Use numbers significantly larger than 768px to account for browser chrome + browser.window.resize_to(1280, 1024) +end + +Given(/^I choose to create an account$/) do + on(SpecialUserLoginPage).create_account_link_element.when_present.click +end + +Given(/^my browser doesn't support JavaScript$/) do + browser_factory.override(browser_user_agent: 'Opera/9.80 (J2ME/MIDP; Opera Mini/9.80 (S60; SymbOS; Opera Mobi/23.348; U; en) Presto/2.5.25 Version/10.54') +end + +Given(/^the "(.*?)" page is protected\.$/) do |page| + api.protect_page(page, 'MobileFrontend Selenium test protected this page') +end + +When(/^I click the browser back button$/) do + on(ArticlePage).back +end + +When(/^I say Cancel in the confirm dialog$/) do + on(ArticlePage).confirm(false) {} +end + +When(/^I say OK in the confirm dialog$/) do + on(ArticlePage).confirm(true) do + end +end + +When(/^I visit the page "(.*?)" with hash "(.*?)"$/) do |article, hash| + # Ensure we do not cause a redirect + article = article.gsub(/ /, '_') + visit(ArticlePage, using_params: { article_name: article, hash: hash }) +end + +Then(/^there should be a red link with text "(.+)"$/) do |text| + # FIXME: Switch to link_element when red links move to stable + expect(on(ArticlePage).content_wrapper_element.link_element(text: text).when_present(10)).to be_visible +end diff --git a/tests/browser/features/step_definitions/create_account_failure_messages_steps.rb b/tests/browser/features/step_definitions/create_account_failure_messages_steps.rb new file mode 100644 index 0000000..6a4bc8b --- /dev/null +++ b/tests/browser/features/step_definitions/create_account_failure_messages_steps.rb @@ -0,0 +1,16 @@ +When(/^I sign up with two different passwords$/) do + on(SpecialUserLoginPage) do |page| + page.username = 'some_username' + page.password = 's0me decent password' + page.confirm_password = 's0me wrong password' + page.signup_submit + end +end + +Then(/^I should see an error indicating they do not match$/) do + expect(on(SpecialUserLoginPage).error_box).to match('The passwords you entered do not match') +end + +Then(/^I should still be on the sign-up page$/) do + expect(on(SpecialUserLoginPage).first_heading).to match('Create account') +end diff --git a/tests/browser/features/step_definitions/create_page_api_steps.rb b/tests/browser/features/step_definitions/create_page_api_steps.rb new file mode 100644 index 0000000..6d343e0 --- /dev/null +++ b/tests/browser/features/step_definitions/create_page_api_steps.rb @@ -0,0 +1,93 @@ +# export MEDIAWIKI_API_URL = http://en.wikipedia.beta.wmflabs.org/w/api.php + +Given(/^I create a random page using the API$/) do + api.create_page @random_string, @random_string +end + +Given(/^I go to a page that has references$/) do + wikitext = "MobileFrontend is a MediaWiki extension.<ref>Test reference</ref> + +==References== +<references />" + + api.create_page 'Selenium References test page', wikitext + step 'I am on the "Selenium References test page" page' +end + +Given(/^I go to a page that has sections$/) do + wikitext = "==Section 1== +Hello world +== Section 2 == +Section 2. +=== Section 2A === +Section 2A. +== Section 3 == +Section 3. +" + + api.create_page 'Selenium section test page2', wikitext + step 'I am on the "Selenium section test page2" page' +end + +Given(/^I am on a page which has cleanup templates$/) do + wikitext = <<-END.gsub(/^ */, '') + This page is used by Selenium to test MediaWiki functionality. + + <table class="metadata plainlinks ambox ambox-content ambox-Refimprove" role="presentation"> + <tr> + <td class="mbox-image">[[File:Question_book-new.svg|thumb]]</td> + <td class="mbox-text"> + <span class="mbox-text-span">This article \'\'\'needs additional citations for [[Wikipedia:Verifiability|verification]]\'\'\'. <span class="hide-when-compact">Please help [[Selenium page issues test page#editor/0|improve this article]] by [[Help:Introduction_to_referencing/1|adding citations to reliable sources]]. Unsourced material may be challenged and removed.</span> <small><i>(October 2012)</i></small></span> + </td> + </tr> + </table> + END + + api.create_page 'Selenium page issues test page', wikitext + step 'I am on the "Selenium page issues test page" page' +end + +Given(/^the page "(.*?)" exists$/) do |title| + api.create_page title, 'Test is used by Selenium web driver' + step 'I am on the "' + title + '" page' +end + +Given(/^at least one article with geodata exists$/) do + api.create_page 'Selenium geo test page', <<-end +This page is used by Selenium to test geo related features. + +{{#coordinates:43|-75|primary}} + end +end + +Given(/^I go to a page that has languages$/) do + wikitext = 'This page is used by Selenium to test language related features. + +[[es:Selenium language test page]]' + + api.create_page 'Selenium language test page', wikitext + step 'I am on the "Selenium language test page" page' +end + +Given(/^the wiki has a terms of use$/) do + api.create_page 'MediaWiki:mobile-frontend-terms-url', 'Terms_of_use' + api.create_page 'MediaWiki:mobile-frontend-terms-text', 'Terms of use' +end + +Given(/^the page "(.*?)" exists and has at least "(\d+)" edits$/) do |title, min_edit_count| + # Page must first exist before we can get edit count information + step 'the page "' + title + '" exists' + min_edit_count = min_edit_count.to_i + visit(ArticlePage, using_params: { article_name: title.gsub(' ', '_') + '?action=info' }) + on(ArticlePage) do |page| + (page.edit_count.gsub(',', '').to_i + 1).upto(min_edit_count) do |n| + api.create_page title, "Test is used by Selenium web driver edit ##{n}" + end + end +end + +Given(/^I visit a protected page$/) do + api.create_page 'Selenium protected test 2', 'Test is used by Selenium web driver' + step 'the "Selenium protected test 2" page is protected.' + step 'I am on the "Selenium protected test 2" page' +end diff --git a/tests/browser/features/step_definitions/diff_steps.rb b/tests/browser/features/step_definitions/diff_steps.rb new file mode 100644 index 0000000..2fcbee9 --- /dev/null +++ b/tests/browser/features/step_definitions/diff_steps.rb @@ -0,0 +1,7 @@ +Then(/^I should see "(.*?)" as added content$/) do |text| + expect(on(DiffPage).inserted_content_element.text).to eq text +end + +Then(/^I should see "(.*?)" as removed content$/) do |text| + expect(on(DiffPage).deleted_content_element.text).to eq text +end diff --git a/tests/browser/features/step_definitions/editor_steps.rb b/tests/browser/features/step_definitions/editor_steps.rb new file mode 100644 index 0000000..fff8809 --- /dev/null +++ b/tests/browser/features/step_definitions/editor_steps.rb @@ -0,0 +1,56 @@ +Given(/^the page "(.+)" has the following edits:$/) do |page, table| + page = page.gsub(' ', '_') + table.rows.each { |(text)| api.edit(title: page, text: text) } +end + +When(/^I clear the editor$/) do + on(ArticlePage).editor_textarea_element.when_present.clear +end + +When(/^I click the edit button$/) do + on(ArticlePage).edit_link_element.when_present.click +end + +When(/^I click the editor mode switcher button$/) do + on(ArticlePage).overlay_editor_mode_switcher_element.when_present.click +end + +When(/^I click the source editor button$/) do + on(ArticlePage).source_editor_button_element.when_present.click +end + +When(/^I click the VisualEditor button$/) do + on(ArticlePage).visual_editor_button_element.when_present.click +end + +When(/^I click the wikitext editor overlay close button$/) do + on(ArticlePage).editor_overlay_close_button_element.when_present.click +end + +When(/^I do not see the wikitext editor overlay$/) do + on(ArticlePage).editor_overlay_element.when_not_visible +end + +When(/^I see the wikitext editor overlay$/) do + on(ArticlePage).editor_textarea_element.when_present +end + +When(/^I type "(.+)" into the editor$/) do |text| + on(ArticlePage).editor_textarea_element.when_present.send_keys(text) +end + +Then(/^I should not see the read in another language button$/) do + expect(on(ArticlePage).language_button_element).not_to be_visible +end + +Then(/^I should not see the wikitext editor overlay$/) do + expect(on(ArticlePage).editor_overlay_element).not_to be_visible +end + +Then(/^I see the anonymous editor warning$/) do + expect(on(ArticlePage).anon_editor_warning_element.when_present).to be_visible +end + +Then /^I should see the read in another language button$/ do + expect(on(ArticlePage).language_button_element.when_present).to be_visible +end diff --git a/tests/browser/features/step_definitions/editor_ve_steps.rb b/tests/browser/features/step_definitions/editor_ve_steps.rb new file mode 100644 index 0000000..42f1541 --- /dev/null +++ b/tests/browser/features/step_definitions/editor_ve_steps.rb @@ -0,0 +1,44 @@ +Given(/^I am editing a new article with VisualEditor$/) do + api.create_page 'Selenium Test Edit', '' + step 'I am on the "Selenium Test Edit" page' + step 'I click the edit button' + step 'I click the editor mode switcher button' + step 'I click the VisualEditor button' + step 'VisualEditor has loaded' +end + +Given(/^VisualEditor has loaded$/) do + on(ArticlePage).editor_ve_element.when_present(20) +end + +When(/^I edit the article using VisualEditor$/) do + on(ArticlePage) do |page| + @text_to_type = "text-#{rand(32**8).to_s(32)}" + page.editor_ve_element.when_present.send_keys(' ') + page.editor_ve_element.send_keys(@text_to_type) + page.wait_until { page.continue_button_element.enabled? } + page.continue_button + page.wait_until { page.submit_button_element.enabled? } + page.confirm(true) { page.submit_button } + sleep 2 # this gets around a race condition bug in ChromeDriver where both the confirm and the toast are in the page at once, and Chrome reports either "stale element reference: element is not attached to the page document" or "Element does not exist in cache" + page.wait_until { page.toast.include?('Your edit was saved') } + page.wait_until { page.content_element.visible? } + end +end + +When(/^I switch to editing the source$/) do + step 'I click the editor mode switcher button' + step 'I click the source editor button' +end + +Then(/^I should no longer see the VisualEditor$/) do + expect(on(ArticlePage).editor_ve_element).to_not be_visible +end + +Then(/^I should see the article content$/) do + expect(on(ArticlePage).content_element.when_present).to be_visible +end + +Then(/^I should see the edit reflected in the article content$/) do + expect(on(ArticlePage).content).to match @text_to_type +end diff --git a/tests/browser/features/step_definitions/issues_steps.rb b/tests/browser/features/step_definitions/issues_steps.rb new file mode 100644 index 0000000..c9ed395 --- /dev/null +++ b/tests/browser/features/step_definitions/issues_steps.rb @@ -0,0 +1,23 @@ +When(/^I click the overlay issue close button$/) do + on(ArticlePage).overlay_close_button_element.when_present.click +end + +When(/^I click the page issues stamp$/) do + on(ArticlePage).issues_stamp_element.when_present.click +end + +When(/^I see the issues overlay$/) do + on(ArticlePage).overlay_element.when_present +end + +When(/^this page has issues$/) do + on(ArticlePage).issues_stamp_element.when_present +end + +Then(/^I should not see the issues overlay$/) do + expect(on(ArticlePage).overlay_element).not_to be_visible +end + +Then(/^I should see the issues overlay$/) do + expect(on(ArticlePage).overlay_element.when_present).to be_visible +end diff --git a/tests/browser/features/step_definitions/language_steps.rb b/tests/browser/features/step_definitions/language_steps.rb new file mode 100644 index 0000000..12179b9 --- /dev/null +++ b/tests/browser/features/step_definitions/language_steps.rb @@ -0,0 +1,15 @@ +When /^I click the language button$/ do + on(ArticlePage).language_button_element.when_present.click +end + +When(/^I click the language overlay close button$/) do + on(ArticlePage).overlay_languages_element.when_present.button_element(class: 'cancel').click +end + +When(/^I see the language overlay$/) do + on(ArticlePage).overlay_languages_element.when_present +end + +Then(/^I should not see the languages overlay$/) do + expect(on(ArticlePage).overlay_languages_element).not_to be_visible +end diff --git a/tests/browser/features/step_definitions/mainmenu_steps.rb b/tests/browser/features/step_definitions/mainmenu_steps.rb new file mode 100644 index 0000000..d59df40 --- /dev/null +++ b/tests/browser/features/step_definitions/mainmenu_steps.rb @@ -0,0 +1,28 @@ +When(/^I click on the main navigation button$/) do + on(ArticlePage).mainmenu_button_element.click +end + +When(/^I click on "(.*?)" in the main navigation menu$/) do |text| + step 'I click on the main navigation button' + on(ArticlePage).navigation_element.link_element(text: text).when_visible.click +end + +Then(/^I should see a link to "(.*?)" in the main navigation menu$/) do |text| + expect(on(ArticlePage).navigation_element.link_element(text: text)).to be_visible +end + +Then(/^I should not see a link to "(.*?)" in the main navigation menu$/) do |text| + expect(on(ArticlePage).navigation_element.link_element(text: text)).not_to be_visible +end + +Then(/^I should see a link to the about page$/) do + expect(on(ArticlePage).about_link_element).to be_visible +end + +Then(/^I should see a link to the disclaimer$/) do + expect(on(ArticlePage).disclaimer_link_element).to be_visible +end + +Then(/^I should see a link to my user profile page in the main navigation menu$/) do + expect(on(ArticlePage).navigation_element.link_element(href: /UserProfile\/#{user}/, text: user_label)).to be_visible +end diff --git a/tests/browser/features/step_definitions/messages_steps.rb b/tests/browser/features/step_definitions/messages_steps.rb new file mode 100644 index 0000000..2d6fcda --- /dev/null +++ b/tests/browser/features/step_definitions/messages_steps.rb @@ -0,0 +1,3 @@ +Then('I should see the error "$message"') do |message| + expect(on(ArticlePage).error_message).to match(message) +end diff --git a/tests/browser/features/step_definitions/nearby_steps.rb b/tests/browser/features/step_definitions/nearby_steps.rb new file mode 100644 index 0000000..80e7541 --- /dev/null +++ b/tests/browser/features/step_definitions/nearby_steps.rb @@ -0,0 +1,20 @@ +Given(/^I give permission for the page to access my location$/) do + unless ENV['NEARBY_FIREFOX'] + puts "NEARBY_FIREFOX environment variable is not defined. This test won't work without it!" + end +end + +When(/^I click a nearby result$/) do + on(ArticlePage).page_list_element.when_present(20).link_element(class: 'title').click +end + +Then(/^I should see at least one result in the nearby items list$/) do + on(ArticlePage) do |page| + expect(page.page_list_element.when_present(20)).to be_visible + expect(page.page_list_element.link_element(class: 'title')).to be_visible + end +end + +Then(/^I should see the page preview overlay$/) do + expect(on(ArticlePage).overlay_element.when_present(20).div_element(class: 'content')).to be_visible +end diff --git a/tests/browser/features/step_definitions/notification_steps.rb b/tests/browser/features/step_definitions/notification_steps.rb new file mode 100644 index 0000000..e2e5e35 --- /dev/null +++ b/tests/browser/features/step_definitions/notification_steps.rb @@ -0,0 +1,37 @@ +When /^I click on the notification icon$/ do + on(ArticlePage) do |page| + page.wait_until do + # Wait for JS to hijack standard link + # TODO: If this approach works well, we should implement general + # `wait_for_resource` and `resource_ready?` helper methods in + # mw-selenium, and document this pattern on mw.org + browser.execute_script("return mw.loader.getState('mobile.notifications') === 'ready'") + end + + page.notifications_button_element.when_present.click + end +end + +Given(/^I have no notifications$/) do + expect(on(ArticlePage).notifications_button_element.when_present).to be_visible + # This is somewhat hacky, but I don't want this test making use of Echo's APIs which may change + browser.execute_script("$( function () { $( '.notification-count' ).hide(); } );") +end + +When(/^I click the notifications overlay close button$/) do + sleep 1 + on(ArticlePage).notifications_overlay_close_button_element.when_present.click +end + +When(/^the notifications overlay appears$/) do + on(ArticlePage).notifications_overlay_element.when_present +end + +Then(/^after (.+) seconds I should not see the notifications overlay$/) do |seconds| + sleep seconds.to_i + expect(on(ArticlePage).notifications_overlay_element).not_to be_visible +end + +Then(/^I should see the notifications overlay$/) do + expect(on(ArticlePage).notifications_overlay_element.when_present).to be_visible +end diff --git a/tests/browser/features/step_definitions/pageactions_steps.rb b/tests/browser/features/step_definitions/pageactions_steps.rb new file mode 100644 index 0000000..2485187 --- /dev/null +++ b/tests/browser/features/step_definitions/pageactions_steps.rb @@ -0,0 +1,7 @@ +Given(/^I click the edit icon holder$/) do + on(ArticlePage).edit_button_holder_element.when_present.click +end + +Then(/^I should not see an upload an image to this page button$/) do + expect(on(ArticlePage).upload_button_element).not_to be_visible +end diff --git a/tests/browser/features/step_definitions/references_steps.rb b/tests/browser/features/step_definitions/references_steps.rb new file mode 100644 index 0000000..f28b94f --- /dev/null +++ b/tests/browser/features/step_definitions/references_steps.rb @@ -0,0 +1,14 @@ +When(/^I click on a reference$/) do + on(ArticlePage) do |page| + page.reference_element.click + page.reference_drawer_element.when_present + end +end + +Then(/^I should see the reference drawer$/) do + expect(on(ArticlePage).reference_drawer_element).to be_visible +end + +Then(/^I should not see the reference drawer$/) do + expect(on(ArticlePage).reference_drawer_element.when_not_present).to be_nil +end 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..5f7592a --- /dev/null +++ b/tests/browser/features/step_definitions/search_steps.rb @@ -0,0 +1,79 @@ +When(/^I click a search result$/) do + on(ArticlePage).search_result_element.when_present.click +end + +When(/^I click the placeholder search box$/) do + on(ArticlePage).search_box_placeholder_element.when_present.click + # this check is needed to accommodate for the hack for opening the virtual + # keyboard (see comments in search.js) + on(ArticlePage).wait_until do + on(ArticlePage).current_url.end_with? '#/search' + end +end + +When(/^I click the search button$/) do + on(ArticlePage).search_button_element.when_present.click +end + +When(/^I see the search in pages button$/) do + expect(on(ArticlePage).search_within_pages_element.when_visible).to be_visible +end + +When(/^I click the search in pages button$/) do + on(ArticlePage).search_within_pages_element.when_present.click +end + +When(/^I click a search watch star$/) do + on(ArticlePage).search_watchstars_element.when_present.click +end + +When(/^I press the enter key$/) do + on(ArticlePage).search_box2_element.when_present.send_keys :enter +end + +When(/^I click the search overlay close button$/) do + on(ArticlePage).search_overlay_close_button_element.click +end + +When(/^I see the search overlay$/) do + on(ArticlePage).search_overlay_element.when_present +end + +When(/^I type into search box "(.+)"$/) do |search_term| + on(ArticlePage) do |page| + if page.search_box2_element.exists? + # Type in JavaScript mode + page.search_box2 = search_term + else + page.search_box_placeholder = search_term + end + end +end + +Then(/^I should not see the search overlay$/) do + expect(on(ArticlePage).search_overlay_element).not_to be_visible +end + +Then(/^I should see a list of search results$/) do + expect(on(SearchPage).list_of_results_element.when_present(10)).to be_visible +end + +Then(/^I should see the search button$/) do + expect(on(ArticlePage).search_button_element.when_present).to be_visible +end + +When(/^I should see the search overlay$/) do + expect(on(ArticlePage).search_overlay_element.when_present).to be_visible +end + +Then(/^search results should contain "(.+)"$/) do |text| + expect(on(ArticlePage).search_result_element.when_present.text).to eq text +end + +Then(/^I should not see '#\/search' in URL$/) do + expect(on(ArticlePage).current_url.end_with? '#/search').to be false +end + +Then(/^I should see a toast$/) do + expect(on(ArticlePage).toast_element.when_present).to be_visible +end diff --git a/tests/browser/features/step_definitions/special_contributions_steps.rb b/tests/browser/features/step_definitions/special_contributions_steps.rb new file mode 100644 index 0000000..e4e6ec0 --- /dev/null +++ b/tests/browser/features/step_definitions/special_contributions_steps.rb @@ -0,0 +1,23 @@ +Given(/^I am on my contributions page$/) do + visit(SpecialContributionsPage, using_params: { user: user }) +end + +When(/^I click the link in the header bar$/) do + on(SpecialContributionsPage).content_header_bar_link_element.click +end + +Then(/^I should see a list of page contributions$/) do + expect(on(SpecialContributionsPage).side_list_element).to be_visible +end + +Then(/^I should see a summary of the last contribution$/) do + expect(on(SpecialContributionsPage).last_contribution_element).to be_visible +end + +Then(/^the last contribution summary should not show the username$/) do + expect(on(SpecialHistoryPage).last_contribution_username_element).not_to be_visible +end + +Then(/^the last contribution summary should show the title of the page edited$/) do + expect(on(SpecialContributionsPage).last_contribution_title_element).to be_visible +end diff --git a/tests/browser/features/step_definitions/special_history_steps.rb b/tests/browser/features/step_definitions/special_history_steps.rb new file mode 100644 index 0000000..21697b9 --- /dev/null +++ b/tests/browser/features/step_definitions/special_history_steps.rb @@ -0,0 +1,28 @@ +When(/^I click the more link$/) do + on(SpecialHistoryPage).more_link_element.click +end + +When(/^I open the latest diff$/) do + on(SpecialHistoryPage).last_contribution_link_element.click + expect(on(SpecialMobileDiffPage).user_info_element.when_present(20)).to be_visible +end + +Then(/^I should see a more button$/) do + expect(on(SpecialHistoryPage).more_link_element).to be_visible +end + +Then(/^the last contribution summary should not show the title of the page edited$/) do + expect(on(SpecialHistoryPage).last_contribution_title_element).not_to be_visible +end + +Then(/^the last contribution summary should show the edit summary$/) do + expect(on(SpecialHistoryPage).last_contribution_edit_summary_element).to be_visible +end + +Then(/^the last contribution summary should show the time of the last edit$/) do + expect(on(SpecialHistoryPage).last_contribution_timestamp_element).to be_visible +end + +Then(/^the last contribution summary should show the username who made the last edit$/) do + expect(on(SpecialHistoryPage).last_contribution_username_element).to be_visible +end diff --git a/tests/browser/features/step_definitions/special_userlogin_steps.rb b/tests/browser/features/step_definitions/special_userlogin_steps.rb new file mode 100644 index 0000000..3328fa4 --- /dev/null +++ b/tests/browser/features/step_definitions/special_userlogin_steps.rb @@ -0,0 +1,15 @@ +Then(/^I should not see a message warning me I am already logged in$/) do + expect(on(SpecialUserLoginPage).warning_box_element).not_to be_visible +end + +Then(/^I should see a message box at the top of the login page$/) do + expect(on(SpecialUserLoginPage).message_box_element).to be_visible +end + +Then(/^I should see a password reset link$/) do + expect(on(SpecialUserLoginPage).password_reset_element).to be_visible +end + +Then /^I should see the log in prompt message "(.+)"$/ do |text| + expect(on(SpecialUserLoginPage).message_box_element.when_present.text).to match text +end diff --git a/tests/browser/features/step_definitions/special_userprofile_steps.rb b/tests/browser/features/step_definitions/special_userprofile_steps.rb new file mode 100644 index 0000000..c837028 --- /dev/null +++ b/tests/browser/features/step_definitions/special_userprofile_steps.rb @@ -0,0 +1,27 @@ +Given(/^I visit my user profile page$/) do + visit(SpecialUserProfilePage, using_params: { user: user }) +end + +Then(/^I should be on my user profile page$/) do + expect(on(SpecialUserProfilePage).activity_heading_element).to be_visible +end + +Then(/^I should see my last edit$/) do + expect(on(SpecialUserProfilePage).last_edit_element).to be_visible +end + +Then(/^there should be a link to my contributions$/) do + expect(on(SpecialUserProfilePage).contributions_link_element).to be_visible +end + +Then(/^there should be a link to my talk page$/) do + expect(on(SpecialUserProfilePage).talk_link_element).to be_visible +end + +Then(/^there should be a link to my uploads$/) do + expect(on(SpecialUserProfilePage).uploads_link_element).to be_visible +end + +Then(/^there should be a link to my user page$/) do + expect(on(SpecialUserProfilePage).user_page_link_element).to be_visible +end diff --git a/tests/browser/features/step_definitions/special_watchlist_steps.rb b/tests/browser/features/step_definitions/special_watchlist_steps.rb new file mode 100644 index 0000000..54a6051 --- /dev/null +++ b/tests/browser/features/step_definitions/special_watchlist_steps.rb @@ -0,0 +1,36 @@ +Given(/^I have recently edited pages on my watchlist$/) do + api.create_page 'Selenium Watchlist', 'Edit by #{user}' + api.action('watch', token_type: 'watch', titles: 'Selenium Watchlist') +end + +When(/^the Pages tab is selected$/) do + expect(on(WatchlistPage).selected_pages_tab_element.when_present).to be_visible +end + +When(/^I click the Pages tab$/) do + on(WatchlistPage).pages_tab_link_element.when_present.click +end + +When(/^I switch to the list view of the watchlist$/) do + on(WatchlistPage).list_link_element.click +end + +When(/^I switch to the modified view of the watchlist$/) do + on(WatchlistPage).feed_link_element.click +end + +Then(/^I should see a list of diff summary links$/) do + expect(on(WatchlistPage).page_list_diffs_element.when_present).to be_visible +end + +Then(/^I should see a list of pages I am watching$/) do + expect(on(WatchlistPage).page_list_a_to_z_element.when_present).to be_visible +end + +Then(/^the a to z button should be selected$/) do + expect(on(WatchlistPage).list_link_element.parent.element.class_name).to match 'active' +end + +Then(/^the modified button should be selected$/) do + expect(on(WatchlistPage).feed_link_element.parent.element.class_name).to match 'active' +end diff --git a/tests/browser/features/step_definitions/talk_steps.rb b/tests/browser/features/step_definitions/talk_steps.rb new file mode 100644 index 0000000..20fa073 --- /dev/null +++ b/tests/browser/features/step_definitions/talk_steps.rb @@ -0,0 +1,24 @@ +When(/^I click the talk button$/) do + on(ArticlePage).talk_element.when_present.click +end + +When(/^I click the add discussion button$/) do + on(ArticlePage).talkadd_element.when_present.click +end + +Then(/^I should see the talk overlay$/) do + expect(on(ArticlePage).overlay_heading_element.when_present.text).to match 'Talk' +end + +Then(/^there should be no talk button$/) do + expect(on(ArticlePage).talk_element).not_to be_visible +end + +Then(/^there should be an add discussion button$/) do + # give overlay time to fully load + expect(on(ArticlePage).talkadd_element.when_present(10)).to be_visible +end + +Then(/^there should be no add discussion button$/) do + except(on(ArticlePage).talkadd_element).not_to be_visible +end diff --git a/tests/browser/features/step_definitions/toc_steps.rb b/tests/browser/features/step_definitions/toc_steps.rb new file mode 100644 index 0000000..2a7d746 --- /dev/null +++ b/tests/browser/features/step_definitions/toc_steps.rb @@ -0,0 +1,10 @@ +Then(/^I should not see the table of contents$/) do + on(ArticlePage) do |page| + page.toc_element.when_not_visible + expect(page.toc_element).not_to be_visible + end +end + +Then(/^I should see the table of contents$/) do + expect(on(ArticlePage).toc_element.when_present(10)).to be_visible +end diff --git a/tests/browser/features/step_definitions/toggling_steps.rb b/tests/browser/features/step_definitions/toggling_steps.rb new file mode 100644 index 0000000..9094929 --- /dev/null +++ b/tests/browser/features/step_definitions/toggling_steps.rb @@ -0,0 +1,15 @@ +When(/^I click on the first collapsible section heading$/) do + on(ArticlePage).first_section_element.when_present.click +end + +Then(/^I should not see the content of the first section$/) do + expect(on(ArticlePage).first_section_content_element).not_to be_visible +end + +Then(/^I should see the content of the first section$/) do + expect(on(ArticlePage).first_section_content_element.when_present(10)).to be_visible +end + +Then(/^the heading element with id "(.*?)" should be visible$/) do |id| + expect(on(ArticlePage).span_element(id: id).when_present(10)).to be_visible +end diff --git a/tests/browser/features/step_definitions/ui_links_steps.rb b/tests/browser/features/step_definitions/ui_links_steps.rb new file mode 100644 index 0000000..aa8433b --- /dev/null +++ b/tests/browser/features/step_definitions/ui_links_steps.rb @@ -0,0 +1,23 @@ +Then(/^I should see a link to the privacy page$/) do + expect(on(ArticlePage).privacy_link_element).to be_visible +end + +Then(/^I should see a link to the terms of use$/) do + expect(on(ArticlePage).terms_link_element).to be_visible +end + +Then(/^I should see the history link$/) do + expect(on(ArticlePage).edit_history_link_element).to be_visible +end + +Then(/^I should see the last modified bar history link$/) do + expect(on(ArticlePage).last_modified_bar_history_link_element).to be_visible +end + +Then(/^I should see the license link$/) do + expect(on(ArticlePage).license_link_element).to be_visible +end + +Then(/^I should see the switch to desktop link$/) do + expect(on(ArticlePage).desktop_link_element).to be_visible +end diff --git a/tests/browser/features/step_definitions/watchstar_steps.rb b/tests/browser/features/step_definitions/watchstar_steps.rb new file mode 100644 index 0000000..c6366e2 --- /dev/null +++ b/tests/browser/features/step_definitions/watchstar_steps.rb @@ -0,0 +1,24 @@ +Given(/^I am viewing a watched page$/) do + api.create_page 'Selenium mobile watch test', 'watch test' + api.watch_page 'Selenium mobile watch test' + step 'I am on the "Selenium mobile watch test" page' +end + +Given(/^I am viewing an unwatched page$/) do + api.create_page 'Selenium mobile watch test', 'watch test' + api.unwatch_page 'Selenium mobile watch test' + step 'I am on the "Selenium mobile watch test" page' +end + +Then(/^I should see a toast with message about watching the page$/) do + expect(on(ArticlePage).toast_element.when_present.text).to match 'Added Selenium mobile watch test to your watchlist' +end + +Then(/^I should see a toast with message about unwatching the page$/) do + on(ArticlePage) do |page| + page.wait_until do + page.text.include? 'Removed' # Chrome needs this, FF does not + end + expect(page.toast_element.when_present.text).to match 'Removed Selenium mobile watch test from your watchlist' + end +end diff --git a/tests/browser/features/support/common_steps.rb b/tests/browser/features/support/common_steps.rb new file mode 100644 index 0000000..2dbb6ad --- /dev/null +++ b/tests/browser/features/support/common_steps.rb @@ -0,0 +1,40 @@ +Given(/^the quick survey test pages are installed$/) do + wikitext = "<!-- test for page with no infobox and no image --> +'''Arcathius''' ({{lang-el| ο Άρκαθίας}} means in Greek ''ruler'', <ref>Book 1</ref> +flourished second half of 2nd century BC and first half of 1st century BC) was a Prince from the +[[Kingdom of Pontus]]. He was a prince of [[Persian people|Persian]] and +[[Macedonia (Greece)|Greek Macedonian ancestry]]. Arcathius was among the sons born to +King [[Mithridates VI of Pontus]] and +[[Laodice (sister-wife of Mithridates VI of Pontus)|his sister-wife Laodice]]. +<ref>Book 1</ref> +He was born and raised in the [[Kingdom of Pontus]]. + +Arcathius joined his father’s generals [[Neoptolemus (Pontic general)|Neoptolemus]] and +[[Archelaus (general)|Archelaus]] with 10,000 horses which he brought from [[Lesser Armenia]] +at the commencement of the [[First Mithridatic War]] (89 BC–85 BC). +<ref>http://wikipedia.org</ref> He participated in the great +battle fought near the [[Gök River|Amnias River]] in [[Paphlagonia]] which +King [[Nicomedes IV of Bithynia]] was defeated.<ref>http://wikipedia.org</ref> + +He was a brilliant cavalry commander. In 86 BC, Arcathius invaded Macedonia with a +separate army and completely conquered the country. He then proceeded to march against +the Roman Dictator [[Lucius Cornelius Sulla]], but on his way, Arcathius died near +Mount Tisaion. +<ref>Some book</ref> +Arcathius was a happy person in character and his father considered him as a +beloved son and as a victorious hero in war. +<ref>Some book</ref> + +==References== +<references />" + + api.create_page 'Quick survey test 1', wikitext +end + +Given(/^I am on the "(.*?)" page with the quick survey flag enabled$/) do |arg1| + visit(ArticlePage, using_params: { article_name: arg1, query_string: '?quicksurvey=true' }) +end + +Then(/^I should see the survey$/) do + expect(on(ArticlePage).survey_element.when_present).to be_visible +end diff --git a/tests/browser/features/support/env.rb b/tests/browser/features/support/env.rb new file mode 100644 index 0000000..5eff4ce --- /dev/null +++ b/tests/browser/features/support/env.rb @@ -0,0 +1,4 @@ +require 'mediawiki_selenium' + +require 'mediawiki_selenium/support' +require 'mediawiki_selenium/step_definitions' diff --git a/tests/browser/features/support/hooks.rb b/tests/browser/features/support/hooks.rb new file mode 100644 index 0000000..56f159b --- /dev/null +++ b/tests/browser/features/support/hooks.rb @@ -0,0 +1,6 @@ +# Needed for cucumber --dry-run -f stepdefs +require_relative 'env' + +Before('@skip') do |scenario| + scenario.skip_invoke! +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..d993f2d --- /dev/null +++ b/tests/browser/features/support/pages/article_page.rb @@ -0,0 +1,7 @@ +class ArticlePage + include PageObject + + + page_url "<%= URI.encode(params[:article_name]) %><%=params[:query_string]%><%= params[:hash] %>" + div(:survey, css: '.panel') +end diff --git a/tests/browser/features/support/permissions.sqlite b/tests/browser/features/support/permissions.sqlite new file mode 100644 index 0000000..06d2031 --- /dev/null +++ b/tests/browser/features/support/permissions.sqlite Binary files differ -- To view, visit https://gerrit.wikimedia.org/r/233764 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I38b27161dd8ad2651bb32c00150e3c76f2ae7b30 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/QuickSurveys Gerrit-Branch: dev Gerrit-Owner: Jdlrobson <jrob...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits