0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2024-12-30 22:34:10 -05:00

enable CLI E2e on 5.x (#2011)

* test: enable e2e

* test: improve setup

* chore: update setup

* test: publish on temp folder

* chore: initial setup example

* chore: add global install to pnpm

* chore: update test script

* test: add info command

* chore: add install tests

* chore: add debug enabled code

* chore: update pnpm lock file
This commit is contained in:
Juan Picado 2020-12-21 10:22:06 +01:00
parent 57cb03cdb7
commit fe60eab99c
45 changed files with 744 additions and 283 deletions

View file

@ -1,13 +1,25 @@
name: E2E CLI name: CI E2E
on: [pull_request] on:
push:
branches:
- 5.x
- 'changeset-release/5.x'
pull_request:
paths:
- .changeset/**
- .github/workflows/ci.yml
- 'packages/**'
- 'jest/**'
- 'package.json'
- 'pnpm-workspace.yaml'
jobs: jobs:
ci: ci:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest] os: [ubuntu-latest, windows-latest]
node_version: [14] node_version: [14]
name: ${{ matrix.os }} / Node ${{ matrix.node_version }} name: ${{ matrix.os }} / Node ${{ matrix.node_version }}
@ -16,12 +28,18 @@ jobs:
steps: steps:
- uses: actions/checkout@v2.3.1 - uses: actions/checkout@v2.3.1
- name: Use Node ${{ matrix.node_version }} - name: Use Node ${{ matrix.node_version }}
uses: actions/setup-node@v2.1.5 uses: actions/setup-node@v1
with: with:
node-version: ${{ matrix.node_version }} node_version: ${{ matrix.node_version }}
- name: Install pnpm
run: npm i -g pnpm@latest
- name: Install - name: Install
run: yarn install run: pnpm recursive install
- name: Clean
run: pnpm clean
- name: Build - name: Build
run: yarn code:build run: pnpm build
- name: Test CLI - name: Test
run: yarn test:e2e:cli run: pnpm test:e2e:cli
env:
DEBUG: verdaccio:e2e*

1
.gitignore vendored
View file

@ -16,6 +16,7 @@ test-storage*
node_modules node_modules
package-lock.json package-lock.json
yarn-error.log yarn-error.log
yarn.lock
# jest # jest

1
.npmrc
View file

@ -1,3 +1,4 @@
always-auth = true always-auth = true
recursive-install = true recursive-install = true
registry = https://registry.verdaccio.org/ registry = https://registry.verdaccio.org/
loglevel=warn

View file

@ -1 +0,0 @@

View file

@ -1,2 +0,0 @@
save-prefix ""
registry "https://registry.verdaccio.org"

View file

@ -111,12 +111,12 @@
"format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"", "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
"format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"", "format:check": "prettier --check \"**/*.{js,jsx,ts,tsx,json,yml,yaml,md}\"",
"lint": "eslint \"**/*.{js,jsx,ts,tsx}\"", "lint": "eslint \"**/*.{js,jsx,ts,tsx}\"",
"test": "pnpm recursive test", "test": "pnpm recursive test --filter ./packages",
"test:e2e:cli": "pnpm test --filter ...@verdaccio/e2e-cli",
"start": "node packages/verdaccio/debug/bootstrap.js", "start": "node packages/verdaccio/debug/bootstrap.js",
"start:ts": "ts-node packages/verdaccio/src/start.ts", "start:ts": "ts-node packages/verdaccio/src/start.ts",
"debug": "node --inspect packages/verdaccio/debug/bootstrap.js", "debug": "node --inspect packages/verdaccio/debug/bootstrap.js",
"debug:break": "node --inspect-brk packages/verdaccio/debug/bootstrap.js", "debug:break": "node --inspect-brk packages/verdaccio/debug/bootstrap.js",
"test:e2e:cli": "cross-env NODE_ENV=test jest --config ./test/e2e-cli/jest.config.e2e.cli.js --passWithNoTests",
"website:lint": "cd website && yarn lint", "website:lint": "cd website && yarn lint",
"website:develop": "cd website && yarn develop", "website:develop": "cd website && yarn develop",
"website:build": "cd website && yarn build", "website:build": "cd website && yarn build",

View file

@ -25,12 +25,12 @@
"dependencies": { "dependencies": {
"@verdaccio/auth": "workspace:5.0.0-alpha.1", "@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/hooks": "workspace:5.0.0-alpha.1", "@verdaccio/hooks": "workspace:5.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/middleware": "workspace:5.0.0-alpha.1", "@verdaccio/middleware": "workspace:5.0.0-alpha.1",
"@verdaccio/store": "workspace:5.0.0-alpha.1", "@verdaccio/store": "workspace:5.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"cookies": "0.8.0", "cookies": "0.8.0",
"debug": "^4.1.1", "debug": "^4.1.1",
"express": "4.17.1", "express": "4.17.1",

View file

@ -23,15 +23,15 @@
}, },
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/loaders": "workspace:5.0.0-alpha.1", "@verdaccio/loaders": "workspace:5.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",
"jsonwebtoken": "8.5.1",
"debug": "^4.1.1", "debug": "^4.1.1",
"express": "4.17.1", "express": "4.17.1",
"jsonwebtoken": "8.5.1",
"lodash": "4.17.15" "lodash": "4.17.15"
}, },
"devDependencies": { "devDependencies": {

View file

@ -15,17 +15,17 @@
"license": "MIT", "license": "MIT",
"homepage": "https://verdaccio.org", "homepage": "https://verdaccio.org",
"dependencies": { "dependencies": {
"debug": "^4.2.0",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"debug": "^4.2.0",
"handlebars": "4.5.3", "handlebars": "4.5.3",
"request": "2.87.0", "node-fetch": "^2.6.1",
"node-fetch": "^2.6.1" "request": "2.87.0"
}, },
"devDependencies": { "devDependencies": {
"@verdaccio/auth": "workspace:5.0.0-alpha.1", "@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/types": "workspace:10.0.0-alpha.1", "@verdaccio/types": "workspace:10.0.0-alpha.1",
"nock": "^13.0.4" "nock": "^13.0.4"
}, },

View file

@ -14,13 +14,13 @@
}, },
"dependencies": { "dependencies": {
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"lodash": "4.17.15", "debug": "^4.1.1",
"debug": "^4.1.1" "lodash": "4.17.15"
}, },
"devDependencies": { "devDependencies": {
"@verdaccio/mock": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/mock": "workspace:5.0.0-alpha.1",
"@verdaccio/types": "workspace:10.0.0-alpha.1" "@verdaccio/types": "workspace:10.0.0-alpha.1"
}, },
"homepage": "https://verdaccio.org", "homepage": "https://verdaccio.org",

