mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[ftr] default window size (#14834)
* [ftr/mocha] revert Mocha UI assigments after loading test files * [ftr] add beforeTopLevelSuite and afterTopLevelSuite lifecycle hooks * [ftr] add defaultWindowWidth and defaultWindowHeight options Adds two configuration parameters to the functional test runner which will set the windowSize before running the tests in any file and restores the original window size when the tests complete. Individual test files can set the windowSize within its own before() or beforeEach() handlers using the same `command.setWindowSize()` command. * [ftr/assignmentProxy] use better naming * [ftr] restore initial window size after each suite * [ftr] improve error message for unexpected suite definitions * [ftr/remote] remove configuration option, rely on suite-level changes * [ftr] fix stack manipulation order * [ftr/remote] write tests for window size management
This commit is contained in:
parent
8f1aa33604
commit
60298ec8b2
11 changed files with 249 additions and 2 deletions
|
@ -2,7 +2,9 @@ export function createLifecycle() {
|
|||
const listeners = {
|
||||
beforeLoadTests: [],
|
||||
beforeTests: [],
|
||||
beforeTestSuite: [],
|
||||
beforeEachTest: [],
|
||||
afterTestSuite: [],
|
||||
testFailure: [],
|
||||
testHookFailure: [],
|
||||
cleanup: [],
|
||||
|
|
|
@ -1,7 +1,25 @@
|
|||
export function createAssignmentProxy(object, interceptor) {
|
||||
const originalValues = new Map();
|
||||
|
||||
return new Proxy(object, {
|
||||
set(target, property, value) {
|
||||
if (!originalValues.has(property)) {
|
||||
originalValues.set(property, object[property]);
|
||||
}
|
||||
|
||||
return Reflect.set(target, property, interceptor(property, value));
|
||||
},
|
||||
|
||||
get(target, property) {
|
||||
if (property === 'revertProxiedAssignments') {
|
||||
return function () {
|
||||
for (const [property, value] of originalValues) {
|
||||
object[property] = value;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return Reflect.get(target, property);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ export function decorateMochaUi(lifecycle, context) {
|
|||
*/
|
||||
function wrapSuiteFunction(name, fn) {
|
||||
return wrapFunction(fn, {
|
||||
before() {
|
||||
before(target, thisArg, argumentsList) {
|
||||
if (suiteCount > 0 && suiteLevel === 0) {
|
||||
throw new Error(`
|
||||
Test files must only define a single top-level suite. Please ensure that
|
||||
|
@ -32,6 +32,23 @@ export function decorateMochaUi(lifecycle, context) {
|
|||
`);
|
||||
}
|
||||
|
||||
const [name, provider] = argumentsList;
|
||||
if (typeof name !== 'string' || typeof provider !== 'function') {
|
||||
throw new Error(`Unexpected arguments to ${name}(${argumentsList.join(', ')})`);
|
||||
}
|
||||
|
||||
argumentsList[1] = function () {
|
||||
before(async () => {
|
||||
await lifecycle.trigger('beforeTestSuite', this);
|
||||
});
|
||||
|
||||
provider.call(this);
|
||||
|
||||
after(async () => {
|
||||
await lifecycle.trigger('afterTestSuite', this);
|
||||
});
|
||||
};
|
||||
|
||||
suiteCount += 1;
|
||||
suiteLevel += 1;
|
||||
},
|
||||
|
|
|
@ -38,7 +38,8 @@ export const loadTestFiles = (mocha, log, lifecycle, providers, paths) => {
|
|||
loadTracer(provider, `testProvider[${path}]`, () => {
|
||||
// mocha.suite hocus-pocus comes from: https://git.io/vDnXO
|
||||
|
||||
mocha.suite.emit('pre-require', decorateMochaUi(lifecycle, global), path, mocha);
|
||||
const context = decorateMochaUi(lifecycle, global);
|
||||
mocha.suite.emit('pre-require', context, path, mocha);
|
||||
|
||||
const returnVal = provider({
|
||||
loadTestFile: innerLoadTestFile,
|
||||
|
@ -53,6 +54,7 @@ export const loadTestFiles = (mocha, log, lifecycle, providers, paths) => {
|
|||
|
||||
mocha.suite.emit('require', returnVal, path, mocha);
|
||||
mocha.suite.emit('post-require', global, path, mocha);
|
||||
context.revertProxiedAssignments();
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import { RemoteProvider } from '../../../remote';
|
||||
|
||||
export default function () {
|
||||
return {
|
||||
testFiles: [
|
||||
require.resolve('./test'),
|
||||
],
|
||||
services: {
|
||||
remote: RemoteProvider
|
||||
}
|
||||
};
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
export default function ({ getService, loadTestFile }) {
|
||||
const remote = getService('remote');
|
||||
|
||||
describe('suite1', () => {
|
||||
before(async () => {
|
||||
process.send({
|
||||
name: 'before suite1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
|
||||
await remote.setWindowSize(1000, 1000);
|
||||
});
|
||||
|
||||
it('has the right window size', async () => {
|
||||
process.send({
|
||||
name: 'in suite1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./test2'));
|
||||
loadTestFile(require.resolve('./test3'));
|
||||
|
||||
after(async () => {
|
||||
process.send({
|
||||
name: 'after suite1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
export default function ({ getService }) {
|
||||
const remote = getService('remote');
|
||||
|
||||
describe('suite2', () => {
|
||||
before(async () => {
|
||||
process.send({
|
||||
name: 'before suite2',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
|
||||
await remote.setWindowSize(900, 900);
|
||||
});
|
||||
|
||||
it('has the right window size', async () => {
|
||||
process.send({
|
||||
name: 'in suite2',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
process.send({
|
||||
name: 'after suite2',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
export default function ({ getService }) {
|
||||
const remote = getService('remote');
|
||||
|
||||
describe('suite3.1', () => {
|
||||
before(async () => {
|
||||
process.send({
|
||||
name: 'before suite3.1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
|
||||
await remote.setWindowSize(700, 700);
|
||||
});
|
||||
|
||||
it('has the right window size', async () => {
|
||||
process.send({
|
||||
name: 'in suite3.1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
process.send({
|
||||
name: 'after suite3.1',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
export default function ({ getService, loadTestFile }) {
|
||||
const remote = getService('remote');
|
||||
|
||||
describe('suite3', () => {
|
||||
before(async () => {
|
||||
process.send({
|
||||
name: 'before suite3',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
|
||||
await remote.setWindowSize(800, 800);
|
||||
});
|
||||
|
||||
it('has the right window size', async () => {
|
||||
process.send({
|
||||
name: 'in suite3',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
|
||||
loadTestFile(require.resolve('./test3.1'));
|
||||
|
||||
after(async () => {
|
||||
process.send({
|
||||
name: 'after suite3',
|
||||
size: await remote.getWindowSize()
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
import { fork } from 'child_process';
|
||||
|
||||
import expect from 'expect.js';
|
||||
|
||||
const FTR_SCRIPT = require.resolve('../../../../../scripts/functional_test_runner');
|
||||
const CONFIG_PATH = require.resolve('./fixtures/several_nested_window_size_changes/config.js');
|
||||
const SECOND = 1000;
|
||||
|
||||
const DEFAULT_SIZE = { width: 1600, height: 1000 };
|
||||
const SUITE1_SIZE = { width: 1000, height: 1000 };
|
||||
const SUITE2_SIZE = { width: 900, height: 900 };
|
||||
const SUITE3_SIZE = { width: 800, height: 800 };
|
||||
const SUITE31_SIZE = { width: 700, height: 700 };
|
||||
|
||||
describe('remote default window size', function () {
|
||||
// give the tests some time to initialize the FTR and Chrome
|
||||
this.timeout(30 * SECOND);
|
||||
|
||||
it('restores the window size after a suite completes', async () => {
|
||||
const proc = fork(FTR_SCRIPT, [
|
||||
'--config', CONFIG_PATH
|
||||
], {
|
||||
silent: true
|
||||
});
|
||||
|
||||
const messages = [];
|
||||
proc.on('message', (msg) => {
|
||||
messages.push(msg);
|
||||
});
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
proc.once('exit', resolve);
|
||||
proc.once('error', reject);
|
||||
});
|
||||
|
||||
expect(messages).to.eql([
|
||||
// default width/height
|
||||
{ name: 'before suite1', size: DEFAULT_SIZE },
|
||||
// suite1 uses 1000X1000
|
||||
{ name: 'in suite1', size: SUITE1_SIZE },
|
||||
// suite2 should start with suite1's size
|
||||
{ name: 'before suite2', size: SUITE1_SIZE },
|
||||
// but it changes it to 900X900
|
||||
{ name: 'in suite2', size: SUITE2_SIZE },
|
||||
// and it should still be 900X900 when it ends
|
||||
{ name: 'after suite2', size: SUITE2_SIZE },
|
||||
// suite3 should then start with suite1's size, because suite2's was rolled back
|
||||
{ name: 'before suite3', size: SUITE1_SIZE },
|
||||
// it then runs in 800x800
|
||||
{ name: 'in suite3', size: SUITE3_SIZE },
|
||||
// suite3.1 runs within 3, so it should start with suite3 size
|
||||
{ name: 'before suite3.1', size: SUITE3_SIZE },
|
||||
// then switch to its 700x700 size
|
||||
{ name: 'in suite3.1', size: SUITE31_SIZE },
|
||||
// and still has 800x800 in it's last after hook
|
||||
{ name: 'after suite3.1', size: SUITE31_SIZE },
|
||||
// but suite3 size should be restored before running suite3's after hook
|
||||
{ name: 'after suite3', size: SUITE3_SIZE },
|
||||
// then finally, suite1 should complete with 1000X1000 because suite3's size was rolled back
|
||||
{ name: 'after suite1', size: SUITE1_SIZE }
|
||||
]);
|
||||
});
|
||||
});
|
|
@ -17,6 +17,22 @@ export async function RemoteProvider({ getService }) {
|
|||
|
||||
log.info('Remote initialized');
|
||||
|
||||
lifecycle.on('beforeTests', async () => {
|
||||
// hard coded default, can be overriden per suite using `remote.setWindowSize()`
|
||||
// and will be automatically reverted after each suite
|
||||
await command.setWindowSize(1600, 1000);
|
||||
});
|
||||
|
||||
const windowSizeStack = [];
|
||||
lifecycle.on('beforeTestSuite', async () => {
|
||||
windowSizeStack.unshift(await command.getWindowSize());
|
||||
});
|
||||
|
||||
lifecycle.on('afterTestSuite', async () => {
|
||||
const { width, height } = windowSizeStack.shift();
|
||||
await command.setWindowSize(width, height);
|
||||
});
|
||||
|
||||
return new Proxy({}, {
|
||||
get(obj, prop) {
|
||||
if (prop === 'then' || prop === 'catch' || prop === 'finally') {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue