diff --git a/package.json b/package.json index 0e3c1e90f..728a68a91 100644 --- a/package.json +++ b/package.json @@ -93,7 +93,8 @@ "supertest": "4.0.2", "typescript": "3.7.1-rc", "verdaccio-auth-memory": "8.3.0", - "verdaccio-memory": "8.2.0" + "verdaccio-memory": "8.2.0", + "verdaccio": "latest" }, "keywords": [ "private", diff --git a/test/e2e-pkg/config/_bootstrap_verdaccio.yaml b/test/e2e-pkg/config/_bootstrap_verdaccio.yaml new file mode 100644 index 000000000..d699b99c2 --- /dev/null +++ b/test/e2e-pkg/config/_bootstrap_verdaccio.yaml @@ -0,0 +1,33 @@ +storage: ./storage + +auth: + htpasswd: + file: ./htpasswd + max_users: -1 + +web: + enable: true + title: verdaccio-e2e-pkg + +uplinks: + npmjs: + url: https://registry.npmjs.org/ + +logs: + - { type: stdout, format: pretty, level: info } + +packages: + '@*/*': + access: $all + publish: $anonymous + unpublish: $authenticated + proxy: npmjs + 'verdaccio': + access: $authenticated + publish: $anonymous + '**': + access: $all + publish: $anonymous + unpublish: $authenticated + proxy: npmjs +_debug: true diff --git a/test/e2e-pkg/env_babel.js b/test/e2e-pkg/env_babel.js new file mode 100644 index 000000000..eddce9aa3 --- /dev/null +++ b/test/e2e-pkg/env_babel.js @@ -0,0 +1,4 @@ +require('@babel/register')({ + extensions: [".ts", ".js"] +}); +module.exports = require('./setup/test_environment'); diff --git a/test/e2e-pkg/jest.config.e2e.pkg.js b/test/e2e-pkg/jest.config.e2e.pkg.js new file mode 100644 index 000000000..7d9476a00 --- /dev/null +++ b/test/e2e-pkg/jest.config.e2e.pkg.js @@ -0,0 +1,10 @@ +const { defaults } = require('jest-config'); + +module.exports = { + name: 'verdaccio-e2e-pkg-jest', + verbose: true, + collectCoverage: false, + moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts'], + testEnvironment: './env_babel.js', + testRegex: '(/test/e2e.*\\.spec)\\.ts' +}; diff --git a/test/e2e-pkg/projects/basic/.npmignore b/test/e2e-pkg/projects/basic/.npmignore new file mode 100644 index 000000000..e69de29bb diff --git a/test/e2e-pkg/projects/basic/README.md b/test/e2e-pkg/projects/basic/README.md new file mode 100644 index 000000000..80c7d1601 --- /dev/null +++ b/test/e2e-pkg/projects/basic/README.md @@ -0,0 +1,3 @@ +# Simple project + +This is a normal readme diff --git a/test/e2e-pkg/projects/basic/index.js b/test/e2e-pkg/projects/basic/index.js new file mode 100644 index 000000000..474a5966c --- /dev/null +++ b/test/e2e-pkg/projects/basic/index.js @@ -0,0 +1,6 @@ +module.exports = function() { + const message = "this is a basic project"; + console.log(message); + + return message; +}; diff --git a/test/e2e-pkg/projects/basic/package.json b/test/e2e-pkg/projects/basic/package.json new file mode 100644 index 000000000..26eb5c0c7 --- /dev/null +++ b/test/e2e-pkg/projects/basic/package.json @@ -0,0 +1,18 @@ +{ + "name": "basic-verdaccio", + "version": "1.0.0", + "description": "this is a basic project", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [ + "verdaccio", + "sample" + ], + "dependencies": { + "lodash": "^4.17.15" + }, + "author": "Juan Picado ", + "license": "MIT" +} diff --git a/test/e2e-pkg/projects/scoped_basic/.npmignore b/test/e2e-pkg/projects/scoped_basic/.npmignore new file mode 100644 index 000000000..e69de29bb diff --git a/test/e2e-pkg/projects/scoped_basic/README.md b/test/e2e-pkg/projects/scoped_basic/README.md new file mode 100644 index 000000000..80c7d1601 --- /dev/null +++ b/test/e2e-pkg/projects/scoped_basic/README.md @@ -0,0 +1,3 @@ +# Simple project + +This is a normal readme diff --git a/test/e2e-pkg/projects/scoped_basic/index.js b/test/e2e-pkg/projects/scoped_basic/index.js new file mode 100644 index 000000000..76e3f217a --- /dev/null +++ b/test/e2e-pkg/projects/scoped_basic/index.js @@ -0,0 +1,6 @@ +module.exports = function() { + const message = "this is a scoped basic project"; + console.log(message); + + return message; +}; diff --git a/test/e2e-pkg/projects/scoped_basic/package.json b/test/e2e-pkg/projects/scoped_basic/package.json new file mode 100644 index 000000000..add49d051 --- /dev/null +++ b/test/e2e-pkg/projects/scoped_basic/package.json @@ -0,0 +1,15 @@ +{ + "name": "@e2e-verdaccio/basic", + "version": "1.0.0", + "description": "this is a scoped basic project", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": ["verdaccio", "sample", "scoped"], + "dependencies": { + "lodash": "^4.17.15" + }, + "author": "Juan Picado ", + "license": "MIT" +} diff --git a/test/e2e-pkg/setup/test_environment.ts b/test/e2e-pkg/setup/test_environment.ts new file mode 100644 index 000000000..60b8cbea8 --- /dev/null +++ b/test/e2e-pkg/setup/test_environment.ts @@ -0,0 +1,49 @@ +import { yellow } from 'kleur'; +const fs = require('fs'); +import os from 'os'; +import {ChildProcess, spawn} from 'child_process'; +import path from 'path'; +import NodeEnvironment from 'jest-environment-node'; +const __global = require('../utils/global'); +import { npm } from '../utils/process'; + + +class PuppeteerEnvironment extends NodeEnvironment { + private registryProcess: ChildProcess | null; + constructor(config) { + super(config) + this.registryProcess = null; + } + + async setup() { + const tempRoot = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'verdaccio-cli-e2e-')); + __global.addItem('dir-root', tempRoot); + console.log(yellow(`Add temp root folder: ${tempRoot}`)); + fs.copyFileSync( + path.join(__dirname, '../config/_bootstrap_verdaccio.yaml'), + path.join(tempRoot, 'verdaccio.yaml'), + ); + this.global.__namespace = __global; + console.log(`current directory: ${process.cwd()}`); + console.log('resolve-->', require.resolve('verdaccio/bin/verdaccio')); + this.registryProcess = spawn( + 'node', + [require.resolve('verdaccio/bin/verdaccio'), '-c', './verdaccio.yaml'], + { cwd: tempRoot, stdio: 'inherit' }, + ); + + // publish current build version on local registry + await npm('publish', '--registry' ,'http://localhost:4873'); + } + + async teardown() { + // @ts-ignore + this.registryProcess.kill() + } + + runScript(script) { + return super.runScript(script); + } +} + +export default PuppeteerEnvironment; diff --git a/test/e2e-pkg/test/publish/publish.private.pkg.spec.ts b/test/e2e-pkg/test/publish/publish.private.pkg.spec.ts new file mode 100644 index 000000000..2c83bcbac --- /dev/null +++ b/test/e2e-pkg/test/publish/publish.private.pkg.spec.ts @@ -0,0 +1,25 @@ +import path from 'path'; +import { npm } from '../../utils/process'; + +function testExample() { + console.log('running example'); + return Promise.resolve(true); +} + +export default async function() { + await testExample(); +} + +describe('test example', ()=> { + + test('sub example', async () => { + console.log(`New directory: ${process.cwd()}`, __dirname); + process.chdir(path.join(__dirname, '../../projects/basic')); + console.log(`New directory: ${process.cwd()}`); + await npm('install', '--registry' ,'http://localhost:4873'); + + // @ts-ignore + console.log('--->', global.__namespace.getItem('dir-root')); + expect(true).toBe(true); + }) +}); diff --git a/test/e2e-pkg/utils/global.js b/test/e2e-pkg/utils/global.js new file mode 100644 index 000000000..fe593662c --- /dev/null +++ b/test/e2e-pkg/utils/global.js @@ -0,0 +1,14 @@ +const namespace = Object.create(null); + +exports.addItem = function(name, value) { + namespace[name] = value; +} + +exports.getItem = function(name) { + console.log("get-item", name, namespace); + if (!(name in namespace)) { + throw new Error("The item ".concat(name, " does exist in the namespace")); + } + + return namespace[name]; +} diff --git a/test/e2e-pkg/utils/process.js b/test/e2e-pkg/utils/process.js new file mode 100644 index 000000000..8f6aee24c --- /dev/null +++ b/test/e2e-pkg/utils/process.js @@ -0,0 +1,88 @@ +import * as child_process from 'child_process'; + +export async function _exec(options, cmd, args) { + let stdout = ''; + let stderr = ''; + const flags = []; + const cwd = process.cwd(); + const env = options.env; + console.log(`Running \`${cmd} ${args.map(x => `"${x}"`).join(' ')}\`${flags}...`); + console.log(`CWD: ${cwd}`); + console.log(`ENV: ${JSON.stringify(env)}`); + const spawnOptions = { + cwd, + ...env ? { env } : {}, + }; + + if (process.platform.startsWith('win')) { + args.unshift('/c', cmd); + cmd = 'cmd.exe'; + spawnOptions['stdio'] = 'pipe'; + } + + + const childProcess = child_process.spawn(cmd, args, spawnOptions); + childProcess.stdout.on('data', (data) => { + stdout += data.toString('utf-8'); + if (options.silent) { + return; + } + data.toString('utf-8') + .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))); + }); + + // Create the error here so the stack shows who called this function. + const err = new Error(`Running "${cmd} ${args.join(' ')}" returned error code `); + return new Promise((resolve, reject) => { + childProcess.on('exit', (error) => { + // _processes = _processes.filter(p => p !== childProcess); + + if (!error) { + resolve({ stdout, stderr }); + } else { + err.message += `${error}...\n\nSTDOUT:\n${stdout}\n\nSTDERR:\n${stderr}\n`; + reject(err); + } + }); + + if (options.waitForMatch) { + const match = options.waitForMatch; + childProcess.stdout.on('data', (data) => { + if (data.toString().match(match)) { + resolve({ stdout, stderr }); + } + }); + childProcess.stderr.on('data', (data) => { + if (data.toString().match(match)) { + resolve({ stdout, stderr }); + } + }); + } + }); +} + + +export function npm(...args) { + return _exec({}, 'npm', args); +} + + +export function node(...args) { + return _exec({}, 'node', args); +} + +export function silentNpm(...args) { + return _exec({silent: true}, 'npm', args); +} diff --git a/yarn.lock b/yarn.lock index adfd65069..8acb0a9b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1705,13 +1705,26 @@ dependencies: lockfile "1.0.4" -"@verdaccio/file-locking@^8.4.2": +"@verdaccio/file-locking@^8.2.0", "@verdaccio/file-locking@^8.4.2": version "8.4.2" resolved "https://registry.verdaccio.org/@verdaccio%2ffile-locking/-/file-locking-8.4.2.tgz#007b15a4f131d9e6bd482c8e631e03b4df9fe647" integrity sha512-XsniyZl2YzbDGf7wsemM97RG/sqtX4/3dfy2quwULKd5WnNtSbX/ewm8EJyL8Ajsfx3y3xtzX9+jj6+7TBGE8g== dependencies: lockfile "1.0.4" +"@verdaccio/local-storage@8.2.0": + version "8.2.0" + resolved "https://registry.verdaccio.org/@verdaccio%2flocal-storage/-/local-storage-8.2.0.tgz#d09406b8738e949ff247fef71386de0e8a1de0f1" + integrity sha512-gIamhfr7TwXAmOv/2NNr/Cisr9UextH/8w3qPnzdAMuZWAyquiZK9/z/DLDZm04H9A6pP9oaSfjXydUVeD4ZYg== + dependencies: + "@verdaccio/commons-api" "^8.2.0" + "@verdaccio/file-locking" "^8.2.0" + "@verdaccio/streams" "^8.2.0" + async "3.1.0" + level "5.0.1" + lodash "4.17.15" + mkdirp "0.5.1" + "@verdaccio/local-storage@8.4.2": version "8.4.2" resolved "https://registry.verdaccio.org/@verdaccio%2flocal-storage/-/local-storage-8.4.2.tgz#b05653eefc7d721fc283a1dd3bfb0436606f1a70" @@ -1725,6 +1738,15 @@ lodash "4.17.15" mkdirp "0.5.1" +"@verdaccio/readme@8.2.0": + version "8.2.0" + resolved "https://registry.verdaccio.org/@verdaccio%2freadme/-/readme-8.2.0.tgz#a1628f633c46fe86e8b5d55fbba44aba11d23e33" + integrity sha512-fII0jdixadOkQFtFktZw3EMyYGvTs2nzhlkGM9WZfv4QH2pVVmrfx1E9sqBrKLHUvwgrO8sDfcC8wHJQ6tsNVw== + dependencies: + dompurify "2.0.7" + jsdom "15.2.0" + marked "0.7.0" + "@verdaccio/readme@8.4.2": version "8.4.2" resolved "https://registry.verdaccio.org/@verdaccio%2freadme/-/readme-8.4.2.tgz#6c3535ae88f66c0adffd29f79257504c1a77f1bb" @@ -1749,6 +1771,11 @@ resolved "https://registry.verdaccio.org/@verdaccio%2ftypes/-/types-8.1.0.tgz#298baa1c0bffd340022537a1d9b064b82b4ae497" integrity sha512-wc0SaH25ioT6xt4HtlFzvmNSjZXQOddJLDuI1VN4/8nHAIlrUdlQ0sGnmky4+bJOuTL3eqbaqx4nHMKep5+lDg== +"@verdaccio/ui-theme@0.3.2": + version "0.3.2" + resolved "https://registry.verdaccio.org/@verdaccio%2fui-theme/-/ui-theme-0.3.2.tgz#6f4a27abb3781a9741473e55bff7af650dce118c" + integrity sha512-bxICDb2dgHXp6DOEx8f1IfU7PsgF1AuuDxa87MbvXqfE3CfMGB2TEwlPWNlX+VSScgWNh/yYSDrOIQ2SqwgAGg== + "@verdaccio/ui-theme@0.3.9": version "0.3.9" resolved "https://registry.verdaccio.org/@verdaccio%2fui-theme/-/ui-theme-0.3.9.tgz#6ff0f05315912b4ba39e29eb589ecc8833640990" @@ -3307,6 +3334,11 @@ end-of-stream@^1.1.0: dependencies: once "^1.4.0" +envinfo@7.4.0: + version "7.4.0" + resolved "https://registry.verdaccio.org/envinfo/-/envinfo-7.4.0.tgz#bef4ece9e717423aaf0c3584651430b735ad6630" + integrity sha512-FdDfnWnCVjxTTpWE3d6Jgh5JDIA3Cw7LCgpM/pI7kK1ORkjaqI2r6NqQ+ln2j0dfpgxY00AWieSvtkiZQKIItA== + envinfo@7.5.0: version "7.5.0" resolved "https://registry.verdaccio.org/envinfo/-/envinfo-7.5.0.tgz#91410bb6db262fb4f1409bd506e9ff57e91023f4" @@ -5245,6 +5277,38 @@ jsbn@~0.1.0: resolved "https://registry.verdaccio.org/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jsdom@15.2.0: + version "15.2.0" + resolved "https://registry.verdaccio.org/jsdom/-/jsdom-15.2.0.tgz#4baead4f464e733533ed6ac607ce440918cf5cbb" + integrity sha512-+hRyEfjRPFwTYMmSQ3/f7U9nP8ZNZmbkmUek760ZpxnCPWJIhaaLRuUSvpJ36fZKCGENxLwxClzwpOpnXNfChQ== + dependencies: + abab "^2.0.0" + acorn "^7.1.0" + acorn-globals "^4.3.2" + array-equal "^1.0.0" + cssom "^0.4.1" + cssstyle "^2.0.0" + data-urls "^1.1.0" + domexception "^1.0.1" + escodegen "^1.11.1" + html-encoding-sniffer "^1.0.2" + nwsapi "^2.1.4" + parse5 "5.1.0" + pn "^1.1.0" + request "^2.88.0" + request-promise-native "^1.0.7" + saxes "^3.1.9" + symbol-tree "^3.2.2" + tough-cookie "^3.0.1" + w3c-hr-time "^1.0.1" + w3c-xmlserializer "^1.1.2" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^7.0.0" + ws "^7.0.0" + xml-name-validator "^3.0.0" + jsdom@15.2.1: version "15.2.1" resolved "https://registry.verdaccio.org/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" @@ -6348,7 +6412,7 @@ nwsapi@^2.0.7: resolved "https://registry.verdaccio.org/nwsapi/-/nwsapi-2.1.4.tgz#e006a878db23636f8e8a67d33ca0e4edf61a842f" integrity sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw== -nwsapi@^2.2.0: +nwsapi@^2.1.4, nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.verdaccio.org/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -8405,6 +8469,46 @@ verdaccio-memory@8.2.0: http-errors "1.7.3" memory-fs "0.5.0" +verdaccio@latest: + version "4.3.5" + resolved "https://registry.verdaccio.org/verdaccio/-/verdaccio-4.3.5.tgz#7e7dea476c0d41f6ac8923d4cdcec31217ab462b" + integrity sha512-184myBmaBc7nVpTYJCTLjhaBV+1dCw/do8clAmwUgxC5immDBf44YXJ/CtbJURgq532SLTrdlI4e4xnRl74RTg== + dependencies: + "@verdaccio/commons-api" "8.3.0" + "@verdaccio/local-storage" "8.2.0" + "@verdaccio/readme" "8.2.0" + "@verdaccio/streams" "8.2.0" + "@verdaccio/ui-theme" "0.3.2" + JSONStream "1.3.5" + async "3.1.0" + body-parser "1.19.0" + bunyan "1.8.12" + commander "3.0.2" + compression "1.7.4" + cookies "0.7.3" + cors "2.8.5" + dayjs "1.8.17" + envinfo "7.4.0" + express "4.17.1" + handlebars "4.5.3" + http-errors "1.7.3" + js-yaml "3.13.1" + jsonwebtoken "8.5.1" + kleur "3.0.3" + lockfile-lint "2.0.1" + lodash "4.17.15" + lunr-mutable-indexes "2.3.2" + marked "0.7.0" + mime "2.4.4" + minimatch "3.0.4" + mkdirp "0.5.1" + mv "2.1.1" + pkginfo "0.4.1" + request "2.87.0" + semver "6.3.0" + verdaccio-audit "8.1.4" + verdaccio-htpasswd "8.2.0" + verror@1.10.0: version "1.10.0" resolved "https://registry.verdaccio.org/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"