diff --git a/README.md b/README.md
index fcb9eaf6..6000bdc1 100644
--- a/README.md
+++ b/README.md
@@ -20,6 +20,10 @@ And then add the plugin's name to the list of build plugins in `netlify.toml` fi
*note:* this plugin assumes you have already installed Cypress as a dev NPM dependency.
+### Chromium install
+
+This plugin installs [via Puppeteer](https://github.com/puppeteer/puppeteer) Chromium browser, which is also cached inside `./node_modules` folder.
+
## How does it work
When Netlify Build runs, it "knows" the output folder name and calls the `netlify-plugin-cypress` after the build has finished with that folder. Then the plugin runs Cypress tests using its [NPM module API](https://on.cypress.io/module-api). If the tests pass, the plugin finishes and the Netlify deploy starts.
@@ -173,6 +177,27 @@ package = "netlify-plugin-cypress"
See [cypress-example-kitchensink](https://github.com/cypress-io/cypress-example-kitchensink) for instance.
+### Chromium
+
+By default all tests run using built-in Electron browser. If you want to use Chromium:
+
+```toml
+[build]
+command = "npm run build"
+publish = "build"
+ [build.environment]
+ # cache Cypress binary in local "node_modules" folder
+ # so Netlify caches it
+ CYPRESS_CACHE_FOLDER = "./node_modules/CypressBinary"
+ # set TERM variable for terminal output
+ TERM = "xterm"
+
+[[plugins]]
+package = "netlify-plugin-cypress"
+ [plugins.inputs]
+ browser = "chromium"
+```
+
### testing SPA routes
SPAs need catch-all redirect setup to make non-root paths accesssible by tests. You can enable this with `spa` parameter.
diff --git a/circle.yml b/circle.yml
index 4a2c8c94..763d0aa6 100644
--- a/circle.yml
+++ b/circle.yml
@@ -89,6 +89,19 @@ jobs:
environment:
DEBUG: netlify-plugin-cypress
+ 'test-using-chromium':
+ executor: cypress/base-12-14-0
+ steps:
+ # all dependencies were installed in previous job
+ - attach_workspace:
+ at: ~/
+ - run:
+ name: Netlify Build 🏗
+ command: npx netlify build
+ working_directory: tests/use-chromium
+ environment:
+ DEBUG: netlify-plugin-cypress
+
routing:
executor: cypress/base-12-14-0
steps:
@@ -123,6 +136,9 @@ workflows:
- 'test-prebuild-only':
requires:
- cypress/install
+ - test-using-chromium:
+ requires:
+ - cypress/install
- routing:
requires:
- cypress/install
@@ -134,6 +150,7 @@ workflows:
- 'recording test'
- 'test-twice'
- 'test-prebuild-only'
+ - test-using-chromium
- 'routing'
filters:
branches:
diff --git a/manifest.yml b/manifest.yml
index 5fa7d872..f462bf50 100644
--- a/manifest.yml
+++ b/manifest.yml
@@ -11,6 +11,11 @@ inputs:
# by default run the tests
- name: skip
default: false
+ # by default the tests run in Electron
+ # but because of the dependency we download Chromium
+ # so you can set "browser = electron"
+ - name: browser
+ default: electron
# tells the plugin how to start the server using custom command
# and waiting for an url, record to the dashboard, tag, etc
diff --git a/netlify.toml b/netlify.toml
index 79f878b3..6ae29701 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -10,8 +10,9 @@ publish = "public"
[[plugins]]
# local Cypress plugin will test our site after it is built
package = "."
- # [plugins.inputs]
- # spec = 'cypress/integration/spec.js'
+ [plugins.inputs]
+ # browser = "electron"
+ # spec = 'cypress/integration/spec.js'
# [plugins.inputs.preBuild]
# start = 'npm start'
# wait-on = 'http://localhost:5000'
diff --git a/package-lock.json b/package-lock.json
index 070e088e..35a8f0b8 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -4111,12 +4111,6 @@
}
}
},
- "node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
- "dev": true
- },
"node-releases": {
"version": "1.1.70",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz",
@@ -6267,6 +6261,15 @@
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==",
"dev": true
},
+ "@types/yauzl": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.1.tgz",
+ "integrity": "sha512-A1b8SU4D10uoPjwb0lnHmmu8wZhR9d+9o2PKBQT2jU5YPTKsxac6M2qGAdY7VcL+dHHhARVUDmeg0rOrcd9EjA==",
+ "optional": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@typescript-eslint/eslint-plugin": {
"version": "2.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.34.0.tgz",
@@ -7786,8 +7789,7 @@
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
- "dev": true
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"base": {
"version": "0.11.2",
@@ -7853,8 +7855,7 @@
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
- "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==",
- "dev": true
+ "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"basic-auth": {
"version": "2.0.1",
@@ -7910,7 +7911,6 @@
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.4.tgz",
"integrity": "sha512-7tdr4EpSd7jJ6tuQ21vu2ke8w7pNEstzj1O8wwq6sNNzO3UDi5MA8Gny/gquCj7r2C6fHudg8tKRGyjRgmvNxQ==",
- "dev": true,
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
@@ -7921,7 +7921,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -8081,7 +8080,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -8256,7 +8254,6 @@
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
- "dev": true,
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
@@ -8281,8 +8278,7 @@
"buffer-crc32": {
"version": "0.2.13",
"resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
- "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
- "dev": true
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI="
},
"buffer-es6": {
"version": "4.9.3",
@@ -8664,8 +8660,7 @@
"chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
- "dev": true
+ "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
},
"chrome-trace-event": {
"version": "1.0.2",
@@ -9406,8 +9401,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
- "dev": true
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
"version": "1.6.2",
@@ -11434,6 +11428,11 @@
"typescript": "^3.8.3"
}
},
+ "devtools-protocol": {
+ "version": "0.0.847576",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.847576.tgz",
+ "integrity": "sha512-0M8kobnSQE0Jmly7Mhbeq0W/PpZfnuK+WjN2ZRVPbGqYwCHCioAVp84H0TcLimgECcN5H976y5QiXMGBC9JKmg=="
+ },
"diff-sequences": {
"version": "24.9.0",
"resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-24.9.0.tgz",
@@ -13914,8 +13913,7 @@
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
- "dev": true
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs-extra": {
"version": "8.1.0",
@@ -13952,8 +13950,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
- "dev": true
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "2.1.2",
@@ -14133,7 +14130,6 @@
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
- "dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
@@ -15020,8 +15016,7 @@
"ieee754": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
- "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
- "dev": true
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
},
"iferr": {
"version": "0.1.5",
@@ -15197,7 +15192,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
@@ -19365,7 +19359,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -19533,6 +19526,11 @@
"minimist": "^1.2.5"
}
},
+ "mkdirp-classic": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
+ "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
+ },
"modify-values": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz",
@@ -19832,12 +19830,6 @@
"integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
"dev": true
},
- "node-fetch": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
- "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==",
- "dev": true
- },
"p-map": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
@@ -20437,10 +20429,9 @@
}
},
"node-fetch": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
- "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
- "dev": true
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz",
+ "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
},
"node-forge": {
"version": "0.9.0",
@@ -25207,8 +25198,7 @@
"pend": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
- "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
- "dev": true
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
},
"performance-now": {
"version": "2.1.0",
@@ -25266,7 +25256,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
- "dev": true,
"requires": {
"find-up": "^4.0.0"
},
@@ -25275,7 +25264,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
- "dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
@@ -25285,7 +25273,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
- "dev": true,
"requires": {
"p-locate": "^4.1.0"
}
@@ -25294,7 +25281,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
- "dev": true,
"requires": {
"p-try": "^2.0.0"
}
@@ -25303,7 +25289,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
"requires": {
"p-limit": "^2.2.0"
}
@@ -25311,14 +25296,12 @@
"p-try": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
- "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
- "dev": true
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
}
}
},
@@ -26778,8 +26761,7 @@
"progress": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
- "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
- "dev": true
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA=="
},
"promise": {
"version": "8.1.0",
@@ -26842,6 +26824,11 @@
"ipaddr.js": "1.9.1"
}
},
+ "proxy-from-env": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
+ "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
+ },
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -26929,6 +26916,51 @@
"escape-goat": "^2.0.0"
}
},
+ "puppeteer": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-7.0.1.tgz",
+ "integrity": "sha512-04V05BKQdloUCOa7JyQBaNXPIiVByz1eAFAElcrpMHIQkfu22J0RKFhRWkXZGXdl03yoHuaZwqyB/qG7YJu5Ew==",
+ "requires": {
+ "debug": "^4.1.0",
+ "devtools-protocol": "0.0.847576",
+ "extract-zip": "^2.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "node-fetch": "^2.6.1",
+ "pkg-dir": "^4.2.0",
+ "progress": "^2.0.1",
+ "proxy-from-env": "^1.0.0",
+ "rimraf": "^3.0.2",
+ "tar-fs": "^2.0.0",
+ "unbzip2-stream": "^1.3.3",
+ "ws": "^7.2.3"
+ },
+ "dependencies": {
+ "extract-zip": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
+ "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
+ "requires": {
+ "@types/yauzl": "^2.9.1",
+ "debug": "^4.1.1",
+ "get-stream": "^5.1.0",
+ "yauzl": "^2.10.0"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "ws": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.3.tgz",
+ "integrity": "sha512-hr6vCR76GsossIRsr8OLR9acVVm1jyfEWvhbNjtgPOrfvAlKzvyeg/P6r8RuDjRyrcQoPQT7K0DGEPc7Ae6jzA=="
+ }
+ }
+ },
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
@@ -30613,11 +30645,21 @@
"integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==",
"dev": true
},
+ "tar-fs": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
+ "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+ "requires": {
+ "chownr": "^1.1.1",
+ "mkdirp-classic": "^0.5.2",
+ "pump": "^3.0.0",
+ "tar-stream": "^2.1.4"
+ }
+ },
"tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "dev": true,
"requires": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
@@ -30630,7 +30672,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
- "dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@@ -31334,7 +31375,6 @@
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
"integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
- "dev": true,
"requires": {
"buffer": "^5.2.1",
"through": "^2.3.8"
@@ -33916,7 +33956,6 @@
"version": "2.10.0",
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
"integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=",
- "dev": true,
"requires": {
"buffer-crc32": "~0.2.3",
"fd-slicer": "~1.1.0"
@@ -33926,7 +33965,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
"integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=",
- "dev": true,
"requires": {
"pend": "~1.2.0"
}
diff --git a/package.json b/package.json
index d19fc31e..a9eb0e84 100644
--- a/package.json
+++ b/package.json
@@ -22,7 +22,8 @@
"dependencies": {
"debug": "4.1.1",
"got": "10.7.0",
- "local-web-server": "^4.2.1"
+ "local-web-server": "^4.2.1",
+ "puppeteer": "^7.0.1"
},
"repository": {
"type": "git",
diff --git a/src/index.js b/src/index.js
index 3afeb082..f91b3e98 100644
--- a/src/index.js
+++ b/src/index.js
@@ -2,9 +2,11 @@
const LocalWebServer = require('local-web-server')
const debug = require('debug')('netlify-plugin-cypress')
const debugVerbose = require('debug')('netlify-plugin-cypress:verbose')
-const { ping } = require('./utils')
+const { ping, getBrowserPath } = require('./utils')
const fs = require('fs')
+const DEFAULT_BROWSER = 'electron'
+
function serveFolder(directory, port, spa) {
if (typeof spa === 'boolean') {
if (spa) {
@@ -88,7 +90,13 @@ async function waitOnMaybe(buildUtils, options = {}) {
}
}
-async function runCypressTests(baseUrl, record, spec, group, tag) {
+const isValidBrowser = (name) => name === 'electron' || name === 'chromium'
+
+async function runCypressTests(baseUrl, record, spec, group, tag, browser) {
+ if (!isValidBrowser(browser)) {
+ throw new Error(`Invalid browser name "${browser}"`)
+ }
+
// we will use Cypress via its NPM module API
// https://on.cypress.io/module-api
const cypress = require('cypress')
@@ -100,6 +108,9 @@ async function runCypressTests(baseUrl, record, spec, group, tag) {
ciBuildId = process.env.BUILD_ID
}
+ const browserPath =
+ browser === 'electron' ? 'electron' : await getBrowserPath()
+
debug('run cypress params %o', {
baseUrl,
record,
@@ -107,6 +118,7 @@ async function runCypressTests(baseUrl, record, spec, group, tag) {
group,
tag,
ciBuildId,
+ browser: browserPath,
})
return await cypress.run({
@@ -118,6 +130,8 @@ async function runCypressTests(baseUrl, record, spec, group, tag) {
group,
tag,
ciBuildId,
+ browser: browserPath,
+ headless: true,
})
}
@@ -208,6 +222,7 @@ async function postBuild({
group,
tag,
spa,
+ browser,
errorCallback,
}) {
const port = 8080
@@ -224,7 +239,14 @@ async function postBuild({
const baseUrl = `http://localhost:${port}`
- const results = await runCypressTests(baseUrl, record, spec, group, tag)
+ const results = await runCypressTests(
+ baseUrl,
+ record,
+ spec,
+ group,
+ tag,
+ browser,
+ )
await new Promise((resolve, reject) => {
server.close((err) => {
@@ -254,6 +276,8 @@ module.exports = {
return
}
+ const browser = arg.inputs.browser || DEFAULT_BROWSER
+
const closeServer = startServerMaybe(arg.utils.run, preBuildInputs)
await waitOnMaybe(arg.utils.build, preBuildInputs)
@@ -272,7 +296,14 @@ module.exports = {
}
}
- const results = await runCypressTests(baseUrl, record, spec, group, tag)
+ const results = await runCypressTests(
+ baseUrl,
+ record,
+ spec,
+ group,
+ tag,
+ browser,
+ )
if (closeServer) {
debug('closing server')
@@ -295,6 +326,8 @@ module.exports = {
const fullPublishFolder = arg.constants.PUBLISH_DIR
debug('folder to publish is "%s"', fullPublishFolder)
+ const browser = arg.inputs.browser || DEFAULT_BROWSER
+
// only if the user wants to record the tests and has set the record key
// then we should attempt recording
const record = hasRecordKey() && Boolean(arg.inputs.record)
@@ -322,6 +355,7 @@ module.exports = {
group,
tag,
spa,
+ browser,
errorCallback,
})
},
@@ -362,6 +396,8 @@ module.exports = {
return errorCallback('Missing DEPLOY_PRIME_URL')
}
+ const browser = arg.inputs.browser || DEFAULT_BROWSER
+
// only if the user wants to record the tests and has set the record key
// then we should attempt recording
const hasKey = hasRecordKey()
@@ -394,6 +430,7 @@ module.exports = {
spec,
group,
tag,
+ browser,
)
processCypressResults(results, errorCallback)
},
diff --git a/src/utils.js b/src/utils.js
index edbff7d5..6bf80357 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,4 +1,5 @@
// @ts-check
+const puppeteer = require('puppeteer')
const got = require('got')
const debug = require('debug')('netlify-plugin-cypress')
const debugVerbose = require('debug')('netlify-plugin-cypress:verbose')
@@ -14,24 +15,45 @@ const ping = (url, timeout) => {
return got(url, {
retry: {
limit: 30,
- calculateDelay({attemptCount, retryOptions, error}) {
+ calculateDelay({ attemptCount, retryOptions, error }) {
const now = +new Date()
const elapsed = now - start
debugVerbose(`attempt ${attemptCount} ${elapsed}ms ${error.message}`)
if (elapsed > timeout) {
- debug('%s timed out after %dms, timeout was %dms',
- url, elapsed, timeout)
- console.error('%s timed out after %dms, timeout was %dms',
- url, elapsed, timeout)
+ debug(
+ '%s timed out after %dms, timeout was %dms',
+ url,
+ elapsed,
+ timeout,
+ )
+ console.error(
+ '%s timed out after %dms, timeout was %dms',
+ url,
+ elapsed,
+ timeout,
+ )
return 0
}
return 1000
- }
- }
+ },
+ },
})
}
+const getBrowserPath = async () => {
+ const browserFetcher = puppeteer.createBrowserFetcher()
+ const revisions = await browserFetcher.localRevisions()
+ debug('local Chromium revisions %o', revisions)
+ if (revisions.length <= 0) {
+ throw new Error('Could not find local browser')
+ }
+ const info = await browserFetcher.revisionInfo(revisions[0])
+ debug('found Chromium %o', info)
+ return info.executablePath
+}
+
module.exports = {
- ping
+ ping,
+ getBrowserPath,
}
diff --git a/tests/use-chromium/cypress.json b/tests/use-chromium/cypress.json
new file mode 100644
index 00000000..e36f9847
--- /dev/null
+++ b/tests/use-chromium/cypress.json
@@ -0,0 +1,5 @@
+{
+ "pluginsFile": false,
+ "supportFile": false,
+ "fixturesFolder": false
+}
diff --git a/tests/use-chromium/cypress/integration/spec.js b/tests/use-chromium/cypress/integration/spec.js
new file mode 100644
index 00000000..27608f29
--- /dev/null
+++ b/tests/use-chromium/cypress/integration/spec.js
@@ -0,0 +1,6 @@
+///