Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bin/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ Standard Options:
Maximum time in ms to wait for an HTTP HEAD/GET request, default 0
which results in using the OS default

--httpContains

string to check in http response, will wait until response body contains this value.
To be used with http(s)-get

-i, --interval

Interval to poll resources in ms, default 250ms
Expand Down
3 changes: 2 additions & 1 deletion bin/wait-on
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const path = require('path');
const waitOn = require('../');

const minimistOpts = {
string: ['c', 'd', 'i', 's', 't', 'w', 'httpTimeout', 'tcpTimeout'],
string: ['c', 'd', 'i', 's', 't', 'w', 'httpTimeout','httpContains', 'tcpTimeout'],
boolean: ['h', 'l', 'r', 'v'],
alias: {
c: 'config',
Expand Down Expand Up @@ -45,6 +45,7 @@ if (argv.help || !hasResources) {
const opts = [
'delay',
'httpTimeout',
'httpContains',
'interval',
'log',
'reverse',
Expand Down
18 changes: 16 additions & 2 deletions lib/wait-on.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const WAIT_ON_SCHEMA = Joi.object({
resources: Joi.array().items(Joi.string().required()).required(),
delay: Joi.number().integer().min(0).default(0),
httpTimeout: Joi.number().integer().min(0),
httpContains: Joi.string(),
interval: Joi.number().integer().min(0).default(250),
log: Joi.boolean().default(false),
reverse: Joi.boolean().default(false),
Expand Down Expand Up @@ -74,6 +75,7 @@ const WAIT_ON_SCHEMA = Joi.object({
@param opts.resources array of string resources to wait for. prefix determines the type of resource with the default type of `file:`
@param opts.delay integer - optional initial delay in ms, default 0
@param opts.httpTimeout integer - optional http HEAD/GET timeout to wait for request, default 0
@param opts.httpContains string - optional the string http response needs to contain
@param opts.interval integer - optional poll resource interval in ms, default 250ms
@param opts.log boolean - optional flag to turn on logging to stdout
@param opts.reverse boolean - optional flag which reverses the mode, succeeds when resources are not available
Expand Down Expand Up @@ -270,6 +272,7 @@ function createHTTP$({ validatedOpts, output }, resource) {
delay,
followRedirect,
httpTimeout: timeout,
httpContains,
interval,
proxy,
reverse,
Expand Down Expand Up @@ -301,22 +304,33 @@ function createHTTP$({ validatedOpts, output }, resource) {
return timer(delay, interval).pipe(
mergeMap(() => {
output(`making HTTP(S) ${method} request to ${socketPathDesc} url:${urlSocketOptions.url} ...`);
return from(checkFn(output, httpOptions));
return from(checkFn(output, httpOptions, httpContains));
}, simultaneous),
startWith(false),
distinctUntilChanged(),
take(2)
);
}

async function httpCallSucceeds(output, httpOptions) {
async function httpCallSucceeds(output, httpOptions, httpContains) {
try {
const result = await axios(httpOptions);
output(
` HTTP(S) result for ${httpOptions.url}: ${util.inspect(
pick(['status', 'statusText', 'headers', 'data'], result)
)}`
);
if(httpContains){
if(!result.data){
output(` HTTP(S) response is empty for ${httpOptions.url}`);
return false;
}
if(!result.data.includes(httpContains)){
output(` HTTP(S) response does not contain string ${httpContains} for ${httpOptions.url}`);
return false;
}
}

return true;
} catch (err) {
output(` HTTP(S) error for ${httpOptions.url} ${err.toString()}`);
Expand Down
45 changes: 45 additions & 0 deletions test/api.mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,26 @@ describe('api', function () {
});
});

it('should succeed when http GET contains httpContains value', function (done) {
const opts = {
resources: ['http-get://localhost:3000'],
httpContains: "abc123"
};

setTimeout(function () {
httpServer = http.createServer().on('request', function (req, res) {
res.write("abc123");
res.end('data');
});
httpServer.listen(3000, 'localhost');
}, 300);

waitOn(opts, function (err) {
expect(err).toNotExist();
done();
});
});

it('should succeed when http GET resource become available later via redirect', function (done) {
const opts = {
// followRedirect: true, // default is true
Expand Down Expand Up @@ -460,6 +480,31 @@ describe('api', function () {
});
});

it('should timeout when http response does not contain requested string', function (done) {
const opts = {
timeout: 1000,
interval: 100,
window: 100,
followRedirect: false,
httpContains: "12345",
resources: ['http-get://localhost:3000']
};

httpServer = http.createServer().on('request', function (req, res) {
const pathname = req.url;
if (pathname === '/') {
res.write("abc123")
}
res.end('data');
});
httpServer.listen(3000, 'localhost');

waitOn(opts, function (err) {
expect(err).toExist();
done();
});
});

it('should timeout when a service is not listening to tcp port', function (done) {
const opts = {
resources: ['tcp:localhost:3010'],
Expand Down
37 changes: 37 additions & 0 deletions test/cli.mocha.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,5 +568,42 @@ describe('cli', function () {
done();
});
});

it('should succeed when http response contains httpContains value', function (done) {
setTimeout(function () {
httpServer = http.createServer().on('request', function (req, res) {
res.write("abc123");
res.end('data');
});
httpServer.listen(3030, 'localhost');
}, 300);

execCLI(
['--httpContains abc123', 'http-get://localhost:3030/'].concat(FAST_OPTS),
{}
).on('exit', function (code) {
expect(code).toBe(0);
done();
});
});

it('should timeout when http response does not contain httpContains value', function (done) {
setTimeout(function () {
httpServer = http.createServer().on('request', function (req, res) {
res.write("abc123");
res.end('data');
});
httpServer.listen(3030, 'localhost');
}, 300);

execCLI(
['--httpContains 1234', 'http-get://localhost:3030/'].concat(FAST_OPTS),
{}
).on('exit', function (code) {
expect(code).toBe(0);
done();
});
});

});
});