Parallel Build steps in Team City - npm

I am Pretty new to Team City and have been set with a task of creating a CI build.
The thing I trying to build is an angular2 app with protractor e2e tests.
All the other build steps in Team City run ok but I am having trouble trying to run the step that does the e2e test.
if I was to do this locally I would open a cmd window and type...
npm run start
I would then open another command window and type...
npm run e2e
How do I run parallel steps in Team City?

Build steps cannot be run parallel in TeamCity. What you need to do, is create a script that runs 'npm run start' in background, and then runs 'npm run e2e'. You can use command line runner to run the script

I still couldn't get the forever thing working properly for me so I created my own node script that fires up live-server and then executes npm run e2e and that seems to have done the trick thanks for your help though Oleg.
This is how I did it in the end...
const exec = require('child_process').exec;
var psTree = require('ps-tree');
const server = exec('live-server ./dist --port=3000 --no-browser');
const tests = exec('npm run e2e');
tests.stdout.on('data', function(data) {
console.log(data);
});
tests.stderr.on('data', function(data) {
console.log(data);
});
tests.on('close', function(code) {
console.log('closing code: ' + code);
exec('taskkill /PID ' + server.pid + ' /T /F');
});

Related

Is it possible to get the filename of the failed test in the _failed() hook?

If I am able to get the filename of the failed test, I could run the test a second time to check if it really is a error or just a coincidence. Until now I couldnt find a sulution.
You get the instance of test in _failed hook, so you can do the same thing as RunFailed extension:
use Codeception\Test\Descriptor;
public function _failed(\Codeception\TestInterface $test, $fail)
{
$fullName = Descriptor::getTestFullName($test);
}
Original answer:
Codeception has RunFailed extension, which is enabled by default.
It saves the names of all failed tests to tests/_output/failed file, and failed tests can be executed by running codecept run -g failed command.
In order to make CI pass if failed tests pass on second run you can use this command:
codecept run || codecept run -g failed

Collecting Coverage Reports in Jest with Integration Tests

