playwright/utils/testrunner/Location.js
Dmitry Gozman 20ff327827
feat(testrunner): catch delegate errors (#1704)
This ensures we get a proper error when something goes wrong. Should
also help with producing the right error code in the case of internal error.

Drive-by: fix location issue which manifests on the bots.
Drive-by: remove the use of Array.prototype.flat to make it work on bots.
2020-04-07 22:56:21 -07:00

89 lines
2.4 KiB
JavaScript

/**
* Copyright 2017 Google Inc. All rights reserved.
* Modifications 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 path = require('path');
// Hack for our own tests.
const testRunnerTestFile = path.join(__dirname, 'test', 'testrunner.spec.js');
class Location {
constructor() {
this._fileName = '';
this._filePath = '';
this._lineNumber = 0;
this._columnNumber = 0;
}
fileName() {
return this._fileName;
}
filePath() {
return this._filePath;
}
lineNumber() {
return this._lineNumber;
}
columnNumber() {
return this._columnNumber;
}
toString() {
return this._fileName + ':' + this._lineNumber;
}
toDetailedString() {
return this._fileName + ':' + this._lineNumber + ':' + this._columnNumber;
}
static getCallerLocation(ignorePrefix = __dirname) {
const error = new Error();
const stackFrames = error.stack.split('\n').slice(1);
const location = new Location();
// Find first stackframe that doesn't point to this file.
for (let frame of stackFrames) {
frame = frame.trim();
if (!frame.startsWith('at '))
return null;
if (frame.endsWith(')')) {
const from = frame.indexOf('(');
frame = frame.substring(from + 1, frame.length - 1);
} else {
frame = frame.substring('at '.length);
}
const match = frame.match(/^(.*):(\d+):(\d+)$/);
if (!match)
return null;
const filePath = match[1];
if (filePath === __filename || (filePath.startsWith(ignorePrefix) && filePath !== testRunnerTestFile))
continue;
location._filePath = filePath;
location._fileName = filePath.split(path.sep).pop();
location._lineNumber = parseInt(match[2], 10);
location._columnNumber = parseInt(match[3], 10);
return location;
}
return location;
}
}
module.exports = Location;