View file

@ -24,8 +24,8 @@
}, },
"dependencies": { "dependencies": {
"@verdaccio/logger-prettify": "workspace:5.0.0-alpha.1", "@verdaccio/logger-prettify": "workspace:5.0.0-alpha.1",
"lodash": "~4.17.20",
"debug": "^4.2.0", "debug": "^4.2.0",
"lodash": "~4.17.20",
"pino": "^6.7.0" "pino": "^6.7.0"
}, },
"devDependencies": { "devDependencies": {

View file

@ -22,10 +22,10 @@
"build": "pnpm run build:js && pnpm run build:types" "build": "pnpm run build:js && pnpm run build:types"
}, },
"dependencies": { "dependencies": {
"@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",
"@verdaccio/auth": "workspace:5.0.0-alpha.1",
"lodash": "4.17.15" "lodash": "4.17.15"
} }
} }

21
packages/mock/LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Verdaccio community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View file

@ -24,13 +24,13 @@
}, },
"dependencies": { "dependencies": {
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1", "@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1",
"debug": "^4.2.0",
"fs-extra": "^8.1.0", "fs-extra": "^8.1.0",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"request": "2.87.0", "request": "2.87.0",
"supertest": "^4.0.2", "supertest": "^4.0.2"
"debug": "^4.2.0"
}, },
"devDependencies": { "devDependencies": {
"@verdaccio/types": "workspace:10.0.0-alpha.1" "@verdaccio/types": "workspace:10.0.0-alpha.1"

View file

@ -24,12 +24,12 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/server": "workspace:5.0.0-alpha.1", "@verdaccio/server": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"lodash": "^4.17.20",
"debug": "^4.2.0",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"debug": "^4.2.0",
"lodash": "^4.17.20",
"selfsigned": "1.10.7" "selfsigned": "1.10.7"
}, },
"devDependencies": { "devDependencies": {

View file

@ -28,8 +28,8 @@
}, },
"devDependencies": { "devDependencies": {
"@verdaccio/types": "workspace:10.0.0-alpha.1", "@verdaccio/types": "workspace:10.0.0-alpha.1",
"nock": "^12.0.3",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
"nock": "^12.0.3",
"supertest": "^4.0.2" "supertest": "^4.0.2"
}, },
"scripts": { "scripts": {

View file

@ -24,8 +24,8 @@
}, },
"dependencies": { "dependencies": {
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/local-storage": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1", "@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/local-storage": "workspace:10.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/streams": "workspace:10.0.0-alpha.1", "@verdaccio/streams": "workspace:10.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",

View file

@ -17,8 +17,8 @@
"dependencies": { "dependencies": {
"@verdaccio/api": "workspace:5.0.0-alpha.1", "@verdaccio/api": "workspace:5.0.0-alpha.1",
"@verdaccio/auth": "workspace:5.0.0-alpha.1", "@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/loaders": "workspace:5.0.0-alpha.1", "@verdaccio/loaders": "workspace:5.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/middleware": "workspace:5.0.0-alpha.1", "@verdaccio/middleware": "workspace:5.0.0-alpha.1",

View file

@ -43,12 +43,13 @@
"@verdaccio/node-api": "workspace:5.0.0-alpha.1", "@verdaccio/node-api": "workspace:5.0.0-alpha.1",
"@verdaccio/ui-theme": "^1.14.0", "@verdaccio/ui-theme": "^1.14.0",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",
"verdaccio-audit": "10.0.0-alpha.1",
"verdaccio-htpasswd": "10.0.0-alpha.1" "verdaccio-htpasswd": "10.0.0-alpha.1"
}, },
"devDependencies": { "devDependencies": {
"@verdaccio/auth": "workspace:5.0.0-alpha.1", "@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1", "@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/store": "workspace:5.0.0-alpha.1" "@verdaccio/store": "workspace:5.0.0-alpha.1"
}, },
"keywords": [ "keywords": [

View file

@ -6,13 +6,13 @@
"types": "build/index.d.ts", "types": "build/index.d.ts",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/auth": "workspace:5.0.0-alpha.1", "@verdaccio/auth": "workspace:5.0.0-alpha.1",
"@verdaccio/commons-api": "workspace:10.0.0-alpha.1",
"@verdaccio/config": "workspace:5.0.0-alpha.1", "@verdaccio/config": "workspace:5.0.0-alpha.1",
"@verdaccio/loaders": "workspace:5.0.0-alpha.1", "@verdaccio/loaders": "workspace:5.0.0-alpha.1",
"@verdaccio/readme": "workspace:10.0.0-alpha.1",
"@verdaccio/logger": "workspace:5.0.0-alpha.1", "@verdaccio/logger": "workspace:5.0.0-alpha.1",
"@verdaccio/middleware": "workspace:5.0.0-alpha.1", "@verdaccio/middleware": "workspace:5.0.0-alpha.1",
"@verdaccio/readme": "workspace:10.0.0-alpha.1",
"@verdaccio/store": "workspace:5.0.0-alpha.1", "@verdaccio/store": "workspace:5.0.0-alpha.1",
"@verdaccio/utils": "workspace:5.0.0-alpha.1", "@verdaccio/utils": "workspace:5.0.0-alpha.1",
"body-parse": "0.1.0", "body-parse": "0.1.0",

View file

@ -718,6 +718,7 @@ importers:
'@verdaccio/node-api': 'link:../node-api' '@verdaccio/node-api': 'link:../node-api'
'@verdaccio/ui-theme': 1.14.0 '@verdaccio/ui-theme': 1.14.0
'@verdaccio/utils': 'link:../utils' '@verdaccio/utils': 'link:../utils'
verdaccio-audit: 'link:../plugins/audit'
verdaccio-htpasswd: 'link:../core/htpasswd' verdaccio-htpasswd: 'link:../core/htpasswd'
devDependencies: devDependencies:
'@verdaccio/auth': 'link:../auth' '@verdaccio/auth': 'link:../auth'
@ -736,6 +737,7 @@ importers:
'@verdaccio/store': 'workspace:5.0.0-alpha.1' '@verdaccio/store': 'workspace:5.0.0-alpha.1'
'@verdaccio/ui-theme': ^1.14.0 '@verdaccio/ui-theme': ^1.14.0
'@verdaccio/utils': 'workspace:5.0.0-alpha.1' '@verdaccio/utils': 'workspace:5.0.0-alpha.1'
verdaccio-audit: 10.0.0-alpha.1
verdaccio-htpasswd: 10.0.0-alpha.1 verdaccio-htpasswd: 10.0.0-alpha.1
packages/web: packages/web:
dependencies: dependencies:
@ -771,6 +773,24 @@ importers:
debug: ^4.1.1 debug: ^4.1.1
express: 4.17.1 express: 4.17.1
lodash: ^4.17.20 lodash: ^4.17.20
test/e2e-cli:
dependencies:
debug: 4.3.1
npm: 7.0.15
pnpm: 5.13.5
request: 2.88.2
yarn: 1.22.10
devDependencies:
get-port: 5.1.1
semver: 7.3.4
specifiers:
debug: 4.3.1
get-port: ^5.1.1
npm: 7.0.15
pnpm: 5.13.5
request: ^2.88.2
semver: ^7.3.4
yarn: 1.22.10
website: website:
dependencies: dependencies:
'@emotion/core': 10.0.28_react@16.13.1 '@emotion/core': 10.0.28_react@16.13.1
@ -9992,6 +10012,18 @@ packages:
optional: true optional: true
resolution: resolution:
integrity: sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== integrity: sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==
/debug/4.3.1:
dependencies:
ms: 2.1.2
engines:
node: '>=6.0'
peerDependencies:
supports-color: '*'
peerDependenciesMeta:
supports-color:
optional: true
resolution:
integrity: sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
/decamelize-keys/1.1.0: /decamelize-keys/1.1.0:
dependencies: dependencies:
decamelize: 1.2.0 decamelize: 1.2.0
@ -13230,6 +13262,12 @@ packages:
node: '>=4' node: '>=4'
resolution: resolution:
integrity: sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= integrity: sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=
/get-port/5.1.1:
dev: true
engines:
node: '>=8'
resolution:
integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==
/get-proxy/2.1.0: /get-proxy/2.1.0:
dependencies: dependencies:
npm-conf: 1.1.3 npm-conf: 1.1.3
@ -17008,7 +17046,6 @@ packages:
/lru-cache/6.0.0: /lru-cache/6.0.0:
dependencies: dependencies:
yallist: 4.0.0 yallist: 4.0.0
dev: false
engines: engines:
node: '>=10' node: '>=10'
resolution: resolution:
@ -18059,6 +18096,81 @@ packages:
hasBin: true hasBin: true
resolution: resolution:
integrity: sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= integrity: sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=
/npm/7.0.15:
bundledDependencies:
- '@npmcli/arborist'
- '@npmcli/ci-detect'
- '@npmcli/config'
- '@npmcli/run-script'
- abbrev
- ansicolors
- ansistyles
- aproba
- archy
- bin-links
- byte-size
- cacache
- chalk
- chownr
- cli-columns
- cli-table3
- columnify
- editor
- glob
- graceful-fs
- hosted-git-info
- inherits
- ini
- init-package-json
- is-cidr
- leven
- libnpmaccess
- libnpmfund
- libnpmhook
- libnpmorg
- libnpmpack
- libnpmpublish
- libnpmsearch
- libnpmteam
- libnpmversion
- make-fetch-happen
- mkdirp
- mkdirp-infer-owner
- ms
- node-gyp
- nopt
- normalize-package-data
- npm-audit-report
- npm-package-arg
- npm-pick-manifest
- npm-profile
- npm-registry-fetch
- npm-user-validate
- npmlog
- opener
- pacote
- parse-conflict-json
- qrcode-terminal
- read
- read-package-json
- read-package-json-fast
- rimraf
- semver
- sorted-object
- ssri
- tar
- text-table
- tiny-relative-date
- uuid
- validate-npm-package-name
- which
- write-file-atomic
dev: false
engines:
node: '>=10'
hasBin: true
resolution:
integrity: sha512-vP4qQMsbfERokwYMDbSHqbtCFFNVMCvLHJXyzrDSka6Mz8GCQwj1Y/OjgF2nji80/yl+RQvMnOjVNgjWQf9NBw==
/npmlog/4.1.2: /npmlog/4.1.2:
dependencies: dependencies:
are-we-there-yet: 1.1.5 are-we-there-yet: 1.1.5
@ -19092,6 +19204,13 @@ packages:
node: '>=6' node: '>=6'
resolution: resolution:
integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==
/pnpm/5.13.5:
dev: false
engines:
node: '>=10.16'
hasBin: true
resolution:
integrity: sha512-EJO8eYZyNpOvW+JhjBnLtxD2xcC6YlrzH8jxjETj8bevLATFa9vnGq614ada6o1XOIMq31JWtj1WyPJNogAzLA==
/popper.js/1.16.1: /popper.js/1.16.1:
deprecated: 'You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1' deprecated: 'You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1'
dev: false dev: false
@ -21256,6 +21375,15 @@ packages:
hasBin: true hasBin: true
resolution: resolution:
integrity: sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity: sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
/semver/7.3.4:
dependencies:
lru-cache: 6.0.0
dev: true
engines:
node: '>=10'
hasBin: true
resolution:
integrity: sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
/send/0.17.1: /send/0.17.1:
dependencies: dependencies:
debug: 2.6.9 debug: 2.6.9
@ -22329,7 +22457,7 @@ packages:
dependencies: dependencies:
component-emitter: 1.3.0 component-emitter: 1.3.0
cookiejar: 2.1.2 cookiejar: 2.1.2
debug: 4.2.0 debug: 4.3.1
fast-safe-stringify: 2.0.7 fast-safe-stringify: 2.0.7
form-data: 2.5.1 form-data: 2.5.1
formidable: 1.2.2 formidable: 1.2.2
@ -24275,7 +24403,6 @@ packages:
resolution: resolution:
integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
/yallist/4.0.0: /yallist/4.0.0:
dev: false
resolution: resolution:
integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
/yaml-loader/0.6.0: /yaml-loader/0.6.0:
@ -24363,6 +24490,14 @@ packages:
node: '>=8' node: '>=8'
resolution: resolution:
integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
/yarn/1.22.10:
dev: false
engines:
node: '>=4.0.0'
hasBin: true
requiresBuild: true
resolution:
integrity: sha512-IanQGI9RRPAN87VGTF7zs2uxkSyQSrSPsju0COgbsKQOOXr5LtcVPeyXWgwVa0ywG3d8dg6kSYKGBuYK021qeA==
/yauzl/2.10.0: /yauzl/2.10.0:
dependencies: dependencies:
buffer-crc32: 0.2.13 buffer-crc32: 0.2.13

View file

@ -3,4 +3,4 @@ packages:
- packages/core/* - packages/core/*
- packages/plugins/* - packages/plugins/*
- website - website
- '!**/test/**' - test/e2e-cli

3
test/e2e-cli/.babelrc Normal file
View file

@ -0,0 +1,3 @@
{
"extends": "../../.babelrc"
}

21
test/e2e-cli/LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Verdaccio
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

48
test/e2e-cli/README.md Normal file
View file

@ -0,0 +1,48 @@
# E2E Testing
## What is included on these test?
- Default configuration only
- Basic commands eg (`install / add`, `info`, `publish`).
- Test with 3 package managers (`yarn classic`, `pnpm` and `npm@7`)
## How it works?
On run test suites, there is a global setup where will install the local source code of verdaccio in a temporary folder.
Each suite will install.
1. `spawn` a registry on port `6001` using `_bootstrap_verdaccio.yaml` which block any local package being
fetched from remote upstream.
2. Publish local project to the spawned registry (with global `pnpm`)
> The published `verdaccio` should be fetch by each suite to ensure reliability of each test.
## How to write test?
Each of the suite must use a package manager command _(eg: `npm install`)_ and validate the output according what the
user see, either verifying the outcome in JSON form, run a command _(`eg: jest ..`)_ and the expected result.
Each Test should start with the initial setup, this step does the following
- `beforeAll`: Install verdaccio to the suite context that returns a `Setup` object.
- `afterAll`: Stop the child process that runs verdaccio.
```js
beforeAll(async () => {
setup = await initialSetup(tempRootFolder, port);
console.log('--setup', setup.install);
});
```
stop the process is the final step that should occur in every suite.
```js
afterAll(async () => {
setup.child.kill();
});
```
### What should not included on these tests?
- Anything is unrelated with client commands usage, eg: (auth permissions, third party integrations,
hooks, plugins)

View file

@ -12,22 +12,42 @@ web:
uplinks: uplinks:
npmjs: npmjs:
url: https://registry.verdaccio.org/ url: https://registry.verdaccio.org/
max_fails: 30
logs: { type: stdout, format: json, level: http } fail_timeout: 10m
timeout: 60s
cache: true
maxage: 30m
agent_options:
keepAlive: true
maxSockets: 40
maxFreeSockets: 10
logs:
- { type: stdout, format: pretty, level: warn }
packages: packages:
'@*/*': ## ui-theme still lives outside of the core project
access: $all '@verdaccio/ui-theme':
access: $anonymous
publish: $anonymous publish: $anonymous
unpublish: $authenticated
proxy: npmjs proxy: npmjs
'@verdaccio/*':
access: $anonymous
publish: $anonymous
'@*/*':
access: $anonymous
publish: $anonymous
unpublish: $anonymous
proxy: npmjs
'verdaccio-*':
access: $anonymous
publish: $anonymous
'verdaccio': 'verdaccio':
access: $all access: $anonymous
publish: $anonymous publish: $anonymous
'**': '**':
access: $all access: $anonymous
publish: $anonymous publish: $anonymous
unpublish: $authenticated unpublish: $anonymous
proxy: npmjs proxy: npmjs
_debug: true _debug: true

View file

@ -1,8 +1,8 @@
storage: ./storage storage: ./storage
#store: store:
# memory: memory:
# limit: 1000 limit: 1000
auth: auth:
htpasswd: htpasswd:
@ -15,7 +15,7 @@ web:
uplinks: uplinks:
local: local:
url: http://localhost:4873 url: http://localhost:6001
logs: { type: stdout, format: json, level: http } logs: { type: stdout, format: json, level: http }

View file

@ -1,6 +1,7 @@
const { defaults } = require('jest-config'); const { defaults } = require('jest-config');
const config = require('../../jest/config');
module.exports = { module.exports = Object.assign({}, config, {
name: 'verdaccio-e2e-cli-jest', name: 'verdaccio-e2e-cli-jest',
verbose: true, verbose: true,
collectCoverage: false, collectCoverage: false,
@ -8,5 +9,6 @@ module.exports = {
testEnvironment: './env_babel.js', testEnvironment: './env_babel.js',
globalSetup: './env_setup.js', globalSetup: './env_setup.js',
globalTeardown: './env_teardown.js', globalTeardown: './env_teardown.js',
testRegex: '(/test/e2e.*\\.spec)\\.ts', // testRegex: '(/test/e2e.*\\.spec)\\.ts',
}; testRegex: '(/test_bk/*.*.spec)\\.ts',
});

19
test/e2e-cli/package.json Normal file
View file

@ -0,0 +1,19 @@
{
"name": "@verdaccio/e2e-cli",
"private": true,
"version": "1.0.0",
"dependencies": {
"debug": "4.3.1",
"npm": "7.0.15",
"pnpm": "5.13.5",
"request": "^2.88.2",
"yarn": "1.22.10"
},
"devDependencies": {
"get-port": "^5.1.1",
"semver": "^7.3.4"
},
"scripts": {
"test": "jest --config jest.config.e2e.cli.js"
}
}

View file

@ -2,29 +2,64 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
import os from 'os'; import os from 'os';
import { spawn } from 'child_process'; import { spawn } from 'child_process';
import buildDebug from 'debug';
import { yellow } from 'kleur'; import { yellow } from 'kleur';
import { npm } from '../utils/process'; import { pnpmGlobal } from '../utils/process';
import * as __global from '../utils/global.js'; import * as __global from '../utils/global.js';
const debug = buildDebug('verdaccio:e2e:setup');
export const SETUP_VERDACCIO_PORT = `6001`;
module.exports = async () => { module.exports = async () => {
const tempRoot = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'verdaccio-cli-e2e-')); const tempRoot = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'verdaccio-cli-e2e-'));
debug('dirname folder %o', __dirname);
debug('temporary folder %o', tempRoot);
// @ts-ignore
__global.addItem('dir-root', tempRoot); __global.addItem('dir-root', tempRoot);
console.log(yellow(`Add temp root folder: ${tempRoot}`)); debug(yellow(`Add temp root folder: ${tempRoot}`));
const destinationConfigFile = path.join(tempRoot, 'verdaccio.yaml');
debug('destination config file %o', destinationConfigFile);
fs.copyFileSync( fs.copyFileSync(
path.join(__dirname, '../config/_bootstrap_verdaccio.yaml'), path.join(__dirname, '../config/_bootstrap_verdaccio.yaml'),
path.join(tempRoot, 'verdaccio.yaml') destinationConfigFile
); );
// @ts-ignore // @ts-ignore
global.__namespace = __global; global.__namespace = __global;
console.log(`current directory: ${process.cwd()}`); debug(`current directory %o`, process.cwd());
// @ts-ignore const verdaccioPath = path.normalize(
global.registryProcess = spawn( path.join(process.cwd(), '../../packages/verdaccio/debug/bootstrap.js')
'node',
[require.resolve('verdaccio/bin/verdaccio'), '-c', './verdaccio.yaml'],
// @ts-ignore
{ cwd: tempRoot, silence: true }
); );
debug(process.env.DEBUG);
debug('verdaccio path %o', verdaccioPath);
const childProcess = spawn(
'node',
[verdaccioPath, '-c', './verdaccio.yaml', '-l', SETUP_VERDACCIO_PORT],
// @ts-ignore
{
cwd: tempRoot,
env: {
...process.env,
},
stdio: 'ignore',
}
);
// @ts-ignore
global.registryProcess = childProcess;
// publish current build version on local registry // publish current build version on local registry
await npm('publish', '--registry', 'http://localhost:4873'); const rootFolder = path.normalize(path.join(process.cwd(), '../../'));
// install the local changes to verdaccio
// the published package will be installed from every suite
await pnpmGlobal(
rootFolder,
'publish',
'--filter',
' ./packages',
'--access',
'public',
'--git-checks',
'false',
'--registry',
`http://localhost:${SETUP_VERDACCIO_PORT}`
);
}; };

