mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-24 07:59:12 -05:00
458db1cd02
* docs: revise contributor advice for node.js setup (#26652)
* feat: initial release of cypress/vite-plugin-cypress-esm (#26663)
* chore: release @cypress/vite-plugin-cypress-esm-v1.0.0
[skip ci]
* chore: upgrade Lerna to v5 and use Nx (#26660)
* dependency(deps): update dependency engine.io to v6.4.2 [security] (#26664)
* dependency(deps): update dependency engine.io to v6.4.2 [security]
* updating changelog
---------
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Matt Schile <mschile@cypress.io>
* fix: updated CYPRESS_DOWNLOAD_PATH_TEMPLATE regex to allow multiple replacements (#25531)
* feat: Component Testing banner (#26625)
Co-authored-by: elevatebart <bart@cypress.io>
* chore: Update v8 snapshot cache (#26647)
Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
* chore: 12.12.0 release updates (#26697)
* chore: cypress[26674] updated github workflows to use checklout@v3 and stop using set-output and move to file use (#26696)
* fix: move types condition to the front (#26630)
* fix: move `types` condition to the front
* chore: update changelog
* optimize deps for vite
* update config
* try optimizeDeps.include
* missing dep
---------
Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
* fix: revert #26452 (Yarn Plug n Play compat regression) (#26735)
* Revert "fix: correctly resolve dependencies for CT onboarding when using Yarn Plug n Play (#26452)"
This reverts commit 7a33f5c1a8.
* changelog
* changelog
* chore: fixing PR link in releaseData.json (#26734)
* chore: update stalebot config (#26745)
* misc: ACI empty state slideshows (#26692)
Co-authored-by: Stokes Player <stokes@cypress.io>
* fix: do not cache module resolution during launchpad dependency detection (#26726)
Co-authored-by: Mike Plummer <mikep@cypress.io>
* fix: Vite esm plugin issues (#26714)
* chore: Update v8 snapshot cache (#26707)
Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
* chore: adding in repo token to explicitly use that while running commands [skip ci] (#26746)
* chore(dependency): update dependency @percy/cypress to ^3.1.2 🌟 (#26717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Chris Breiding <chrisbreiding@users.noreply.github.com>
* chore: Remove console.log (#26756)
* chore: put types condition first in the syncing script (#26743)
Co-authored-by: Chris Breiding <chrisbreiding@users.noreply.github.com>
* test: create lists files after folders when in same directory in specs list (#26723)
Co-authored-by: Chris Breiding <chrisbreiding@users.noreply.github.com>
* chore: update vm2 to 3.9.19 (#26772)
* chore: add telemetry to the proxy (#26695)
* chore: set up instrumentation and instrument middleware
* chore: set up console exporter
* chore: add parent span option to telemetry package
* chore: set up telemetry verbose mode
* chore: instrument the network proxy - part 1
* chore: make sure to terminate spans when request is aborted
* fix telemetry, create/end the request middle prior to sending the outbound request
* avoid telemetry ts build step, create entrypoint into packages/telemetry using TS conventions
* allow env vars to be "true" or "1"
* when creating child span, inherit their attributes directly from the parent
* create custom honeycomb exporter and span processor to log traces
* remove duplicate code that's already called in this.setRootContext
* cleanup
* more clean up
* update honeycomb network:proxy attributes, update console.log message
* yarn lock
* chore: remove performance API in middleware
* chore: end response on correct event
* recursively gather parent attributes on close
* added key and some clean up
* github action detector, move verbose into index, verbose log commands
* some tests
* clean up honeycomb exporter
* some renaming
* testing console trace link exporter
* Don't lose the top span when running in verbose.
* link to the right place for prod/dev
* changes to verbose to make sure it is read in the browser
* Apply suggestions from code review
* pass parent attributes between telemetry instances
* default to false
* 'fix' build issues
* src not dist
* add back on start span
* once more with feeling
* Fix some tests
* try this i guess
* revert auto build
* Apply suggestions from code review
Co-authored-by: Bill Glesias <bglesias@gmail.com>
* support failed commands
* Address PR comments
* Address PR Comments
* error handling
* handle all the errors
---------
Co-authored-by: Bill Glesias <bglesias@gmail.com>
Co-authored-by: Brian Mann <brian.mann86@gmail.com>
* chore: update triage workflow to add comment to contributor prs (#26493)
Co-authored-by: Ben M <benm@cypress.io>
* chore: telemetry pr cleanup (#26776)
* fix: fix UI flash when switching to debug page (#26761)
* chore: add Nx Cloud (#26712)
* chore: add empty nx.json [run ci]
* chore: add nx cloud runner [run ci]
* chore: add nx-cloud dep [run ci]
* chore: update local nx cloud accessToken to be read-only
* feat: update git related messages for runs and debug (#26758)
* feat(app): update DebugError copy
* feat: set isUsingGit project flag and consume in DebugContainer
* feat(app): update not using git icon for DebugError
* feat(app): displays alert on runs page when not using git
* feat(app): add component for when no runs for current branch
* feat(app): add warning for no runs for branch on runs container
* chore: add feat to CHANGELOG
* chore: remove logged status value
* chore: resolve import from merge conflict
* test(app): stub branch name for e2e runs spec
* chore: add line break in changelog entry
* chore: cleanup PR
* chore: fix i18n import for DebugBranchError
* chore: add utm and update Warning links to inline
* chore: capitalize Git in i18n
* ref: warning liink
* test: add i18n to tests
* test(app): change utm_source assertions
* chore: cleanup pr
* chore: remove unused prop
* test(app): remove no git warning when moving to runs page in e2e
* chore: change template logic
* chore: remove duplicate RUNS_TAB_MEDIUM const
* Changed Debug test assertion and reordered new components for Debug
---------
Co-authored-by: Stokes Player <stokes.player@gmail.com>
* chore: rename video processing events to capture/compress (#26800)
* chore: change processing nomenclature to compressing when printing the run.
* chore: rename 'capturing of' to 'capturing'
* chore: rename upload results to upload screenshots & videos (#26811)
* chore: rename upload results to upload screenshots & videos
* run ci
* chore: capture versions of relevant dependencies with `x-dependencies` header (#26814)
* chore: update changlelog script to handle revert pr ref (#26801)
* fix: Correct typescript scaffold dependency (#26815)
* fix: correct typescript scaffold dependency (#26204)
* add changelog
* Update change log for PR comment
Co-authored-by: Mike Plummer <mike-plummer@users.noreply.github.com>
---------
Co-authored-by: Mike Plummer <mike-plummer@users.noreply.github.com>
Co-authored-by: Mark Noonan <mark@cypress.io>
* chore: 12.13.0 prep (#26833)
* chore: 12.13.0 release (#26834)
* chore: 12.13.0 changelog fix
* remove pending, bump version
* fix typo
* chore: release @cypress/vite-plugin-cypress-esm-v1.0.1
[skip ci]
* chore: Implement runSpec mutation (#26782)
* chore: replace gitter badge with discord on readme (#26771)
* chore: add GraphQL mutation for sending system notifications via Electron (#26773)
* fix: upgrade typescript from 4.7.4 to 4.9.5 (#26826)
Snyk has created this PR to upgrade typescript from 4.7.4 to 4.9.5.
See this package in npm:
See this project in Snyk:
https://app.snyk.io/org/cypress-opensource/project/d5b36925-e6ee-455d-9649-6560a9aca413?utm_source=github&utm_medium=referral&page=upgrade-pr
* test: fix 2 broken tests for Windows (#26854)
* Update stale_issues_and_pr_cleanup.yml
Upped the number of operations per run. Have been manually doing that so this job can get through all the issues in the repo with no problems.
* chore(dep): [Snyk] Upgrade vite from 2.9.13 to 2.9.15 (#26830)
Co-authored-by: Ben M <benm@cypress.io>
* Update triage_add_to_project.yml
* chore: fix minor background color styling in debug results component (#26887)
* Update stale_issues_and_pr_cleanup.yml
stalebot was incorrectly configured to run in debug mode. I have updated the default to run in normal mode when running scheduled
* chore: Deprecate @cypress/xpath package (#26893)
* chore: add telemetry realworld app (#26896)
* chore: capture telemetry for realworld app maybe
* idk what i was doing
* setup record key and telemetry
* testing
* override project id
* some times we just need a little context.
* Adding tests
* Adding comment
* chore(deps): update dependency find-process to v1.4.7 🌟 (#26906)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
* chore(deps): update dependency firefox-profile to v4.3.2 🌟 (#26912)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
* chore: add browser state action for debug (#26884)
* chore: add browser state action for debug (#26763)
* Address PR comments
- remove unneeded async and test context
- genericize openProject function
* Revert route change, update spec description
* chore: replace gift devDep with simple-git (#26728)
* chore: replace arg devDep with minimist; remove unused shx devDep (#26727)
* chore: enable caching for lint task (#26791)
* chore: remove old performance reporting (#26920)
* chore: remove old performance reporting
* remove libhoney dep
* try this
* build and build snapshots if deps are out of date
* foiled by a comma
* freaking comma
* no snapshots maybe ugh
* ignore engines instead
* don't need this
* remove rename support file step
* chore: update Snyk to scan all projects (#26867)
* SEC-544 chore: [Snyk] Update Snyk flag in Git actn
* Update snyk_sca_scan.yaml
Removed --debug switch from the test command
---------
Co-authored-by: brady-cypressio <90723145+brady-cypressio@users.noreply.github.com>
* chore: skip problematic component tests that fail on contributor PRs (#26924)
* chore: omit unused circle variables that cause contributor PR issues (#26935)
* chore: make git message warnings remain dismissable (#26812)
* feat: make git message warnings remain dismissable
* chore: update CHANGELOG
* chore: update CHANGELOG
* chore: remove unneeded code
* chore: update BannerId types
* chore: fix queryies
* chore: clean up PR
* chore: move TrackedWarning to frontend-shared
* chore: update import
* ref: move TrackedWarning to TrackedBanner
* chore: udpate CHANGELOG
* fix: update TrackedBanner to parse markdown message
* chore: set TrackedBanner default message prop
* chore: update RunsContainer
* chore: add missing tests and update alert type
---------
Co-authored-by: Stokes Player <stokes@cypress.io>
* chore: replace fast-glob with globby; remove unneeded getenv dep (#26730)
* fix: update angular dep min versions (#26908)
* fix: update angular dep min versions
* chore: update CHANGELOG
* chore: add line break to changelog
* chore: update changelog pending release date
* chore: remove whitespace
* fix: upgrade typescript from 4.2.3 to 4.9.5 (#26858)
Snyk has created this PR to upgrade typescript from 4.2.3 to 4.9.5.
See this package in npm:
See this project in Snyk:
https://app.snyk.io/org/cypress-opensource/project/5fdaebf8-b115-41d1-a2d9-857261769179?utm_source=github&utm_medium=referral&page=upgrade-pr
Co-authored-by: Bill Glesias <bglesias@gmail.com>
* chore: Update v8 snapshot cache (#26762)
Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
* feat: Implement testing type switch promos (#26894)
* feat: Implement testing type switch promos
* Add tests, changelog entry
* Add tests
* Fix button styling
* Styling fixes, add framework links
* Add missing testId
* run ci
* Fix spec
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
* Fix styling issues
* Resolve code review findings
* Fix issue with yarn.lock
* Fix extra padding at bottom of promo
* Add tests for utm params
* Add test for switching testing type when both configured
* Fix changelog version
* Address review comments
* Widen promo when no image defined
* Prevent flash of promo before query resolves
* Reduce top margin
* reduce size of text box to match latest figma
* update button style to match figma
* increase width at which we collapse sidenav
* add short versions of the headings
* remove skeletons from header
* avoid extra height
* adjustments for column alignment
* fix flaky test
* update tests for responsive text changes
* update changelog
* restore spacing between header items
* avoid occasional flash of promo on page load
* update text handling
* fix types and tests
* Update packages/app/src/specs/SpecsList.vue
Co-authored-by: Stokes Player <stokes@cypress.io>
* updated final e2e bullet
* fix question mark icon flashing
* text formatting
* remove superfluous snapshot [skip ci]
---------
Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
Co-authored-by: marktnoonan <mark@cypress.io>
Co-authored-by: astone123 <adams@cypress.io>
Co-authored-by: Stokes Player <stokes@cypress.io>
Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
* chore: release internal-scripts-v1.0.0
[skip ci]
* chore: fix changelog links (#26948)
* chore: 12.14.0 release (#26950)
* chore: Update Chrome (stable) to 114.0.5735.106 and Chrome (beta) to 115.0.5790.13 (#26650)
* chore: bump cache version (#26952)
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
* chore: move release date (#26958)
* chore(deps): update dependency @antfu/utils to ^0.7.0 [security] (#26923)
* chore: fix base error styling (#26954)
* chore: remove low value percy snapshots (#26934)
* chore: remove low value percy snapshots
* chore: remove more low value percy snapshots [run ci]
* chore: remove more low value percy snapshots
* remove additional snapshots
* reduce snapshots
* fix types
---------
Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
* chore: changelog updates (#26964)
* chore: stabilize side navigation bar during loading and switching testing types (#26953)
* fix: log video path if exists, regardless of compression (#26813)
* chore: print the video path whether or not compression is on or fails
* chore: fix video replacement regex
* chore: add bugfix entry
* feat: allow users to pass true to videoCompression config and only a… (#26810)
* chore: allow users to pass true to videoCompression config and only allow valudes 1-51 inclusively to be passed in
* run ci
* chore: allow zero to be option for CRF as we will coerve it to false and skip compression to have a lossless video, which has the same effect
* Update cli/CHANGELOG.md
* chore: update videoCompression types
* chore: update changelog
* Update cli/CHANGELOG.md
* Update cli/types/cypress.d.ts
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
* Update packages/config/src/validation.ts
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
* chore: update config snapshots
* Update packages/config/test/validation.spec.ts
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
* chore: add system test on videoCompression=true coersion
* chore: document 0 as being false and not a valid CRF option for cypress video compression and make CRF valid values 1-51
* chore: fix types
* chore: fix types
* chore: fix change to log as feature and not bugfix
* chore: fix server side unit tests
---------
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
* chore: trigger mac/linux/windows binary builds and v8 snapshot cache update tests
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
* chore: fix possible bad merge from mismatched snapshot in CLOUD_AUTO_CANCEL_MISMATCH test
* chore: fix possible bad merge from mismatched snapshot in record_spec system test
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
* chore: updating v8 snapshot cache
---------
Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com>
Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com>
Co-authored-by: semantic-release-bot <semantic-release-bot@martynus.net>
Co-authored-by: Adam Stone-Lord <adams@cypress.io>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Matt Schile <mschile@cypress.io>
Co-authored-by: Mahdi Khashan <58775404+mahdikhashan@users.noreply.github.com>
Co-authored-by: Mike Plummer <mike-plummer@users.noreply.github.com>
Co-authored-by: elevatebart <bart@cypress.io>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Manuel <ryanm@cypress.io>
Co-authored-by: Ben M <benm@cypress.io>
Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-authored-by: Stokes Player <stokes@cypress.io>
Co-authored-by: Mike Plummer <mikep@cypress.io>
Co-authored-by: Chris Breiding <chrisbreiding@users.noreply.github.com>
Co-authored-by: Luis Furtado <46112985+luis-furtado@users.noreply.github.com>
Co-authored-by: Matt Henkes <mjhenkes@gmail.com>
Co-authored-by: Brian Mann <brian.mann86@gmail.com>
Co-authored-by: Emily Rohrbough <emilyrohrbough@users.noreply.github.com>
Co-authored-by: Jordan <jordan@jpdesigning.com>
Co-authored-by: Stokes Player <stokes.player@gmail.com>
Co-authored-by: Dave Kasper <dave.m.kasper@gmail.com>
Co-authored-by: Mark Noonan <mark@cypress.io>
Co-authored-by: Ely Lucas <ely@meta-tek.net>
Co-authored-by: Snyk bot <snyk-bot@snyk.io>
Co-authored-by: Jennifer Shehane <jennifer@cypress.io>
Co-authored-by: cypresschris <96069059+cypresschris@users.noreply.github.com>
Co-authored-by: brady-cypressio <90723145+brady-cypressio@users.noreply.github.com>
717 lines
21 KiB
JavaScript
717 lines
21 KiB
JavaScript
require('../../spec_helper')
|
|
|
|
const _ = require('lodash')
|
|
const os = require('os')
|
|
const cp = require('child_process')
|
|
const la = require('lazy-ass')
|
|
const is = require('check-more-types')
|
|
const path = require('path')
|
|
const nock = require('nock')
|
|
const hasha = require('hasha')
|
|
const debug = require('debug')('test')
|
|
const snapshot = require('../../support/snapshot')
|
|
|
|
const fs = require(`${lib}/fs`)
|
|
const logger = require(`${lib}/logger`)
|
|
const util = require(`${lib}/util`)
|
|
const download = require(`${lib}/tasks/download`)
|
|
|
|
const stdout = require('../../support/stdout')
|
|
const normalize = require('../../support/normalize')
|
|
const { mockSpawn } = require('../../support/spawn-mock')
|
|
|
|
const downloadDestination = path.join(os.tmpdir(), 'Cypress', 'download', 'cypress.zip')
|
|
const version = '1.2.3'
|
|
const examplePath = 'test/fixture/example.zip'
|
|
|
|
describe('lib/tasks/download', function () {
|
|
require('mocha-banner').register()
|
|
|
|
const rootFolder = '/home/user/git'
|
|
|
|
beforeEach(function () {
|
|
logger.reset()
|
|
|
|
this.stdout = stdout.capture()
|
|
|
|
this.options = {
|
|
downloadDestination,
|
|
version,
|
|
}
|
|
|
|
os.platform.returns('OS')
|
|
sinon.stub(util, 'pkgVersion').returns('1.2.3')
|
|
sinon.stub(util, 'cwd').returns(rootFolder)
|
|
})
|
|
|
|
afterEach(function () {
|
|
stdout.restore()
|
|
})
|
|
|
|
context('download url', () => {
|
|
it('returns url', () => {
|
|
const url = download.getUrl('ARCH')
|
|
|
|
la(is.url(url), url)
|
|
})
|
|
|
|
it('returns latest desktop url', () => {
|
|
const url = download.getUrl('ARCH')
|
|
|
|
snapshot('latest desktop url 1', normalize(url))
|
|
})
|
|
|
|
it('returns specific desktop version url', () => {
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('specific version desktop url 1', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = '${endpoint}/${platform}-${arch}/cypress.zip'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template with version', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = 'https://mycompany/${version}/${platform}-${arch}/cypress.zip'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template with version', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template with multiple replacements', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = '${endpoint}/${platform}/${arch}/cypress-${version}-${platform}-${arch}.zip?referrer=${endpoint}&version=${version}'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template with multiple replacements', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template with escaped dollar sign', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = '\\${endpoint}/\\${platform}-\\${arch}/cypress.zip'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template with escaped dollar sign', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template wrapped in quote', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = '"${endpoint}/${platform}-${arch}/cypress.zip"'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template wrapped in quote', normalize(url))
|
|
})
|
|
|
|
it('returns custom url from template with escaped dollar sign wrapped in quote', () => {
|
|
process.env.CYPRESS_DOWNLOAD_PATH_TEMPLATE = '"\\${endpoint}/\\${platform}-\\${arch}/cypress.zip"'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('desktop url from template with escaped dollar sign wrapped in quote', normalize(url))
|
|
})
|
|
|
|
it('returns input if it is already an https link', () => {
|
|
const url = 'https://somewhere.com'
|
|
const result = download.getUrl('ARCH', url)
|
|
|
|
expect(result).to.equal(url)
|
|
})
|
|
|
|
it('returns input if it is already an http link', () => {
|
|
const url = 'http://local.com'
|
|
const result = download.getUrl('ARCH', url)
|
|
|
|
expect(result).to.equal(url)
|
|
})
|
|
})
|
|
|
|
context('download base url from CYPRESS_DOWNLOAD_MIRROR env var', () => {
|
|
it('env var', () => {
|
|
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR 1', normalize(url))
|
|
})
|
|
|
|
it('env var with trailing slash', () => {
|
|
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with trailing slash 1', normalize(url))
|
|
})
|
|
|
|
it('env var with subdirectory', () => {
|
|
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/example'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with subdirectory 1', normalize(url))
|
|
})
|
|
|
|
it('env var with subdirectory and trailing slash', () => {
|
|
process.env.CYPRESS_DOWNLOAD_MIRROR = 'https://cypress.example.com/example/'
|
|
const url = download.getUrl('ARCH', '0.20.2')
|
|
|
|
snapshot('base url from CYPRESS_DOWNLOAD_MIRROR with subdirectory and trailing slash 1', normalize(url))
|
|
})
|
|
})
|
|
|
|
it('saves example.zip to options.downloadDestination', function () {
|
|
nock('https://aws.amazon.com')
|
|
.get('/some.zip')
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
})
|
|
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/some.zip',
|
|
'x-version': '0.11.1',
|
|
})
|
|
|
|
const onProgress = sinon.stub().returns(undefined)
|
|
|
|
return download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress },
|
|
})
|
|
.then((responseVersion) => {
|
|
expect(responseVersion).to.eq('0.11.1')
|
|
|
|
return fs.statAsync(downloadDestination)
|
|
})
|
|
})
|
|
|
|
context('verify downloaded file', function () {
|
|
before(function () {
|
|
this.expectedChecksum = hasha.fromFileSync(examplePath)
|
|
this.expectedFileSize = fs.statSync(examplePath).size
|
|
this.onProgress = sinon.stub().returns(undefined)
|
|
debug('example file %s should have checksum %s and file size %d',
|
|
examplePath, this.expectedChecksum, this.expectedFileSize)
|
|
})
|
|
|
|
it('throws if file size is different from expected', function () {
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
}, {
|
|
// definitely incorrect file size
|
|
'content-length': '10',
|
|
})
|
|
|
|
return expect(download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress: this.onProgress },
|
|
})).to.be.rejected
|
|
})
|
|
|
|
it('throws if file size is different from expected x-amz-meta-size', function () {
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
}, {
|
|
// definitely incorrect file size
|
|
'x-amz-meta-size': '10',
|
|
})
|
|
|
|
return expect(download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress: this.onProgress },
|
|
})).to.be.rejected
|
|
})
|
|
|
|
it('throws if checksum is different from expected', function () {
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
}, {
|
|
'x-amz-meta-checksum': 'incorrect-checksum',
|
|
})
|
|
|
|
return expect(download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress: this.onProgress },
|
|
})).to.be.rejected
|
|
})
|
|
|
|
it('throws if checksum and file size are different from expected', function () {
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
}, {
|
|
'x-amz-meta-checksum': 'incorrect-checksum',
|
|
'x-amz-meta-size': '10',
|
|
})
|
|
|
|
return expect(download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress: this.onProgress },
|
|
})).to.be.rejected
|
|
})
|
|
|
|
it('passes when checksum and file size match', function () {
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(200, () => {
|
|
debug('creating read stream for %s', examplePath)
|
|
|
|
return fs.createReadStream(examplePath)
|
|
}, {
|
|
'x-amz-meta-checksum': this.expectedChecksum,
|
|
'x-amz-meta-size': String(this.expectedFileSize),
|
|
})
|
|
|
|
debug('downloading %s to %s for test version %s',
|
|
examplePath, this.options.downloadDestination, this.options.version)
|
|
|
|
return download.start({
|
|
downloadDestination: this.options.downloadDestination,
|
|
version: this.options.version,
|
|
progress: { onProgress: this.onProgress },
|
|
})
|
|
})
|
|
})
|
|
|
|
it('resolves with response x-version if present', function () {
|
|
nock('https://aws.amazon.com')
|
|
.get('/some.zip')
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
})
|
|
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/some.zip',
|
|
'x-version': '0.11.1',
|
|
})
|
|
|
|
return download.start(this.options).then((responseVersion) => {
|
|
expect(responseVersion).to.eq('0.11.1')
|
|
})
|
|
})
|
|
|
|
it('handles quadruple redirect with response x-version to the latest if present', function () {
|
|
nock('https://aws.amazon.com')
|
|
.get('/some.zip')
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/someone.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somebody.zip',
|
|
'x-version': '0.11.2',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/something.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/some.zip',
|
|
'x-version': '0.11.4',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somebody.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/something.zip',
|
|
'x-version': '0.11.3',
|
|
})
|
|
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/someone.zip',
|
|
'x-version': '0.11.1',
|
|
})
|
|
|
|
return download.start(this.options).then((responseVersion) => {
|
|
expect(responseVersion).to.eq('0.11.4')
|
|
})
|
|
})
|
|
|
|
it('errors on too many redirects', async function () {
|
|
function stubRedirects () {
|
|
nock('https://aws.amazon.com')
|
|
.get('/some.zip')
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
})
|
|
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/someone.zip',
|
|
'x-version': '0.11.1',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/someone.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somebody.zip',
|
|
'x-version': '0.11.2',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somebody.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/something.zip',
|
|
'x-version': '0.11.3',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/something.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somewhat.zip',
|
|
'x-version': '0.11.4',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somewhat.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/sometime.zip',
|
|
'x-version': '0.11.5',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/sometime.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somewhen.zip',
|
|
'x-version': '0.11.6',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somewhen.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somewise.zip',
|
|
'x-version': '0.11.7',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somewise.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/someways.zip',
|
|
'x-version': '0.11.8',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/someways.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somerset.zip',
|
|
'x-version': '0.11.9',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somerset.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/somedeal.zip',
|
|
'x-version': '0.11.10',
|
|
})
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/somedeal.zip')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/some.zip',
|
|
'x-version': '0.11.11',
|
|
})
|
|
}
|
|
|
|
stubRedirects()
|
|
|
|
await download.start(this.options).catch((error) => {
|
|
expect(error).to.be.instanceof(Error)
|
|
expect(error.message).to.contain('redirect loop')
|
|
})
|
|
|
|
stubRedirects()
|
|
|
|
// Double check to make sure that raising redirectTTL changes result
|
|
await download.start({ ...this.options, redirectTTL: 12 }).then((responseVersion) => {
|
|
expect(responseVersion).to.eq('0.11.11')
|
|
})
|
|
})
|
|
|
|
it('can specify cypress version in arguments', function () {
|
|
this.options.version = '0.13.0'
|
|
|
|
nock('https://aws.amazon.com')
|
|
.get('/some.zip')
|
|
.reply(200, () => {
|
|
return fs.createReadStream(examplePath)
|
|
})
|
|
|
|
nock('https://download.cypress.io')
|
|
.get('/desktop/0.13.0')
|
|
.query(true)
|
|
.reply(302, undefined, {
|
|
Location: 'https://aws.amazon.com/some.zip',
|
|
'x-version': '0.13.0',
|
|
})
|
|
|
|
return download.start(this.options).then((responseVersion) => {
|
|
expect(responseVersion).to.eq('0.13.0')
|
|
|
|
return fs.statAsync(downloadDestination)
|
|
})
|
|
})
|
|
|
|
context('architecture detection', () => {
|
|
beforeEach(() => {
|
|
sinon.stub(os, 'arch')
|
|
})
|
|
|
|
context('Apple Silicon/M1', () => {
|
|
function nockDarwinArm64 () {
|
|
return nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query({ arch: 'arm64', platform: 'darwin' })
|
|
.reply(200, undefined, {
|
|
'x-version': '1.2.3',
|
|
})
|
|
}
|
|
|
|
it('downloads darwin-arm64 on M1', async function () {
|
|
os.platform.returns('darwin')
|
|
os.arch.returns('arm64')
|
|
nockDarwinArm64()
|
|
|
|
const responseVersion = await download.start(this.options)
|
|
|
|
expect(responseVersion).to.eq('1.2.3')
|
|
|
|
await fs.statAsync(downloadDestination)
|
|
})
|
|
|
|
it('downloads darwin-arm64 on M1 translated by Rosetta', async function () {
|
|
os.platform.returns('darwin')
|
|
os.arch.returns('x64')
|
|
nockDarwinArm64()
|
|
|
|
sinon.stub(cp, 'spawn').withArgs('sysctl', ['-n', 'sysctl.proc_translated'])
|
|
.callsFake(mockSpawn(((cp) => {
|
|
cp.stdout.write('1')
|
|
cp.emit('exit', 0, null)
|
|
cp.end()
|
|
})))
|
|
|
|
const responseVersion = await download.start(this.options)
|
|
|
|
expect(responseVersion).to.eq('1.2.3')
|
|
|
|
await fs.statAsync(downloadDestination)
|
|
})
|
|
})
|
|
|
|
context('Linux arm64/aarch64', () => {
|
|
function nockLinuxArm64 () {
|
|
return nock('https://download.cypress.io')
|
|
.get('/desktop/1.2.3')
|
|
.query({ arch: 'arm64', platform: 'linux' })
|
|
.reply(200, undefined, {
|
|
'x-version': '1.2.3',
|
|
})
|
|
}
|
|
|
|
it('downloads linux-arm64 on arm64 processor', async function () {
|
|
os.platform.returns('linux')
|
|
os.arch.returns('arm64')
|
|
nockLinuxArm64()
|
|
|
|
const responseVersion = await download.start(this.options)
|
|
|
|
expect(responseVersion).to.eq('1.2.3')
|
|
|
|
await fs.statAsync(downloadDestination)
|
|
})
|
|
|
|
it('downloads linux-arm64 on non-arm64 node running on arm machine', async function () {
|
|
os.platform.returns('linux')
|
|
os.arch.returns('x64')
|
|
sinon.stub(cp, 'spawn')
|
|
|
|
for (const arch of ['aarch64_be', 'aarch64', 'armv8b', 'armv8l']) {
|
|
nockLinuxArm64()
|
|
cp.spawn.withArgs('uname', ['-m'])
|
|
.callsFake(mockSpawn(((cp) => {
|
|
cp.stdout.write(arch)
|
|
cp.emit('exit', 0, null)
|
|
cp.end()
|
|
})))
|
|
|
|
const responseVersion = await download.start(this.options)
|
|
|
|
expect(responseVersion).to.eq('1.2.3')
|
|
|
|
await fs.statAsync(downloadDestination)
|
|
}
|
|
})
|
|
})
|
|
})
|
|
|
|
it('catches download status errors and exits', function () {
|
|
const ctx = this
|
|
|
|
const err = new Error()
|
|
|
|
err.statusCode = 404
|
|
err.statusMessage = 'Not Found'
|
|
this.options.version = null
|
|
|
|
// not really the download error, but the easiest way to
|
|
// test the error handling
|
|
sinon.stub(fs, 'ensureDirAsync').rejects(err)
|
|
|
|
return download
|
|
.start(this.options)
|
|
.then(() => {
|
|
throw new Error('should have caught')
|
|
})
|
|
.catch((err) => {
|
|
logger.error(err)
|
|
|
|
return snapshot('download status errors 1', normalize(ctx.stdout.toString()))
|
|
})
|
|
})
|
|
|
|
context('with proxy env vars', () => {
|
|
const testUriHttp = 'http://anything.com'
|
|
const testUriHttps = 'https://anything.com'
|
|
|
|
beforeEach(function () {
|
|
this.env = _.clone(process.env)
|
|
// prevent ambient environment masking of environment variables referenced in this test
|
|
|
|
;([
|
|
'NO_PROXY', 'http_proxy',
|
|
'https_proxy', 'npm_config_ca', 'npm_config_cafile',
|
|
'npm_config_https_proxy', 'npm_config_proxy',
|
|
]).forEach((e) => {
|
|
delete process.env[e.toLowerCase()]
|
|
delete process.env[e.toUpperCase()]
|
|
})
|
|
|
|
// add a default no_proxy which does not match the testUri
|
|
process.env.NO_PROXY = 'localhost,.org'
|
|
})
|
|
|
|
afterEach(function () {
|
|
process.env = this.env
|
|
})
|
|
|
|
it('uses http_proxy on http request', () => {
|
|
process.env.http_proxy = 'http://foo'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttp)).to.eq('http://foo')
|
|
})
|
|
|
|
it('ignores http_proxy on https request', () => {
|
|
process.env.http_proxy = 'http://foo'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq(null)
|
|
process.env.https_proxy = 'https://bar'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('https://bar')
|
|
})
|
|
|
|
it('falls back to npm_config_proxy', () => {
|
|
process.env.npm_config_proxy = 'http://foo'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('http://foo')
|
|
process.env.npm_config_https_proxy = 'https://bar'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('https://bar')
|
|
process.env.https_proxy = 'https://baz'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('https://baz')
|
|
})
|
|
|
|
it('respects no_proxy on http and https requests', () => {
|
|
process.env.NO_PROXY = 'localhost,.com'
|
|
|
|
process.env.http_proxy = 'http://foo'
|
|
process.env.https_proxy = 'https://bar'
|
|
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttp)).to.eq(null)
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq(null)
|
|
})
|
|
|
|
it('ignores no_proxy for npm proxy configs, prefers https over http', () => {
|
|
process.env.NO_PROXY = 'localhost,.com'
|
|
|
|
process.env.npm_config_proxy = 'http://foo'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttp)).to.eq('http://foo')
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('http://foo')
|
|
|
|
process.env.npm_config_https_proxy = 'https://bar'
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttp)).to.eq('https://bar')
|
|
expect(download.getProxyForUrlWithNpmConfig(testUriHttps)).to.eq('https://bar')
|
|
})
|
|
})
|
|
|
|
context('with CA and CAFILE env vars', () => {
|
|
beforeEach(function () {
|
|
this.env = _.clone(process.env)
|
|
})
|
|
|
|
afterEach(function () {
|
|
process.env = this.env
|
|
})
|
|
|
|
it('returns undefined if not set', () => {
|
|
return download.getCA().then((ca) => {
|
|
expect(ca).to.be.undefined
|
|
})
|
|
})
|
|
|
|
it('returns CA from npm_config_ca', () => {
|
|
process.env.npm_config_ca = 'foo'
|
|
|
|
return download.getCA().then((ca) => {
|
|
expect(ca).to.eqls('foo')
|
|
})
|
|
})
|
|
|
|
it('returns CA from npm_config_cafile', () => {
|
|
process.env.npm_config_cafile = 'test/fixture/cafile.pem'
|
|
|
|
return download.getCA().then((ca) => {
|
|
expect(ca).to.eqls('bar\n')
|
|
})
|
|
})
|
|
|
|
it('returns undefined if failed reading npm_config_cafile', () => {
|
|
process.env.npm_config_cafile = 'test/fixture/not-exists.pem'
|
|
|
|
return download.getCA().then((ca) => {
|
|
expect(ca).to.be.undefined
|
|
})
|
|
})
|
|
})
|
|
})
|