DCausse has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/393196 )

Change subject: Port create_new_page.feature to nodejs
......................................................................

Port create_new_page.feature to nodejs

Silenced logs in world.js
Not sure that how I export page class is right, tbh I don't really
understand. We export the class when we want to inherit but an
instance when we want to use methods statically?
Not entirely sure either if the way to test the page in the browser is
right... well it seems to work.

Not a big fan of chai to.be.true. Spent some time figuring out why it
did not work and was because I wrote is.true that was silently
ignored. I replaced with to.equal(true|false|undefined) that seems more
concise since we save the jshints.

Change-Id: I1fb6c5fa294d7480841502277fc508397fe50c92
---
M tests/browser/features/step_definitions/search_steps.rb
A tests/integration/features/create_new_page.feature
M tests/integration/features/step_definitions/page_steps.js
M tests/integration/features/step_definitions/search_steps.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
M tests/integration/features/support/pages/title_page.js
M tests/integration/features/support/world.js
9 files changed, 211 insertions(+), 37 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CirrusSearch 
refs/changes/96/393196/1

diff --git a/tests/browser/features/step_definitions/search_steps.rb 
b/tests/browser/features/step_definitions/search_steps.rb
index f71a846..2cecbfc 100644
--- a/tests/browser/features/step_definitions/search_steps.rb
+++ b/tests/browser/features/step_definitions/search_steps.rb
@@ -563,7 +563,10 @@
     on(ArticlePage).title_element.should exist
   end
 end
-Then(/^there are( no)? search results with (.+) in the data/) do 
|should_not_find, within|
+Then(/^there are( no)? search results with (.+)
+
+
+data/) do |should_not_find, within|
   with_browser do
     found = on(SearchResultsPage).result_data.map(&:text)
     if should_not_find