View file

@ -1,4 +1,9 @@
import buildDebug from 'debug';
const debug = buildDebug('verdaccio:e2e:teardown');
module.exports = async function () { module.exports = async function () {
debug('e2e teardown kill server');
// @ts-ignore // @ts-ignore
global.registryProcess.kill(); global.registryProcess.kill();
}; };

View file

@ -1,24 +1,33 @@
import os from 'os'; import os from 'os';
import path from 'path'; import path from 'path';
import buildDebug from 'debug';
import NodeEnvironment from 'jest-environment-node'; import NodeEnvironment from 'jest-environment-node';
const fs = require('fs'); const fs = require('fs');
const __global = require('../utils/global'); const __global = require('../utils/global');
const debug = buildDebug('verdaccio:e2e:env');
class E2ECliTestEnvironment extends NodeEnvironment { class E2ECliTestEnvironment extends NodeEnvironment {
constructor(config) { constructor(config) {
super(config); super(config);
} }
async setup() { async setup() {
// create an unique suite location peer test to avoid conflicts
const tempRoot = fs.mkdtempSync( const tempRoot = fs.mkdtempSync(
path.join(fs.realpathSync(os.tmpdir()), 'verdaccio-suite-test-') path.join(fs.realpathSync(os.tmpdir()), 'verdaccio-suite-test-')
); );
__global.addItem('dir-root', tempRoot); debug('suite temporary folder %o', tempRoot);
__global.addItem('dir-suite-root', tempRoot);
// @ts-ignore
this.global.__namespace = __global; this.global.__namespace = __global;
console.log(`current directory: ${process.cwd()}`); debug(`current directory: ${process.cwd()}`);
} }
async teardown() {} async teardown() {
// TODO: clean folder
}
runScript(script): any { runScript(script): any {
return super.runScript(script); return super.runScript(script);

View file

@ -1,33 +0,0 @@
import path from 'path';
import { runVerdaccio } from '../../utils/process';
import { installVerdaccio } from '../__partials/npm_commands';
describe('verdaccio info', () => {
jest.setTimeout(90000);
// @ts-ignore
const tempRootFolder = global.__namespace.getItem('dir-root');
const verdaccioInstall = path.join(tempRootFolder, 'verdaccio-root-info');
let registryProcess;
beforeAll(async () => {
await installVerdaccio(verdaccioInstall);
});
test('should run verdaccio info command', async () => {
const pathVerdaccioModule = require.resolve('verdaccio/bin/verdaccio', {
paths: [verdaccioInstall],
});
const hasMatch = await runVerdaccio(
pathVerdaccioModule,
verdaccioInstall,
['--info'],
/Environment/
);
expect(hasMatch.ok).toBeTruthy();
});
afterAll(() => {
registryProcess.kill();
});
});

View file

@ -1,41 +0,0 @@
import path from 'path';
import fs from 'fs';
import { installVerdaccio } from '../__partials/npm_commands';
import { spawnRegistry } from '../../utils/registry';
import { callRegistry } from '../../utils/web';
describe('npm install', () => {
jest.setTimeout(90000);
const port = '9012';
// @ts-ignore
const tempRootFolder = global.__namespace.getItem('dir-root');
const verdaccioInstall = path.join(tempRootFolder, 'verdaccio-root-install');
let registryProcess;
const configPath = path.join(tempRootFolder, 'verdaccio.yaml');
beforeAll(async () => {
await installVerdaccio(verdaccioInstall);
fs.copyFileSync(path.join(__dirname, '../../config/default.yaml'), configPath);
});
test('should match the listing port and load metadata', async () => {
const pathVerdaccioModule = require.resolve('verdaccio/bin/verdaccio', {
paths: [verdaccioInstall],
});
registryProcess = await spawnRegistry(pathVerdaccioModule, ['-c', configPath, '-l', port], {
cwd: verdaccioInstall,
silent: true,
});
const body = await callRegistry(`http://localhost:${port}/verdaccio`);
const parsedBody = JSON.parse(body);
expect(parsedBody.name).toEqual('verdaccio');
});
afterAll(async () => {
registryProcess.kill();
});
});

View file

@ -1,65 +0,0 @@
import path from 'path';
import fs from 'fs';
import * as __global from '../../utils/global';
import { spawnRegistry } from '../../utils/registry';
import { execAndWaitForOutputToMatch } from '../../utils/process';
import { installVerdaccio } from '../__partials/npm_commands';
import { expectFileToExist } from '../../utils/expect';
describe('npm install', () => {
jest.setTimeout(90000);
const port = '9011';
// @ts-ignore
const tempRootFolder = global.__namespace.getItem('dir-root');
const verdaccioInstall = path.join(tempRootFolder, 'verdaccio-root-install');
let registryProcess;
beforeAll(async () => {
await installVerdaccio(verdaccioInstall);
const configPath = path.join(tempRootFolder, 'verdaccio.yaml');
fs.copyFileSync(path.join(__dirname, '../../config/default.yaml'), configPath);
// @ts-ignore
global.__namespace = __global;
const pathVerdaccioModule = require.resolve('verdaccio/bin/verdaccio', {
paths: [verdaccioInstall],
});
registryProcess = await spawnRegistry(pathVerdaccioModule, ['-c', configPath, '-l', port], {
cwd: verdaccioInstall,
silent: true,
});
});
test('should match on npm info verdaccio', async () => {
// FIXME: not the best match, looking for a better way to match the terminal output
const output = await execAndWaitForOutputToMatch(
'npm',
['info', 'verdaccio', '--registry'],
/A lightweight private npm proxy registry/
);
expect(output.ok).toBeTruthy();
});
test('should install jquery', async () => {
const testCwd = path.join(tempRootFolder, '_jquery_');
await execAndWaitForOutputToMatch(
'npm',
['install', '--prefix', testCwd, 'jquery', '--registry', `http://localhost:${port}`],
/''/,
{
cwd: verdaccioInstall,
}
);
const exist = await expectFileToExist(
path.join(testCwd, 'node_modules', 'jquery', 'package.json')
);
expect(exist).toBeTruthy();
});
afterAll(async () => {
registryProcess.kill();
});
});

View file

@ -7,7 +7,7 @@ export function installVerdaccio(verdaccioInstall) {
verdaccioInstall, verdaccioInstall,
'verdaccio', 'verdaccio',
'--registry', '--registry',
'http://localhost:4873', 'http://localhost:6001',
'--no-package-lock' '--no-package-lock'
); );
} }

View file

@ -0,0 +1,37 @@
import { initialSetup } from '../utils/registry';
import { npm, pnpm, yarn } from '../utils/process';
describe('install a package', () => {
jest.setTimeout(90000);
const port = '9010';
let registryProcess;
beforeAll(async () => {
registryProcess = await initialSetup(port);
});
test('should run npm info json body', async () => {
const resp = await npm('info', 'verdaccio', '--json');
const parsedBody = JSON.parse(resp.stdout as string);
expect(parsedBody.name).toEqual('verdaccio');
expect(parsedBody.dependencies).toBeDefined();
});
test('should run yarn classic info json body', async () => {
const resp = await yarn('info', 'verdaccio', '--json');
const parsedBody = JSON.parse(resp.stdout as string);
expect(parsedBody.data.name).toEqual('verdaccio');
expect(parsedBody.data.dependencies).toBeDefined();
});
test('should run pnpm info json body', async () => {
const resp = await pnpm('info', 'verdaccio', '--json');
const parsedBody = JSON.parse(resp.stdout as string);
expect(parsedBody.name).toEqual('verdaccio');
expect(parsedBody.dependencies).toBeDefined();
});
afterAll(async () => {
registryProcess.child.kill();
});
});

View file

@ -0,0 +1,61 @@
import semver from 'semver';
import { addNpmPrefix, addRegistry, addYarnPrefix, initialSetup, Setup } from '../utils/registry';
import { npm, pnpm, pnpmWithCwd, yarn, yarnWithCwd } from '../utils/process';
import { createProject } from '../utils/utils';
describe('install a package', () => {
jest.setTimeout(90000);
const port = '9011';
let setup: Setup;
beforeAll(async () => {
setup = await initialSetup(port);
});
test('should run npm install', async () => {
const projectFolder = createProject('webpack-npm-jest');
const resp = await npm(
'install',
'jest',
'--json',
...addNpmPrefix(projectFolder),
...addRegistry(port)
);
expect(resp.stderr).toBeUndefined();
const resp2 = await npm('run', 'jest', '--version', ...addNpmPrefix(projectFolder));
expect(semver.valid(resp2.stdout)).toBeTruthy();
});
test('should run pnpm install', async () => {
const projectFolder = createProject('webpack-pnpm-test');
const resp = await pnpm(
'install',
'jest@26.6.3',
...addNpmPrefix(projectFolder),
...addRegistry(port)
);
expect(resp.stderr).toBeUndefined();
// TODO: verify package was correctly installed
});
test('should run yarn classic install', async () => {
const projectFolder = createProject('jest-yarn-test');
const resp = await yarn(
'add',
'jest@26.6.3',
...addYarnPrefix(projectFolder),
...addRegistry(port)
);
expect(resp.stderr).toBeUndefined();
const resp2 = await yarnWithCwd(projectFolder, 'jest', '--version');
// yarn output is to verbose
expect(resp2.stdout).toMatch(/26.6.3/);
});
afterAll(async () => {
setup.child.kill();
});
});

View file

@ -0,0 +1,23 @@
import { initialSetup } from '../utils/registry';
import { callRegistry } from '../utils/web';
describe('install a package', () => {
jest.setTimeout(90000);
const port = '9012';
let registryProcess;
beforeAll(async () => {
registryProcess = await initialSetup(port);
});
test('should match the listing port and load metadata', async () => {
const body = await callRegistry(`http://localhost:${port}/verdaccio`);
const parsedBody = JSON.parse(body);
expect(parsedBody.name).toEqual('verdaccio');
});
afterAll(async () => {
registryProcess.child.kill();
});
});

View file

@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.reference.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./build"
}
}

