Testcafe V1.9.0 UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
Testcafe V1.9.0 UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
我正在失去理智,试图弄清楚为什么 testcafe 如此痛苦。所以这是我的场景:
我有一个跑步者可以启动我对 browserstack 的测试。美好的。一旦我将 testcafe 版本从 1.6.1 升级到 1.9.0,browserstack runner 就无法启动。我收到此错误:
(node:12310) UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
at Function.entries (<anonymous>)
at TestCafeConfiguration.mergeOptions (/Users/testcafe/node_modules/testcafe/lib/configuration/configuration-base.js:50:16)
at TestCafeConfiguration.init (/Users/testcafe/node_modules/testcafe/lib/configuration/testcafe-configuration.js:48:14)
at async getConfiguration (/Users/testcafe/node_modules/testcafe/lib/index.js:41:9)
at async createTestCafe (/Users/testcafe/node_modules/testcafe/lib/index.js:57:27)
(node:12310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12310) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
奇怪的是,如果我将我的版本升级到 1.7.0,我没有遇到任何问题。任何版本 1.8.0 及以上我都会收到上述错误。
有人也遇到过这种情况吗?有人可以阐明这个问题吗?
这是我的跑步者SetupRunners.js文件:
import getRunnerSrc from "./getRunnerSrc";
import getRunnerBrowsers from "./getRunnerBrowsers";
export default function setupRunner(runner, options = {}, cb) {
let stream = false;
const src = options.src || getRunnerSrc(options.breakpoint);
if (src && src.length) {
runner.src(src);
runner.browsers(
options.browsers || getRunnerBrowsers(options.breakpoint)
);
return cb(runner).then(data => {
if (stream) {
stream.end();
}
return data;
});
}
}
这是针对 browserstack 启动测试的文件
import getArgs from "./getArgs";
import sanitizeArg from "./sanitizeArg";
import isBrowserStack from "./getIsBrowserStack";
const defaultBrowsers = {
desktop: "Chrome:OS X",
mobile: "Safari:iOS",
};
const browserStackPrefix = "browserstack:";
export default function getRunnerBrowsers(breakpoint) {
const useBrowserStack = isBrowserStack();
if (useBrowserStack && breakpoint) {
return getBrowserstackDevices(breakpoint);
}
return `${useBrowserStack ? browserStackPrefix : ""}${sanitizeArg(
getArgs("browsers") || defaultBrowsers.desktop
)}`;
}
function getBrowserstackDevices(breakpoint) {
return `${browserStackPrefix}${getArgs(`${breakpoint}_devices`) ||
defaultBrowsers[breakpoint]}`;
}
帮手来了getArgs.js:
function getArgs(key) {
if (process && process.argv && process.argv.length) {
return process.argv.reduce((val, arg) => {
const split = arg.split("=");
if (split[0] === key || split[0] === "--" + key) {
val = split[1];
}
return val;
}, null);
}
return null;
}
module.exports = getArgs;
和santizeArgs.js
export default function sanitizeArg(ar) {
return filterEmpty((ar || "").split(",").map(str => str.trim()));
}
export function filterEmpty(items) {
return items.filter(item => item && item.length);
}
=======更新========
在 v1.7.0 中创建 TESTCAFE 函数
async function createTestCafe(hostname, port1, port2, sslOptions, developmentMode, retryTestPages) {
console.dir
const configuration = new testcafe_configuration_1.default();
await configuration.init({
hostname,
port1,
port2,
ssl: sslOptions,
developmentMode,
retryTestPages
});
将 TESTCAFE 更新到 v1.9.2 后创建 TESTCAFE 函数
async function createTestCafe(...args) {
const configuration = await getConfiguration(args); // HERE IS WHERE THE ERROR IS
const [hostname, port1, port2] = await Promise.all([
getValidHostname(configuration.getOption(option_names_1.default.hostname)),
getValidPort(configuration.getOption(option_names_1.default.port1)),
getValidPort(configuration.getOption(option_names_1.default.port2))
]);
configuration.mergeOptions({ hostname, port1, port2 });
const testcafe = new TestCafe(configuration);
setupExitHook(cb => testcafe.close().then(cb));
return testcafe;
}
我根据您的信息重现了该问题,并在 TestCafe GitHub 存储库中创建了一个 issue。作为解决方法,您可以更正传递给 'createTestCafe' 函数的参数值。
根据您共享的输出,您将 'null' 值作为 'hostname' 参数传递。我猜 'null' 值意味着未指定 'hostname' 值。在这种情况下,您需要 return 'undefined' 而不是 'null' 到 'createTestCafe' 函数。
我正在失去理智,试图弄清楚为什么 testcafe 如此痛苦。所以这是我的场景: 我有一个跑步者可以启动我对 browserstack 的测试。美好的。一旦我将 testcafe 版本从 1.6.1 升级到 1.9.0,browserstack runner 就无法启动。我收到此错误:
(node:12310) UnhandledPromiseRejectionWarning: TypeError: Cannot convert undefined or null to object
at Function.entries (<anonymous>)
at TestCafeConfiguration.mergeOptions (/Users/testcafe/node_modules/testcafe/lib/configuration/configuration-base.js:50:16)
at TestCafeConfiguration.init (/Users/testcafe/node_modules/testcafe/lib/configuration/testcafe-configuration.js:48:14)
at async getConfiguration (/Users/testcafe/node_modules/testcafe/lib/index.js:41:9)
at async createTestCafe (/Users/testcafe/node_modules/testcafe/lib/index.js:57:27)
(node:12310) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:12310) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
奇怪的是,如果我将我的版本升级到 1.7.0,我没有遇到任何问题。任何版本 1.8.0 及以上我都会收到上述错误。
有人也遇到过这种情况吗?有人可以阐明这个问题吗?
这是我的跑步者SetupRunners.js文件:
import getRunnerSrc from "./getRunnerSrc";
import getRunnerBrowsers from "./getRunnerBrowsers";
export default function setupRunner(runner, options = {}, cb) {
let stream = false;
const src = options.src || getRunnerSrc(options.breakpoint);
if (src && src.length) {
runner.src(src);
runner.browsers(
options.browsers || getRunnerBrowsers(options.breakpoint)
);
return cb(runner).then(data => {
if (stream) {
stream.end();
}
return data;
});
}
}
这是针对 browserstack 启动测试的文件
import getArgs from "./getArgs";
import sanitizeArg from "./sanitizeArg";
import isBrowserStack from "./getIsBrowserStack";
const defaultBrowsers = {
desktop: "Chrome:OS X",
mobile: "Safari:iOS",
};
const browserStackPrefix = "browserstack:";
export default function getRunnerBrowsers(breakpoint) {
const useBrowserStack = isBrowserStack();
if (useBrowserStack && breakpoint) {
return getBrowserstackDevices(breakpoint);
}
return `${useBrowserStack ? browserStackPrefix : ""}${sanitizeArg(
getArgs("browsers") || defaultBrowsers.desktop
)}`;
}
function getBrowserstackDevices(breakpoint) {
return `${browserStackPrefix}${getArgs(`${breakpoint}_devices`) ||
defaultBrowsers[breakpoint]}`;
}
帮手来了getArgs.js:
function getArgs(key) {
if (process && process.argv && process.argv.length) {
return process.argv.reduce((val, arg) => {
const split = arg.split("=");
if (split[0] === key || split[0] === "--" + key) {
val = split[1];
}
return val;
}, null);
}
return null;
}
module.exports = getArgs;
和santizeArgs.js
export default function sanitizeArg(ar) {
return filterEmpty((ar || "").split(",").map(str => str.trim()));
}
export function filterEmpty(items) {
return items.filter(item => item && item.length);
}
=======更新========
在 v1.7.0 中创建 TESTCAFE 函数
async function createTestCafe(hostname, port1, port2, sslOptions, developmentMode, retryTestPages) {
console.dir
const configuration = new testcafe_configuration_1.default();
await configuration.init({
hostname,
port1,
port2,
ssl: sslOptions,
developmentMode,
retryTestPages
});
将 TESTCAFE 更新到 v1.9.2 后创建 TESTCAFE 函数
async function createTestCafe(...args) {
const configuration = await getConfiguration(args); // HERE IS WHERE THE ERROR IS
const [hostname, port1, port2] = await Promise.all([
getValidHostname(configuration.getOption(option_names_1.default.hostname)),
getValidPort(configuration.getOption(option_names_1.default.port1)),
getValidPort(configuration.getOption(option_names_1.default.port2))
]);
configuration.mergeOptions({ hostname, port1, port2 });
const testcafe = new TestCafe(configuration);
setupExitHook(cb => testcafe.close().then(cb));
return testcafe;
}
我根据您的信息重现了该问题,并在 TestCafe GitHub 存储库中创建了一个 issue。作为解决方法,您可以更正传递给 'createTestCafe' 函数的参数值。
根据您共享的输出,您将 'null' 值作为 'hostname' 参数传递。我猜 'null' 值意味着未指定 'hostname' 值。在这种情况下,您需要 return 'undefined' 而不是 'null' 到 'createTestCafe' 函数。