jenkins-bot has submitted this change and it was merged. (
https://gerrit.wikimedia.org/r/393776 )
Change subject: Port full_text_browser.feature to nodejs
......................................................................
Port full_text_browser.feature to nodejs
Not a perfect port:
- Switched starting point to SRP instead of a random page (to avoid
having go interfere with the expectations)
- Added Waffle* pages to hook tags, I see no reason why it was added
like that
- Simplified the steps and did not implement the "imageresult" steps
- Added a optional suffix " and has an image link" to assert that the
result is decorated with an image (meant to cover the imageresult
check).
Change-Id: I5a57e1f68a7a2507466e8cea84b043f7372080cd
---
A tests/integration/features/full_text_browser.feature
M tests/integration/features/step_definitions/search_steps.js
M tests/integration/features/support/hooks.js
M tests/integration/features/support/pages/article_page.js
M tests/integration/features/support/pages/page.js
M tests/integration/features/support/pages/search_results_page.js
6 files changed, 245 insertions(+), 19 deletions(-)
Approvals:
Cindy-the-browser-test-bot: Looks good to me, but someone else must approve
EBernhardson: Looks good to me, approved
jenkins-bot: Verified
diff --git a/tests/integration/features/full_text_browser.feature
b/tests/integration/features/full_text_browser.feature
new file mode 100644
index 0000000..a2a1d49
--- /dev/null
+++ b/tests/integration/features/full_text_browser.feature
@@ -0,0 +1,102 @@
+@clean @phantomjs
+Feature: Full text search
+ Background:
+ Given I am at the search results page
+
+ @setup_main @setup_namespaces
+ Scenario Outline: Query string search
+ When I search for <term>
+ Then I am on a page titled Search results
+ And <first_result> is 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 | in
|
+ | pickles | Two Words | in
|
+ | rdir | Two Words | in
|
+ | talk:catapult | Talk:Two Words | not in
|
+ | talk:intitle:words | Talk:Two Words | not in
|
+ | template:pickles | Template:Template Test | not in
|
+ | pickles/ | Two Words | in
|
+ | catapult/pickles | Two Words | in
|
+ | File:"Screenshot, for test purposes" | File:Savepage-greyed.png | not in
|
+ # You can't search for text inside a <video> or <audio> tag
+ | "JavaScript disabled" | none | not in
|
+ # You can't search for text inside the table of contants
+ | "3.1 Conquest of Persian empire" | none | not in
|
+ # You can't search for the [edit] tokens that users can click to edit
sections
+ | "Succession of Umar edit" | none | not in
|
+
+ @setup_main
+ Scenario Outline: Searching for empty-string like values
+ When I search for <term>
+ Then I am on a page titled <title>
+ And there are no search results
+ And there are no errors reported
+ Examples:
+ | term | title |
+ | the empty string | Search |
+ | ♙ | Search results |
+ | %{exact: } | Search results |
+ | %{exact: } | Search results |
+ | %{exact: } | Search results |
+
+ @javascript_injection
+ Scenario: Searching for a page with javascript doesn't execute it (in this
case, removing the page title)
+ When I search for Javascript findme
+ Then the title still exists
+
+ @file_text
+ Scenario: When you search for text that is in a file, you can find it!
+ When I search for File:debian rhino
+ Then File:Linux Distribution Timeline text version.pdf is the first search
result and has an image link
+
+ @js_and_css
+ Scenario: JS pages don't corrupt the output
+ When I search for User:Tools/some.js jQuery
+ Then there is not alttitle on the first search result
+
+ @js_and_css
+ Scenario: CSS pages don't corrupt the output
+ When I search for User:Tools/some.css jQuery
+ Then there is not alttitle on the first search result
+
+ @setup_main
+ Scenario: Word count is output in the results
+ When I search for Two Words
+ Then there are search results with (4 words) in the data
+
+ @setup_main @filenames
+ Scenario Outline: Portions of file names
+ When I search for <term>
+ Then I am on a page titled Search results
+ And <first_result> is the first search result
+ Examples:
+ | term | first_result |
+ | File:Savepage-greyed.png | File:Savepage-greyed.png |
+ | File:Savepage | File:Savepage-greyed.png |
+ | File:greyed.png | File:Savepage-greyed.png |
+ | File:greyed | File:Savepage-greyed.png |
+ | File:Savepage png | File:Savepage-greyed.png |
+ | File:No_SVG.svg | File:No SVG.svg |
+ | File:No SVG.svg | File:No SVG.svg |
+ | File:No svg | File:No SVG.svg |
+ | File:svg.svg | File:Somethingelse svg SVG.svg |
+
+ @setup_main
+ Scenario Outline: Text separated by a <br> tag is not jammed together
+ When I search for <term>
+ Then I am on a page titled Search results
+ Then <page> is the first search result
+ Examples:
+ | term | page |
+ | Waffle Squash | Waffle Squash |
+ | Waffle Squash 2 | Waffle Squash 2 |
+ | wafflesquash | none |
+
+ # Just take too long to run on a regular basis
+ # @huge
+ # Scenario: Searches for a huge phrase is reasonably fast (faster than the
40 second timeout)
+ # Given there are 3000 pages named Zeros%s with contents 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0
+ # When I search for 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0.
0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0.
0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0. 0.0.0.0.0.0.0.0.
+ # Then Zeros is in the first search result
diff --git a/tests/integration/features/step_definitions/search_steps.js
b/tests/integration/features/step_definitions/search_steps.js
index 3a3adc9..c56d012 100644
--- a/tests/integration/features/step_definitions/search_steps.js
+++ b/tests/integration/features/step_definitions/search_steps.js
@@ -1,13 +1,19 @@
/*jshint esversion: 6, node:true */
-const defineSupportCode = require('cucumber').defineSupportCode,
+const {defineSupportCode, defineParameterType} = require('cucumber'),
SearchResultsPage = require('../support/pages/search_results_page'),
ArticlePage = require('../support/pages/article_page'),
TitlePage = require('../support/pages/title_page'),
expect = require( 'chai' ).expect;
+defineParameterType( {
+ regexp: /.+/,
+ transformer: s => s === 'the empty string' ? '' : s.replace(
/%{exact:([^}]*)}/g, '$1' ),
+ name: 'exact'
+} );
+
defineSupportCode( function( {Then,When,Given} ) {
- When( /^I go search for (.*)$/, function ( title ) {
+ When( /^I go search for (.+)$/, function ( title ) {
return this.visit( SearchResultsPage.search( title ) );
} );
@@ -15,7 +21,7 @@
expect(SearchResultsPage.has_search_results(), 'there are no
search results').to.equal(false);
} );
- When( /^I search for (.*)$/, function( search ) {
+ When( /^I search for (.+)$/, function( search ) {
// If on the SRP already use the main search
if ( SearchResultsPage.is_on_srp() ) {
SearchResultsPage.search_query = search;
@@ -33,10 +39,15 @@
Then( /^there is no warning$/, function () {
let msg = 'there is no warning';
- expect(SearchResultsPage.get_warnings(),
msg).to.have.lengthOf(0);
+ expect(SearchResultsPage.has_warnings(), msg).to.equal(false);
} );
- Then( /^(.*) is the first search result$/, function (result) {
+ Then( /^there are no errors reported$/, function () {
+ let msg = 'there are no errors reported';
+ expect(SearchResultsPage.has_errors(), msg).to.equal(false);
+ } );
+
+ Then( /^(.+) is the first search result( and has an image link)?$/,
function (result, imagelink) {
let msg = `${result} is the first search result`;
if ( result === "none" ) {
expect(SearchResultsPage.has_search_results(),
msg).to.equal(false);
@@ -44,22 +55,51 @@
expect(SearchResultsPage.is_on_srp(),
msg).to.equal(true);
expect(SearchResultsPage.has_search_results(),
msg).to.equal(true);
expect(SearchResultsPage.get_result_at(1),
msg).to.equal(result);
+ if ( imagelink ) {
+
expect(SearchResultsPage.get_result_image_link_at(1), msg).to.not.equal(null);
+ }
}
+ } );
+
+ Then( /^(.+) is( not)? in the search results$/, function (result, not) {
+ let msg = `${result} is${not === undefined ? '' : not} in the
search results`;
+ expect(SearchResultsPage.is_on_srp(), msg).to.equal(true);
+ if ( not === undefined ) {
+ expect(SearchResultsPage.has_search_results(),
msg).to.equal(true);
+ }
+ expect(SearchResultsPage.in_search_results(result),
msg).to.equal(not === undefined);
} );
Given( /^I am at the search results page$/, function() {
this.visit( new TitlePage( 'Special:Search' ) );
} );
- When( /^I click the (.*) link$/, function( filter ) {
+ When( /^I click the (.+) link$/, function( filter ) {
SearchResultsPage.click_filter( filter );
} );
- When( /^I click the (.*) labels?$/, function( filter ) {
+ When( /^I click the (.+) labels?$/, function( filter ) {
let and_labels = filter.split(/, /, 10);
for ( let labels of and_labels ) {
let or_labels = labels.split(/ or /, 10);
SearchResultsPage.select_namespaces( or_labels, true );
}
} );
+
+ Then( /^the title still exists$/, function() {
+ let msg = "the title still exists";
+ expect( ArticlePage.title_element().isExisting(), msg
).to.equal(true);
+ } );
+
+ Then( /^there is not alttitle on the first search result$/, function() {
+ let msg = "there is not alttitle on the first search result";
+ expect(SearchResultsPage.get_search_alt_title_at(1,
msg)).to.equal(null);
+ } );
+
+ Then( /^there are search results with \((.+)\) in the data$/,
function(what) {
+ let msg = `there are search results with ${what} in the data`;
+ expect(SearchResultsPage.is_on_srp()).to.equal(true);
+ expect(SearchResultsPage.has_search_results(),
msg).to.equal(true);
+ expect(SearchResultsPage.has_search_data_in_results(what),
msg).to.equal(true);
+ } );
});
diff --git a/tests/integration/features/support/hooks.js
b/tests/integration/features/support/hooks.js
index 2c78666..19f560f 100644
--- a/tests/integration/features/support/hooks.js
+++ b/tests/integration/features/support/hooks.js
@@ -162,7 +162,9 @@
"\u0935\u093e\u0919\u094d\u200c\u092e\u092f":
"\u0935\u093e\u0919\u094d\u200c\u092e\u092f",
"ChangeMe": "foo",
"Wikitext": "{{#tag:somebug}}",
- "Page with non ascii letters": "ἄνθρωπος, широкий"
+ "Page with non ascii letters": "ἄνθρωπος, широкий",
+ "Waffle Squash": articleText("wafflesquash.txt"),
+ "Waffle Squash 2": "waffle<br>squash"
}
} ) );
diff --git a/tests/integration/features/support/pages/article_page.js
b/tests/integration/features/support/pages/article_page.js
index f7c4450..1c8d63d 100644
--- a/tests/integration/features/support/pages/article_page.js
+++ b/tests/integration/features/support/pages/article_page.js
@@ -10,7 +10,11 @@
class ArticlePage extends TitlePage {
get articleTitle() {
- return browser.getText("h1#firstHeading");
+ return this.title_element().getText();
+ }
+
+ title_element() {
+ return browser.element( "h1#firstHeading" );
}
/**
diff --git a/tests/integration/features/support/pages/page.js
b/tests/integration/features/support/pages/page.js
index 81bb47c..bd9ce48 100644
--- a/tests/integration/features/support/pages/page.js
+++ b/tests/integration/features/support/pages/page.js
@@ -46,6 +46,15 @@
} );
}
+ collect_element_texts( selector ) {
+ let elements = browser.elements(selector).value;
+ let texts = [];
+ for ( let text of elements ) {
+ texts.push( text.getText() );
+ }
+ return texts;
+ }
+
get url() {
return this._url;
}
diff --git a/tests/integration/features/support/pages/search_results_page.js
b/tests/integration/features/support/pages/search_results_page.js
index 3083c56..16473ae 100644
--- a/tests/integration/features/support/pages/search_results_page.js
+++ b/tests/integration/features/support/pages/search_results_page.js
@@ -15,16 +15,23 @@
}
has_search_results() {
- return browser.elements(".searchresults
p.mw-search-nonefound").value.length === 0;
+ return browser.elements(".searchresults
ul.mw-search-results").value.length > 0;
}
get_warnings() {
- let elements = browser.elements(".searchresults div.warningbox
p").value;
- let warnings = [];
- for ( let warning of elements ) {
- warnings.push( warning.getText() );
- }
- return warnings;
+ return this.collect_element_texts(".searchresults
div.warningbox p");
+ }
+
+ has_warnings() {
+ return this.get_warnings().length > 0;
+ }
+
+ get_errors() {
+ return this.collect_element_texts(".searchresults div.errorbox
p");
+ }
+
+ has_errors() {
+ return this.get_errors().length > 0;
}
has_create_page_link() {
@@ -36,16 +43,78 @@
browser.elements("form#powersearch
div#mw-search-top-table").value.length > 0;
}
- set search_query(search ) {
+ set search_query( search ) {
browser.setValue( 'div#searchText input[name="search"]', search
);
}
get search_query() {
- browser.getValue( 'div#searchText input[name="search"]' );
+ return browser.getValue( 'div#searchText input[name="search"]'
);
+ }
+
+ get_result_element_at( nth ) {
+ let resultLink = this.results_block().element(
`a[data-serp-pos=\"${nth-1}\"]` );
+ if ( !resultLink.isExisting() ) {
+ return null;
+ }
+ return resultLink.element("..");
+ }
+
+ get_result_image_link_at( nth ) {
+ let resElem = this.get_result_element_at( nth );
+ if ( resElem === null ) {
+ return null;
+ }
+ // Image links are inside a table
+ // move to the tr parent to switch the td holding the images
+ // <tbody>
+ // <tr>
+ // <td>[THUMB IMAGE LINK BLOCK]</td>
+ // <td>[RESULT ELEMENT BLOCK] position returned by
get_result_element_at</td>
+ // </tr>
+ // </tbody>
+ let tr = resElem.element("..");
+ if ( tr.getTagName() !== 'tr' ) {
+ return null;
+ }
+ let imageTag = tr.element( 'td a.image img' );
+ if ( imageTag.isExisting() ) {
+ return imageTag.getAttribute( 'src' );
+ }
+ return null;
+ }
+
+ has_search_data_in_results( data ) {
+ return this.results_block().element(
`div.mw-search-result-data*=${data}`).isExisting();
+ }
+
+ get_search_alt_title_at( nth ) {
+ let resultBlock = this.get_result_element_at( nth );
+ if ( resultBlock === null ) {
+ return null;
+ }
+ let elt = resultBlock.element("span.searchalttitle");
+ if ( elt.isExisting() ) {
+ return elt.getText();
+ }
+ return null;
}
get_result_at( nth ) {
- return browser.getAttribute( `ul.mw-search-results li
div.mw-search-result-heading a[data-serp-pos=\"${nth-1}\"]`, 'title' );
+ return this.results_block().getAttribute(
`a[data-serp-pos=\"${nth-1}\"]`, 'title' );
+ }
+
+ in_search_results( title ) {
+ let elt = this.results_block().element(`a[title="${title}"]` );
+ return elt.isExisting();
+ }
+
+ results_block() {
+ let elt = browser.elements( "div.searchresults" );
+
+ if ( !elt.value ) {
+ throw new Error("Cannot locate search results block,
are you on the SRP?");
+ }
+ return elt;
}
click_search() {
--
To view, visit https://gerrit.wikimedia.org/r/393776
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I5a57e1f68a7a2507466e8cea84b043f7372080cd
Gerrit-PatchSet: 3
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: DCausse <[email protected]>
Gerrit-Reviewer: Cindy-the-browser-test-bot <[email protected]>
Gerrit-Reviewer: DCausse <[email protected]>
Gerrit-Reviewer: EBernhardson <[email protected]>
Gerrit-Reviewer: Gehel <[email protected]>
Gerrit-Reviewer: Smalyshev <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits