Cannot run vscode extension starter project tests twice in a row on macos - testing

I am implementing a VSCode extension and I have set up the project following this link.
It creates a starter project and with it a src/test/runTest.ts:
import * as path from 'path';
import { runTests } from '#vscode/test-electron';
async function main() {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath = path.resolve(__dirname, '../../');
// The path to test runner
// Passed to --extensionTestsPath
const extensionTestsPath = path.resolve(__dirname, './suite/index');
// Download VS Code, unzip it and run the integration test
await runTests({ extensionDevelopmentPath, extensionTestsPath });
} catch (err) {
console.error('Failed to run tests');
process.exit(1);
}
}
main();
and a package.json:
{
"compile": "tsc -p ./",
"pretest": "npm run compile && npm run lint",
"lint": "eslint src --ext ts",
"test": "node ./out/test/runTest.js"
}
I cannot run
npm test
twice in a row.
The first time, everything goes well, and it looks like it is downloading VSCode in the folder .vscode-test.
Downloading VS Code 1.65.2 from https://update.code.visualstudio.com/1.65.2/darwin/stable
Downloading VS Code [==============================] 100%Downloaded VS Code 1.65.2 into /my-path/my-project/.vscode-test/vscode-darwin-1.65.2
However, I get a warning:
WARNING: IPC handle "/my-path/my-project/.vscode-test/user-data/1.65.2-main.sock" is longer than 103 chars, try a shorter --user-data-dir
When I run the tests a second time, if fails:
Found existing install in /my-path/my-project/.vscode-test/vscode-darwin-1.65.2. Skipping download
WARNING: IPC handle "/my-path/my-project/.vscode-test/user-data/1.65.2-main.sock" is longer than 103 chars, try a shorter --user-data-dir
[main 2022-03-29T14:44:22.271Z] Could not delete obsolete instance handle Error: ENOENT: no such file or directory, unlink '/my-path/my-project/.vscode-test/user-data/1.65.2-main.sock'
at unlinkSync (original-fs.js:1210:3)
at ne.claimInstance (/my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:5083)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async /my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:2282
at async ne.startup (/my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:2151) {
errno: -2,
syscall: 'unlink',
code: 'ENOENT',
path: '/my-path/my-project/.vscode-test/user-data/1.65.2-main.sock'
}
[main 2022-03-29T14:44:22.274Z] Error: ENOENT: no such file or directory, unlink '/my-path/my-project/.vscode-test/user-data/1.65.2-main.sock'
at unlinkSync (original-fs.js:1210:3)
at ne.claimInstance (/my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:5083)
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at async /my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:2282
at async ne.startup (/my-path/my-project/.vscode-test/vscode-darwin-1.65.2/Visual Studio Code.app/Contents/Resources/app/out/vs/code/electron-main/main.js:77:2151)
Exit code: 1
Failed to run tests
But it works fine if I delete the folder .vscode-test.
What is happening and what can I do?

try to make your work directory shorter
or
use the os temporary directory
for example:
await runTests({
extensionDevelopmentPath,
extensionTestsPath,
launchArgs: ['--user-data-dir', `${os.tmpdir()}`]
});

Related

DRY way to change working directory for npm scripts

I'm just trying out NPM as my build system for a small project and I'd like to ask if there is a clean and easy to maintain way to change the working directory for the build scripts. My first thought was something like
"scripts": {
"cd:workdir": "cd src/path/to/my/work/dir/",
"task:1": "npm run cd:workdir && command1",
"task:2": "npm run cd:workdir && command2",
[...]
}
But it seams command* is executed in a different process then npm run cd:workdir, so this doesn't work.
The only working way I found so far is:
"scripts": {
"task:1": "cd src/path/to/my/work/dir/ && command1",
"task:2": "cd src/path/to/my/work/dir/ && command2",
[...]
}
But there must be a better way to do this to keep it DRY and better maintainable. Thanks!
I think you can use child_process.exec to execute some commands from a javascript file:
// task.js
const { exec } = require('child_process');
exec('command', {
cwd: 'src/path/to/my/work/dir/'
}, (error, stdout, stderr) => {
// handle error, stderr...
console.log(stdout)
});
and execute that javascript file using node in npm script: "task:1": "node task.js"

