Update Composer, update everything

This commit is contained in:
Oliver Davies 2018-11-23 12:29:20 +00:00
parent ea3e94409f
commit dda5c284b6
19527 changed files with 1135420 additions and 351004 deletions

View file

@ -0,0 +1,68 @@
/**
* Creates role with given permissions.
*
* @param {object} settings
* Settings object
* @param {array} settings.permissions
* The list of roles granted for the user.
* @param {string} [settings.name=null]
* The role name.
* @param {function} callback
* A callback which will be called, when creating the role is finished.
* @return {object}
* The drupalCreateRole command.
*/
exports.command = function drupalCreateRole(
{ permissions, name = null },
callback,
) {
const self = this;
const roleName =
name ||
Math.random()
.toString(36)
.substring(2, 15);
let machineName;
this.drupalLoginAsAdmin(() => {
this.drupalRelativeURL('/admin/people/roles/add')
.setValue('input[name="label"]', roleName)
// Wait for the machine name to appear so that it can be used later to
// select the permissions from the permission page.
.expect.element('.user-role-form .machine-name-value')
.to.be.visible.before(2000);
this.perform(done => {
this.getText('.user-role-form .machine-name-value', element => {
machineName = element.value;
done();
});
})
.submitForm('#user-role-form')
.drupalRelativeURL('/admin/people/permissions')
.perform((client, done) => {
Promise.all(
permissions.map(
permission =>
new Promise(resolve => {
client.click(
`input[name="${machineName}[${permission}]"]`,
() => {
resolve();
},
);
}),
),
).then(() => {
done();
});
})
.submitForm('#user-admin-permissions');
}).perform(() => {
if (typeof callback === 'function') {
callback.call(self, machineName);
}
});
return this;
};

View file

