Skip to content

Commit 17a427c

Browse files
authoredDec 5, 2022
feat: use the --expect parameter to specify HTTP response code (#343)
* feat: add --expect argument parsing * feat: specify the --expected http status code * chore: update the README
1 parent 6bedc4c commit 17a427c

File tree

6 files changed

+58
-22
lines changed

6 files changed

+58
-22
lines changed
 

‎.github/workflows/ci.yml

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ jobs:
5454
- name: Run demo multiple 📊
5555
run: npm run demo-multiple
5656

57+
- name: Run demo expect 403 code 📊
58+
run: npm run demo-expect-403
59+
5760
- name: Semantic Release 🚀
5861
if: github.ref == 'refs/heads/master'
5962
uses: cycjimmy/semantic-release-action@v3

‎README.md

+10
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,16 @@ If you want to start the server, wait for it to respond, and then run multiple t
167167

168168
The above script `ci` after the `localhost:9000` responds executes the `npm run test:unit` command. Then when it finishes it runs `npm run test:e2e`. If the first or second command fails, the `ci` script fails. Of course, your mileage on Windows might vary.
169169

170+
#### expected
171+
172+
The server might respond, but require authorization, returning an error HTTP code by default. You can still know that the server is responding by using `--expect` argument (or its alias `--expected`):
173+
174+
```
175+
$ start-test --expect 403 start :9000 test:e2e
176+
```
177+
178+
See `demo-expect-403` NPM script.
179+
170180
## `npx` and `yarn`
171181

172182
If you have [npx](https://www.npmjs.com/package/npx) available, you can execute locally installed tools from the shell. For example, if the `package.json` has the following local tools:

‎package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
"main": "src/",
4949
"private": false,
5050
"publishConfig": {
51-
"registry": "http://registry.npmjs.org/"
51+
"registry": "https://registry.npmjs.org/"
5252
},
5353
"repository": {
5454
"type": "git",
@@ -93,7 +93,7 @@
9393
"demo10": "node src/bin/start.js start-fail http://127.0.0.1:9000 test",
9494
"demo11": "node src/bin/start.js http-get://127.0.0.1:9000",
9595
"demo12": "node src/bin/start.js start-304 9000 test2",
96-
"demo13": "node src/bin/start.js --expect 403 start-403 9000 'echo Waited'",
96+
"demo-expect-403": "node src/bin/start.js --expect 403 start-403 9000 'echo Waited'",
9797
"demo-interval": "WAIT_ON_INTERVAL=1000 node src/bin/start.js start http://127.0.0.1:9000 test2",
9898
"demo-timeout": "WAIT_ON_TIMEOUT=10000 node src/bin/start.js start http://127.0.0.1:9000 test2",
9999
"demo-cross-env": "node src/bin/start.js start-cross-env 9000",

‎src/bin/start.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ const debug = require('debug')('start-server-and-test')
44

55
const startAndTest = require('..').startAndTest
66
const utils = require('../utils')
7-
const args = utils.crossArguments(process.argv.slice(2))
87

8+
const namedArguments = utils.getNamedArguments(process.argv.slice(2))
9+
debug('named arguments: %o', namedArguments)
10+
11+
const args = utils.crossArguments(process.argv.slice(2))
912
debug('parsing CLI arguments: %o', args)
1013
const parsed = utils.getArguments(args)
1114
debug('parsed args: %o', parsed)
@@ -15,9 +18,9 @@ if (!Array.isArray(services)) {
1518
throw new Error(`Could not parse arguments %o, got %o`, args, parsed)
1619
}
1720

18-
utils.printArguments({ services, test })
21+
utils.printArguments({ services, test, namedArguments })
1922

20-
startAndTest({ services, test }).catch(e => {
23+
startAndTest({ services, test, namedArguments }).catch(e => {
2124
console.error(e)
2225
process.exit(1)
2326
})

‎src/index.js

+11-5
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@ const isDebug = () =>
2828

2929
const isInsecure = () => process.env.START_SERVER_AND_TEST_INSECURE
3030

31-
function waitAndRun ({ start, url, runFn }) {
31+
function waitAndRun ({ start, url, runFn, namedArguments }) {
3232
la(is.unemptyString(start), 'missing start script name', start)
3333
la(is.fn(runFn), 'missing test script name', runFn)
3434
la(
3535
is.unemptyString(url) || is.unemptyArray(url),
3636
'missing url to wait on',
3737
url
3838
)
39+
const isSuccessfulHttpCode = status =>
40+
(status >= 200 && status < 300) || status === 304
41+
const validateStatus = namedArguments.expect
42+
? status => status === namedArguments.expect
43+
: isSuccessfulHttpCode
3944

4045
debug('starting server with command "%s", verbose mode?', start, isDebug())
4146

@@ -89,8 +94,7 @@ function waitAndRun ({ start, url, runFn }) {
8994
headers: {
9095
Accept: 'text/html, application/json, text/plain, */*'
9196
},
92-
validateStatus: status =>
93-
(status >= 200 && status < 300) || status === 304
97+
validateStatus
9498
}
9599
debug('wait-on options %o', options)
96100

@@ -121,7 +125,7 @@ const runTheTests = testCommand => () => {
121125
* Starts a single service and runs tests or recursively
122126
* runs a service, then goes to the next list, until it reaches 1 service and runs test.
123127
*/
124-
function startAndTest ({ services, test }) {
128+
function startAndTest ({ services, test, namedArguments }) {
125129
if (services.length === 0) {
126130
throw new Error('Got zero services to start ...')
127131
}
@@ -132,16 +136,18 @@ function startAndTest ({ services, test }) {
132136
return waitAndRun({
133137
start: services[0].start,
134138
url: services[0].url,
139+
namedArguments,
135140
runFn: runTests
136141
})
137142
}
138143

139144
return waitAndRun({
140145
start: services[0].start,
141146
url: services[0].url,
147+
namedArguments,
142148
runFn: () => {
143149
debug('previous service started, now going to the next one')
144-
return startAndTest({ services: services.slice(1), test })
150+
return startAndTest({ services: services.slice(1), test, namedArguments })
145151
}
146152
})
147153
}

‎src/utils.js

+26-12
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,20 @@ const { existsSync } = require('fs')
55
const arg = require('arg')
66
const debug = require('debug')('start-server-and-test')
77

8+
const namedArguments = {
9+
'--expect': Number
10+
}
11+
812
/**
913
* Returns new array of command line arguments
1014
* where leading and trailing " and ' are indicating
1115
* the beginning and end of an argument.
1216
*/
1317
const crossArguments = cliArguments => {
14-
const args = arg(
15-
{
16-
'--expect': Number
17-
},
18-
{
19-
permissive: true,
20-
argv: cliArguments
21-
}
22-
)
18+
const args = arg(namedArguments, {
19+
permissive: true,
20+
argv: cliArguments
21+
})
2322
debug('initial parsed arguments %o', args)
2423
// all other arguments
2524
const cliArgs = args._
@@ -58,6 +57,19 @@ const crossArguments = cliArguments => {
5857
return combinedArgs
5958
}
6059

60+
const getNamedArguments = cliArgs => {
61+
const args = arg(namedArguments, {
62+
permissive: true,
63+
argv: cliArgs
64+
})
65+
debug('initial parsed arguments %o', args)
66+
return {
67+
expect: args['--expect'],
68+
// aliases
69+
'--expected': '--expect'
70+
}
71+
}
72+
6173
/**
6274
* Returns parsed command line arguments.
6375
* If start command is NPM script name defined in the package.json
@@ -205,12 +217,13 @@ const normalizeUrl = input => {
205217
})
206218
}
207219

208-
function printArguments ({ services, test }) {
220+
function printArguments ({ services, test, namedArguments }) {
209221
services.forEach((service, k) => {
210222
console.log('%d: starting server using command "%s"', k + 1, service.start)
211223
console.log(
212-
'and when url "%s" is responding with HTTP status code 200',
213-
service.url
224+
'and when url "%s" is responding with HTTP status code %d',
225+
service.url,
226+
namedArguments.expect
214227
)
215228
})
216229

@@ -231,6 +244,7 @@ function printArguments ({ services, test }) {
231244
const UTILS = {
232245
crossArguments,
233246
getArguments,
247+
getNamedArguments,
234248
isPackageScriptName,
235249
isUrlOrPort,
236250
normalizeUrl,

0 commit comments

Comments
 (0)
Please sign in to comment.