Merge "selenium: invoke jobs to enforce eventual consistency"
authorjenkins-bot <jenkins-bot@gerrit.wikimedia.org>
Fri, 21 Sep 2018 07:59:13 +0000 (07:59 +0000)
committerGerrit Code Review <gerrit@wikimedia.org>
Fri, 21 Sep 2018 07:59:13 +0000 (07:59 +0000)
tests/selenium/specs/specialrecentchanges.js
tests/selenium/wdio-mediawiki/RunJobs.js [new file with mode: 0644]

index 4328d3f..a872d6e 100644 (file)
@@ -1,7 +1,8 @@
 const assert = require( 'assert' ),
-       EditPage = require( '../pageobjects/edit.page' ),
+       Api = require( 'wdio-mediawiki/Api' ),
        RecentChangesPage = require( '../pageobjects/recentchanges.page' ),
-       Util = require( 'wdio-mediawiki/Util' );
+       Util = require( 'wdio-mediawiki/Util' ),
+       RunJobs = require( 'wdio-mediawiki/RunJobs' );
 
 describe( 'Special:RecentChanges', function () {
        let content,
@@ -13,9 +14,11 @@ describe( 'Special:RecentChanges', function () {
                name = Util.getTestString();
        } );
 
-       // Skip due to failures on many repos (T199644)
-       it.skip( 'shows page creation', function () {
-               EditPage.edit( name, content );
+       it( 'shows page creation', function () {
+               browser.call( function () {
+                       return Api.edit( name, content );
+               } );
+               RunJobs.run();
 
                RecentChangesPage.open();
 
diff --git a/tests/selenium/wdio-mediawiki/RunJobs.js b/tests/selenium/wdio-mediawiki/RunJobs.js
new file mode 100644 (file)
index 0000000..9d02d4d
--- /dev/null
@@ -0,0 +1,73 @@
+const MWBot = require( 'mwbot' ),
+       Page = require( 'wdio-mediawiki/Page' ),
+       FRONTPAGE_REQUESTS_MAX_RUNS = 10; // (arbitrary) safe-guard against endless execution
+
+/**
+ * Trigger the execution of jobs
+ *
+ * @see https://www.mediawiki.org/wiki/Manual:Job_queue/For_developers#Execution_of_jobs
+ *
+ * Use RunJobs.run() to ensure that jobs are executed before making assertions that depend on it.
+ *
+ * Systems that are selenium-tested are usually provisioned for that purpose, see no organic
+ * traffic, consequently typical post-send job queue processing rarely happens. Additionally,
+ * test set-up is often done through the API, requests to which do not trigger job queue
+ * processing at all.
+ *
+ * This can lead to an accumulation of unprocessed jobs, which in turn would render certain
+ * assertions impossible - e.g. checking a page is listed on Special:RecentChanges right
+ * after creating it.
+ *
+ * This class will try to trigger job execution through
+ * repeated blunt requests against the wiki's home page to trigger them at a rate
+ * of $wgJobRunRate per request.
+ */
+class RunJobs {
+
+       static run() {
+               browser.call( () => {
+                       return this.runThroughFrontPageRequests();
+               } );
+       }
+
+       static getJobCount() {
+               let bot = new MWBot( {
+                       apiUrl: `${browser.options.baseUrl}/api.php`
+               } );
+               return new Promise( ( resolve ) => {
+                       return bot.request( {
+                               action: 'query',
+                               meta: 'siteinfo',
+                               siprop: 'statistics'
+                       } ).then( ( response ) => {
+                               resolve( response.query.statistics.jobs );
+                       } );
+               } );
+       }
+
+       static runThroughFrontPageRequests( runCount = 1 ) {
+               let page = new Page();
+               this.log( `through requests to the front page (run ${runCount}).` );
+
+               page.openTitle( '' );
+
+               return this.getJobCount().then( ( jobCount ) => {
+                       if ( jobCount === 0 ) {
+                               this.log( 'found no more queued jobs.' );
+                               return;
+                       }
+                       this.log( `detected ${jobCount} more queued job(s).` );
+                       if ( runCount >= FRONTPAGE_REQUESTS_MAX_RUNS ) {
+                               this.log( 'stopping requests to the front page due to reached limit.' );
+                               return;
+                       }
+                       return this.runThroughFrontPageRequests( ++runCount );
+               } );
+       }
+
+       static log( message ) {
+               process.stdout.write( `RunJobs ${message}\n` );
+       }
+}
+
+module.exports = RunJobs;