Page MenuHomePhabricator

Prototype MW API based resource factory
Closed, DeclinedPublic

Description

In order to achieve better test isolation and determinism, we want a factory that can create "resources" during test case setup via the MW API. The initial entry point for this interface should authenticate using a single privileged account (that can at least create other users without CAPTCHA restrictions) but it should also be able to create subsequent resources as the newly provisioned user(s).

Simple usage might look something like:

// Test scenario
describe('Special:UserLogin', function () {
  var user;

  it('accepts a valid username/password', function () {
    return factory('user').create().then(function (user) {
      driver.findElement(page.username).sendKeys(user.name);
      driver.findElement(page.password).sendKeys(user.password);
      driver.findElement(page.login).click();

      return assert(driver.isElementPresent(page.userPageLink)).isTrue();
    });
  });
});

Creation of a custom factory might look something like:

tests/e2e/suite.js
registerFactory('flow-topic', require('./factories/flow-topic.js'));
tests/e2e/factories/flow-topic.js
// Custom factories would define a single factory function that accepts an
// authenticated API client instance and arbitrary parameters passed to
// `create()`
var random = require('malu').random;

module.exports = function (client, params) {
  // Enforce parameters
  if (params.page === undefined) throw 'supply a page: for the flow topic';

  // Factories should return a promise that wraps the nodemw request
  return new Promise(function (fulfill, reject) { 
    client.api.call({
      action: 'flow',
      submodule: 'new-topic',
      page: params.page.title,

      // Use default parameter values
      nttitle: params.title || random('Flow topic'),
      ntcontent: params.content || random('Some random content'),
      ntformat: params.format || 'wikitext'
    }, function (err, info, next, data) {
      if (err) reject(err);
      fulfill(data.flowstuff);
    });
  });
};
tests/e2e/scenarios/some-flow-functionality.js
var page = require('../pages/some-flow-page.js');

// Test scenario
describe('Some flow functionality', function () {
  var userB,
      topicA;

  beforeEach(function () {
    return Promise.all([
      factory('user').create().then(function (user) {
        return factory('flow-topic').as(user).create().then(function (topic) {
          topicA = topic;
        });
      }),
      factory('user').create().then(function (user) {
        userB = user;
      });
    ]);
  });

  it('does something when a user replies', function () {
    // Have userB reply to topicA
  });

  // ...
});

Related Objects

Event Timeline

We are using Webdriver.io with the middlewar being directly into mediawiki/core, see https://www.mediawiki.org/wiki/Selenium/Node.js . Hence MALU tasks are all obsoletes and to be archived (T163159)