How add variable npm run build in package.json

I have 6 projects in an Angular workspace and I have to build each. Instead of write six lines in my package.json for each projet, for example :
"build_a":" npm run build a"
"buiild_b": "npm run build b"
I would like to create only one line like this :
"build_app": "npm run build name="aaa""
How I can do it ?
you could rely on environment variables in order to discover such names.
however it depends on which operating system you're using on how to define env variables.
"scripts":{
"build:a":"cross-env NAME=a npm run build",
"build:b":"cross-env NAME=b npm run build",
"build:c":"cross-env NAME=c npm run build",
"build":"browserify src/main.js -o build.js"
}
You would end up with a script section more or less like this.
Finally I found the solution using a node.js script: build-subproject.js.
const { exec } = require('child_process');
const args = process.argv.slice(2).join(' ');
console.log(`RUNNING build with args: ${args}`);
exec(
`ng build ${args} && cd dist/${args} && npm pack `,
(error, stdout) => {
if (error) {
console.error(`exec error: ${error}`);
return;
}
console.info(`stdout: ${stdout}`);
}
);
In package.json,
"build-subproject": "node ./build-subproject.js",
Then run , npm run build-subproject my-project-name

how do I echo a message to the terminal at the end of npm install?

I've created a repo I want to be cloned
after cloning, you run npm install
How do I echo a log message to the terminal that will show up at the end of the installation?
In your case, you can add a post-install script, that outputs, for example, a string to the console if you mark a version as alpha.
package.json
{
"version": "1.2.3-alpha.2",
"scripts": {
"postinstall": "node postinstall.js"
}
}
postinstall.js
const package = require('./package.json')
console.log('End of installation');
//Example using properties from package.json
if (package.version.includes('alpha')) {
console.log('Warning: Alpha version!')
}
BONUS
Append this to the command --loglevel verbose and all logs will be saved to npm-debug.log in current working directory.
It will show the logs in realtime + saves the log to directory its running.
You can just edit npm config npm config edit and add loglevel=verbose

Pulling files from a directory into the root folder for NPM

