Skip to content

Commit 88d7e9e

Browse files
authored
fix: improve the ping code (#114)
Now should work with Gatsby sites
1 parent fd778c8 commit 88d7e9e

File tree

5 files changed

+97
-39
lines changed

5 files changed

+97
-39
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ Name | Description
274274
[netlify-plugin-prebuild-example](https://github.com/cypress-io/netlify-plugin-prebuild-example) | Runs tests twice, first using the development version of the site, then after Netlify builds the production bundles, runs the tests again
275275
[cypress-example-kitchensink](https://github.com/cypress-io/cypress-example-kitchensink) | Runs only a subset of all tests before publishing the folder to Netlify
276276
[bahmutov/eleventyone](https://github.com/bahmutov/eleventyone) | Example used in [Test Sites Deployed To Netlify Using netlify-plugin-cypress](https://glebbahmutov.com/blog/test-netlify/) tutorial
277+
[gatsby-starter-portfolio-cara](https://github.com/bahmutov/gatsby-starter-portfolio-cara) | A Gatsby site example
277278

278279
## Debugging
279280

src/ping-cli.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// a little CLI utility for testing pinging websites
2+
// node ./src/ping-cli <url>
3+
4+
const { ping } = require('./utils')
5+
const timeoutSeconds = 60
6+
const url = process.argv[2]
7+
console.log('pinging url %s for %d seconds', url, timeoutSeconds)
8+
if (!url) {
9+
console.error('Missing url to ping')
10+
process.exit(1)
11+
}
12+
ping(url, timeoutSeconds * 1000).then(
13+
() => {
14+
console.log('all good')
15+
},
16+
(err) => {
17+
console.error('a problem', err)
18+
},
19+
)

src/ping.js

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
const got = require('got')
2+
const debug = require('debug')('netlify-plugin-cypress')
3+
const debugVerbose = require('debug')('netlify-plugin-cypress:verbose')
4+
5+
/**
6+
* A small utility for checking when an URL responds, kind of
7+
* a poor man's https://www.npmjs.com/package/wait-on. This version
8+
* is implemented using https://github.com/sindresorhus/got
9+
*/
10+
const ping = (url, timeout) => {
11+
if (!timeout) {
12+
throw new Error('Expected timeout in ms')
13+
}
14+
15+
debug('pinging "%s" for %d ms max', url, timeout)
16+
17+
// make copy of the error codes that "got" retries on
18+
const errorCodes = [...got.defaults.options.retry.errorCodes]
19+
errorCodes.push('ESOCKETTIMEDOUT')
20+
21+
// we expect the server to respond within a time limit
22+
// and if it does not - retry up to total "timeout" duration
23+
const individualPingTimeout = Math.min(timeout, 30000)
24+
const limit = Math.ceil(timeout / individualPingTimeout)
25+
26+
debug(`total ping timeout ${timeout}`)
27+
debug(`individual ping timeout ${individualPingTimeout}ms`)
28+
debug(`retries limit ${limit}`)
29+
30+
const start = +new Date()
31+
return got(url, {
32+
headers: {
33+
Accept: 'text/html, application/json, text/plain, */*',
34+
},
35+
timeout: individualPingTimeout,
36+
errorCodes,
37+
retry: {
38+
limit,
39+
calculateDelay({ error, attemptCount }) {
40+
if (error) {
41+
debugVerbose(`got error ${JSON.stringify(error)}`)
42+
}
43+
const now = +new Date()
44+
const elapsed = now - start
45+
debugVerbose(
46+
`${elapsed}ms ${error.method} ${error.host} ${error.code} attempt ${attemptCount}`,
47+
)
48+
if (elapsed > timeout) {
49+
console.error(
50+
'%s timed out on retry %d of %d',
51+
url,
52+
attemptCount,
53+
limit,
54+
)
55+
return 0
56+
}
57+
58+
// if the error code is ECONNREFUSED use shorter timeout
59+
// because the server is probably starting
60+
if (error.code === 'ECONNREFUSED') {
61+
return 1000
62+
}
63+
64+
// default "long" timeout
65+
return individualPingTimeout
66+
},
67+
},
68+
}).then(() => {
69+
const now = +new Date()
70+
const elapsed = now - start
71+
debug(`pinging ${url} has finished ok after ${elapsed}ms`)
72+
})
73+
}
74+
75+
module.exports = { ping }

src/utils.js

Lines changed: 1 addition & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,7 @@
11
// @ts-check
22
const puppeteer = require('puppeteer')
3-
const got = require('got')
43
const debug = require('debug')('netlify-plugin-cypress')
5-
const debugVerbose = require('debug')('netlify-plugin-cypress:verbose')
6-
7-
/**
8-
* A small utility for checking when an URL responds, kind of
9-
* a poor man's https://www.npmjs.com/package/wait-on
10-
*/
11-
const ping = (url, timeout) => {
12-
debug('pinging "%s" for %d ms max', url, timeout)
13-
const start = +new Date()
14-
15-
return got(url, {
16-
retry: {
17-
limit: 30,
18-
calculateDelay({ attemptCount, retryOptions, error }) {
19-
const now = +new Date()
20-
const elapsed = now - start
21-
debugVerbose(`attempt ${attemptCount} ${elapsed}ms ${error.message}`)
22-
23-
if (elapsed > timeout) {
24-
debug(
25-
'%s timed out after %dms, timeout was %dms',
26-
url,
27-
elapsed,
28-
timeout,
29-
)
30-
console.error(
31-
'%s timed out after %dms, timeout was %dms',
32-
url,
33-
elapsed,
34-
timeout,
35-
)
36-
return 0
37-
}
38-
return 1000
39-
},
40-
},
41-
})
42-
}
4+
const { ping } = require('./ping')
435

446
const getBrowserPath = async () => {
457
const browserFetcher = puppeteer.createBrowserFetcher()

tests/routing/netlify.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ TERM = "xterm"
2222
[plugins.inputs.preBuild]
2323
start = 'npm start'
2424
wait-on = 'http://localhost:3000'
25+
wait-on-timeout = '45' # seconds
2526

2627
# and test the built site after
2728
[plugins.inputs]

0 commit comments

Comments
 (0)