I have a bunch of tests setup with Jest that test Express server endpoints in the same repo. In order to accomplish this testing, I have Jest spinning up an Express server in the beforeAll() method. When I run Jest with the --coverage flag, I get coverage information for just the scripts that were run in order to start Jest and no reporting on the scripts that were triggered by hitting the endpoints. That makes sense, but is there a way to get coverage information on the endpoint code?
Snippet of test code:
const rp = require('request-promise')
describe('testFunctions', () => {
beforeAll(done => {
app.listen(config.PORT, async () => {
done()
})
})
it('hit endpoint', async () => {
const response = await rp({ uri: '/testFunctions', method: 'POST' })
expect(response).toEqual('response)
})
})
I'm trying to get a coverage report for all of the server code hit with the /testFunctions request.
This is the solution that worked for me. It required a bit of refactoring, but I think it was cleaner in the end. In my ecosystem, we are running a Parse Server as middleware with an Express server, but this could apply to anyone who needs to run a separate server with the tests.
So to get my server in a place that nyc (the coverage reporting tool I'm using) could monitor, I abstracted the server initialization completely out of the jest test suite and created a special npm script to run it in an entirely separate process.
NPM Script (package.json):
"scripts": {
"coverage": "nyc --silent npm start & ./listen_on_port_5000.sh && jest test/cloud/integration && kill $(lsof -t -i tcp:5000) && nyc report --reporter=html",
}
listen_on_port_5000.sh
while ! nc -z localhost 5000
do
sleep 0.5
done
So how does this work?
nyc --silent npm start runs which is the normal command we would run to start our server with Express and Parse but with the prepended nyc part with the --silent flag so that nyc can run in the background and watch the server code.
Because we know that the server always starts on port 5000, we run the start script in the background and start a separate process running a shell script (listen_on_port_5000.sh) to wait for the server to boot up.
Once the listener script detects anything running on port 5000, the npm script moves onto the jest command (all while the Express server is up and running).
When Jest finishes running, the final script runs a kill script to close the server running on port 5000.
We then run a second nyc script to generate the report that it collected in the first script. The generated report can be found in your project's directory under /coverage/lcov-report/ (or you can use a different coverage reporter.

Pass git commit message to npm script and append to predefined string

In an NPM project, I'd like to have a commit for each build version. This will allow me to go back to the current build version, fix a bug, without having to go through all the QA of a new version.
We can commit using npm scripts like this (see this answer):
package.json
"scripts": {
"git": "git add . && git commit -m",
}
Then invoke the script by running:
npm run git -- "Message of the commit"
I'd like to automate it to run after npm run build. For this purpose we can create a new command.
package.json
"scripts": {
"buildAndCommit": "npm run build && git add . && git commit -m",
}
This could be run using npm run buildAndCommit -- "commit for a new build"
The only thing left is that I'd like to identify this commit as one that could be linked to a commit. Is it possible to start the message automatically with "BUILD -" and to add to that the unique message which is passed in the command line? Something like:
package.json
"scripts": {
"buildAndCommit": "npm run build && git add . && git commit -'Build' + $uniqueMessageFromTheCommandLine`",
}
If it is not possible to template the string in package.json, how could I achieve it using a command line script? (Powershell is my command line tool).
Running on *nix platforms
On a *nix platform npm utilizes sh by default to execute the npm script(s). In this scenario you can simply use a shell function and reference the git message argument passed via the CLI using the $1 positional parameter.
Your npm script would be redefined like this:
"scripts": {
"build": "...",
"buildAndCommit": "func() { npm run build && git add . && git commit -m \"BUILD - $1\"; }; func"
}
Cross platform
Unfortunately, via Windows Powershell the solution is not quite as simple and terse.
When using Powershell npm utilizes cmd by default to execute npm script(s). Likewise npm utilizes cmd by default via other Windows consoles too, such as Command Prompt.
One way to achieve your requirement is to invoke a node.js via your npm script. The following provides two different methods that are essentially the same. Either will run successfully cross-platform (in your case via Powershell).
Method A - Using a separate node.js script
Create the following node.js script. Let's name the file script.js and save it in the root of the project directory, i.e. in the same directory where package.json resides.
script.js
const execSync = require('child_process').execSync;
const mssg = 'BUILD - ' + process.argv[2];
execSync('npm run build && git add . && git commit -m \"' + mssg + '\"', { stdio:[0, 1, 2] });
Explanation
The node.js builtin process.argv captures the argument at index two, i.e. the git commit message, that was provided via the CLI. The git commit message is concatenated with with the substring BUILD - to form the desired commit message. The resultant string is assigned to the variable mssg.
We then utilize the node.js builtin execSync() to execute your given npm script. As you can see, the value of the mssg variable is used as the git commit message.
The stdio option is utilized to ensure the correct configuration of the pipes, i.e. stdin, stdout, 'stderr', are established between the parent and child process.
Define your npm script named buildAndCommit as follows:
package.json
"scripts": {
"build": "...",
"buildAndCommit": "node script"
}
Above node invokes script.js.
Method B - Inline the node.js script in npm script
Alternatively, the aforementioned node.js script (i.e. script.js) can be provided inline in your npm script instead - therefore negating the use of a separate .js file.
package.json
"scripts": {
"build": "...",
"buildAndCommit": "node -e \"const mssg = 'BUILD - ' + process.argv[1]; require('child_process').execSync('npm run build && git add . && git commit -m \\\"' + mssg + '\\\"', { stdio:[0, 1, 2] })\""
}
This utilizes the same code from Method A albeit it slightly refactored. The notable differences are:
The nodejs command line option -e is utilized to evaluate the inline JavaScript.
process.argv this time will capture the argument, i.e. the git commit message, at index one in the array of arguments.
Additional escaping of the double quotes is necessary, i.e. \\\"
Running the npm script
Using either Method A or Method B run the command via your CLI as desired: For instance:
$ npm run buildAndCommit -- "commit for a new build"
This will produce the following git commit message:
BUILD - commit for a new build

How to break Travis CI build if Appium/Mocha tests fail?

I have a Travis CI project which builds an iOS app then starts Appium and runs tests with Appium/Mocha.
The problem is that even though the Mocha tests fail and throw exception, the shell script which runs them via Gulp still exits with 0 and the build is deemed passing.
How can I make the build break/fail when the Mocha tests fail?
Here is how I managed to make this work:
Instead of running the Mocha tests via Gulp, run them directly from the shell script
Save the output to mocha.log besides displaying on stdout
./node_modules/.bin/mocha --reporter spec "appium/hybrid/*uat.js" 2>&1 | tee mocha.log
Check mocha.log for the string " failing" and exit with 1 if found
.
if grep -q " failing" mocha.log; then
exit 1
fi
The exit 1 will make the Travis build fail.

Forever Node.JS Express 4

How do you run the Express 4 app with Forever? (or is there a new package?)
I am running my Express 3 apps with Forever installed locally with the package manager. I use the command:
forever -a start app.js
Try this:
forever start ./bin/www
Let's take a look to package.json:
"scripts": {
"start": "node ./bin/www"
},
I guess when we call npm start, ./bin/www will be executed at some point.
Then look at the content of./bin/www:
var server = app.listen(app.get('port'), function() {
debug('Express server listening on port ' + server.address().port);
});
so we are ready to listen for connections.
forever start --minUptime 1000 --spinSleepTime 1000 ./bin/www
If you use npm start to run your app, this works in place of it:
forever start -c "npm start" /path/to/app/dir/
Source: https://github.com/foreverjs/forever/issues/540
Try node app.js first, for me, I added a new module in code base, but i did not run npm install in my AWS box, forever is not giving you the error, it just stopped silently, but node will give you the error
http://expressjs.com/guide.html
in Expressjs guide doc,
use 'npm start'
I want use 'forever' but can not too
so,
add code at 'app.js'
var server = app.listen(3000, function() {
console.log('Listening on port %d', server.address().port);
});
and
$node app.js
can use it.
and forever can use too
Feb 2021
This solution is for express.js & forever, on Windows OS.
package.json
"scripts": {
"start": "set PORT=3001 && set DEBUG=myapp:* && forever start --minUptime 1000 --spinSleepTime 1000 ./bin/www",
}
Now run:
npm start
NOTE: For other OS, and customization see following link: https://expressjs.com/en/starter/generator.html