feat(testrunner): implement "dit" command (#312)

This commit is contained in:
Andrey Lushnikov 2019-12-19 15:47:35 -08:00 committed by Yury Semikhatsky
parent 12ac458614
commit a7f3490e48
43 changed files with 92 additions and 65 deletions

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, headless, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Browser.process', function() {

View file

@ -19,7 +19,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, playwright, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('BrowserContext', function() {

View file

@ -3,7 +3,7 @@
module.exports.describe = function({testRunner, expect, headless, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('CrBrowser', function() {

View file

@ -18,7 +18,7 @@ const { waitEvent } = require('../utils');
module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Chromium', function() {

View file

@ -19,7 +19,7 @@ const utils = require('../utils');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Playwright.connect', function() {

View file

@ -16,7 +16,7 @@
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('JSCoverage', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function ({ testRunner, expect }) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
// FIXME: not supported in WebKit (as well as Emulation domain in general).

View file

@ -26,7 +26,7 @@ const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
module.exports.describe = function({testRunner, expect, playwright, defaultBrowserOptions, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
const headfulOptions = Object.assign({}, defaultBrowserOptions, {

View file

@ -28,7 +28,7 @@ const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, WIN}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('CrPlaywright', function() {

View file

@ -16,7 +16,7 @@
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('OOPIF', function() {

View file

@ -19,7 +19,7 @@ const path = require('path');
module.exports.describe = function({testRunner, expect, headless, ASSETS_DIR}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
// Printing to pdf is currently only supported in headless

View file

@ -18,7 +18,7 @@ const { waitEvent } = require('../utils');
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Chromium.createCDPSession', function() {

View file

@ -19,7 +19,7 @@ const path = require('path');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, ASSETS_DIR}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Chromium.startTracing', function() {

View file

@ -20,7 +20,7 @@ const { waitEvent } = utils;
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Workers', function() {

View file

@ -19,7 +19,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.click', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('BrowserContext.cookies', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function ({ testRunner, expect, defaultBrowserOptions, playwright }) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('defaultContext()', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.Events.Dialog', function() {

View file

@ -19,7 +19,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('ElementHandle.boundingBox', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
const iPhone = playwright.devices['iPhone 6'];
const iPhoneLandscape = playwright.devices['iPhone 6 landscape'];

View file

@ -21,7 +21,7 @@ const bigint = typeof BigInt !== 'undefined';
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.evaluate', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe.skip(WEBKIT)('Accessibility', function() {

View file

@ -21,7 +21,7 @@ const utils = require('../utils');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Interception.enable', function() {

View file

@ -20,7 +20,7 @@ const path = require('path');
module.exports.describe = function({testRunner, expect, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
// Permissions API is not implemented in WebKit (see https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)

View file

@ -24,7 +24,7 @@ const TMP_FOLDER = path.join(os.tmpdir(), 'pptr_tmp_folder-');
module.exports.describe = function ({ testRunner, expect, defaultBrowserOptions, playwright }) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('FFPlaywright', function() {

View file

@ -19,7 +19,7 @@ const path = require('path');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, playwrightPath, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe.skip(WEBKIT)('Fixtures', function() {

View file

@ -19,7 +19,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Frame.evaluateHandle', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('ignoreHTTPSErrors', function() {
it('should work', async({newPage, httpsServer}) => {

View file

@ -21,7 +21,7 @@ const FILE_TO_UPLOAD = path.join(__dirname, '/assets/file-to-upload.txt');
module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('input', function() {
it('should upload the file', async({page, server}) => {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, CHROME, FFOX, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.evaluateHandle', function() {

View file

@ -20,7 +20,7 @@ const os = require('os');
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT, MAC}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Keyboard', function() {

View file

@ -25,7 +25,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, defaultBrowserOptions, playwright, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Playwright', function() {

View file

@ -28,7 +28,7 @@ function dimensions() {
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT, MAC}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Mouse', function() {

View file

@ -20,7 +20,7 @@ const { performance } = require('perf_hooks');
module.exports.describe = function({testRunner, expect, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.goto', function() {

View file

@ -21,7 +21,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.Events.Request', function() {

View file

@ -21,7 +21,7 @@ const {waitEvent} = utils;
module.exports.describe = function({testRunner, expect, headless, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.close', function() {

View file

@ -26,7 +26,7 @@ const RESET_COLOR = '\x1b[0m';
module.exports.describe = ({testRunner, product, playwrightPath}) => {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
const CHROME = product === 'Chromium';

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, product, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.$eval', function() {

View file

@ -17,7 +17,7 @@
module.exports.describe = function({testRunner, expect, product, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.screenshot', function() {

View file

@ -19,7 +19,7 @@ const utils = require('./utils');
module.exports.describe = function({testRunner, expect, product, playwright, FFOX, CHROME, WEBKIT}) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('Page.waitFor', function() {

View file

@ -25,7 +25,7 @@ const utils = require('../utils');
module.exports.describe = function ({ testRunner, expect, playwright }) {
const {describe, xdescribe, fdescribe} = testRunner;
const {it, fit, xit} = testRunner;
const {it, fit, xit, dit} = testRunner;
const {beforeAll, beforeEach, afterAll, afterEach} = testRunner;
describe('WKPlaywright', function() {

View file

@ -14,9 +14,17 @@
* limitations under the License.
*/
const util = require('util');
const url = require('url');
const inspector = require('inspector');
const path = require('path');
const EventEmitter = require('events');
const Multimap = require('./Multimap');
const fs = require('fs');
const INFINITE_TIMEOUT = 2147483647;
const readFileAsync = util.promisify(fs.readFile.bind(fs));
const TimeoutError = new Error('Timeout');
const TerminatedError = new Error('Terminated');
@ -71,8 +79,8 @@ class UserCallback {
if (!match)
return null;
const filePath = match[1];
const lineNumber = match[2];
const columnNumber = match[3];
const lineNumber = parseInt(match[2], 10);
const columnNumber = parseInt(match[3], 10);
if (filePath === __filename)
continue;
const fileName = filePath.split(path.sep).pop();
@ -294,18 +302,17 @@ class TestRunner extends EventEmitter {
this._rootSuite = new Suite(null, '', TestMode.Run);
this._currentSuite = this._rootSuite;
this._tests = [];
this._timeout = timeout === 0 ? 2147483647 : timeout;
this._timeout = timeout === 0 ? INFINITE_TIMEOUT : timeout;
this._parallel = parallel;
this._breakOnFailure = breakOnFailure;
this._hasFocusedTestsOrSuites = false;
if (MAJOR_NODEJS_VERSION >= 8 && disableTimeoutWhenInspectorIsEnabled) {
const inspector = require('inspector');
if (inspector.url()) {
console.log('TestRunner detected inspector; overriding certain properties to be debugger-friendly');
console.log(' - timeout = 0 (Infinite)');
this._timeout = 2147483647;
this._timeout = INFINITE_TIMEOUT;
}
}
@ -317,13 +324,22 @@ class TestRunner extends EventEmitter {
this.xdescribe = this._addSuite.bind(this, TestMode.Skip);
this.xdescribe.skip = () => this.xdescribe; // no-op
this.it = this._addTest.bind(this, TestMode.Run);
this.it = (name, callback) => void this._addTest(name, callback, TestMode.Run, this._timeout);
this.it.skip = condition => condition ? this.xit : this.it;
this.fit = this._addTest.bind(this, TestMode.Focus);
this.fit = (name, callback) => void this._addTest(name, callback, TestMode.Focus, this._timeout);
this.fit.skip = () => this.fit; // no-op
this.xit = this._addTest.bind(this, TestMode.Skip);
this.xit = (name, callback) => void this._addTest(name, callback, TestMode.Skip, this._timeout);
this.xit.skip = () => this.xit; // no-op
this._debuggerLogBreakpointLines = new Multimap();
this.dit = (name, callback) => {
const test = this._addTest(name, callback, TestMode.Focus, INFINITE_TIMEOUT);
const N = callback.toString().split('\n').length;
for (let i = 0; i < N; ++i)
this._debuggerLogBreakpointLines.set(test.location.filePath, i + test.location.lineNumber);
};
this.dit.skip = () => this.dit; // no-op;
this.beforeAll = this._addHook.bind(this, 'beforeAll');
this.beforeEach = this._addHook.bind(this, 'beforeEach');
this.afterAll = this._addHook.bind(this, 'afterAll');
@ -339,15 +355,16 @@ class TestRunner extends EventEmitter {
this._addSuite(TestMode.Skip, '', module.xdescribe, ...args);
}
_addTest(mode, name, callback) {
_addTest(name, callback, mode, timeout) {
let suite = this._currentSuite;
let isSkipped = suite.declaredMode === TestMode.Skip;
while ((suite = suite.parentSuite))
isSkipped |= suite.declaredMode === TestMode.Skip;
const test = new Test(this._currentSuite, name, callback, isSkipped ? TestMode.Skip : mode, this._timeout);
const test = new Test(this._currentSuite, name, callback, isSkipped ? TestMode.Skip : mode, timeout);
this._currentSuite.children.push(test);
this._tests.push(test);
this._hasFocusedTestsOrSuites = this._hasFocusedTestsOrSuites || mode === TestMode.Focus;
return test;
}
_addSuite(mode, name, callback, ...args) {
@ -367,6 +384,7 @@ class TestRunner extends EventEmitter {
}
async run() {
let session = this._debuggerLogBreakpointLines.size ? await setLogBreakpoints(this._debuggerLogBreakpointLines) : null;
const runnableTests = this._runnableTests();
this.emit(TestRunner.Events.Started, runnableTests);
this._runningPass = new TestPass(this, this._rootSuite, runnableTests, this._parallel, this._breakOnFailure);
@ -381,6 +399,8 @@ class TestRunner extends EventEmitter {
result.result = this.failedTests().length ? TestResult.Failed : TestResult.Ok;
}
this.emit(TestRunner.Events.Finished, result);
if (session)
session.disconnect();
return result;
}
@ -458,6 +478,27 @@ class TestRunner extends EventEmitter {
}
}
async function setLogBreakpoints(debuggerLogBreakpoints) {
const session = new inspector.Session();
session.connect();
const postAsync = util.promisify(session.post.bind(session));
await postAsync('Debugger.enable');
const setBreakpointCommands = [];
for (const filePath of debuggerLogBreakpoints.keysArray()) {
const lineNumbers = debuggerLogBreakpoints.get(filePath);
const lines = (await readFileAsync(filePath, 'utf8')).split('\n');
for (const lineNumber of lineNumbers) {
setBreakpointCommands.push(postAsync('Debugger.setBreakpointByUrl', {
url: url.pathToFileURL(filePath),
lineNumber,
condition: `console.log('${String(lineNumber + 1).padStart(6, ' ')} | ' + ${JSON.stringify(lines[lineNumber])})`,
}).catch(e => {}));
};
}
await Promise.all(setBreakpointCommands);
return session;
}
/**
* @param {*} value
* @param {string=} message

View file

@ -381,20 +381,6 @@ module.exports.addTests = function({testRunner, expect}) {
await t.run();
expect(log.join()).toBe('1,2,3,4');
});
it('should support async test suites', async() => {
const log = [];
const t = new TestRunner();
t.it('uno', () => log.push(1));
await t.describe('suite1', async() => {
await Promise.resolve();
t.it('dos', () => log.push(2));
await Promise.resolve();
t.it('tres', () => log.push(3));
});
t.it('cuatro', () => log.push(4));
await t.run();
expect(log.join()).toBe('1,2,3,4');
});
});
describe('TestRunner.run result', () => {