diff --git a/tests/integration/features/create_new_page.feature 
b/tests/integration/features/create_new_page.feature
new file mode 100644
index 0000000..fd4d01e
--- /dev/null
+++ b/tests/integration/features/create_new_page.feature
@@ -0,0 +1,105 @@
+@clean @phantomjs @bad_syntax
+Feature: Searches that prompt, or not, for new page creation
+  Background:
+    Given I am at a random page
+
+  @incategory @wildcard
+  Scenario Outline: Something something
+    When I search for <query>
+    Then there is <condition> to create a new page from the search result
+  Examples:
+  |               query                                       | condition |
+  | "ffnonsesnseword catapult"~anotherword                    |  no link  |
+  | catapult~~~~....[[\|\|.\|\|\|\|\|\|+\|+\|=\\\\=\\*.$.$.$. |  no link  |
+  | \|\| catapult                                             |  no link  |
+  | *ickle                                                    |   a link  |
+  | incategory:weaponry                                       |  no link  |
+  | catapu\\?t                                                |  no link  |
+  | catapul\\?                                                |  no link  |
+  | morelike:ThisPageDoesNotExist                             |  no link  |
+  | morelike:ChangeMe                                         |  no link  |
+
+  @boolean_operators
+  Scenario Outline: boolean operators in bad positions in the query are 
ignored so you get the option to create a new page
+    When I search for <query>
+    Then there is no warning
+      And <page> is the first search result
+      And there is a link to create a new page from the search result
+  Examples:
+  |         query          |     page         |
+  | catapult +             | Catapult         |
+  | catapult -             | Catapult         |
+  | catapult !             | Catapult         |
+  # Bug 60362
+  #| catapult AND           | Catapult         |
+  #| catapult OR            | Catapult         |
+  #| catapult NOT           | Catapult         |
+  | + catapult             | Catapult         |
+  | - catapult             | Catapult         |
+  | ! catapult             | Catapult         |
+  # Bug 60362
+  #| AND catapult           | Catapult         |
+  #| OR catapult            | Catapult         |
+  | catapult + amazing     | Amazing Catapult |
+  | catapult - amazing     | Amazing Catapult |
+  | catapult ! amazing     | Amazing Catapult |
+  | amazing+catapult       | Amazing Catapult |
+  | catapult-amazing       | Amazing Catapult |
+  | amazing!catapult       | Amazing Catapult |
+  | catapult!!!!!!!        | Catapult         |
+  | catapult !!!!!!!!      | Catapult         |
+  | !!!! catapult          | Catapult         |
+  | ------- catapult       | Catapult         |
+  | ++++ catapult ++++     | Catapult         |
+  | ++amazing++++catapult  | Amazing Catapult |
+  | catapult ~/            | Catapult         |
+  | catapult ~/            | Catapult         |
+  | amazing~◆~catapult     | Amazing Catapult |
+  | ******* catapult       | Catapult         |
+
+  @boolean_operators
+  Scenario Outline: boolean operators in bad positions in the query are 
ignored but if there are other valid operators then you don't get the option to 
create a new page
+    When I search for <query>
+    Then there is no warning
+      And <page> is the first search result
+      And there is no link to create a new page from the search result
+  Examples:
+  |         query          |     page         |
+  | catapult AND + amazing | Amazing Catapult |
+  | catapult AND - amazing | Amazing Catapult |
+  | catapult AND ! amazing | Amazing Catapult |
+  | catapult \|\|---       | Catapult         |
+  | catapult~~~~....[[\|\|.\|\|\|\|\|\|+\|+\|=\\\\=\\*.$.$.$. | Catapult |
+  | T:8~=~¥9:77:7:57;7;76;6346- OR catapult | Catapult |
+  | catapult OR T:8~=~¥9:77:7:57;7;76;6346- | Catapult |
+  | --- AND catapult       | Catapult |
+  | *catapult*             | Catapult |
+  | ***catapult*           | Catapult |
+  | ****** catapult*       | Catapult |
+
+  @boolean_operators
+  Scenario Outline: boolean operators in bad positions in the query are 
ignored and if the title isn't a valid article title then you don't get the 
option to create a new page
+    When I search for <query>
+    Then there is no warning
+      And Catapult is the first search result
+      And there is no link to create a new page from the search result
+  Examples:
+  |         query          |
+  | :~!$$=!~\!{<} catapult |
+  | catapult -_~^_~^_^^    |
+  | catapult \|\|          |
+  | catapult ~~~~~~        |
+  | catapult \|\|---       |
+  | \|\| catapult          |
+
+  @wildcard
+  Scenario Outline: Wildcards can't start a term but they aren't valid titles 
so you still don't get the link to create an article
+    When I search for <wildcard>ickle
+    Then there is no warning
+      And there are no search results
+      And there is a link to create a new page from the search result
+  Examples:
+    | wildcard |
+    | *        |
+    | ?        |
+
diff --git a/tests/integration/features/step_definitions/page_steps.js 
b/tests/integration/features/step_definitions/page_steps.js
index 9d0430d..01cceb6 100644
--- a/tests/integration/features/step_definitions/page_steps.js
+++ b/tests/integration/features/step_definitions/page_steps.js
@@ -12,6 +12,7 @@
 const defineSupportCode = require('cucumber').defineSupportCode,
        SpecialVersion = require('../support/pages/special_version'),
        ArticlePage = require('../support/pages/article_page'),
+       TitlePage = require('../support/pages/title_page'),
        expect = require( 'chai' ).expect,
        querystring = require( 'querystring' ),
        Promise = require( 'bluebird' ); // jshint ignore:line
@@ -39,7 +40,7 @@
 defineSupportCode( function( {Given, When, Then} ) {
 
        When( /^I go to (.*)$/, function ( title ) {
-               return this.visit( ArticlePage.title( title ) );
+               return this.visit( new TitlePage( title ) );
        } );
 
        When( /^I ask suggestion API for (.*)$/, function ( query ) {
@@ -152,9 +153,9 @@
                                // Chai doesnt (yet) have a native assertion 
for this:
                                // https://github.com/chaijs/chai/issues/858
                                let ok = found.reduce( ( a, b ) => a || 
b.indexOf( title ) > -1, false );
-                               return expect( ok, `expected 
${JSON.stringify(found)} to include "${title}"` ).to.be.true;
+                               expect( ok, `expected ${JSON.stringify(found)} 
to include "${title}"` ).to.equal(true);
                        } else {
-                               return expect( found ).to.include(title);
+                               expect( found ).to.include(title);
                        }
                }
        }
@@ -173,9 +174,9 @@
                        let msg = `Expected ${JSON.stringify(found)} 
to${not_searching ? ' not' : ''} include ${title}`;
 
                        if ( not_searching ) {
-                               return expect( ok, msg ).to.be.false;
+                               expect( ok, msg ).to.equal(false);
                        } else {
-                               return expect( ok, msg ).to.be.true;
+                               expect( ok, msg ).to.equal(true);
                        }
                } );
        } );
@@ -209,7 +210,7 @@
 
        Then( /there are no errors reported by the api/, function () {
                return withApi( this, () => {
-                       return expect( this.apiError ).to.be.undefined;
+                       expect( this.apiError ).to.equal(undefined);
                } );
        } );
 
@@ -358,11 +359,15 @@
                                yield stepHelpers.waitForMs( 100 );
                        } while ( ( new Date() - time ) < ( seconds * 1000 ) );
                        let msg = `Expected ${page} on commons to have ${value} 
in local_sites_with_dupe within ${seconds}s.`;
-                       return expect( found, msg ).to.be.true;
+                       expect( found, msg ).to.equal(true);
                } ).call( this );
        } );
 
        Then(/^I am on a page titled (.*)$/, function( title ) {
                expect(ArticlePage.articleTitle, `I am on 
${title}`).to.equal(title);
        } );
