nativescript
Version:
Command-line interface for building NativeScript projects
148 lines • 7.07 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.TestExecutionService = void 0;
const constants = require("../constants");
const path = require("path");
const os = require("os");
const _ = require("lodash");
const yok_1 = require("../common/yok");
const package_path_helper_1 = require("../helpers/package-path-helper");
class TestExecutionService {
constructor($runController, $httpClient, $config, $logger, $fs, $options, $pluginsService, $projectDataService, $childProcess) {
this.$runController = $runController;
this.$httpClient = $httpClient;
this.$config = $config;
this.$logger = $logger;
this.$fs = $fs;
this.$options = $options;
this.$pluginsService = $pluginsService;
this.$projectDataService = $projectDataService;
this.$childProcess = $childProcess;
this.allowedParameters = [];
}
async startKarmaServer(platform, liveSyncInfo, deviceDescriptors) {
platform = platform.toLowerCase();
this.platform = platform;
const projectData = this.$projectDataService.getProjectData(liveSyncInfo.projectDir);
// We need the dependencies installed here, so we can start the Karma server.
await this.$pluginsService.ensureAllDependenciesAreInstalled(projectData);
const karmaConfig = this.getKarmaConfiguration(platform, projectData);
// In case you want to debug the unit test runner, add "--inspect-brk=<port>" as a first element in the array of args.
const karmaRunner = this.$childProcess.spawn(process.execPath, [path.join(__dirname, "karma-execution.js")], { stdio: ["inherit", "inherit", "inherit", "ipc"] });
const launchKarmaTests = async (karmaData) => {
this.$logger.trace("## Unit-testing: Parent process received message", karmaData);
let port;
if (karmaData.url) {
port = karmaData.url.port;
const socketIoJsUrl = `http://${karmaData.url.host}/socket.io/socket.io.js`;
const socketIoJs = (await this.$httpClient.httpRequest(socketIoJsUrl))
.body;
this.$fs.writeFile(path.join(liveSyncInfo.projectDir, TestExecutionService.SOCKETIO_JS_FILE_NAME), JSON.parse(socketIoJs));
}
if (karmaData.launcherConfig) {
const configOptions = JSON.parse(karmaData.launcherConfig);
const configJs = this.generateConfig(port, configOptions);
this.$fs.writeFile(path.join(liveSyncInfo.projectDir, TestExecutionService.CONFIG_FILE_NAME), configJs);
}
// Prepare the project AFTER the TestExecutionService.CONFIG_FILE_NAME file is created in node_modules
// so it will be sent to device.
await this.$runController.run({
liveSyncInfo,
deviceDescriptors,
});
};
karmaRunner.on("message", (karmaData) => {
this.$logger.trace(`The received message from karma is: `, karmaData);
if (!karmaData.launcherConfig && !karmaData.url) {
return;
}
launchKarmaTests(karmaData).catch((result) => {
this.$logger.error(result);
process.exit(130 /* ErrorCodes.KARMA_FAIL */);
});
});
return new Promise((resolve, reject) => {
karmaRunner.on("exit", (exitCode) => {
if (exitCode !== 0) {
//End our process with a non-zero exit code
const testError = new Error("Test run failed.");
reject(testError);
}
else {
resolve();
}
});
karmaRunner.send({ karmaConfig: karmaConfig });
});
}
async canStartKarmaServer(projectData) {
let canStartKarmaServer = true;
const requiredDependencies = ["@nativescript/unit-test-runner"]; // we need @nativescript/unit-test-runner at the local level because of hooks!
_.each(requiredDependencies, (dep) => {
if (!projectData.dependencies[dep] && !projectData.devDependencies[dep]) {
canStartKarmaServer = false;
return;
}
});
const pathToKarma = (0, package_path_helper_1.resolvePackagePath)("karma", {
paths: [projectData.projectDir],
});
canStartKarmaServer = canStartKarmaServer && !!pathToKarma;
return canStartKarmaServer;
}
generateConfig(port, options) {
const nics = os.networkInterfaces();
const ips = Object.keys(nics)
.map((nicName) => nics[nicName].filter((binding) => binding.family === "IPv4" || binding.family === 4)[0])
.filter((binding) => !!binding)
.map((binding) => binding.address);
const config = {
port,
ips,
options,
};
return "module.exports = " + JSON.stringify(config);
}
getKarmaConfiguration(platform, projectData) {
const karmaConfig = {
browsers: [platform],
configFile: path.join(projectData.projectDir, "karma.conf.js"),
_NS: {
log: this.$logger.getLevel(),
path: this.$options.path,
tns: process.argv[1],
node: process.execPath,
env: this.$options.env,
options: {
debugTransport: this.$options.debugTransport,
debugBrk: this.$options.debugBrk,
watch: !!this.$options.watch,
bundle: true,
appDirectoryRelativePath: projectData.getAppDirectoryRelativePath(),
},
},
};
if (this.$config.DEBUG || this.$logger.getLevel() === "TRACE") {
karmaConfig.logLevel = "DEBUG";
}
if (!this.$options.watch) {
// Setting singleRun to true will automatically start the tests when new browser (device in our case) is registered in karma.
karmaConfig.singleRun = true;
}
if (this.$options.debugBrk) {
karmaConfig.browserNoActivityTimeout = 1000000000;
}
karmaConfig.projectDir = projectData.projectDir;
karmaConfig.bundle = true;
karmaConfig.debugBrk = this.$options.debugBrk;
karmaConfig.appPath = projectData.getAppDirectoryRelativePath();
karmaConfig.platform = platform.toLowerCase();
this.$logger.trace(JSON.stringify(karmaConfig, null, 4));
return karmaConfig;
}
}
exports.TestExecutionService = TestExecutionService;
TestExecutionService.CONFIG_FILE_NAME = `node_modules/${constants.TEST_RUNNER_NAME}/config.js`;
TestExecutionService.SOCKETIO_JS_FILE_NAME = `node_modules/${constants.TEST_RUNNER_NAME}/socket.io.js`;
yok_1.injector.register("testExecutionService", TestExecutionService);
//# sourceMappingURL=test-execution-service.js.map
;