@ -0,0 +1,60 @@
/**
* Logs into Drupal as the given user.
*
* @param {object} settings
* Settings object
* @param {string} settings.name
* The user name.
* @param {string} settings.password
* The user password.
* @param {array} [settings.permissions=[]]
* The list of permissions granted for the user.
* @param {function} callback
* A callback which will be called, when the creating the use is finished.
* @return {object}
* The drupalCreateUser command.
*/
exports.command = function drupalCreateUser(
{ name, password, permissions = [] },
callback,
) {
const self = this;
let role;
this.perform((client, done) => {
if (permissions) {
client.drupalCreateRole({ permissions, name: null }, newRole => {
role = newRole;
done();
});
} else {
done();
}
}).drupalLoginAsAdmin(() => {
this.drupalRelativeURL('/admin/people/create')
.setValue('input[name="name"]', name)
.setValue('input[name="pass[pass1]"]', password)
.setValue('input[name="pass[pass2]"]', password)
.perform((client, done) => {
if (role) {
client.click(`input[name="roles[${role}]`, () => {
done();
});
} else {
done();
}
})
.submitForm('#user-register-form')
.assert.containsText(
'.messages',
'Created a new user account',
`User "${name}" was created succesfully.`,
);
});
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,57 @@
import { execSync } from 'child_process';
import { URL } from 'url';
import { commandAsWebserver } from '../globals';
/**
* Installs a Drupal test site.
*
* @param {oject} [settings={}]
* Settings object
* @param {string} [settings.setupFile='']
* Setup file used by TestSiteApplicationTest
* @param {function} callback
* A callback which will be called, when the installation is finished.
* @return {object}
* The 'browser' object.
*/
exports.command = function drupalInstall({ setupFile = '' } = {}, callback) {
const self = this;
try {
setupFile = setupFile ? `--setup-file "${setupFile}"` : '';
const dbOption =
process.env.DRUPAL_TEST_DB_URL.length > 0
? `--db-url ${process.env.DRUPAL_TEST_DB_URL}`
: '';
const install = execSync(
commandAsWebserver(
`php ./scripts/test-site.php install ${setupFile} --base-url ${
process.env.DRUPAL_TEST_BASE_URL
} ${dbOption} --json`,
),
);
const installData = JSON.parse(install.toString());
this.drupalDbPrefix = installData.db_prefix;
this.drupalSitePath = installData.site_path;
const url = new URL(process.env.DRUPAL_TEST_BASE_URL);
this.url(process.env.DRUPAL_TEST_BASE_URL).setCookie({
name: 'SIMPLETEST_USER_AGENT',
// Colons need to be URL encoded to be valid.
value: encodeURIComponent(installData.user_agent),
path: url.pathname,
domain: url.host,
});
} catch (error) {
this.assert.fail(error);
}
// Nightwatch doesn't like it when no actions are added in a command file.
// https://github.com/nightwatchjs/nightwatch/issues/1792
this.pause(1);
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,27 @@
/**
* Ends the browser session and logs the console log if there were any errors.
* See globals.js.
*
* @param {Object}
* (optional) Settings object
* @param onlyOnError
* (optional) Only writes out the console log file if the test failed.
* @param {function} callback
* A callback which will be called.
* @return {object}
* The 'browser' object.
*/
exports.command = function drupalLogAndEnd({ onlyOnError = true }, callback) {
const self = this;
this.drupalLogConsole = true;
this.drupalLogConsoleOnlyOnError = onlyOnError;
// Nightwatch doesn't like it when no actions are added in a command file.
// https://github.com/nightwatchjs/nightwatch/issues/1792
this.pause(1);
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,33 @@
/**
* Logs into Drupal as the given user.
*
* @param {string} name
* The user name.
* @param {string} password
* The user password.
* @return {object}
* The drupalUserIsLoggedIn command.
*/
exports.command = function drupalLogin({ name, password }) {
this.drupalUserIsLoggedIn(sessionExists => {
// Log the current user out if necessary.
if (sessionExists) {
this.drupalLogout();
}
// Log in with the given credentials.
this.drupalRelativeURL('/user/login')
.setValue('input[name="name"]', name)
.setValue('input[name="pass"]', password)
.submitForm('#user-login-form');
// Assert that a user is logged in.
this.drupalUserIsLoggedIn(sessionExists => {
this.assert.equal(
sessionExists,
true,
`The user "${name}" was logged in.`,
);
});
});
return this;
};

View file

@ -0,0 +1,43 @@
import { execSync } from 'child_process';
import { URL } from 'url';
import { commandAsWebserver } from '../globals';
/**
* Logs in as the admin user.
*
* @param {function} callback
* A callback which will allow running commands as an administrator.
* @return {object}
* The drupalLoginAsAdmin command.
*/
exports.command = function drupalLoginAsAdmin(callback) {
const self = this;
this.drupalUserIsLoggedIn(sessionExists => {
if (sessionExists) {
this.drupalLogout();
}
const userLink = execSync(
commandAsWebserver(
`php ./scripts/test-site.php user-login 1 --site-path ${
this.drupalSitePath
}`,
),
);
this.drupalRelativeURL(userLink.toString());
this.drupalUserIsLoggedIn(sessionExists => {
if (!sessionExists) {
throw new Error('Logging in as an admin user failed.');
}
});
});
if (typeof callback === 'function') {
callback.call(self);
}
this.drupalLogout({ silent: true });
return this;
};

View file

@ -0,0 +1,36 @@
import { execSync } from 'child_process';
import { URL } from 'url';
/**
* Logs out from a Drupal site.
*
* @param {object} [settings={}]
* The settings object.
* @param {boolean} [settings.silent=false]
* If the command should be run silently.
* @param {function} callback
* A callback which will be called, when the logout is finished.
* @return {object}
* The drupalLogout command.
*/
exports.command = function drupalLogout({ silent = false } = {}, callback) {
const self = this;
this.drupalRelativeURL('/user/logout');
this.drupalUserIsLoggedIn(sessionExists => {
if (silent) {
if (sessionExists) {
throw new Error('Logging out failed.');
}
} else {
this.assert.equal(sessionExists, false, 'The user was logged out.');
}
});
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,21 @@
/**
* Concatenate a DRUPAL_TEST_BASE_URL variable and a pathname.
*
* This provides a custom command, .relativeURL()
*
* @param {string} pathname
* The relative path to append to DRUPAL_TEST_BASE_URL
* @param {function} callback
* A callback which will be called.
* @return {object}
* The 'browser' object.
*/
exports.command = function drupalRelativeURL(pathname, callback) {
const self = this;
this.url(`${process.env.DRUPAL_TEST_BASE_URL}${pathname}`);
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,46 @@
import { execSync } from 'child_process';
import { commandAsWebserver } from '../globals';
/**
* Uninstalls a test Drupal site.
*
* @param {function} callback
* A callback which will be called, when the uninstallation is finished.
* @return {object}
* The 'browser' object.
*/
exports.command = function drupalUninstal(callback) {
const self = this;
const prefix = self.drupalDbPrefix;
// Check for any existing errors, because running this will cause Nightwatch to hang.
if (!this.currentTest.results.errors && !this.currentTest.results.failed) {
const dbOption =
process.env.DRUPAL_TEST_DB_URL.length > 0
? `--db-url ${process.env.DRUPAL_TEST_DB_URL}`
: '';
try {
if (!prefix || !prefix.length) {
throw new Error(
'Missing database prefix parameter, unable to uninstall Drupal (the initial install was probably unsuccessful).',
);
}
execSync(
commandAsWebserver(
`php ./scripts/test-site.php tear-down ${prefix} ${dbOption}`,
),
);
} catch (error) {
this.assert.fail(error);
}
}
// Nightwatch doesn't like it when no actions are added in a command file.
// https://github.com/nightwatchjs/nightwatch/issues/1792
this.pause(1);
if (typeof callback === 'function') {
callback.call(self);
}
return this;
};

View file

@ -0,0 +1,21 @@
/**
* Checks if a user is logged in.
*
* @param {function} callback
* A callback which will be called, when the login status has been checked.
* @return {object}
* The drupalUserIsLoggedIn command.
*/
exports.command = function drupalUserIsLoggedIn(callback) {
if (typeof callback === 'function') {
this.getCookies(cookies => {
const sessionExists = cookies.value.some(cookie =>
cookie.name.match(/^SESS/),
);
callback.call(this, sessionExists);
});
}
return this;
};

View file

@ -0,0 +1,18 @@
module.exports = {
'@tags': ['core'],
before(browser) {
browser.drupalInstall({
setupFile: 'core/tests/Drupal/TestSite/TestSiteInstallTestScript.php',
});
},
after(browser) {
browser.drupalUninstall();
},
'Test page': browser => {
browser
.drupalRelativeURL('/test-page')
.waitForElementVisible('body', 1000)
.assert.containsText('body', 'Test page text')
.drupalLogAndEnd({ onlyOnError: false });
},
};

View file

@ -0,0 +1,23 @@
module.exports = {
'@tags': ['core'],
before(browser) {
browser.drupalInstall();
},
after(browser) {
browser.drupalUninstall();
},
'Test login': browser => {
browser
.drupalCreateUser({
name: 'user',
password: '123',
permissions: ['access site reports'],
})
.drupalLogin({ name: 'user', password: '123' })
.drupalRelativeURL('/admin/reports')
.expect.element('h1.page-title')
.text.to.contain('Reports');
},
};

View file

@ -0,0 +1,23 @@
module.exports = {
'@tags': ['core'],
before(browser) {
browser.drupalInstall().drupalLoginAsAdmin(() => {
browser
.drupalRelativeURL('/admin/modules')
.setValue('input[type="search"]', 'FormAPI')
.waitForElementVisible('input[name="modules[form_test][enable]"]', 1000)
.click('input[name="modules[form_test][enable]"]')
.click('input[type="submit"]') // Submit module form.
.click('input[type="submit"]'); // Confirm installation of dependencies.
});
},
after(browser) {
browser.drupalUninstall();
},
'Test form with state API': browser => {
browser
.drupalRelativeURL('/form-test/javascript-states-form')
.waitForElementVisible('body', 1000)
.waitForElementNotVisible('input[name="textfield"]', 1000);
},
};

View file

@ -0,0 +1,66 @@
import { spawn } from 'child_process';
import path from 'path';
import fs from 'fs';
import mkdirp from 'mkdirp';
import chromedriver from 'chromedriver';
import nightwatchSettings from './nightwatch.conf';
const commandAsWebserver = command => {
if (process.env.DRUPAL_TEST_WEBSERVER_USER) {
return `sudo -u ${process.env.DRUPAL_TEST_WEBSERVER_USER} ${command}`;
}
return command;
};
module.exports = {
before: done => {
if (JSON.parse(process.env.DRUPAL_TEST_CHROMEDRIVER_AUTOSTART)) {
chromedriver.start();
}
done();
},
after: done => {
if (JSON.parse(process.env.DRUPAL_TEST_CHROMEDRIVER_AUTOSTART)) {
chromedriver.stop();
}
done();
},
afterEach: (browser, done) => {
// Writes the console log - used by the "logAndEnd" command.
if (
browser.drupalLogConsole &&
(!browser.drupalLogConsoleOnlyOnError ||
browser.currentTest.results.errors > 0 ||
browser.currentTest.results.failed > 0)
) {
const resultPath = path.join(
__dirname,
`../../../${nightwatchSettings.output_folder}/consoleLogs/${
browser.currentTest.module
}`,
);
const status =
browser.currentTest.results.errors > 0 ||
browser.currentTest.results.failed > 0
? 'FAILED'
: 'PASSED';
mkdirp.sync(resultPath);
const now = new Date().toString().replace(/[\s]+/g, '-');
const testName = (
browser.currentTest.name || browser.currentTest.module
).replace(/[\s/]+/g, '-');
browser
.getLog('browser', logEntries => {
const browserLog = JSON.stringify(logEntries, null, ' ');
fs.writeFileSync(
`${resultPath}/${testName}_${status}_${now}_console.json`,
browserLog,
);
})
.end(done);
} else {
browser.end(done);
}
},
commandAsWebserver,
};

View file

@ -0,0 +1,76 @@
import path from 'path';
import glob from 'glob';
// Find directories which have Nightwatch tests in them.
const regex = /(.*\/?tests\/?.*\/Nightwatch)\/.*/g;
const collectedFolders = {
Tests: [],
Commands: [],
Assertions: [],
};
const searchDirectory = process.env.DRUPAL_NIGHTWATCH_SEARCH_DIRECTORY || '';
glob
.sync('**/tests/**/Nightwatch/**/*.js', {
cwd: path.resolve(process.cwd(), `../${searchDirectory}`),
ignore: process.env.DRUPAL_NIGHTWATCH_IGNORE_DIRECTORIES
? process.env.DRUPAL_NIGHTWATCH_IGNORE_DIRECTORIES.split(',')
: [],
})
.forEach(file => {
let m = regex.exec(file);
while (m !== null) {
// This is necessary to avoid infinite loops with zero-width matches.
if (m.index === regex.lastIndex) {
regex.lastIndex += 1;
}
const key = `../${m[1]}`;
Object.keys(collectedFolders).forEach(folder => {
if (file.includes(`Nightwatch/${folder}`)) {
collectedFolders[folder].push(`${searchDirectory}${key}/${folder}`);
}
});
m = regex.exec(file);
}
});
// Remove duplicate folders.
Object.keys(collectedFolders).forEach(folder => {
collectedFolders[folder] = Array.from(new Set(collectedFolders[folder]));
});
module.exports = {
src_folders: collectedFolders.Tests,
output_folder: process.env.DRUPAL_NIGHTWATCH_OUTPUT,
custom_commands_path: collectedFolders.Commands,
custom_assertions_path: collectedFolders.Assertions,
page_objects_path: '',
globals_path: 'tests/Drupal/Nightwatch/globals.js',
selenium: {
start_process: false,
},
test_settings: {
default: {
selenium_port: process.env.DRUPAL_TEST_WEBDRIVER_PORT,
selenium_host: process.env.DRUPAL_TEST_WEBDRIVER_HOSTNAME,
default_path_prefix: process.env.DRUPAL_TEST_WEBDRIVER_PATH_PREFIX || '',
desiredCapabilities: {
browserName: 'chrome',
acceptSslCerts: true,
chromeOptions: {
args: process.env.DRUPAL_TEST_WEBDRIVER_CHROME_ARGS
? process.env.DRUPAL_TEST_WEBDRIVER_CHROME_ARGS.split(' ')
: [],
},
},
screenshots: {
enabled: true,
on_failure: true,
on_error: true,
path: `${process.env.DRUPAL_NIGHTWATCH_OUTPUT}/screenshots`,
},
end_session_on_fail: false,
},
},
};