+
+       Given(/^I am at a random page$/, function() {
+               return this.visit( new TitlePage( 'Special:Random' ) );
+       } );
 });
diff --git a/tests/integration/features/step_definitions/search_steps.js 
b/tests/integration/features/step_definitions/search_steps.js
index e72f4cd..1d498db 100644
--- a/tests/integration/features/step_definitions/search_steps.js
+++ b/tests/integration/features/step_definitions/search_steps.js
@@ -2,6 +2,7 @@
 
 const defineSupportCode = require('cucumber').defineSupportCode,
        SearchResultsPage = require('../support/pages/search_results_page'),
+       ArticlePage = require('../support/pages/article_page'),
        expect = require( 'chai' ).expect;
 
 defineSupportCode( function( {Then,When} ) {
@@ -10,6 +11,34 @@
        } );
 
        Then( /^there are no search results/, function() {
-               return expect(SearchResultsPage.has_search_results(), 'there 
are no search results').is.false;
+               expect(SearchResultsPage.has_search_results(), 'there are no 
search results').to.equal(false);
+       } );
+
+       When( /^I search for (.*)$/, function( search ) {
+               // If on the SRP already use the main search
+               if ( SearchResultsPage.is_on_srp() ) {
+                       SearchResultsPage.search_query = search;
+                       SearchResultsPage.click_search();
+               } else {
+                       ArticlePage.search_query_top_right = search;
+                       ArticlePage.click_search_top_right();
+               }
+       } );
+
+       Then( /there is (no|a) link to create a new page from the search 
result/, function (no_or_a) {
+               let msg = `there is ${no_or_a} link to create a new page from 
the search result`;
+               expect(SearchResultsPage.has_create_page_link(), msg).to.equal( 
no_or_a !== 'no' );
+       } );
+
+       Then( /there is no warning/, function () {
+               let msg = 'there is no warning';
+               expect(SearchResultsPage.has_warnings(), msg).to.equal(false);
+       } );
+
+       Then( /(.*) is the first search result/, function (result) {
+               let msg = `${result} is the first search result`;
+               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 );
        } );
 });
diff --git a/tests/integration/features/support/pages/article_page.js 
b/tests/integration/features/support/pages/article_page.js
index e1e2d65..f7c4450 100644
--- a/tests/integration/features/support/pages/article_page.js
+++ b/tests/integration/features/support/pages/article_page.js
@@ -8,13 +8,25 @@
 const TitlePage = require('./title_page');
 
 class ArticlePage extends TitlePage {
-       constructor(){
-               super();
-       }
 
        get articleTitle() {
                return browser.getText("h1#firstHeading");
        }
+
+       /**
+        * Performs a search using the search button top-right
+        */
+       click_search_top_right() {
+               browser.click( "#simpleSearch #searchButton" );
+       }
+
+       set search_query_top_right( search ) {
+               browser.setValue( "#simpleSearch #searchInput", search );
+       }
+
+       get search_query_top_right() {
+               return browser.getValue('#simpleSearch #searchInput');
+       }
 }
 
 module.exports = new ArticlePage();
\ No newline at end of file
diff --git a/tests/integration/features/support/pages/page.js 
b/tests/integration/features/support/pages/page.js
index 9321fde..81bb47c 100644
--- a/tests/integration/features/support/pages/page.js
+++ b/tests/integration/features/support/pages/page.js
@@ -6,8 +6,7 @@
  */
 
 class Page {
-
-       constructor( url ){
+       constructor(){
                // tag selector shortcut.
                // analogous to Ruby's link(:create_link, text: "Create") etc.
                // assuming first param is a selector, second is text.
@@ -45,7 +44,6 @@
                                return elems;
                        };
                } );
