Skip to content

Commit 51b789d

Browse files
committed
Feat: Enhanced TS support for browserstack-cypress-cli
1 parent 2949cc6 commit 51b789d

File tree

2 files changed

+77
-15
lines changed

2 files changed

+77
-15
lines changed

bin/helpers/readCypressConfigUtil.js

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,68 @@ exports.detectLanguage = (cypress_config_filename) => {
1313
return constants.CYPRESS_V10_AND_ABOVE_CONFIG_FILE_EXTENSIONS.includes(extension) ? extension : 'js'
1414
}
1515

16+
function generateTscCommandAndTempTsConfig(bsConfig, bstack_node_modules_path, complied_js_dir, cypress_config_filepath) {
17+
const working_dir = path.dirname(cypress_config_filepath);
18+
const typescript_path = path.join(bstack_node_modules_path, 'typescript', 'bin', 'tsc');
19+
const tsc_alias_path = path.join(bstack_node_modules_path, 'tsc-alias', 'dist', 'bin', 'index.js');
20+
const tsConfigFilePath = bsConfig.run_settings.ts_config_file_path;
21+
22+
// Prepare base temp tsconfig
23+
const tempTsConfig = {
24+
compilerOptions: {
25+
"outDir": `./${path.basename(complied_js_dir)}`, // Add ./ prefix for consistency
26+
"listEmittedFiles": true,
27+
"allowSyntheticDefaultImports": true,
28+
"module": "commonjs",
29+
"declaration": false,
30+
"baseUrl": ".", // Default fallback baseUrl
31+
"skipLibCheck": true
32+
},
33+
include: [cypress_config_filepath]
34+
};
35+
36+
// Inject paths and baseUrl from original tsconfig if available
37+
if (tsConfigFilePath && fs.existsSync(tsConfigFilePath) && path.extname(tsConfigFilePath).toLowerCase() === '.json') {
38+
const tsConfig = JSON.parse(fs.readFileSync(tsConfigFilePath, 'utf8'));
39+
if (tsConfig.compilerOptions) {
40+
if (tsConfig.compilerOptions.baseUrl) {
41+
// Use the directory containing the original tsconfig as baseUrl
42+
tempTsConfig.compilerOptions.baseUrl = path.dirname(tsConfigFilePath);
43+
} else {
44+
logger.warn(`tsconfig at ${tsConfigFilePath} does not define baseUrl, defaulting to "."`);
45+
}
46+
if (tsConfig.compilerOptions.paths) {
47+
tempTsConfig.compilerOptions.paths = tsConfig.compilerOptions.paths;
48+
}
49+
}
50+
} else {
51+
logger.warn(`tsconfig file not found or invalid: ${tsConfigFilePath}`);
52+
}
53+
54+
// Write the temporary tsconfig
55+
const tempTsConfigPath = path.join(working_dir, 'tsconfig.singlefile.tmp.json');
56+
fs.writeFileSync(tempTsConfigPath, JSON.stringify(tempTsConfig, null, 2));
57+
logger.info(`Temporary tsconfig created at: ${tempTsConfigPath}`);
58+
59+
// Platform-specific command generation
60+
const isWindows = /^win/.test(process.platform);
61+
62+
if (isWindows) {
63+
// Windows: Use && to chain commands, no space after SET
64+
const setNodePath = isWindows
65+
? `set NODE_PATH=${nodePath}`
66+
: `NODE_PATH="${nodePath}"`;
67+
68+
const tscCommand = `${setNodePath} && node "${typescript_path}" --project "${tempTsConfigPath}" && ${setNodePath} && node "${tsc_alias_path}" --project "${tempTsConfigPath}"`;
69+
return { tscCommand, tempTsConfigPath };
70+
} else {
71+
// Unix/Linux/macOS: Use ; to separate commands or && to chain
72+
const nodePathPrefix = `NODE_PATH=${bsConfig.run_settings.bstack_node_modules_path}`;
73+
const tscCommand = `${nodePathPrefix} node "${typescript_path}" --project "${tempTsConfigPath}" && ${nodePathPrefix} node "${tsc_alias_path}" --project "${tempTsConfigPath}"`;
74+
return { tscCommand, tempTsConfigPath };
75+
}
76+
}
77+
1678
exports.convertTsConfig = (bsConfig, cypress_config_filepath, bstack_node_modules_path) => {
1779
const cypress_config_filename = bsConfig.run_settings.cypress_config_filename
1880
const working_dir = path.dirname(cypress_config_filepath);
@@ -22,19 +84,12 @@ exports.convertTsConfig = (bsConfig, cypress_config_filepath, bstack_node_module
2284
}
2385
fs.mkdirSync(complied_js_dir, { recursive: true })
2486

25-
const typescript_path = path.join(bstack_node_modules_path, 'typescript', 'bin', 'tsc')
26-
27-
let tsc_command = `NODE_PATH=${bstack_node_modules_path} node "${typescript_path}" --outDir "${complied_js_dir}" --listEmittedFiles true --allowSyntheticDefaultImports --module commonjs --declaration false "${cypress_config_filepath}"`
87+
const { tscCommand, tempTsConfigPath } = generateTscCommandAndTempTsConfig(bsConfig, bstack_node_modules_path, complied_js_dir, cypress_config_filepath);
2888

29-
if (/^win/.test(process.platform)) {
30-
tsc_command = `set NODE_PATH=${bstack_node_modules_path}&& node "${typescript_path}" --outDir "${complied_js_dir}" --listEmittedFiles true --allowSyntheticDefaultImports --module commonjs --declaration false "${cypress_config_filepath}"`
31-
}
32-
33-
3489
let tsc_output
3590
try {
36-
logger.debug(`Running: ${tsc_command}`)
37-
tsc_output = cp.execSync(tsc_command, { cwd: working_dir })
91+
logger.debug(`Running: ${tscCommand}`)
92+
tsc_output = cp.execSync(tscCommand, { cwd: working_dir })
3893
} catch (err) {
3994
// error while compiling ts files
4095
logger.debug(err.message);
@@ -44,6 +99,12 @@ exports.convertTsConfig = (bsConfig, cypress_config_filepath, bstack_node_module
4499
logger.debug(`Saved compiled js output at: ${complied_js_dir}`);
45100
logger.debug(`Finding compiled cypress config file in: ${complied_js_dir}`);
46101

102+
// Clean up the temporary tsconfig file
103+
if (fs.existsSync(tempTsConfigPath)) {
104+
fs.unlinkSync(tempTsConfigPath);
105+
logger.info(`Temporary tsconfig file removed: ${tempTsConfigPath}`);
106+
}
107+
47108
const lines = tsc_output.toString().split('\n');
48109
let foundLine = null;
49110
for (let i = 0; i < lines.length; i++) {
@@ -53,7 +114,7 @@ exports.convertTsConfig = (bsConfig, cypress_config_filepath, bstack_node_module
53114
}
54115
}
55116
if (foundLine === null) {
56-
logger.error(`No compiled cypress config found. There might some error running ${tsc_command} command`)
117+
logger.error(`No compiled cypress config found. There might some error running ${tscCommand} command`)
57118
return null
58119
} else {
59120
const compiled_cypress_config_filepath = foundLine.split('TSFILE: ').pop()

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,25 @@
1919
"browserstack-local": "1.5.4",
2020
"chalk": "4.1.2",
2121
"cli-progress": "^3.10.0",
22+
"decompress": "4.2.1",
2223
"form-data": "^4.0.0",
2324
"fs-extra": "8.1.0",
2425
"getmac": "5.20.0",
2526
"git-last-commit": "^1.0.1",
2627
"git-repo-info": "^2.1.1",
2728
"gitconfiglocal": "^2.1.0",
2829
"glob": "^7.2.0",
29-
"mocha": "^10.2.0",
3030
"mkdirp": "1.0.4",
31+
"mocha": "^10.2.0",
3132
"node-ipc": "9.1.1",
3233
"table": "5.4.6",
34+
"tsc-alias": "^1.8.16",
35+
"unzipper": "^0.12.3",
3336
"update-notifier": "7.0.0",
3437
"uuid": "8.3.2",
3538
"windows-release": "^5.1.0",
3639
"winston": "2.4.4",
37-
"yargs": "14.2.3",
38-
"decompress": "4.2.1",
39-
"unzipper": "^0.12.3"
40+
"yargs": "14.2.3"
4041
},
4142
"repository": {
4243
"type": "git",

0 commit comments

Comments
 (0)