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 }); // ... });