View file

@ -1,11 +1,14 @@
const namespace = Object.create(null); const namespace = Object.create(null);
import buildDebug from 'debug';
const debug = buildDebug('verdaccio:e2e:global');
exports.addItem = function (name, value) { exports.addItem = function (name, value) {
namespace[name] = value; namespace[name] = value;
}; };
exports.getItem = function (name) { exports.getItem = function (name) {
console.log('get-item', name, namespace); debug('get-item %o:%o', name, namespace);
if (!(name in namespace)) { if (!(name in namespace)) {
throw new Error('The item '.concat(name, ' does exist in the namespace')); throw new Error('The item '.concat(name, ' does exist in the namespace'));
} }

View file

@ -1,17 +1,26 @@
import * as child_process from 'child_process'; import { spawn } from 'child_process';
import { SpawnOptions } from 'child_process'; import { SpawnOptions } from 'child_process';
import readline from 'readline';
import buildDebug from 'debug';
export async function _exec(options, cmd, args) { const debug = buildDebug('verdaccio:e2e:process');
export type ExecOutput = {
stdout: string;
stderr: string;
};
export async function _exec(options: SpawnOptions, cmd, args): Promise<ExecOutput> {
debug('start _exec %o %o %o', options, cmd, args);
let stdout = ''; let stdout = '';
let stderr = ''; let stderr;
const flags = [];
const cwd = process.cwd();
const env = options.env; const env = options.env;
console.log(`Running \`${cmd} ${args.map((x) => `"${x}"`).join(' ')}\`${flags}...`); debug(`Running \`${cmd} ${args.join(' ')}`);
console.log(`CWD: ${cwd}`); debug(`CWD: %o`, options.cwd);
console.log(`ENV: ${JSON.stringify(env)}`); debug(`ENV: ${JSON.stringify(env)}`);
const spawnOptions = { const spawnOptions = {
cwd, cwd: options.cwd,
stdio: options.stdio || 'pipe',
...(env ? { env } : {}), ...(env ? { env } : {}),
}; };
@ -21,31 +30,11 @@ export async function _exec(options, cmd, args) {
spawnOptions['stdio'] = 'pipe'; spawnOptions['stdio'] = 'pipe';
} }
const childProcess = child_process.spawn(cmd, args, spawnOptions); const childProcess = spawn(cmd, args, spawnOptions);
childProcess.stdout.on('data', (data) => { const rl = readline.createInterface({ input: childProcess.stdout });
stdout += data.toString('utf-8');
if (options.silent) {
return;
}
data rl.on('line', function (line) {
.toString('utf-8') stdout += line;
.split(/[\n\r]+/)
.filter((line) => line !== '')
.forEach((line) => console.log(' ' + line));
});
childProcess.stderr.on('data', (data) => {
stderr += data.toString('utf-8');
if (options.silent) {
return;
}
data
.toString('utf-8')
.split(/[\n\r]+/)
.filter((line) => line !== '')
.forEach((line) => console.error(' ' + line));
}); });
const err = new Error(`Running "${cmd} ${args.join(' ')}" returned error code `); const err = new Error(`Running "${cmd} ${args.join(' ')}" returned error code `);
@ -55,44 +44,59 @@ export async function _exec(options, cmd, args) {
resolve({ stdout, stderr }); resolve({ stdout, stderr });
} else { } else {
err.message += `${error}...\n\nSTDOUT:\n${stdout}\n\nSTDERR:\n${stderr}\n`; err.message += `${error}...\n\nSTDOUT:\n${stdout}\n\nSTDERR:\n${stderr}\n`;
reject(err); reject({ stdout, stderr: err });
} }
}); });
if (options.waitForMatch) {
const match = options.waitForMatch;
childProcess.stdout.on('data', (data) => {
// console.log("-->data==>", data.toString(), data.toString().match(match));
if (data.toString().match(match)) {
resolve({ ok: true, stdout, stderr });
}
});
childProcess.stderr.on('data', (data) => {
if (data.toString().match(match)) {
resolve({ stdout, stderr });
}
});
}
}); });
} }
export function execAndWaitForOutputToMatch( // export function execAndWaitForOutputToMatch(
cmd: string, // cmd: string,
args: string[], // args: string[],
match: RegExp, // match: RegExp,
spawnOptions: SpawnOptions = {} // spawnOptions: SpawnOptions = {}
): any { // ): any {
return _exec({ waitForMatch: match, ...spawnOptions, silence: true }, cmd, args); // return _exec({ waitForMatch: match, ...spawnOptions, silence: true }, cmd, args);
// }
export function pnpmGlobal(rootFolder, ...args) {
const pnpmCmd = require.resolve('pnpm');
debug('pnpmCommand %o', pnpmCmd);
debug('run pnpm on %o', rootFolder);
return _exec(
{
cwd: rootFolder,
},
'pnpm',
args
);
} }
export function npm(...args) { export function npm(...args): Promise<ExecOutput> {
return _exec({}, 'npm', args); return _exec({}, 'npm', args);
} }
export function runVerdaccio(cmd, installation, args, match: RegExp): any { export function yarn(...args): Promise<ExecOutput> {
return _exec({ cwd: installation, silent: true, waitForMatch: match }, cmd, args); return _exec({}, 'yarn', args);
} }
export function silentNpm(...args) { export function pnpm(...args): Promise<ExecOutput> {
return _exec({}, 'pnpm', args);
}
export function pnpmWithCwd(cwd, ...args): Promise<ExecOutput> {
return _exec({ cwd }, 'pnpm', args);
}
export function yarnWithCwd(cwd, ...args): Promise<ExecOutput> {
return _exec({ cwd }, 'yarn', args);
}
export function nodeCwd(cwd, ...args): Promise<ExecOutput> {
return _exec({ cwd }, 'yarn', args);
}
export function silentNpm(...args): Promise<ExecOutput> {
debug('run silent npm %o', args);
return _exec({ silent: true }, 'npm', args); return _exec({ silent: true }, 'npm', args);
} }

