test: add support for mocha (#3376)

This commit is contained in:
Pavel Feldman 2020-08-10 20:10:39 -07:00 committed by GitHub
parent 7580360f59
commit 823ef86470
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 2260 additions and 1793 deletions

3764
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -80,6 +80,7 @@
"jest": "^26.2.2",
"jest-circus": "^26.2.2",
"jest-image-snapshot": "^4.0.2",
"mocha": "^8.1.1",
"ncp": "^2.0.0",
"node-stream-zip": "^1.8.2",
"pirates": "^4.0.1",

View file

@ -1,20 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`should work with complicated usecases 1`] = `
"[
{
\\"url\\": \\"http://localhost:<PORT>/csscoverage/involved.html\\",
\\"ranges\\": [
{
\\"start\\": 149,
\\"end\\": 297
},
{
\\"start\\": 327,
\\"end\\": 433
}
],
\\"text\\": \\"\\\\n@charset \\\\\\"utf-8\\\\\\";\\\\n@namespace svg url(http://www.w3.org/2000/svg);\\\\n@font-face {\\\\n font-family: \\\\\\"Example Font\\\\\\";\\\\n src: url(\\\\\\"./Dosis-Regular.ttf\\\\\\");\\\\n}\\\\n\\\\n#fluffy {\\\\n border: 1px solid black;\\\\n z-index: 1;\\\\n /* -webkit-disabled-property: rgb(1, 2, 3) */\\\\n -lol-cats: \\\\\\"dogs\\\\\\" /* non-existing property */\\\\n}\\\\n\\\\n@media (min-width: 1px) {\\\\n span {\\\\n -webkit-border-radius: 10px;\\\\n font-family: \\\\\\"Example Font\\\\\\";\\\\n animation: 1s identifier;\\\\n }\\\\n}\\\\n\\"
}
]"
`;

View file