-               this._url = url;
        }
 
        get url() {
diff --git a/tests/integration/features/support/pages/search_results_page.js 
b/tests/integration/features/support/pages/search_results_page.js
index aeea196..4c382ed 100644
--- a/tests/integration/features/support/pages/search_results_page.js
+++ b/tests/integration/features/support/pages/search_results_page.js
@@ -4,6 +4,7 @@
 const Page = require('./page');
 
 class SearchResultsPage extends Page {
+
        /**
         * Open the Search results searching for search
         * @param {string} search
@@ -16,6 +17,35 @@
        has_search_results() {
                return browser.elements(".searchresults 
p.mw-search-nonefound").value.length === 0;
        }
+
+       has_warnings() {
+               return browser.elements(".searchresults div.warningbox 
p").value.length > 0;
+       }
+
+       has_create_page_link() {
+               return browser.elements(".searchresults p.mw-search-createlink 
a.new").value.length === 1;
+       }
+
+       is_on_srp() {
+               // Q: why selecting form.search div.mw-search-top-table does 
not work?
+               return browser.elements("form#search 
div#mw-search-top-table").value.length > 0;
+       }
+
+       set search_query(search ) {
+               browser.setValue( 'div#searchText input[name="search"]', search 
);
+       }
+
+       get search_query() {
+               browser.getValue( 'div#searchText input[name="search"]' );
+       }
+
+       get_result_at( nth ) {
+               return browser.getText( `ul.mw-search-results li 
div.mw-search-result-heading a[data-serp-pos=\"${nth-1}\"]` );
+       }
+
+       click_search() {
+               browser.click( "#simpleSearch #searchButton" );
+       }
 }
 
 module.exports = new SearchResultsPage();
\ No newline at end of file
diff --git a/tests/integration/features/support/pages/title_page.js 
b/tests/integration/features/support/pages/title_page.js
index 4bed813..9a92434 100644
--- a/tests/integration/features/support/pages/title_page.js
+++ b/tests/integration/features/support/pages/title_page.js
@@ -7,10 +7,11 @@
 const Page = require('./page');
 
 class TitlePage extends Page {
-
-       constructor( title ){
-               super( `/wiki/${title}` );
-               this._title = title || '';
+       constructor( title ) {
+               super();
+               if ( title ) {
+                       this.url = title;
+               }
        }
 
        get url() {
@@ -18,16 +19,6 @@
        }
        set url( title ) {
                super.url =  `/wiki/${title}`;
-       }
-
-       title( title ) {
-               if ( !title ) {
-                       return this._title;
-               } else {
-                       this.url = title;
-                       this._title = title;
-                       return this;
-               }
        }
 }
 module.exports = TitlePage;
diff --git a/tests/integration/features/support/world.js 
b/tests/integration/features/support/world.js
index 58e3139..56c12bb 100644
--- a/tests/integration/features/support/world.js
+++ b/tests/integration/features/support/world.js
@@ -22,15 +22,16 @@
 // tracks what tags have already been initialized so we don't have
 // to do it for every feature file.
 class TagClient {
-       constructor( path ) {
+       constructor( options ) {
                this.tags = {};
                this.connection = new net.Socket();
-               this.connection.connect( path );
+               this.connection.connect( options.trackerPath );
                this.nextRequestId = 0;
                this.pendingResponses = {};
+               this.silentLog = options.logLevel !== 'verbose';
                this.connection.on( 'data', ( data ) => {
                        let parsed = JSON.parse( data );
-                       log( `received response for request 
${parsed.requestId}: ${data}` );
+                       log( `[D] TAG << ${parsed.requestId}: ${data}`, 
this.silentLog );
                        if ( parsed && this.pendingResponses[parsed.requestId] 
) {
                                this.pendingResponses[parsed.requestId]( parsed 
);
                                delete this.pendingResponses[parsed.requestId];
@@ -42,7 +43,7 @@
                req.requestId = this.nextRequestId++;
                return new Promise( ( resolve ) => {
                        let data = JSON.stringify( req );
-                       log( `Issuing request: ${data}` );
+                       log( `[D] TAG >> ${data}`, this.silentLog );
                        this.pendingResponses[req.requestId] = resolve;
                        this.connection.write( data );
                } );
@@ -78,7 +79,7 @@
        }
 }
 
-let tagClient = new TagClient( browser.options.trackerPath );
+let tagClient = new TagClient( browser.options );
 // world gets re-created all the time. Try and save some time logging
 // in by sharing api clients
 let apiClients = {};
@@ -158,7 +159,7 @@
        // as well as a string, assumes the Page object
        // has a url property
        this.visit = function( page, wiki = this.config.wikis.default ) {
-               var tmpUrl;
+               let tmpUrl;
                if ( page instanceof Page && page.url ) {
                        tmpUrl = page.url;
                }
@@ -169,10 +170,10 @@
                        throw Error( `In "World.visit(page)" page is falsy: 
page=${ page }` );
                }
                tmpUrl = this.config.wikis[wiki].baseUrl + tmpUrl;
-               log( `Visiting page: ${tmpUrl}` );
+               log( `[D] Visiting page: ${tmpUrl}`, this.tags.silentLog );
                browser.url( tmpUrl );
                // logs full URL in case of typos, misplaced backslashes.
-               log( `Visited page: ${browser.getUrl()}` );
+               log( `[D] Visited page: ${browser.getUrl()}`, 
this.tags.silentLog );
        };
 
        // Variables held between steps and substituted into queries

-- 
To view, visit https://gerrit.wikimedia.org/r/393196
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1fb6c5fa294d7480841502277fc508397fe50c92
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CirrusSearch
Gerrit-Branch: master
Gerrit-Owner: DCausse <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to