cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
46.69k stars 3.16k forks source link

Unable to run `npm ls -all` To List Cypress Dependencies #30168

Open colinbjohnson opened 1 week ago

colinbjohnson commented 1 week ago

What would you like?

I would like to be able to utilize the command npm ls -all to get a list of all dependencies that the cypress package installs.

Why is this needed?

For the purposes of security and, potentially, modifying the cypress package.

Other

To reproduce, do the following:

  1. Run the command docker run -it node:20-slim /bin/bash
  2. Once inside the docker container, run the following commands:
cd /var/tmp
npm install cypress
npm ls --all
# this will output the following
`-- cypress@13.14.1
  +-- @cypress/request@3.0.1
  | +-- aws-sign2@0.7.0
  | +-- aws4@1.13.2
  | +-- caseless@0.12.0
  | +-- combined-stream@1.0.8
  | | `-- delayed-stream@1.0.0
  | +-- extend@3.0.2
  | +-- forever-agent@0.6.1
  | +-- form-data@2.3.3
  | | +-- asynckit@0.4.0
  | | +-- combined-stream@1.0.8 deduped
  | | `-- mime-types@2.1.35 deduped
  | +-- http-signature@1.3.6
  | | +-- assert-plus@1.0.0
  | | +-- jsprim@2.0.2
  | | | +-- assert-plus@1.0.0 deduped
  | | | +-- extsprintf@1.3.0
  | | | +-- json-schema@0.4.0
  | | | `-- verror@1.10.0
  | | |   +-- assert-plus@1.0.0 deduped
  | | |   +-- core-util-is@1.0.2
  | | |   `-- extsprintf@1.3.0 deduped
  | | `-- sshpk@1.18.0
  | |   +-- asn1@0.2.6
  | |   | `-- safer-buffer@2.1.2 deduped
  | |   +-- assert-plus@1.0.0 deduped
  | |   +-- bcrypt-pbkdf@1.0.2
  | |   | `-- tweetnacl@0.14.5 deduped
  | |   +-- dashdash@1.14.1
  | |   | `-- assert-plus@1.0.0 deduped
  | |   +-- ecc-jsbn@0.1.2
  | |   | +-- jsbn@0.1.1 deduped
  | |   | `-- safer-buffer@2.1.2 deduped
  | |   +-- getpass@0.1.7
  | |   | `-- assert-plus@1.0.0 deduped
  | |   +-- jsbn@0.1.1
  | |   +-- safer-buffer@2.1.2
  | |   `-- tweetnacl@0.14.5
  | +-- is-typedarray@1.0.0
  | +-- isstream@0.1.2
  | +-- json-stringify-safe@5.0.1
  | +-- mime-types@2.1.35
  | | `-- mime-db@1.52.0
  | +-- performance-now@2.1.0
  | +-- qs@6.10.4
  | | `-- side-channel@1.0.6
  | |   +-- call-bind@1.0.7
  | |   | +-- es-define-property@1.0.0
  | |   | | `-- get-intrinsic@1.2.4 deduped
  | |   | +-- es-errors@1.3.0 deduped
  | |   | +-- function-bind@1.1.2
  | |   | +-- get-intrinsic@1.2.4 deduped
  | |   | `-- set-function-length@1.2.2
  | |   |   +-- define-data-property@1.1.4
  | |   |   | +-- es-define-property@1.0.0 deduped
  | |   |   | +-- es-errors@1.3.0 deduped
  | |   |   | `-- gopd@1.0.1 deduped
  | |   |   +-- es-errors@1.3.0 deduped
  | |   |   +-- function-bind@1.1.2 deduped
  | |   |   +-- get-intrinsic@1.2.4 deduped
  | |   |   +-- gopd@1.0.1
  | |   |   | `-- get-intrinsic@1.2.4 deduped
  | |   |   `-- has-property-descriptors@1.0.2
  | |   |     `-- es-define-property@1.0.0 deduped
  | |   +-- es-errors@1.3.0
  | |   +-- get-intrinsic@1.2.4
  | |   | +-- es-errors@1.3.0 deduped
  | |   | +-- function-bind@1.1.2 deduped
  | |   | +-- has-proto@1.0.3
  | |   | +-- has-symbols@1.0.3
  | |   | `-- hasown@2.0.2
  | |   |   `-- function-bind@1.1.2 deduped
  | |   `-- object-inspect@1.13.2
  | +-- safe-buffer@5.2.1
  | +-- tough-cookie@4.1.4
  | | +-- psl@1.9.0
  | | +-- punycode@2.3.1
  | | +-- universalify@0.2.0
  | | `-- url-parse@1.5.10
  | |   +-- querystringify@2.2.0
  | |   `-- requires-port@1.0.0
  | +-- tunnel-agent@0.6.0
  | | `-- safe-buffer@5.2.1 deduped
  | `-- uuid@8.3.2
  +-- @cypress/xvfb@1.2.4
  | +-- debug@3.2.7
  | | `-- ms@2.1.2 deduped
  | `-- lodash.once@4.1.1
  +-- @types/sinonjs__fake-timers@8.1.1
  +-- @types/sizzle@2.3.8
  +-- arch@2.2.0
  +-- blob-util@2.0.2
  +-- bluebird@3.7.2
  +-- buffer@5.7.1
  | +-- base64-js@1.5.1
  | `-- ieee754@1.2.1
  +-- cachedir@2.4.0
  +-- chalk@4.1.2
  | +-- ansi-styles@4.3.0
  | | `-- color-convert@2.0.1
  | |   `-- color-name@1.1.4
  | `-- supports-color@7.2.0
  |   `-- has-flag@4.0.0 deduped
  +-- check-more-types@2.24.0
  +-- cli-cursor@3.1.0
  | `-- restore-cursor@3.1.0
  |   +-- onetime@5.1.2 deduped
  |   `-- signal-exit@3.0.7 deduped
  +-- cli-table3@0.6.5
  | +-- @colors/colors@1.5.0
  | `-- string-width@4.2.3
  |   +-- emoji-regex@8.0.0
  |   +-- is-fullwidth-code-point@3.0.0
  |   `-- strip-ansi@6.0.1 deduped
  +-- commander@6.2.1
  +-- common-tags@1.8.2
  +-- dayjs@1.11.13
  +-- debug@4.3.6
  | `-- ms@2.1.2
  +-- enquirer@2.4.1
  | +-- ansi-colors@4.1.3
  | `-- strip-ansi@6.0.1
  |   `-- ansi-regex@5.0.1
  +-- eventemitter2@6.4.7
  +-- execa@4.1.0
  | +-- cross-spawn@7.0.3
  | | +-- path-key@3.1.1
  | | +-- shebang-command@2.0.0
  | | | `-- shebang-regex@3.0.0
  | | `-- which@2.0.2
  | |   `-- isexe@2.0.0
  | +-- get-stream@5.2.0
  | | `-- pump@3.0.0
  | |   +-- end-of-stream@1.4.4
  | |   | `-- once@1.4.0 deduped
  | |   `-- once@1.4.0
  | |     `-- wrappy@1.0.2
  | +-- human-signals@1.1.1
  | +-- is-stream@2.0.1
  | +-- merge-stream@2.0.0
  | +-- npm-run-path@4.0.1
  | | `-- path-key@3.1.1 deduped
  | +-- onetime@5.1.2
  | | `-- mimic-fn@2.1.0
  | +-- signal-exit@3.0.7
  | `-- strip-final-newline@2.0.0
  +-- executable@4.1.1
  | `-- pify@2.3.0
  +-- extract-zip@2.0.1
  | +-- @types/yauzl@2.10.3
  | | `-- @types/node@22.5.2
  | |   `-- undici-types@6.19.8
  | +-- debug@4.3.6 deduped
  | +-- get-stream@5.2.0 deduped
  | `-- yauzl@2.10.0 deduped
  +-- figures@3.2.0
  | `-- escape-string-regexp@1.0.5
  +-- fs-extra@9.1.0
  | +-- at-least-node@1.0.0
  | +-- graceful-fs@4.2.11
  | +-- jsonfile@6.1.0
  | | +-- graceful-fs@4.2.11 deduped
  | | `-- universalify@2.0.1 deduped
  | `-- universalify@2.0.1
  +-- getos@3.2.1
  | `-- async@3.2.6
  +-- is-ci@3.0.1
  | `-- ci-info@3.9.0
  +-- is-installed-globally@0.4.0
  | +-- global-dirs@3.0.1
  | | `-- ini@2.0.0
  | `-- is-path-inside@3.0.3
  +-- lazy-ass@1.6.0
  +-- listr2@3.14.0
  | +-- cli-truncate@2.1.0
  | | +-- slice-ansi@3.0.0
  | | | +-- ansi-styles@4.3.0 deduped
  | | | +-- astral-regex@2.0.0
  | | | `-- is-fullwidth-code-point@3.0.0 deduped
  | | `-- string-width@4.2.3 deduped
  | +-- colorette@2.0.20
  | +-- enquirer@2.4.1 deduped
  | +-- log-update@4.0.0
  | | +-- ansi-escapes@4.3.2
  | | | `-- type-fest@0.21.3
  | | +-- cli-cursor@3.1.0 deduped
  | | +-- slice-ansi@4.0.0
  | | | +-- ansi-styles@4.3.0 deduped
  | | | +-- astral-regex@2.0.0 deduped
  | | | `-- is-fullwidth-code-point@3.0.0 deduped
  | | `-- wrap-ansi@6.2.0
  | |   +-- ansi-styles@4.3.0 deduped
  | |   +-- string-width@4.2.3 deduped
  | |   `-- strip-ansi@6.0.1 deduped
  | +-- p-map@4.0.0
  | | `-- aggregate-error@3.1.0
  | |   +-- clean-stack@2.2.0
  | |   `-- indent-string@4.0.0
  | +-- rfdc@1.4.1
  | +-- rxjs@7.8.1
  | | `-- tslib@2.7.0
  | +-- through@2.3.8
  | `-- wrap-ansi@7.0.0
  |   +-- ansi-styles@4.3.0 deduped
  |   +-- string-width@4.2.3 deduped
  |   `-- strip-ansi@6.0.1 deduped
  +-- lodash@4.17.21
  +-- log-symbols@4.1.0
  | +-- chalk@4.1.2 deduped
  | `-- is-unicode-supported@0.1.0
  +-- minimist@1.2.8
  +-- ospath@1.2.2
  +-- pretty-bytes@5.6.0
  +-- process@0.11.10
  +-- proxy-from-env@1.0.0
  +-- request-progress@3.0.0
  | `-- throttleit@1.0.1
  +-- semver@7.6.3
  +-- supports-color@8.1.1
  | `-- has-flag@4.0.0
  +-- tmp@0.2.3
  +-- untildify@4.0.0
  `-- yauzl@2.10.0
    +-- buffer-crc32@0.2.13
    `-- fd-slicer@1.1.0
      `-- pend@1.2.0

The above list is not a complete list of installed dependencies.

Note (1): there may be (or with slight modification) there may be a way to get a proper dependency tree after cypress is installed. I don't know how to do this.

Note(2): most folks who are familiar with npm would expect npm ls -all to render a proper dependency tree and would understand that certain dependencies (i.e. operating system dependencies) would be excluded.

jennifer-shehane commented 1 week ago

@colinbjohnson This command would represent all of the dependencies that are installed with the Cypress CLI, the npm package which is used to then install Cypress, a binary application that runs your tests.

At that point it's a desktop application on your system. That would be like asking run a command to see all the dependencies used to build the the Slack or VS Code application.

What do you feel is missing with the current list?

colinbjohnson commented 1 week ago

@jennifer-shehane - thank you!!! I now understand there are two cypress components:

  1. the cypress CLI where npm ls --all would provide a list of all dependencies (I'm assuming that the modules for the CLI are installed in ./nodemodules and added to the file package-lock.json).
  2. the cypress "app" - this feels like it would be the particular app installed either
    • linux/Docker: ~/.cache/Cypress/13.14.1/Cypress/resources/app where npm ls --all does run but renders really strangely (if you run cd ~/.cache/Cypress/13.14.1/Cypress/resources/app && npm ls --all 2>&1 | grep 'npm error extraneous' | wc -l you'll get 1617 extraneous packages)
    • macOS (via CDN Download) - if you run something like cd ./cypress.app/Contents/Resources/app && npm ls --all 2>&1 | grep -c 'npm error extraneous' you'll get 1614 extraneous packages)

So the ask/issue is (as we can use npm ls --all for the celery cli) how would one (or should one be able to) get the installed modules for the app (and, possibly, why are there npm error extraneous package errors).

BTW: this is a legit request - we work with companies that are concerned about the modules installed on systems that contain cypress so understanding the dependency tree and how to understand which and how those packages are installed is important. The best tool I know for accomplishing this is npm.

MikeMcC399 commented 1 week ago

@colinbjohnson

how would one (or should one be able to) get the installed modules for the app (and, possibly, why are there npm error extraneous package errors).

You can use npm ls on the cache sub-directory of the Cypress binary as you have already done (location depends on OS - see https://docs.cypress.io/guides/references/advanced-installation#Binary-cache) which will give you the versions. You could also just list the contents of the Cypress/resources/app/node_modules which will list the modules without the versions.

npm ls is intended to be used on a regular npm project, not an Electron application. If you had a regular npm project then the package.json would describe the top level of installed dependencies. The Cypress binary Electron application doesn't work this way, so the package.json doesn't contain any dependencies or devDependencies. That's the reason why npm ls annotates everything it found in node_modules with the text extraneous because there is nothing in the package.json to call them out.

The document https://github.com/cypress-io/cypress/blob/develop/guides/building-release-artifacts.md describes how the Cypress binary is built.