@ -72,8 +72,25 @@ it.skip(!CHROMIUM)('should work with media queries', async function({page, serve
it.skip(!CHROMIUM)('should work with complicated usecases', async function({page, server}) {
await page.coverage.startCSSCoverage();
await page.goto(server.PREFIX + '/csscoverage/involved.html');
const coverage = await page.coverage.stopCSSCoverage();
expect(JSON.stringify(coverage, null, 2).replace(/:\d{4}\//g, ':<PORT>/')).toMatchSnapshot();
const coverage: any = await page.coverage.stopCSSCoverage();
delete coverage[0].text;
delete coverage[0].url;
expect(coverage).toEqual(
[
{
"ranges": [
{
"start": 149,
"end": 297
},
{
"start": 327,
"end": 433
}
]
}
]
);
});
it.skip(!CHROMIUM)('should ignore injected stylesheets', async function({page, server}) {

View file

@ -117,6 +117,8 @@ class FixturePool {
}
wrapTestCallback(callback) {
if (!callback)
return callback;
return async() => {
try {
return await this.resolveParametersAndRun(callback);

View file

@ -15,7 +15,6 @@
*/
const colors = require('colors/safe');
const { runTestsByPath } = require('../../jest.config');
const failures = [];
module.exports = function Reporter() {

51
test/mocha/dot.js Normal file
View file

@ -0,0 +1,51 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const Base = require('mocha/lib/reporters/base');
const constants = require('mocha/lib/runner').constants;
const colors = require('colors/safe');
class Dot extends Base {
constructor(runner, options) {
super(runner, options);
runner.on(constants.EVENT_RUN_BEGIN, () => {
process.stdout.write('\n');
});
runner.on(constants.EVENT_TEST_PENDING, test => {
process.stdout.write(colors.yellow('\u00B7'))
});
runner.on(constants.EVENT_TEST_PASS, () => {
process.stdout.write(colors.green('\u00B7'));
});
runner.on(constants.EVENT_TEST_FAIL, test => {
if (test.duration >= test.timeout())
process.stdout.write(colors.red('T'));
else
process.stdout.write(colors.red('F'));
});
runner.once(constants.EVENT_RUN_END, () => {
process.stdout.write('\n');
this.epilogue();
});
}
}
module.exports = Dot;

134
test/mocha/fixturesUI.js Normal file
View file

@ -0,0 +1,134 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const { FixturePool, registerFixture, registerWorkerFixture } = require('../harness/fixturePool');
const { Test, Suite } = require('mocha');
const pirates = require('pirates');
const babel = require('@babel/core');
const commonSuite = require('mocha/lib/interfaces/common');
Error.stackTraceLimit = 15;
global.testOptions = require('../harness/testOptions');
global.registerFixture = registerFixture;
global.registerWorkerFixture = registerWorkerFixture;
process.env.JEST_WORKER_ID = 1;
const fixturePool = new FixturePool();
let revertBabelRequire;
function fixturesUI(suite) {
const suites = [suite];
suite.on(Suite.constants.EVENT_FILE_PRE_REQUIRE, function(context, file, mocha) {
const common = commonSuite(suites, context, mocha);
context.beforeEach = common.beforeEach;
context.afterEach = common.afterEach;
fixturePool.patchToEnableFixtures(context, 'beforeEach');
fixturePool.patchToEnableFixtures(context, 'afterEach');
context.run = mocha.options.delay && common.runWithSuite(suite);
context.describe = (title, fn) => {
return common.suite.create({
title: title,
file: file,
fn: fn
});
};
context.xdescribe = (title, fn) => {
return common.suite.skip({
title: title,
file: file,
fn: fn
});
};
context.describe.skip = function(condition) {
return condition ? context.xdescribe : context.describe;
};
context.describe.only = (title, fn) => {
return common.suite.only({
title: title,
file: file,
fn: fn
});
};
context.fdescribe = context.describe.only;
context.it = context.specify = function(title, fn) {
const suite = suites[0];
if (suite.isPending()) {
fn = null;
}
const wrapped = fixturePool.wrapTestCallback(fn);
const wrapper = wrapped ? (done, ...args) => {
wrapped(...args).then(done).catch(done);
} : undefined;
const test = new Test(title, wrapper);
test.file = file;
suite.addTest(test);
return test;
};
context.it.only = function(title, fn) {
return common.test.only(mocha, context.it(title, fn));
};
context.fit = context.it.only;
context.xit = function(title) {
return context.it(title);
};
context.it.skip = function(condition) {
return condition ? context.xit : context.it;
};
context.it.fail = function(condition) {
return condition ? context.xit : context.it;
};
context.it.slow = function(condition) {
return context.it;
};
context.it.retries = function(n) {
context.retries(n);
};
revertBabelRequire = pirates.addHook((code, filename) => {
const result = babel.transformFileSync(filename, {
presets: [
['@babel/preset-env', {targets: {node: 'current'}}],
'@babel/preset-typescript']
});
return result.code;
}, {
exts: ['.ts']
});
});
suite.on(Suite.constants.EVENT_FILE_POST_REQUIRE, function(context, file, mocha) {
revertBabelRequire();
});
};
module.exports = { fixturesUI, fixturePool, registerFixture, registerWorkerFixture };

51
test/mocha/index.js Normal file
View file

@ -0,0 +1,51 @@
/**
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const fs = require('fs');
const path = require('path');
const Mocha = require('mocha');
const { fixturesUI, fixturePool } = require('./fixturesUI');
const dot = require('./dot');
const { Matchers } = require('../../utils/testrunner/Matchers');
const browserName = process.env.BROWSER || 'chromium';
const goldenPath = path.join(__dirname, '..', 'golden-' + browserName);
const outputPath = path.join(__dirname, '..', 'output-' + browserName);
global.expect = new Matchers({ goldenPath, outputPath }).expect;
global.testOptions = require('../harness/testOptions');
const mocha = new Mocha({
ui: fixturesUI,
reporter: dot,
timeout: 10000,
});
const testDir = path.join(process.cwd(), 'test');
const filter = process.argv[2];
fs.readdirSync(testDir).filter(function(file) {
return file.includes('.spec.') && (!filter || file.includes(filter));
}).forEach(function(file) {
mocha.addFile(path.join(testDir, file));
});
const runner = mocha.run((failures) => {
process.exitCode = failures ? 1 : 0;
});
const constants = Mocha.Runner.constants;
runner.on(constants.EVENT_RUN_END, test => {
fixturePool.teardownScope('worker');
});

View file

@ -22,7 +22,6 @@ const pirates = require('pirates');
const babel = require('@babel/core');
const TestRunner = require('../../utils/testrunner');
const { FixturePool, registerFixture, registerWorkerFixture } = require('../harness/fixturePool');
const testOptions = require('../harness/testOptions');
Error.stackTraceLimit = 15;
global.testOptions = require('../harness/testOptions');

View file

@ -100,7 +100,12 @@ class Matchers {
outputPath: config.outputPath,
goldenName
});
}
},
toMatch: function(received, other, message) {
message = message || `${received}`;
return { pass: received.match(other), message };
}
}
}