I am publishing a library to NPM.
When I build the library, the resulting artifact is placed in the dist folder located in the root of my project as index.js.
When users install from NPM I would like index.js to be present in the root of the folder created in their node_modules folder. Presently, it remains in a directory named dist.
How can I do this?
My packages.json:
{
"name": "my-package",
"version": "0.0.9",
"files": ["dist/*"],
"main": "index.min.js",
"private": false,
"dependencies": {},
"devDependencies": {},
"repository": "git#github.com:username/my-package.git"
}
I had exactly the same problem.
I solved it not by copying the files up, but by copying the files I needed down into the ./dist/ folder and then doing an npm publish from there; NPM then treats that folder as a complete package and everything works very nicely. The only files I needed to copy from the root folder were:
package.json
README.md
Because we're going to copy these files down into the ./dist/ folder before we do the publish, we do NOT want the package.json file to reference ./dist/. So remove the package.json's files entry completely, because we don't need to tell it which files we'll take - we're going to take everything in the ./dist/ folder. I'm using TypeScript so I also have a typings entry, and again no reference to ./dist/.
{
"name": "my-package",
"version": "0.0.9",
"main": "index.min.js",
"typings": "index.d.ts",
"private": false,
"dependencies": {},
"devDependencies": {},
"repository": "git#github.com:username/my-package.git"
}
Now for the publish step. I built a gulp task that will perform the publish for me, making it nice and automated (except for incrementing the package version #).
From gulp I'll use Node's spawn() to kick-off the npm process. However, because I'm actually working on Windows I used "cross-spawn" rather than the normal built-in Node.js spawn (which I learned the hard way didn't work when I had spaces in my path!).
Here's my gulp file, with the TypeScript bits removed:
var gulp = require('gulp');
var del = require('del');
var spawn = require('cross-spawn'); // WAS: require('child_process').spawn;
var config = {
src: { tsFiles: './src/**/*.ts' },
out: { path: './dist/' }
}
gulp.task('clean', () => {
return del('dist/*');
});
gulp.task('build', ['clean'], () => {
....
});
gulp.task('publish', ['build'], (done) => {
// Copy the files we'll need to publish
// We just use built-in gulp commands to do the copy
gulp.src(['package.json', 'README.md']).pipe(gulp.dest(config.out.path));
// We'll start the npm process in the dist directory
var outPath = config.out.path.replace(/(\.)|(\/)/gm,'');
var distDir = __dirname + '\\' + outPath + '\\';
console.log("dist directory = " + distDir);
// Start the npm process
spawn('npm', ['publish'], { stdio:'inherit', cwd:distDir } )
.on('close', done)
.on('error', function(error) {
console.error(' Underlying spawn error: ' + error);
throw error;
});
});
Notice when we call spawn() we pass in a 3rd argument which is the options. The main entry here is the cwd:distDir, which tells spawn to run the npm process from the ./dist/ directory. Because using spawn can cause problems I've hooked into the spawn error handling. As I was troubleshooting my use of spawn() I found the following StackOverflow article very helpful.
This worked like a charm; my published package has all the files in the root directory and the ./dist/ folder is not published.

Watch and rerun Jest JS tests

The Jest documentation suggests using npm test to execute tests.
Is there a way of watching your source and tests to rerun Jest tests automatically when relevant files have been changed?
Thanks to Erin Stanfill for pointing out, Jest already has support for automatically re-running. The better configuration for package.json would be
{
"scripts": {
"test": "jest"
}
}
To turn on the watch mode, just use
$ npm run test -- --watch
Or
$ yarn run test --watch
If you have npm test configured, you can just run npm test -- --watch.
As a complement suggestion you can add "--watchAll"
into your package.json file like this:
"scripts": {
"test": "jest --watchAll"
},
Each time you run npm test, the watch mode will be enable by default.
For more info npm CLI docs
Start you tests in watch mode.
jest --watch fileName.test.js
As per documentation
Run tests that match this spec name (match against the name in describe or test, basically).
jest -t name-of-spec
// or in watch mode
jest --watch -t="TestName"
This example shows how to use gulp to run your Jest tests using jest-cli, as well as a tdd gulp task to watch files and rerun Jest tests when a file changes:
var gulp = require('gulp');
var jest = require('jest-cli');
var jestConfig = {
rootDir: 'source'
};
gulp.task('test', function(done) {
jest.runCLI({ config : jestConfig }, ".", function() {
done();
});
});
gulp.task('tdd', function(done) {
gulp.watch([ jestConfig.rootDir + "/**/*.js" ], [ 'test' ]);
});
gulp.task('default', function() {
// place code for your default task here
});
install a couple of Grunt packages:
npm install grunt-contrib-watch grunt-exec --save-dev
make a Gruntfile.js with the following:
module.exports = function(grunt) {
grunt.initConfig({
exec: {
jest: 'node node_modules/jest-cli/bin/jest'
},
watch: {
files: ['**/*.js'],
tasks: ['exec:jest']
}
});
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-exec');
}
then simply run:
grunt watch
If you want to run a single file in watch mode:
yarn run test --watch FileName.test.jsx
I personally use the npm package jest-watch-typeahead.
You need to do 3 steps:
Install npm packege:
npm install --save-dev jest jest-watch-typeahead
Add to jest.config.js next code:
module.exports = {
watchPlugins: [
'jest-watch-typeahead/filename',
'jest-watch-typeahead/testname',
],
};
Run Jest in watch mode
yarn jest --watch