View file

@ -0,0 +1,7 @@
import { addNpmPrefix } from './registry';
describe('registry utils', function () {
test('prefix', () => {
expect([...addNpmPrefix('foo')]).toEqual('');
});
});

View file

@ -1,20 +1,134 @@
/* eslint-disable prefer-promise-reject-errors */ /* eslint-disable prefer-promise-reject-errors */
import { fork } from 'child_process'; import { ChildProcess, fork } from 'child_process';
import path from 'path';
import fs from 'fs';
import buildDebug from 'debug';
export function spawnRegistry(verdaccioPath: string, args: string[], childOptions) { import { silentNpm } from './process';
const debug = buildDebug('verdaccio:e2e:registry-utils');
export function createInstallationFolder(tempRootFolder) {
const verdaccioInstall = path.join(tempRootFolder, 'verdaccio-root-install');
fs.mkdirSync(verdaccioInstall);
return verdaccioInstall;
}
export function addNpmPrefix(installFolder) {
return ['--prefix', installFolder];
}
export function addYarnPrefix(installFolder) {
// info regarding cwd flag
// https://github.com/yarnpkg/yarn/pull/4174
return ['--cwd', installFolder];
}
export function addRegistry(port) {
return ['--registry', `http://localhost:${port}`];
}
export function installVerdaccio(verdaccioInstall) {
debug('installing verdaccio from internal registry');
return silentNpm(
'install',
...addNpmPrefix(verdaccioInstall),
'verdaccio',
...addRegistry('6001'),
// lock file is not useful for this purpose
'--no-package-lock',
'-no-shrinkwrap',
// reduce external calls and potential test failures
'--no-audit'
);
}
export type Setup = {
child: ChildProcess;
install: string;
};
export async function initialSetup(port: string | number): Promise<Setup> {
// temp folder created on test_environment.ts
const tempRootFolder = global.__namespace.getItem('dir-suite-root');
debug('initial setup on %o and port %o', tempRootFolder, port);
// create temporary installation folder
const verdaccioInstall = createInstallationFolder(tempRootFolder);
debug('install folder %o', verdaccioInstall);
// create a file path for the future the configuration file
const verdaccioConfigPathOnInstallLocation = path.join(tempRootFolder, 'verdaccio.yaml');
debug('config file location %o', verdaccioConfigPathOnInstallLocation);
// install a global verdaccio
debug('install verdaccio start');
await installVerdaccio(verdaccioInstall);
debug('install verdaccio finish');
// copy the original config verdaccio file
fs.copyFileSync(
path.join(__dirname, '../../../packages/config/src/conf/default.yaml'),
verdaccioConfigPathOnInstallLocation
);
// location of verdaccio binary installed in the previous step
const pathVerdaccioModule = require.resolve('verdaccio/bin/verdaccio', {
paths: [verdaccioInstall],
});
debug('path verdaccio module %o', pathVerdaccioModule);
// spawn the registry
const processChild = await forkRegistry(
pathVerdaccioModule,
['-c', verdaccioConfigPathOnInstallLocation, '-l', port],
{
cwd: verdaccioInstall,
silent: false,
},
port
);
return {
child: processChild,
install: verdaccioInstall,
};
}
export function getVerdaccioPath() {
const verdaccioPath = path.normalize(
path.join(process.cwd(), '../../packages/verdaccio/debug/bootstrap.js')
);
return verdaccioPath;
}
export function forkRegistry(
verdaccioPath: string,
args: string[],
childOptions,
port
): Promise<ChildProcess> {
debug('spawning registry for %o in port %o', verdaccioPath, port);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let _childOptions = { silent: true, ...childOptions }; let _childOptions = { silent: true, ...childOptions };
debug('options %o', _childOptions);
debug('fork path %o', verdaccioPath);
debug('args %o', args);
const childFork = fork(verdaccioPath, args, _childOptions); const childFork = fork(verdaccioPath, args, _childOptions);
childFork.on('message', (msg: {verdaccio_started: boolean}) => { childFork.on('message', (msg) => {
if (msg.verdaccio_started) { if ('verdaccio_started' in msg) {
debug('spawning registry [started] in port %o', port);
resolve(childFork); resolve(childFork);
} }
}); });
childFork.on('error', (err) => reject([err])); childFork.on('error', (err) => {
childFork.on('disconnect', (err) => reject([err])); debug('error %o', err);
childFork.on('exit', (err) => reject([err])); reject([err]);
});
childFork.on('disconnect', (err) => {
debug('disconnect %o', err);
reject([err]);
});
childFork.on('exit', (err) => {
debug('exit %o', err);
reject([err]);
});
}); });
} }

View file

@ -1,6 +1,14 @@
import path from 'path'; import path from 'path';
import fs from 'fs'; import fs from 'fs';
export function createProject(projectName: string) {
// @ts-ignore
const tempRootFolder = global.__namespace.getItem('dir-suite-root');
const verdaccioInstall = path.join(tempRootFolder, projectName);
fs.mkdirSync(verdaccioInstall);
return verdaccioInstall;
}
export function copyConfigFile(rootFolder, configTemplate): string { export function copyConfigFile(rootFolder, configTemplate): string {
const configPath = path.join(rootFolder, 'verdaccio.yaml'); const configPath = path.join(rootFolder, 'verdaccio.yaml');
fs.copyFileSync(path.join(__dirname, configTemplate), configPath); fs.copyFileSync(path.join(__dirname, configTemplate), configPath);