mirror of
https://github.com/cypress-io/cypress.git
synced 2025-12-29 10:39:50 -06:00
chore: merge in develop to unified-desktop-gui (#18103)
* merge in develop * remove accidentally merged file * update types
This commit is contained in:
@@ -2,8 +2,7 @@ branches:
|
||||
only:
|
||||
- master
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- windows-code-signing
|
||||
- fix-test-other-projects
|
||||
- /win*/
|
||||
|
||||
# https://www.appveyor.com/docs/lang/nodejs-iojs/
|
||||
|
||||
22
circle.yml
22
circle.yml
@@ -8,7 +8,7 @@ macBuildFilters: &macBuildFilters
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
|
||||
defaults: &defaults
|
||||
parallelism: 1
|
||||
@@ -42,7 +42,7 @@ onlyMainBranches: &onlyMainBranches
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
|
||||
@@ -1504,7 +1504,7 @@ jobs:
|
||||
- run:
|
||||
name: Check current branch to persist artifacts
|
||||
command: |
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "issue-17944-remove-source-files" ]]; then
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "fix-test-other-projects" ]]; then
|
||||
echo "Not uploading artifacts or posting install comment for this branch."
|
||||
circleci-agent step halt
|
||||
fi
|
||||
@@ -2142,7 +2142,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- build
|
||||
- test-kitchensink:
|
||||
@@ -2154,7 +2154,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- build
|
||||
- create-build-artifacts:
|
||||
@@ -2204,7 +2204,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-npm-module-and-verify-binary:
|
||||
@@ -2212,7 +2212,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
- test-binary-against-staging:
|
||||
@@ -2221,7 +2221,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
|
||||
@@ -2246,7 +2246,7 @@ linux-workflow: &linux-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- create-build-artifacts
|
||||
|
||||
@@ -2318,7 +2318,7 @@ mac-workflow: &mac-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- darwin-create-build-artifacts
|
||||
|
||||
@@ -2330,7 +2330,7 @@ mac-workflow: &mac-workflow
|
||||
branches:
|
||||
only:
|
||||
- develop
|
||||
- issue-17944-remove-source-files
|
||||
- fix-test-other-projects
|
||||
requires:
|
||||
- darwin-create-build-artifacts
|
||||
|
||||
|
||||
23
cli/types/cypress.d.ts
vendored
23
cli/types/cypress.d.ts
vendored
@@ -22,6 +22,19 @@ declare namespace Cypress {
|
||||
password: string
|
||||
}
|
||||
|
||||
interface RemoteState {
|
||||
auth?: {
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
domainName: string
|
||||
strategy: 'file' | 'http'
|
||||
origin: string
|
||||
fileServer: string
|
||||
props: Record<string, any>
|
||||
visiting: string
|
||||
}
|
||||
|
||||
interface Backend {
|
||||
/**
|
||||
* Firefox only: Force Cypress to run garbage collection routines.
|
||||
@@ -2856,19 +2869,15 @@ declare namespace Cypress {
|
||||
projectName: string
|
||||
projectRoot: string
|
||||
proxyUrl: string
|
||||
remote: RemoteState
|
||||
report: boolean
|
||||
reporterRoute: string
|
||||
reporterUrl: string
|
||||
socketId: null | string
|
||||
socketIoCookie: string
|
||||
socketIoRoute: string
|
||||
spec: {
|
||||
absolute: string
|
||||
name: string
|
||||
relative: string
|
||||
specFilter: null | string
|
||||
specType: 'integration' | 'component'
|
||||
}
|
||||
spec: Cypress['spec']
|
||||
specs: Array<Cypress['spec']>
|
||||
xhrRoute: string
|
||||
xhrUrl: string
|
||||
}
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/schematic-v1.5.1](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v1.5.0...@cypress/schematic-v1.5.1) (2021-09-10)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **cypress/schematic:** add edge to list of allowed browsers ([#17637](https://github.com/cypress-io/cypress/issues/17637)) ([49de24f](https://github.com/cypress-io/cypress/commit/49de24f6178e0ef7bfd654c3efc0bfa8008e962e))
|
||||
|
||||
# [@cypress/schematic-v1.5.0](https://github.com/cypress-io/cypress/compare/@cypress/schematic-v1.4.2...@cypress/schematic-v1.5.0) (2021-07-20)
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/react-v5.10.0](https://github.com/cypress-io/cypress/compare/@cypress/react-v5.9.4...@cypress/react-v5.10.0) (2021-09-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow usage of @react/plugins with cypress.config.js ([#17738](https://github.com/cypress-io/cypress/issues/17738)) ([da4b1e0](https://github.com/cypress-io/cypress/commit/da4b1e06ce33945aabddda0e6e175dc0e1b488a5))
|
||||
|
||||
# [@cypress/react-v5.9.4](https://github.com/cypress-io/cypress/compare/@cypress/react-v5.9.3...@cypress/react-v5.9.4) (2021-08-10)
|
||||
|
||||
|
||||
|
||||
@@ -4,16 +4,19 @@
|
||||
"description": "Test React components using Cypress",
|
||||
"main": "dist/cypress-react.cjs.js",
|
||||
"scripts": {
|
||||
"build": "rimraf dist && yarn rollup -c rollup.config.js",
|
||||
"build": "rimraf dist && yarn transpile-plugins && yarn rollup -c rollup.config.js",
|
||||
"build-prod": "yarn build",
|
||||
"cy:open": "node ../../scripts/cypress.js open-ct",
|
||||
"cy:open:debug": "node --inspect-brk ../../scripts/start.js --component-testing --run-project ${PWD}",
|
||||
"cy:run": "node ../../scripts/cypress.js run-ct",
|
||||
"cy:run:debug": "node --inspect-brk ../../scripts/start.js --component-testing --run-project ${PWD}",
|
||||
"pretest": "yarn transpile",
|
||||
"test": "yarn cy:run",
|
||||
"test": "yarn test-unit && yarn test-component",
|
||||
"test-unit": "mocha -r @packages/ts/register test/**/*.spec.*",
|
||||
"test-component": "yarn cy:run",
|
||||
"test-ci": "node ../../scripts/run-ct-examples.js --examplesList=./examples.env",
|
||||
"transpile": "tsc",
|
||||
"transpile-plugins": "yarn transpile --project ./plugins",
|
||||
"watch": "yarn build --watch --watch.exclude ./dist/**/*"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/// <reference types="next" />
|
||||
const debug = require('debug')('@cypress/react')
|
||||
const getNextJsBaseWebpackConfig = require('next/dist/build/webpack-config').default
|
||||
const { findPagesDir } = require('../../dist/next/findPagesDir')
|
||||
|
||||
async function getNextWebpackConfig (config) {
|
||||
let loadConfig
|
||||
@@ -26,7 +27,7 @@ async function getNextWebpackConfig (config) {
|
||||
config: nextConfig,
|
||||
dev: true,
|
||||
isServer: false,
|
||||
pagesDir: config.projectRoot,
|
||||
pagesDir: findPagesDir(config.projectRoot),
|
||||
entrypoints: {},
|
||||
rewrites: { fallback: [], afterFiles: [], beforeFiles: [] },
|
||||
},
|
||||
|
||||
33
npm/react/plugins/next/findPagesDir.ts
Normal file
33
npm/react/plugins/next/findPagesDir.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import * as fs from 'fs'
|
||||
import * as path from 'path'
|
||||
|
||||
const existsSync = (file: string) => {
|
||||
try {
|
||||
fs.accessSync(file, fs.constants.F_OK)
|
||||
|
||||
return true
|
||||
} catch (_) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Next allows the `pages` directory to be located at either
|
||||
* `${projectRoot}/pages` or `${projectRoot}/src/pages`.
|
||||
* If neither is found, return projectRoot
|
||||
*/
|
||||
export function findPagesDir (projectRoot: string) {
|
||||
// prioritize ./pages over ./src/pages
|
||||
let pagesDir = path.join(projectRoot, 'pages')
|
||||
|
||||
if (existsSync(pagesDir)) {
|
||||
return pagesDir
|
||||
}
|
||||
|
||||
pagesDir = path.join(projectRoot, 'src/pages')
|
||||
if (existsSync(pagesDir)) {
|
||||
return pagesDir
|
||||
}
|
||||
|
||||
return projectRoot
|
||||
}
|
||||
11
npm/react/plugins/tsconfig.json
Normal file
11
npm/react/plugins/tsconfig.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./",
|
||||
"types": [
|
||||
"cypress",
|
||||
"node"
|
||||
]
|
||||
},
|
||||
"include": ["./**/*.ts"]
|
||||
}
|
||||
0
npm/react/test/fixtures/next-plugin/next-project-one/pages/foo.js
vendored
Normal file
0
npm/react/test/fixtures/next-plugin/next-project-one/pages/foo.js
vendored
Normal file
0
npm/react/test/fixtures/next-plugin/next-project-two/src/pages/foo.js
vendored
Normal file
0
npm/react/test/fixtures/next-plugin/next-project-two/src/pages/foo.js
vendored
Normal file
19
npm/react/test/unit/findPagesDir.spec.ts
Normal file
19
npm/react/test/unit/findPagesDir.spec.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { expect } from 'chai'
|
||||
import * as path from 'path'
|
||||
import { findPagesDir } from '../../plugins/next/findPagesDir'
|
||||
|
||||
describe('Next.js findPagesDir', () => {
|
||||
it('should find the correct pagesDir', () => {
|
||||
const nextPluginFixturePath = path.join(__dirname, '../fixtures/next-plugin')
|
||||
|
||||
let projectRoot = nextPluginFixturePath
|
||||
|
||||
expect(findPagesDir(projectRoot)).to.equal(projectRoot)
|
||||
|
||||
projectRoot = path.join(nextPluginFixturePath, 'next-project-one')
|
||||
expect(findPagesDir(projectRoot)).to.equal(path.join(projectRoot, 'pages'))
|
||||
|
||||
projectRoot = path.join(nextPluginFixturePath, 'next-project-two')
|
||||
expect(findPagesDir(projectRoot)).to.equal(path.join(projectRoot, 'src/pages'))
|
||||
})
|
||||
})
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/vite-dev-server-v2.1.0](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.0.8...@cypress/vite-dev-server-v2.1.0) (2021-09-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow usage of @react/plugins with cypress.config.js ([#17738](https://github.com/cypress-io/cypress/issues/17738)) ([da4b1e0](https://github.com/cypress-io/cypress/commit/da4b1e06ce33945aabddda0e6e175dc0e1b488a5))
|
||||
|
||||
# [@cypress/vite-dev-server-v2.0.8](https://github.com/cypress-io/cypress/compare/@cypress/vite-dev-server-v2.0.7...@cypress/vite-dev-server-v2.0.8) (2021-08-30)
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
# [@cypress/webpack-dev-server-v1.6.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.5.0...@cypress/webpack-dev-server-v1.6.0) (2021-09-10)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* allow usage of @react/plugins with cypress.config.js ([#17738](https://github.com/cypress-io/cypress/issues/17738)) ([da4b1e0](https://github.com/cypress-io/cypress/commit/da4b1e06ce33945aabddda0e6e175dc0e1b488a5))
|
||||
|
||||
# [@cypress/webpack-dev-server-v1.5.0](https://github.com/cypress-io/cypress/compare/@cypress/webpack-dev-server-v1.4.0...@cypress/webpack-dev-server-v1.5.0) (2021-08-30)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cypress",
|
||||
"version": "8.3.1",
|
||||
"version": "8.4.0",
|
||||
"description": "Cypress.io end to end testing tool",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -162,7 +162,7 @@
|
||||
"lint-staged": "11.0.0",
|
||||
"listr2": "3.8.3",
|
||||
"lodash": "4.17.21",
|
||||
"make-empty-github-commit": "1.2.0",
|
||||
"make-empty-github-commit": "cypress-io/make-empty-github-commit#4a592aedb776ba2f4cc88979055315a53eec42ee",
|
||||
"minimist": "1.2.5",
|
||||
"mocha": "3.5.3",
|
||||
"mocha-banner": "1.1.2",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import _ from 'lodash'
|
||||
import type CyServer from '@packages/server'
|
||||
import { blocked, cors } from '@packages/network'
|
||||
import { InterceptRequest } from '@packages/net-stubbing'
|
||||
import debugModule from 'debug'
|
||||
@@ -126,7 +125,7 @@ const StripUnsupportedAcceptEncoding: RequestMiddleware = function () {
|
||||
this.next()
|
||||
}
|
||||
|
||||
function reqNeedsBasicAuthHeaders (req, { auth, origin }: CyServer.RemoteState) {
|
||||
function reqNeedsBasicAuthHeaders (req, { auth, origin }: Cypress.RemoteState) {
|
||||
//if we have auth headers, this request matches our origin, protection space, and the user has not supplied auth headers
|
||||
return auth && !req.headers['authorization'] && cors.urlMatchesOriginProtectionSpace(req.proxiedUrl, origin)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ import path from 'path'
|
||||
|
||||
let fs: typeof import('fs-extra')
|
||||
|
||||
type FoldersWithDist = 'static' | 'runner' | 'runner-ct' | 'driver'
|
||||
export type RunnerPkg = 'runner' | 'runner-ct'
|
||||
|
||||
type FoldersWithDist = 'static' | 'driver' | RunnerPkg
|
||||
|
||||
export const getPathToDist = (folder: FoldersWithDist, ...args: string[]) => {
|
||||
return path.join(...[__dirname, '..', '..', folder, 'dist', ...args])
|
||||
@@ -14,7 +16,7 @@ export const getRunnerInjectionContents = () => {
|
||||
return fs.readFile(getPathToDist('runner', 'injection.js'))
|
||||
}
|
||||
|
||||
export const getPathToIndex = (pkg: 'runner' | 'runner-ct') => {
|
||||
export const getPathToIndex = (pkg: RunnerPkg) => {
|
||||
return getPathToDist(pkg, 'index.html')
|
||||
}
|
||||
|
||||
|
||||
14
packages/server/index.d.ts
vendored
14
packages/server/index.d.ts
vendored
@@ -14,7 +14,7 @@
|
||||
|
||||
// types for the `server` package
|
||||
export namespace CyServer {
|
||||
export type getRemoteState = () => RemoteState
|
||||
export type getRemoteState = () => Cypress.RemoteState
|
||||
|
||||
// TODO: pull this from main types
|
||||
export interface Config {
|
||||
@@ -28,18 +28,6 @@ export namespace CyServer {
|
||||
responseTimeout: number
|
||||
}
|
||||
|
||||
export interface RemoteState {
|
||||
auth?: {
|
||||
username: string
|
||||
password: string
|
||||
}
|
||||
domainName: string
|
||||
strategy: 'file' | 'http'
|
||||
origin: string
|
||||
fileServer: string
|
||||
visiting: string
|
||||
}
|
||||
|
||||
export interface Socket {
|
||||
toDriver: (eventName: string, ...args: any) => void
|
||||
}
|
||||
|
||||
56
packages/server/lib/controllers/iframes.ts
Normal file
56
packages/server/lib/controllers/iframes.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import type { Request, Response } from 'express'
|
||||
import type httpProxy from 'http-proxy'
|
||||
import Debug from 'debug'
|
||||
import files from './files'
|
||||
import type { Cfg } from '../project-base'
|
||||
|
||||
const debug = Debug('cypress:server:iframes')
|
||||
|
||||
interface IFramesController {
|
||||
config: Cfg
|
||||
}
|
||||
|
||||
interface E2E extends IFramesController {
|
||||
getRemoteState: () => any
|
||||
getSpec: () => Cypress.Cypress['spec'] | null
|
||||
}
|
||||
|
||||
interface CT extends IFramesController {
|
||||
nodeProxy: httpProxy
|
||||
}
|
||||
|
||||
export const iframesController = {
|
||||
e2e: ({ getSpec, getRemoteState, config }: E2E, req: Request, res: Response) => {
|
||||
const extraOptions = {
|
||||
specFilter: getSpec()?.specFilter,
|
||||
specType: 'integration',
|
||||
}
|
||||
|
||||
debug('handling iframe for project spec %o', {
|
||||
spec: getSpec(),
|
||||
extraOptions,
|
||||
})
|
||||
|
||||
files.handleIframe(req, res, config, getRemoteState, extraOptions)
|
||||
},
|
||||
|
||||
component: ({ config, nodeProxy }: CT, req: Request, res: Response) => {
|
||||
// always proxy to the index.html file
|
||||
// attach header data for webservers
|
||||
// to properly intercept and serve assets from the correct src root
|
||||
// TODO: define a contract for dev-server plugins to configure this behavior
|
||||
req.headers.__cypress_spec_path = req.params[0]
|
||||
req.url = `${config.devServerPublicPathRoute}/index.html`
|
||||
|
||||
// user the node proxy here instead of the network proxy
|
||||
// to avoid the user accidentally intercepting and modifying
|
||||
// our internal index.html handler
|
||||
|
||||
nodeProxy.web(req, res, {}, (e) => {
|
||||
if (e) {
|
||||
// eslint-disable-next-line
|
||||
debug('Proxy request error. This is likely the socket hangup issue, we can basically ignore this because the stream will automatically continue once the asset will be available', e)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
const _ = require('lodash')
|
||||
const send = require('send')
|
||||
const os = require('os')
|
||||
const { fs } = require('../util/fs')
|
||||
const path = require('path')
|
||||
const debug = require('debug')('cypress:server:runner')
|
||||
const pkg = require('@packages/root')
|
||||
/**
|
||||
* @type {import('@packages/resolve-dist')}
|
||||
*/
|
||||
const { getPathToDist, getPathToIndex } = require('@packages/resolve-dist')
|
||||
|
||||
const PATH_TO_NON_PROXIED_ERROR = path.join(__dirname, '..', 'html', 'non_proxied_error.html')
|
||||
|
||||
const _serveNonProxiedError = (res) => {
|
||||
return fs.readFile(PATH_TO_NON_PROXIED_ERROR)
|
||||
.then((html) => {
|
||||
return res.type('html').end(html)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
serve (req, res, options = {}) {
|
||||
if (req.proxiedUrl.startsWith('/')) {
|
||||
debug('request was not proxied via Cypress, erroring %o', _.pick(req, 'proxiedUrl'))
|
||||
|
||||
return _serveNonProxiedError(res)
|
||||
}
|
||||
|
||||
let { config, getRemoteState, getCurrentBrowser, getSpec, specsStore } = options
|
||||
|
||||
config = _.clone(config)
|
||||
config.remote = getRemoteState()
|
||||
config.version = pkg.version
|
||||
config.platform = os.platform()
|
||||
config.arch = os.arch()
|
||||
config.spec = getSpec()
|
||||
config.specs = specsStore.specFiles
|
||||
config.browser = getCurrentBrowser()
|
||||
|
||||
debug('serving runner index.html with config %o',
|
||||
_.pick(config, 'version', 'platform', 'arch', 'projectName'))
|
||||
|
||||
// log the env object's keys without values to avoid leaking sensitive info
|
||||
debug('env object has the following keys: %s', _.keys(config.env).join(', '))
|
||||
|
||||
// base64 before embedding so user-supplied contents can't break out of <script>
|
||||
// https://github.com/cypress-io/cypress/issues/4952
|
||||
const base64Config = Buffer.from(JSON.stringify(config)).toString('base64')
|
||||
|
||||
const runnerPath = process.env.CYPRESS_INTERNAL_RUNNER_PATH || getPathToIndex('runner')
|
||||
|
||||
return res.render(runnerPath, {
|
||||
base64Config,
|
||||
projectName: config.projectName,
|
||||
})
|
||||
},
|
||||
|
||||
handle (req, res) {
|
||||
const pathToFile = getPathToDist('runner', req.params[0])
|
||||
|
||||
return send(req, pathToFile)
|
||||
.pipe(res)
|
||||
},
|
||||
}
|
||||
91
packages/server/lib/controllers/runner.ts
Normal file
91
packages/server/lib/controllers/runner.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import _ from 'lodash'
|
||||
import type { Response } from 'express'
|
||||
import send from 'send'
|
||||
import os from 'os'
|
||||
import { fs } from '../util/fs'
|
||||
import path from 'path'
|
||||
import Debug from 'debug'
|
||||
import pkg from '@packages/root'
|
||||
import { getPathToDist, getPathToIndex, RunnerPkg } from '@packages/resolve-dist'
|
||||
import type { InitializeRoutes } from '../routes'
|
||||
import type { PlatformName } from '@packages/types'
|
||||
import type { Cfg } from '../project-base'
|
||||
|
||||
const debug = Debug('cypress:server:runner')
|
||||
|
||||
const PATH_TO_NON_PROXIED_ERROR = path.join(__dirname, '..', 'html', 'non_proxied_error.html')
|
||||
|
||||
const _serveNonProxiedError = (res: Response) => {
|
||||
return fs.readFile(PATH_TO_NON_PROXIED_ERROR)
|
||||
.then((html) => {
|
||||
return res.type('html').end(html)
|
||||
})
|
||||
}
|
||||
|
||||
export interface ServeOptions extends Pick<InitializeRoutes, 'getSpec' | 'config' | 'getCurrentBrowser' | 'getRemoteState' | 'specsStore'> {
|
||||
testingType: Cypress.TestingType
|
||||
}
|
||||
|
||||
export const serveRunner = (runnerPkg: RunnerPkg, config: Cfg, res: Response) => {
|
||||
// base64 before embedding so user-supplied contents can't break out of <script>
|
||||
// https://github.com/cypress-io/cypress/issues/4952
|
||||
const base64Config = Buffer.from(JSON.stringify(config)).toString('base64')
|
||||
|
||||
const runnerPath = process.env.CYPRESS_INTERNAL_RUNNER_PATH || getPathToIndex(runnerPkg)
|
||||
|
||||
return res.render(runnerPath, {
|
||||
base64Config,
|
||||
projectName: config.projectName,
|
||||
})
|
||||
}
|
||||
|
||||
export const runner = {
|
||||
serve (req, res, runnerPkg: RunnerPkg, options: ServeOptions) {
|
||||
if (req.proxiedUrl.startsWith('/')) {
|
||||
debug('request was not proxied via Cypress, erroring %o', _.pick(req, 'proxiedUrl'))
|
||||
|
||||
return _serveNonProxiedError(res)
|
||||
}
|
||||
|
||||
let { config, getRemoteState, getCurrentBrowser, getSpec, specsStore } = options
|
||||
|
||||
config = _.clone(config)
|
||||
// at any given point, rather than just arbitrarily modifying it.
|
||||
// @ts-ignore
|
||||
config.testingType = options.testingType
|
||||
|
||||
// TODO #1: bug. Passing `remote.domainName` breaks CT for unknown reasons.
|
||||
// If you pass a remote object with a domainName key, we get cross-origin
|
||||
// iframe access errors.
|
||||
// repro:
|
||||
// {
|
||||
// "domainName": "localhost"
|
||||
// }
|
||||
// TODO: Find out what the problem.
|
||||
if (options.testingType === 'e2e') {
|
||||
config.remote = getRemoteState()
|
||||
}
|
||||
|
||||
config.version = pkg.version
|
||||
config.platform = os.platform() as PlatformName
|
||||
config.arch = os.arch()
|
||||
config.spec = getSpec() ?? undefined
|
||||
config.specs = specsStore.specFiles
|
||||
config.browser = getCurrentBrowser()
|
||||
|
||||
debug('serving runner index.html with config %o',
|
||||
_.pick(config, 'version', 'platform', 'arch', 'projectName'))
|
||||
|
||||
// log the env object's keys without values to avoid leaking sensitive info
|
||||
debug('env object has the following keys: %s', _.keys(config.env).join(', '))
|
||||
|
||||
return serveRunner(runnerPkg, config, res)
|
||||
},
|
||||
|
||||
handle (testingType, req, res) {
|
||||
const pathToFile = getPathToDist(testingType === 'e2e' ? 'runner' : 'runner-ct', req.params[0])
|
||||
|
||||
return send(req, pathToFile)
|
||||
.pipe(res)
|
||||
},
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
const send = require('send')
|
||||
/**
|
||||
* @type {import('@packages/resolve-dist')}
|
||||
*/
|
||||
const { getPathToDist } = require('@packages/resolve-dist')
|
||||
|
||||
module.exports = {
|
||||
handle (req, res) {
|
||||
const pathToFile = getPathToDist('static', req.params[0])
|
||||
|
||||
return send(req, pathToFile)
|
||||
.pipe(res)
|
||||
},
|
||||
}
|
||||
12
packages/server/lib/controllers/static.ts
Normal file
12
packages/server/lib/controllers/static.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import send from 'send'
|
||||
import type { Request, Response } from 'express'
|
||||
import { getPathToDist } from '@packages/resolve-dist'
|
||||
|
||||
export const staticCtrl = {
|
||||
handle (req: Request, res: Response) {
|
||||
const pathToFile = getPathToDist('static', req.params[0])
|
||||
|
||||
return send(req, pathToFile)
|
||||
.pipe(res)
|
||||
},
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
const human = require('human-interval')
|
||||
const _ = require('lodash')
|
||||
const Debug = require('debug')
|
||||
|
||||
const { getBrowsers } = require('../browsers/utils')
|
||||
const errors = require('../errors')
|
||||
const browsers = require('../browsers')
|
||||
const { openProject } = require('../open_project')
|
||||
const Updater = require('../updater')
|
||||
import Debug from 'debug'
|
||||
import _ from 'lodash'
|
||||
import browserUtils from '../browsers/utils'
|
||||
import human from 'human-interval'
|
||||
import browsers from '../browsers'
|
||||
import { openProject } from '../open_project'
|
||||
import type { LaunchArgs } from '@packages/types'
|
||||
import * as Updater from '../updater'
|
||||
import * as errors from '../errors'
|
||||
|
||||
const debug = Debug('cypress:server:interactive-ct')
|
||||
|
||||
const registerCheckForUpdates = () => {
|
||||
const checkForUpdates = (initialLaunch) => {
|
||||
const checkForUpdates = (initialLaunch: boolean) => {
|
||||
Updater.check({
|
||||
initialLaunch,
|
||||
testingType: 'component',
|
||||
@@ -24,10 +24,7 @@ const registerCheckForUpdates = () => {
|
||||
checkForUpdates(true)
|
||||
}
|
||||
|
||||
// Partial because there are probably other options that are not included in this type.
|
||||
// projectRoot: string
|
||||
// args: LaunchArgs
|
||||
const start = async (projectRoot, args) => {
|
||||
const start = async (projectRoot: string, args: LaunchArgs) => {
|
||||
if (process.env['CYPRESS_INTERNAL_ENV'] === 'production') {
|
||||
registerCheckForUpdates()
|
||||
}
|
||||
@@ -36,13 +33,13 @@ const start = async (projectRoot, args) => {
|
||||
|
||||
// add chrome as a default browser if none has been specified
|
||||
return browsers.ensureAndGetByNameOrPath(args.browser)
|
||||
.then((browser) => {
|
||||
.then((browser: Cypress.Browser) => {
|
||||
const spec = {
|
||||
name: 'All Specs',
|
||||
absolute: '__all',
|
||||
relative: '__all',
|
||||
specType: 'component',
|
||||
}
|
||||
} as const
|
||||
|
||||
const options = {
|
||||
browsers: [browser],
|
||||
@@ -51,7 +48,7 @@ const start = async (projectRoot, args) => {
|
||||
debug('create project')
|
||||
|
||||
return openProject.create(projectRoot, args, options)
|
||||
.then((project) => {
|
||||
.then(() => {
|
||||
debug('launch project')
|
||||
|
||||
return openProject.launch(browser, spec, {
|
||||
@@ -65,9 +62,12 @@ const start = async (projectRoot, args) => {
|
||||
})
|
||||
}
|
||||
|
||||
const browsersForCtInteractive = ['chrome', 'chromium', 'edge', 'electron', 'firefox']
|
||||
export const browsersForCtInteractive = ['chrome', 'chromium', 'edge', 'electron', 'firefox'] as const
|
||||
|
||||
const returnDefaultBrowser = (browsersByPriority, installedBrowsers) => {
|
||||
export const returnDefaultBrowser = (
|
||||
browsersByPriority: typeof browsersForCtInteractive,
|
||||
installedBrowsers: any[],
|
||||
) => {
|
||||
const browserMap = installedBrowsers.reduce((acc, curr) => {
|
||||
acc[curr.name] = true
|
||||
|
||||
@@ -79,14 +79,16 @@ const returnDefaultBrowser = (browsersByPriority, installedBrowsers) => {
|
||||
return browser
|
||||
}
|
||||
}
|
||||
|
||||
return undefined
|
||||
}
|
||||
|
||||
const run = async (options) => {
|
||||
const installedBrowsers = await getBrowsers()
|
||||
export const run = async (options: LaunchArgs) => {
|
||||
const installedBrowsers = await browserUtils.getBrowsers()
|
||||
|
||||
options.browser = options.browser || returnDefaultBrowser(browsersForCtInteractive, installedBrowsers)
|
||||
|
||||
return start(options.projectRoot, options).catch((e) => {
|
||||
return start(options.projectRoot, options).catch((e: Error) => {
|
||||
// Usually this kind of error management is doen inside cypress.js start
|
||||
// But here we bypassed this since we don't use the window of the gui
|
||||
// Handle errors here to avoid multiple errors appearing.
|
||||
@@ -95,9 +97,3 @@ const run = async (options) => {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
run,
|
||||
returnDefaultBrowser,
|
||||
browsersForCtInteractive,
|
||||
}
|
||||
@@ -31,18 +31,15 @@ import Watchers from './watchers'
|
||||
import devServer from './plugins/dev-server'
|
||||
import preprocessor from './plugins/preprocessor'
|
||||
import { SpecsStore } from './specs-store'
|
||||
import { createRoutes as createE2ERoutes } from './routes'
|
||||
import { createRoutes as createCTRoutes } from './routes-ct'
|
||||
import { checkSupportFile } from './project_utils'
|
||||
import type { FoundBrowser, OpenProjectLaunchOptions, ResolvedConfigurationOptions } from '@packages/types'
|
||||
|
||||
// Cannot just use RuntimeConfigOptions as is because some types are not complete.
|
||||
// Instead, this is an interface of values that have been manually validated to exist
|
||||
// and are required when creating a project.
|
||||
// TODO: Figure out how to type this better.
|
||||
type ReceivedCypressOptions =
|
||||
Partial<Pick<Cypress.RuntimeConfigOptions, 'hosts' | 'projectName' | 'clientRoute' | 'devServerPublicPathRoute' | 'namespace' | 'report' | 'socketIoCookie' | 'configFile' | 'isTextTerminal' | 'isNewProject' | 'proxyUrl' | 'browsers' | 'browserUrl' | 'socketIoRoute'>>
|
||||
& Partial<Pick<Cypress.ResolvedConfigOptions, 'chromeWebSecurity' | 'supportFolder' | 'experimentalSourceRewriting' | 'fixturesFolder' | 'reporter' | 'reporterOptions' | 'screenshotsFolder' | 'pluginsFile' | 'supportFile' | 'integrationFolder' | 'baseUrl' | 'viewportHeight' | 'viewportWidth' | 'port' | 'experimentalInteractiveRunEvents' | 'componentFolder' | 'userAgent' | 'downloadsFolder'>>
|
||||
Partial<Pick<Cypress.RuntimeConfigOptions, 'hosts' | 'projectName' | 'clientRoute' | 'devServerPublicPathRoute' | 'namespace' | 'report' | 'socketIoCookie' | 'configFile' | 'isTextTerminal' | 'isNewProject' | 'proxyUrl' | 'browsers' | 'browserUrl' | 'socketIoRoute' | 'arch' | 'platform' | 'spec' | 'specs' | 'browser' | 'version' | 'remote'>>
|
||||
& Partial<Pick<Cypress.ResolvedConfigOptions, 'chromeWebSecurity' | 'supportFolder' | 'experimentalSourceRewriting' | 'fixturesFolder' | 'reporter' | 'reporterOptions' | 'screenshotsFolder' | 'pluginsFile' | 'supportFile' | 'integrationFolder' | 'baseUrl' | 'viewportHeight' | 'viewportWidth' | 'port' | 'experimentalInteractiveRunEvents' | 'componentFolder' | 'userAgent' | 'downloadsFolder' | 'env'>>// TODO: Figure out how to type this better.
|
||||
|
||||
export interface Cfg extends ReceivedCypressOptions {
|
||||
projectRoot: string
|
||||
@@ -208,7 +205,6 @@ export class ProjectBase<TServer extends Server> extends EE {
|
||||
shouldCorrelatePreRequests: this.shouldCorrelatePreRequests,
|
||||
testingType: this.testingType,
|
||||
SocketCtor: this.testingType === 'e2e' ? SocketE2E : SocketCt,
|
||||
createRoutes: this.testingType === 'e2e' ? createE2ERoutes : createCTRoutes,
|
||||
specsStore,
|
||||
})
|
||||
|
||||
|
||||
@@ -1,39 +1,32 @@
|
||||
import Debug from 'debug'
|
||||
import type { ErrorRequestHandler, Express } from 'express'
|
||||
|
||||
import httpProxy from 'http-proxy'
|
||||
import send from 'send'
|
||||
import type { NetworkProxy } from '@packages/proxy'
|
||||
|
||||
import { handle, serve, makeServeConfig, serveChunk } from './runner-ct'
|
||||
import xhrs from './controllers/xhrs'
|
||||
import type { SpecsStore } from './specs-store'
|
||||
import type { Cfg } from './project-base'
|
||||
import { handle, makeServeConfig } from './runner-ct'
|
||||
import { Request, Response, Router } from 'express'
|
||||
import { getPathToDist } from '@packages/resolve-dist'
|
||||
import type { Browser } from './browsers/types'
|
||||
import { runner } from './controllers/runner'
|
||||
import type { InitializeRoutes } from './routes'
|
||||
|
||||
const debug = Debug('cypress:server:routes')
|
||||
const debug = Debug('cypress:server:routes-ct')
|
||||
|
||||
export interface InitializeRoutes {
|
||||
app: Express
|
||||
specsStore: SpecsStore
|
||||
config: Cfg
|
||||
getSpec: () => Cypress.Cypress['spec'] | null
|
||||
getCurrentBrowser: () => Browser
|
||||
nodeProxy: httpProxy
|
||||
networkProxy: NetworkProxy
|
||||
getRemoteState: () => any
|
||||
testingType: Cypress.TestingType
|
||||
onError: (...args: unknown[]) => any
|
||||
const serveChunk = (req: Request, res: Response, clientRoute: string) => {
|
||||
let pathToFile = getPathToDist('runner-ct', req.originalUrl.replace(clientRoute, ''))
|
||||
|
||||
return send(req, pathToFile).pipe(res)
|
||||
}
|
||||
|
||||
export const createRoutes = ({
|
||||
app,
|
||||
export const createRoutesCT = ({
|
||||
config,
|
||||
specsStore,
|
||||
nodeProxy,
|
||||
networkProxy,
|
||||
getCurrentBrowser,
|
||||
testingType,
|
||||
getSpec,
|
||||
getRemoteState,
|
||||
}: InitializeRoutes) => {
|
||||
const routesCt = Router()
|
||||
|
||||
// If development
|
||||
const myProxy = httpProxy.createProxyServer({
|
||||
target: 'http://localhost:3333/',
|
||||
@@ -41,7 +34,7 @@ export const createRoutes = ({
|
||||
|
||||
// TODO If prod, serve the build app files from app/dist
|
||||
|
||||
app.get('/__/api', (req, res) => {
|
||||
routesCt.get('/__/api', (req, res) => {
|
||||
const options = makeServeConfig({
|
||||
config,
|
||||
getCurrentBrowser,
|
||||
@@ -53,21 +46,21 @@ export const createRoutes = ({
|
||||
|
||||
// TODO: can namespace this onto a "unified" route like __app-unified__
|
||||
// make sure to update the generated routes inside of vite.config.ts
|
||||
app.get('/__vite__/*', (req, res) => {
|
||||
routesCt.get('/__vite__/*', (req, res) => {
|
||||
myProxy.web(req, res, {}, (e) => {
|
||||
})
|
||||
})
|
||||
|
||||
app.get('/__cypress/runner/*', handle)
|
||||
routesCt.get('/__cypress/runner/*', handle)
|
||||
|
||||
app.get('/__cypress/static/*', (req, res) => {
|
||||
routesCt.get('/__cypress/static/*', (req, res) => {
|
||||
const pathToFile = getPathToDist('static', req.params[0])
|
||||
|
||||
return send(req, pathToFile)
|
||||
.pipe(res)
|
||||
})
|
||||
|
||||
app.get('/__cypress/iframes/*', (req, res) => {
|
||||
routesCt.get('/__cypress/iframes/*', (req, res) => {
|
||||
// always proxy to the index.html file
|
||||
// attach header data for webservers
|
||||
// to properly intercept and serve assets from the correct src root
|
||||
@@ -89,7 +82,7 @@ export const createRoutes = ({
|
||||
|
||||
// user app code + spec code
|
||||
// default mounted to /__cypress/src/*
|
||||
app.get(`${config.devServerPublicPathRoute}*`, (req, res) => {
|
||||
routesCt.get(`${config.devServerPublicPathRoute}*`, (req, res) => {
|
||||
// user the node proxy here instead of the network proxy
|
||||
// to avoid the user accidentally intercepting and modifying
|
||||
// their own app.js files + spec.js files
|
||||
@@ -107,49 +100,28 @@ export const createRoutes = ({
|
||||
throw Error(`clientRoute is required. Received ${clientRoute}`)
|
||||
}
|
||||
|
||||
app.all('/__cypress/xhrs/*', (req, res, next) => {
|
||||
xhrs.handle(req, res, config, next)
|
||||
})
|
||||
|
||||
app.get(clientRoute, (req, res) => {
|
||||
routesCt.get(clientRoute, (req, res) => {
|
||||
debug('Serving Cypress front-end by requested URL:', req.url)
|
||||
|
||||
serve(req, res, {
|
||||
runner.serve(req, res, 'runner-ct', {
|
||||
config,
|
||||
testingType,
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
getRemoteState,
|
||||
specsStore,
|
||||
})
|
||||
})
|
||||
|
||||
// enables runner-ct to make a dynamic import
|
||||
app.get(`${clientRoute}ctChunk-*`, (req, res) => {
|
||||
routesCt.get([
|
||||
`${clientRoute}ctChunk-*`,
|
||||
`${clientRoute}vendors~ctChunk-*`,
|
||||
], (req, res) => {
|
||||
debug('Serving Cypress front-end chunk by requested URL:', req.url)
|
||||
|
||||
serveChunk(req, res, { config })
|
||||
serveChunk(req, res, clientRoute)
|
||||
})
|
||||
|
||||
app.get(`${clientRoute}vendors~ctChunk-*`, (req, res) => {
|
||||
debug('Serving Cypress front-end vendor chunk by requested URL:', req.url)
|
||||
|
||||
serveChunk(req, res, { config })
|
||||
})
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
networkProxy.handleHttpRequest(req, res)
|
||||
})
|
||||
|
||||
// when we experience uncaught errors
|
||||
// during routing just log them out to
|
||||
// the console and send 500 status
|
||||
// and report to raygun (in production)
|
||||
const errorHandlingMiddleware: ErrorRequestHandler = (err, req, res) => {
|
||||
console.log(err.stack) // eslint-disable-line no-console
|
||||
|
||||
res.set('x-cypress-error', err.message)
|
||||
res.set('x-cypress-stack', JSON.stringify(err.stack))
|
||||
|
||||
res.sendStatus(500)
|
||||
}
|
||||
|
||||
app.use(errorHandlingMiddleware)
|
||||
return routesCt
|
||||
}
|
||||
|
||||
156
packages/server/lib/routes-e2e.ts
Normal file
156
packages/server/lib/routes-e2e.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import path from 'path'
|
||||
import la from 'lazy-ass'
|
||||
import check from 'check-more-types'
|
||||
import Debug from 'debug'
|
||||
import { Router } from 'express'
|
||||
|
||||
import AppData from './util/app_data'
|
||||
import CacheBuster from './util/cache_buster'
|
||||
import specController from './controllers/spec'
|
||||
import reporter from './controllers/reporter'
|
||||
import { runner } from './controllers/runner'
|
||||
import client from './controllers/client'
|
||||
import files from './controllers/files'
|
||||
import type { InitializeRoutes } from './routes'
|
||||
|
||||
const debug = Debug('cypress:server:routes-e2e')
|
||||
|
||||
export const createRoutesE2E = ({
|
||||
config,
|
||||
specsStore,
|
||||
getRemoteState,
|
||||
networkProxy,
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
onError,
|
||||
testingType,
|
||||
}: InitializeRoutes) => {
|
||||
const routesE2E = Router()
|
||||
|
||||
// routing for the actual specs which are processed automatically
|
||||
// this could be just a regular .js file or a .coffee file
|
||||
routesE2E.get('/__cypress/tests', (req, res, next) => {
|
||||
// slice out the cache buster
|
||||
const test = CacheBuster.strip(req.query.p)
|
||||
|
||||
specController.handle(test, req, res, config, next, onError)
|
||||
})
|
||||
|
||||
routesE2E.get('/__cypress/socket.io.js', (req, res) => {
|
||||
client.handle(req, res)
|
||||
})
|
||||
|
||||
routesE2E.get('/__cypress/reporter/*', (req, res) => {
|
||||
reporter.handle(req, res)
|
||||
})
|
||||
|
||||
routesE2E.get('/__cypress/automation/getLocalStorage', (req, res) => {
|
||||
// gathers and sends localStorage and sessionStorage via postMessage to the Cypress frame
|
||||
// detect existence of local/session storage with JSON.stringify(...).length since localStorage.length may not be accurate
|
||||
res.send(`<html><body><script>(${(function () {
|
||||
const _localStorageStr = JSON.stringify(window.localStorage)
|
||||
const _localStorage = _localStorageStr.length > 2 && JSON.parse(_localStorageStr)
|
||||
const _sessionStorageStr = JSON.stringify(window.sessionStorage)
|
||||
const _sessionStorage = _sessionStorageStr.length > 2 && JSON.parse(JSON.stringify(window.sessionStorage))
|
||||
|
||||
const value = {} as any
|
||||
|
||||
if (_localStorage) {
|
||||
value.localStorage = _localStorage
|
||||
}
|
||||
|
||||
if (_sessionStorage) {
|
||||
value.sessionStorage = _sessionStorage
|
||||
}
|
||||
|
||||
window.parent.postMessage({
|
||||
value,
|
||||
type: 'localStorage',
|
||||
}, '*')
|
||||
}).toString()})()</script></body></html>`)
|
||||
})
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
routesE2E.get('/__cypress/automation/setLocalStorage', (req, res) => {
|
||||
const origin = req.originalUrl.slice(req.originalUrl.indexOf('?') + 1)
|
||||
|
||||
networkProxy.http.getRenderedHTMLOrigins()[origin] = true
|
||||
res.send(`<html><body><script>(${(function () {
|
||||
window.onmessage = function (event) {
|
||||
const msg = event.data
|
||||
|
||||
if (msg.type === 'set:storage:data') {
|
||||
const { data } = msg
|
||||
|
||||
const setData = (storageData, type) => {
|
||||
if (!storageData) return
|
||||
|
||||
const { clear, value } = storageData
|
||||
|
||||
if (clear) {
|
||||
// @ts-ignore
|
||||
window[type].clear()
|
||||
}
|
||||
|
||||
if (value) {
|
||||
Object.keys(value).forEach((key) => {
|
||||
// @ts-ignore
|
||||
window[type].setItem(key, value[key])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setData(data.localStorage, 'localStorage')
|
||||
setData(data.sessionStorage, 'sessionStorage')
|
||||
|
||||
window.parent.postMessage({ type: 'set:storage:complete' }, '*')
|
||||
}
|
||||
}
|
||||
|
||||
window.parent.postMessage({ type: 'set:storage:load' }, '*')
|
||||
}).toString()})()</script></body></html>`)
|
||||
})
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
// routing for /files JSON endpoint
|
||||
routesE2E.get('/__cypress/files', (req, res) => {
|
||||
files.handleFiles(req, res, config)
|
||||
})
|
||||
|
||||
routesE2E.get('/__cypress/source-maps/:id.map', (req, res) => {
|
||||
networkProxy.handleSourceMapRequest(req, res)
|
||||
})
|
||||
|
||||
// special fallback - serve local files from the project's root folder
|
||||
routesE2E.get('/__root/*', (req, res) => {
|
||||
const file = path.join(config.projectRoot, req.params[0])
|
||||
|
||||
res.sendFile(file, { etag: false })
|
||||
})
|
||||
|
||||
// special fallback - serve dist'd (bundled/static) files from the project path folder
|
||||
routesE2E.get('/__cypress/bundled/*', (req, res) => {
|
||||
const file = AppData.getBundledFilePath(config.projectRoot, path.join('src', req.params[0]))
|
||||
|
||||
debug(`Serving dist'd bundle at file path: %o`, { path: file, url: req.url })
|
||||
|
||||
res.sendFile(file, { etag: false })
|
||||
})
|
||||
|
||||
la(check.unemptyString(config.clientRoute), 'missing client route in config', config)
|
||||
|
||||
routesE2E.get(`${config.clientRoute}`, (req, res) => {
|
||||
debug('Serving Cypress front-end by requested URL:', req.url)
|
||||
|
||||
runner.serve(req, res, 'runner', {
|
||||
config,
|
||||
testingType,
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
getRemoteState,
|
||||
specsStore,
|
||||
})
|
||||
})
|
||||
|
||||
return routesE2E
|
||||
}
|
||||
@@ -1,185 +1,60 @@
|
||||
import path from 'path'
|
||||
import la from 'lazy-ass'
|
||||
import check from 'check-more-types'
|
||||
import Debug from 'debug'
|
||||
import type httpProxy from 'http-proxy'
|
||||
import { ErrorRequestHandler, Router } from 'express'
|
||||
|
||||
import type { InitializeRoutes } from './routes-ct'
|
||||
import AppData from './util/app_data'
|
||||
import CacheBuster from './util/cache_buster'
|
||||
import specController from './controllers/spec'
|
||||
import reporter from './controllers/reporter'
|
||||
import runner from './controllers/runner'
|
||||
import type { SpecsStore } from './specs-store'
|
||||
import { staticCtrl } from './controllers/static'
|
||||
import type { Browser } from './browsers/types'
|
||||
import type { NetworkProxy } from '@packages/proxy'
|
||||
import type { Cfg } from './project-base'
|
||||
import xhrs from './controllers/xhrs'
|
||||
import client from './controllers/client'
|
||||
import files from './controllers/files'
|
||||
import staticCtrl from './controllers/static'
|
||||
import { runner } from './controllers/runner'
|
||||
import { iframesController } from './controllers/iframes'
|
||||
|
||||
const debug = Debug('cypress:server:routes')
|
||||
export interface InitializeRoutes {
|
||||
specsStore: SpecsStore
|
||||
config: Cfg
|
||||
getSpec: () => Cypress.Spec | null
|
||||
getCurrentBrowser: () => Browser
|
||||
nodeProxy: httpProxy
|
||||
networkProxy: NetworkProxy
|
||||
getRemoteState: () => Cypress.RemoteState
|
||||
onError: (...args: unknown[]) => any
|
||||
testingType: Cypress.TestingType
|
||||
}
|
||||
|
||||
export const createRoutes = ({
|
||||
app,
|
||||
export const createCommonRoutes = ({
|
||||
config,
|
||||
specsStore,
|
||||
getRemoteState,
|
||||
networkProxy,
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
onError,
|
||||
testingType,
|
||||
getSpec,
|
||||
getRemoteState,
|
||||
nodeProxy,
|
||||
}: InitializeRoutes) => {
|
||||
// routing for the actual specs which are processed automatically
|
||||
// this could be just a regular .js file or a .coffee file
|
||||
app.get('/__cypress/tests', (req, res, next) => {
|
||||
// slice out the cache buster
|
||||
const test = CacheBuster.strip(req.query.p)
|
||||
const router = Router()
|
||||
|
||||
specController.handle(test, req, res, config, next, onError)
|
||||
router.get('/__cypress/runner/*', (req, res) => {
|
||||
runner.handle(testingType, req, res)
|
||||
})
|
||||
|
||||
app.get('/__cypress/socket.io.js', (req, res) => {
|
||||
client.handle(req, res)
|
||||
})
|
||||
|
||||
app.get('/__cypress/reporter/*', (req, res) => {
|
||||
reporter.handle(req, res)
|
||||
})
|
||||
|
||||
app.get('/__cypress/runner/*', (req, res) => {
|
||||
runner.handle(req, res)
|
||||
})
|
||||
|
||||
app.get('/__cypress/automation/getLocalStorage', (req, res) => {
|
||||
// gathers and sends localStorage and sessionStorage via postMessage to the Cypress frame
|
||||
// detect existence of local/session storage with JSON.stringify(...).length since localStorage.length may not be accurate
|
||||
res.send(`<html><body><script>(${(function () {
|
||||
const _localStorageStr = JSON.stringify(window.localStorage)
|
||||
const _localStorage = _localStorageStr.length > 2 && JSON.parse(_localStorageStr)
|
||||
const _sessionStorageStr = JSON.stringify(window.sessionStorage)
|
||||
const _sessionStorage = _sessionStorageStr.length > 2 && JSON.parse(JSON.stringify(window.sessionStorage))
|
||||
|
||||
const value = {} as any
|
||||
|
||||
if (_localStorage) {
|
||||
value.localStorage = _localStorage
|
||||
}
|
||||
|
||||
if (_sessionStorage) {
|
||||
value.sessionStorage = _sessionStorage
|
||||
}
|
||||
|
||||
window.parent.postMessage({
|
||||
value,
|
||||
type: 'localStorage',
|
||||
}, '*')
|
||||
}).toString()})()</script></body></html>`)
|
||||
})
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
app.get('/__cypress/automation/setLocalStorage', (req, res) => {
|
||||
const origin = req.originalUrl.slice(req.originalUrl.indexOf('?') + 1)
|
||||
|
||||
networkProxy.http.getRenderedHTMLOrigins()[origin] = true
|
||||
res.send(`<html><body><script>(${(function () {
|
||||
window.onmessage = function (event) {
|
||||
const msg = event.data
|
||||
|
||||
if (msg.type === 'set:storage:data') {
|
||||
const { data } = msg
|
||||
|
||||
const setData = (storageData, type) => {
|
||||
if (!storageData) return
|
||||
|
||||
const { clear, value } = storageData
|
||||
|
||||
if (clear) {
|
||||
// @ts-ignore
|
||||
window[type].clear()
|
||||
}
|
||||
|
||||
if (value) {
|
||||
Object.keys(value).forEach((key) => {
|
||||
// @ts-ignore
|
||||
window[type].setItem(key, value[key])
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
setData(data.localStorage, 'localStorage')
|
||||
setData(data.sessionStorage, 'sessionStorage')
|
||||
|
||||
window.parent.postMessage({ type: 'set:storage:complete' }, '*')
|
||||
}
|
||||
}
|
||||
|
||||
window.parent.postMessage({ type: 'set:storage:load' }, '*')
|
||||
}).toString()})()</script></body></html>`)
|
||||
})
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
app.get('/__cypress/static/*', (req, res) => {
|
||||
staticCtrl.handle(req, res)
|
||||
})
|
||||
|
||||
// routing for /files JSON endpoint
|
||||
app.get('/__cypress/files', (req, res) => {
|
||||
files.handleFiles(req, res, config)
|
||||
})
|
||||
|
||||
// routing for the dynamic iframe html
|
||||
app.get('/__cypress/iframes/*', (req, res) => {
|
||||
const extraOptions = {
|
||||
specFilter: getSpec()?.specFilter,
|
||||
specType: 'integration',
|
||||
}
|
||||
|
||||
debug('handling iframe for project spec %o', {
|
||||
spec: getSpec(),
|
||||
extraOptions,
|
||||
})
|
||||
|
||||
files.handleIframe(req, res, config, getRemoteState, extraOptions)
|
||||
})
|
||||
|
||||
app.all('/__cypress/xhrs/*', (req, res, next) => {
|
||||
router.all('/__cypress/xhrs/*', (req, res, next) => {
|
||||
xhrs.handle(req, res, config, next)
|
||||
})
|
||||
|
||||
app.get('/__cypress/source-maps/:id.map', (req, res) => {
|
||||
networkProxy.handleSourceMapRequest(req, res)
|
||||
router.get('/__cypress/static/*', (req, res) => {
|
||||
staticCtrl.handle(req, res)
|
||||
})
|
||||
|
||||
// special fallback - serve local files from the project's root folder
|
||||
app.get('/__root/*', (req, res) => {
|
||||
const file = path.join(config.projectRoot, req.params[0])
|
||||
router.get('/__cypress/iframes/*', (req, res) => {
|
||||
if (testingType === 'e2e') {
|
||||
iframesController.e2e({ config, getSpec, getRemoteState }, req, res)
|
||||
}
|
||||
|
||||
res.sendFile(file, { etag: false })
|
||||
if (testingType === 'component') {
|
||||
iframesController.component({ config, nodeProxy }, req, res)
|
||||
}
|
||||
})
|
||||
|
||||
// special fallback - serve dist'd (bundled/static) files from the project path folder
|
||||
app.get('/__cypress/bundled/*', (req, res) => {
|
||||
const file = AppData.getBundledFilePath(config.projectRoot, path.join('src', req.params[0]))
|
||||
|
||||
debug(`Serving dist'd bundle at file path: %o`, { path: file, url: req.url })
|
||||
|
||||
res.sendFile(file, { etag: false })
|
||||
})
|
||||
|
||||
la(check.unemptyString(config.clientRoute), 'missing client route in config', config)
|
||||
|
||||
app.get(`${config.clientRoute}`, (req, res) => {
|
||||
debug('Serving Cypress front-end by requested URL:', req.url)
|
||||
|
||||
runner.serve(req, res, {
|
||||
// testingType should be passed below to send `testingType` to the client
|
||||
config: { ...config, testingType },
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
getRemoteState,
|
||||
specsStore,
|
||||
})
|
||||
})
|
||||
|
||||
app.all('*', (req, res) => {
|
||||
router.all('*', (req, res) => {
|
||||
networkProxy.handleHttpRequest(req, res)
|
||||
})
|
||||
|
||||
@@ -187,19 +62,16 @@ export const createRoutes = ({
|
||||
// during routing just log them out to
|
||||
// the console and send 500 status
|
||||
// and report to raygun (in production)
|
||||
app.use((err, req, res) => {
|
||||
// TODO: Figure out if types are wrong, or if this code is wrong
|
||||
// and we just have no tests around it.
|
||||
|
||||
// @ts-ignore
|
||||
const errorHandlingMiddleware: ErrorRequestHandler = (err, req, res) => {
|
||||
console.log(err.stack) // eslint-disable-line no-console
|
||||
|
||||
// @ts-ignore
|
||||
res.set('x-cypress-error', err.message)
|
||||
// @ts-ignore
|
||||
res.set('x-cypress-stack', JSON.stringify(err.stack))
|
||||
|
||||
// @ts-ignore
|
||||
res.sendStatus(500)
|
||||
})
|
||||
}
|
||||
|
||||
router.use(errorHandlingMiddleware)
|
||||
|
||||
return router
|
||||
}
|
||||
|
||||
@@ -53,10 +53,3 @@ export const serve = (req, res, options: ServeOptions) => {
|
||||
|
||||
return res.render(runnerPath, config)
|
||||
}
|
||||
|
||||
export const serveChunk = (req, res, options) => {
|
||||
let { config } = options
|
||||
let pathToFile = getPathToDist('runner-ct', req.originalUrl.replace(config.clientRoute, ''))
|
||||
|
||||
return send(req, pathToFile).pipe(res)
|
||||
}
|
||||
|
||||
@@ -26,9 +26,11 @@ import { allowDestroy, DestroyableHttpServer } from './util/server_destroy'
|
||||
import { SocketAllowed } from './util/socket_allowed'
|
||||
import { createInitialWorkers } from '@packages/rewriter'
|
||||
import type { SpecsStore } from './specs-store'
|
||||
import type { InitializeRoutes } from './routes-ct'
|
||||
import type { Cfg } from './project-base'
|
||||
import type { Browser } from '@packages/server/lib/browsers/types'
|
||||
import { InitializeRoutes, createCommonRoutes } from './routes'
|
||||
import { createRoutesE2E } from './routes-e2e'
|
||||
import { createRoutesCT } from './routes-ct'
|
||||
|
||||
const ALLOWED_PROXY_BYPASS_URLS = [
|
||||
'/',
|
||||
@@ -100,7 +102,6 @@ export interface OpenServerOptions {
|
||||
getCurrentBrowser: () => Browser
|
||||
getSpec: () => Cypress.Cypress['spec'] | null
|
||||
shouldCorrelatePreRequests: () => boolean
|
||||
createRoutes: (args: InitializeRoutes) => any
|
||||
}
|
||||
|
||||
export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
@@ -174,7 +175,6 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
onWarning,
|
||||
shouldCorrelatePreRequests,
|
||||
specsStore,
|
||||
createRoutes,
|
||||
testingType,
|
||||
SocketCtor,
|
||||
}: OpenServerOptions) {
|
||||
@@ -210,8 +210,7 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
|
||||
this.createHosts(config.hosts)
|
||||
|
||||
createRoutes({
|
||||
app,
|
||||
const routeOptions: InitializeRoutes = {
|
||||
config,
|
||||
specsStore,
|
||||
getRemoteState,
|
||||
@@ -221,7 +220,14 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
getSpec,
|
||||
getCurrentBrowser,
|
||||
testingType,
|
||||
})
|
||||
}
|
||||
|
||||
const runnerSpecificRouter = testingType === 'e2e'
|
||||
? createRoutesE2E(routeOptions)
|
||||
: createRoutesCT(routeOptions)
|
||||
|
||||
app.use(runnerSpecificRouter)
|
||||
app.use(createCommonRoutes(routeOptions))
|
||||
|
||||
return this.createServer(app, config, onWarning)
|
||||
}
|
||||
@@ -397,7 +403,7 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
})
|
||||
}
|
||||
|
||||
_getRemoteState () {
|
||||
_getRemoteState (): Cypress.RemoteState {
|
||||
// {
|
||||
// origin: "http://localhost:2020"
|
||||
// fileServer:
|
||||
@@ -425,7 +431,7 @@ export abstract class ServerBase<TSocket extends SocketE2E | SocketCt> {
|
||||
visiting: this._remoteVisitingUrl,
|
||||
domainName: this._remoteDomainName,
|
||||
fileServer: this._remoteFileServer,
|
||||
})
|
||||
}) as Cypress.RemoteState
|
||||
|
||||
debug('Getting remote state: %o', props)
|
||||
|
||||
|
||||
@@ -1,182 +0,0 @@
|
||||
import Chai from 'chai'
|
||||
import Bluebird from 'bluebird'
|
||||
import http from 'http'
|
||||
import sinon from 'sinon'
|
||||
import { Express } from 'express'
|
||||
|
||||
import { Cfg } from '../../lib/project-base'
|
||||
import { ServerBase, WarningErr } from '../../lib/server-base'
|
||||
import { SocketE2E } from '../../lib/socket-e2e'
|
||||
import SinonChai from 'sinon-chai'
|
||||
import { SpecsStore } from '../../lib/specs-store'
|
||||
const expect = Chai.expect
|
||||
|
||||
Chai.use(SinonChai)
|
||||
|
||||
const browser = {
|
||||
name: 'chrome',
|
||||
family: 'chromium',
|
||||
displayName: 'chrome',
|
||||
path: '/usr/chrome.app',
|
||||
channel: 'canary',
|
||||
version: '90',
|
||||
majorVersion: null,
|
||||
isHeaded: true,
|
||||
isHeadless: false,
|
||||
} as const
|
||||
|
||||
class ServerTest extends ServerBase<SocketE2E> {
|
||||
createServer (
|
||||
app: Express,
|
||||
config: Cfg,
|
||||
onWarning: unknown,
|
||||
): Bluebird<[number, WarningErr?]> {
|
||||
return Bluebird.try(() => {
|
||||
return [1111]
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
describe('ServerBase', () => {
|
||||
it('smoke test', () => {
|
||||
new ServerTest()
|
||||
})
|
||||
|
||||
describe('#createExpressApp', () => {
|
||||
beforeEach(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
it('removes x-powered-by header', (done) => {
|
||||
const server = new ServerTest()
|
||||
|
||||
const app = server.createExpressApp({ morgan: true })
|
||||
|
||||
app.get('/test', (req, res) => res.end('OK'))
|
||||
|
||||
const srv = app.listen(3344, () => {
|
||||
http.request('http://localhost:3344/test,', (res) => {
|
||||
expect(res.headers['x-powered-by']).to.be.undefined
|
||||
srv.close(done)
|
||||
}).end()
|
||||
})
|
||||
})
|
||||
|
||||
it('does not use morgan when morgan: false', () => {
|
||||
const useMorgan = sinon.stub(ServerTest.prototype, 'useMorgan').returns(() => {})
|
||||
const server = new ServerTest()
|
||||
|
||||
server.createExpressApp({ morgan: false })
|
||||
|
||||
expect(useMorgan).not.to.have.been.called
|
||||
})
|
||||
|
||||
it('does use morgan when morgan: true', () => {
|
||||
const useMorgan = sinon.stub(ServerTest.prototype, 'useMorgan').returns(() => {})
|
||||
const server = new ServerTest()
|
||||
|
||||
server.createExpressApp({ morgan: true })
|
||||
|
||||
expect(useMorgan).to.have.been.called
|
||||
})
|
||||
|
||||
it('uses middleware if provided', (done) => {
|
||||
const server = new ServerTest()
|
||||
const middleware = sinon.stub()
|
||||
|
||||
server.__setMiddleware(middleware)
|
||||
server.createExpressApp({})
|
||||
|
||||
const app = server.createExpressApp({})
|
||||
|
||||
app.get('/test', (req, res) => res.end('OK'))
|
||||
|
||||
const srv = app.listen(3344, () => {
|
||||
http.request('http://localhost:3344/test,', (res) => {
|
||||
expect(middleware).to.have.been.called
|
||||
srv.close(done)
|
||||
}).end()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('#open', () => {
|
||||
beforeEach(() => {
|
||||
sinon.restore()
|
||||
})
|
||||
|
||||
const cfg = { projectRoot: '/foo/bar' }
|
||||
const noop = (...args: any[]) => ({} as any)
|
||||
const defaults = {
|
||||
getSpec: noop,
|
||||
getCurrentBrowser: () => browser,
|
||||
onError: noop,
|
||||
onWarning: noop,
|
||||
shouldCorrelatePreRequests: () => false,
|
||||
specsStore: new SpecsStore({}, 'e2e'),
|
||||
createRoutes: () => {},
|
||||
testingType: 'e2e',
|
||||
SocketCtor: SocketE2E,
|
||||
} as const
|
||||
|
||||
it('smoke test', async () => {
|
||||
const server = new ServerTest()
|
||||
|
||||
await server.open(cfg, defaults)
|
||||
})
|
||||
|
||||
it('errors when using component testing without config.baseUrl', () => {
|
||||
const server = new ServerTest()
|
||||
|
||||
try {
|
||||
server.open({ ...cfg, baseUrl: undefined }, { ...defaults, testingType: 'component' })
|
||||
} catch (e) {
|
||||
expect(e.message).to.eq('ServerCt#open called without config.baseUrl.')
|
||||
}
|
||||
})
|
||||
|
||||
it('assigns socket', async () => {
|
||||
const server = new ServerTest()
|
||||
|
||||
await server.open(cfg, defaults)
|
||||
expect(server.socket).not.to.be.undefined
|
||||
})
|
||||
|
||||
it('calls createNetworkProxy, assigns `_networkProxy`', async () => {
|
||||
const server = new ServerTest()
|
||||
|
||||
await server.open(cfg, defaults)
|
||||
expect(server.networkProxy).not.to.be.undefined
|
||||
})
|
||||
|
||||
it('calls createHosts with config.hosts', async () => {
|
||||
const hosts = ['/host']
|
||||
const createHostsStub = sinon.stub(ServerTest.prototype, 'createHosts')
|
||||
const server = new ServerTest()
|
||||
|
||||
await server.open({ ...cfg, hosts }, defaults)
|
||||
|
||||
expect(createHostsStub).to.have.been.calledWith(hosts)
|
||||
})
|
||||
|
||||
it('calls createRoutes with correct params', async () => {
|
||||
const server = new ServerTest()
|
||||
const createRoutesStub = sinon.stub()
|
||||
|
||||
await server.open(cfg, { ...defaults, createRoutes: createRoutesStub })
|
||||
expect(createRoutesStub).to.have.been.calledWithMatch({
|
||||
config: cfg,
|
||||
specsStore: defaults.specsStore,
|
||||
onError: defaults.onError,
|
||||
getSpec: defaults.getSpec,
|
||||
getCurrentBrowser: defaults.getCurrentBrowser,
|
||||
})
|
||||
|
||||
const args = createRoutesStub.getCalls()[0].args[0]
|
||||
|
||||
expect(args.networkProxy).to.eq(server.networkProxy)
|
||||
expect(args.nodeProxy).to.eq(server.nodeProxy)
|
||||
expect(args.app).not.to.be.undefined
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -115,7 +115,7 @@ index 0ef9f80..4cd787e 100644
|
||||
catch (e) {
|
||||
return false;
|
||||
diff --git a/node_modules/socket.io-parser/dist/is-binary.js b/node_modules/socket.io-parser/dist/is-binary.js
|
||||
index 4b7c234..e444014 100644
|
||||
index 4b7c234..f588141 100644
|
||||
--- a/node_modules/socket.io-parser/dist/is-binary.js
|
||||
+++ b/node_modules/socket.io-parser/dist/is-binary.js
|
||||
@@ -1,6 +1,7 @@
|
||||
@@ -126,10 +126,11 @@ index 4b7c234..e444014 100644
|
||||
const withNativeArrayBuffer = typeof ArrayBuffer === "function";
|
||||
const isView = (obj) => {
|
||||
return typeof ArrayBuffer.isView === "function"
|
||||
@@ -15,23 +16,37 @@ const withNativeFile = typeof File === "function" ||
|
||||
@@ -14,24 +15,38 @@ const withNativeBlob = typeof Blob === "function" ||
|
||||
const withNativeFile = typeof File === "function" ||
|
||||
(typeof File !== "undefined" &&
|
||||
toString.call(File) === "[object FileConstructor]");
|
||||
/**
|
||||
+/**
|
||||
+ * Returns true if obj is an ArrayBuffer.
|
||||
+ * This extra check is made because the "instanceof ArrayBuffer" check does not work
|
||||
+ * across different execution contexts.
|
||||
@@ -138,7 +139,7 @@ index 4b7c234..e444014 100644
|
||||
+function isArrayBuffer(obj) {
|
||||
+ return typeof obj === 'object' && obj !== null && toString.call(obj) === '[object ArrayBuffer]';
|
||||
+}
|
||||
+/**
|
||||
/**
|
||||
* Returns true if obj is a Buffer, an ArrayBuffer, a Blob or a File.
|
||||
*
|
||||
* @private
|
||||
@@ -153,7 +154,7 @@ index 4b7c234..e444014 100644
|
||||
}
|
||||
exports.isBinary = isBinary;
|
||||
-function hasBinary(obj, toJSON) {
|
||||
+function hasBinary(obj, known = []) {
|
||||
+function hasBinary(obj, known = [], toJSON = false) {
|
||||
if (!obj || typeof obj !== "object") {
|
||||
return false;
|
||||
}
|
||||
@@ -168,12 +169,14 @@ index 4b7c234..e444014 100644
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -43,10 +58,10 @@ function hasBinary(obj, toJSON) {
|
||||
@@ -42,11 +57,11 @@ function hasBinary(obj, toJSON) {
|
||||
}
|
||||
if (obj.toJSON &&
|
||||
typeof obj.toJSON === "function" &&
|
||||
arguments.length === 1) {
|
||||
- arguments.length === 1) {
|
||||
- return hasBinary(obj.toJSON(), true);
|
||||
+ return hasBinary(obj.toJSON(), known);
|
||||
+ arguments.length === 2) {
|
||||
+ return hasBinary(obj.toJSON(), known, true);
|
||||
}
|
||||
for (const key in obj) {
|
||||
- if (Object.prototype.hasOwnProperty.call(obj, key) && hasBinary(obj[key])) {
|
||||
|
||||
@@ -3,6 +3,7 @@ const path = require('path')
|
||||
const server = require('socket.io')
|
||||
const client = require('socket.io-client')
|
||||
const parser = require('socket.io-parser')
|
||||
const { hasBinary } = require('socket.io-parser/dist/is-binary')
|
||||
const expect = require('chai').expect
|
||||
const pkg = require('../package.json')
|
||||
const lib = require('../index')
|
||||
@@ -217,4 +218,18 @@ describe('Socket', function () {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
context('hasBinary', () => {
|
||||
it('hasBinary handles binary data in toJSON()', () => {
|
||||
const x = {
|
||||
toJSON () {
|
||||
return Buffer.from('123', 'utf8')
|
||||
},
|
||||
}
|
||||
|
||||
const data = ['a', x]
|
||||
|
||||
expect(hasBinary(data)).to.be.true
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -25,7 +25,7 @@ const isRightBranch = () => {
|
||||
process.env.APPVEYOR_REPO_COMMIT_MESSAGE || ''
|
||||
).includes('[build binary]')
|
||||
|
||||
const branchesToBuildBinary = ['develop', 'windows-code-signing']
|
||||
const branchesToBuildBinary = ['develop', 'fix-test-other-projects']
|
||||
|
||||
return branchesToBuildBinary.includes(branch) || shouldForceBinaryBuild
|
||||
}
|
||||
|
||||
174
yarn.lock
174
yarn.lock
@@ -5687,16 +5687,17 @@
|
||||
dependencies:
|
||||
"@octokit/types" "^6.0.3"
|
||||
|
||||
"@octokit/core@^3.2.3":
|
||||
version "3.2.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/core/-/core-3.2.5.tgz#57becbd5fd789b0592b915840855f3a5f233d554"
|
||||
integrity sha512-+DCtPykGnvXKWWQI0E1XD+CCeWSBhB6kwItXqfFmNBlIlhczuDPbg+P6BtLnVBaRJDAjv+1mrUJuRsFSjktopg==
|
||||
"@octokit/core@^3.5.1":
|
||||
version "3.5.1"
|
||||
resolved "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz#8601ceeb1ec0e1b1b8217b960a413ed8e947809b"
|
||||
integrity sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==
|
||||
dependencies:
|
||||
"@octokit/auth-token" "^2.4.4"
|
||||
"@octokit/graphql" "^4.5.8"
|
||||
"@octokit/request" "^5.4.12"
|
||||
"@octokit/request" "^5.6.0"
|
||||
"@octokit/request-error" "^2.0.5"
|
||||
"@octokit/types" "^6.0.3"
|
||||
before-after-hook "^2.1.0"
|
||||
before-after-hook "^2.2.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/endpoint@^3.2.0":
|
||||
@@ -5727,10 +5728,10 @@
|
||||
"@octokit/types" "^6.0.3"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/openapi-types@^5.3.0":
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-5.3.1.tgz#a49d119a1b9e47b7a9f5133ab14be2d8afaa183d"
|
||||
integrity sha512-TvVk2QuIA0lQZcIMd6xbdGaGDVeNYIOa3l1ZVagAIk5K3t/WMYbcg4BISNDhzdVhm/TgQB26frAgd/GV81aHJA==
|
||||
"@octokit/openapi-types@^10.1.4":
|
||||
version "10.1.5"
|
||||
resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-10.1.5.tgz#deafbec805896ae963d7d3846e70b18003cafda1"
|
||||
integrity sha512-OoShNYzhAU8p8JbGHe1rRs1GIErRtmN2230AQCJAjL5lc0AUU5OhppVe6693HIZ2eCBLUhoLPhnnnmQ5ASH7Wg==
|
||||
|
||||
"@octokit/plugin-enterprise-rest@^3.6.1":
|
||||
version "3.6.2"
|
||||
@@ -5744,17 +5745,17 @@
|
||||
dependencies:
|
||||
"@octokit/types" "^2.0.1"
|
||||
|
||||
"@octokit/plugin-paginate-rest@^2.6.2":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.11.0.tgz#3568c43896a3355f4a0bbb3a64f443b2abdc760d"
|
||||
integrity sha512-7L9xQank2G3r1dGqrVPo1z62V5utbykOUzlmNHPz87Pww/JpZQ9KyG5CHtUzgmB4n5iDRKYNK/86A8D98HP0yA==
|
||||
"@octokit/plugin-paginate-rest@^2.16.0":
|
||||
version "2.16.1"
|
||||
resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.16.1.tgz#699ea5c4d0274626bd7c4b896b4789c21ea3540e"
|
||||
integrity sha512-53RGhlRNhQVepZq063YCoIssZkAYjIU1kWQi9m7Qjdq/1IiuZOB9iSHdjDQmKtHWDRSqNwbtsX+tlJNhP1DHEQ==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.11.0"
|
||||
"@octokit/types" "^6.27.1"
|
||||
|
||||
"@octokit/plugin-request-log@^1.0.0", "@octokit/plugin-request-log@^1.0.2":
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.3.tgz#70a62be213e1edc04bb8897ee48c311482f9700d"
|
||||
integrity sha512-4RFU4li238jMJAzLgAwkBAw+4Loile5haQMQr+uhFq27BmyJXcXSKvoQKqh0agsZEiUlW6iSv3FAgvmGkur7OQ==
|
||||
"@octokit/plugin-request-log@^1.0.0", "@octokit/plugin-request-log@^1.0.4":
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85"
|
||||
integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@2.4.0":
|
||||
version "2.4.0"
|
||||
@@ -5764,12 +5765,12 @@
|
||||
"@octokit/types" "^2.0.1"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods@4.13.4":
|
||||
version "4.13.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.13.4.tgz#093b130d558760f6bc912c6f622ce502522410af"
|
||||
integrity sha512-MGxptzVfiP8O+aydC/riheYzS/yJ9P16M29OuvtZep/sF5sKuOCQP8Wf83YCKXRsQF+ZpYfke2snbPPSIMZKzg==
|
||||
"@octokit/plugin-rest-endpoint-methods@^5.9.0":
|
||||
version "5.10.2"
|
||||
resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.10.2.tgz#84ae65ae3f40b2d8a25bf7db7c1054a15d9383b6"
|
||||
integrity sha512-Q1QdPqA1HuKbXBuUnyNEImp948htcxgOVwUFTbUbRUsWSJPhabDe3Imd+C8vZg2czpBkl9uR8zx71WE1CP9TxA==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.12.0"
|
||||
"@octokit/types" "^6.27.1"
|
||||
deprecation "^2.3.1"
|
||||
|
||||
"@octokit/request-error@^1.0.2":
|
||||
@@ -5781,10 +5782,10 @@
|
||||
deprecation "^2.0.0"
|
||||
once "^1.4.0"
|
||||
|
||||
"@octokit/request-error@^2.0.0":
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-2.0.5.tgz#72cc91edc870281ad583a42619256b380c600143"
|
||||
integrity sha512-T/2wcCFyM7SkXzNoyVNWjyVlUwBvW3igM3Btr/eKYiPmucXTtkxt2RBsf6gn3LTzaLSLTQtNmvg+dGsOxQrjZg==
|
||||
"@octokit/request-error@^2.0.5", "@octokit/request-error@^2.1.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz#9e150357831bfc788d13a4fd4b1913d60c74d677"
|
||||
integrity sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==
|
||||
dependencies:
|
||||
"@octokit/types" "^6.0.3"
|
||||
deprecation "^2.0.0"
|
||||
@@ -5802,18 +5803,16 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^2.0.1"
|
||||
|
||||
"@octokit/request@^5.2.0", "@octokit/request@^5.3.0", "@octokit/request@^5.4.12":
|
||||
version "5.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.4.14.tgz#ec5f96f78333bb2af390afa5ff66f114b063bc96"
|
||||
integrity sha512-VkmtacOIQp9daSnBmDI92xNIeLuSRDOIuplp/CJomkvzt7M18NXgG044Cx/LFKLgjKt9T2tZR6AtJayba9GTSA==
|
||||
"@octokit/request@^5.2.0", "@octokit/request@^5.3.0", "@octokit/request@^5.6.0":
|
||||
version "5.6.1"
|
||||
resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.1.tgz#f97aff075c37ab1d427c49082fefeef0dba2d8ce"
|
||||
integrity sha512-Ls2cfs1OfXaOKzkcxnqw5MR6drMA/zWX/LIS/p8Yjdz7QKTPQLMsB3R+OvoxE6XnXeXEE2X7xe4G4l4X0gRiKQ==
|
||||
dependencies:
|
||||
"@octokit/endpoint" "^6.0.1"
|
||||
"@octokit/request-error" "^2.0.0"
|
||||
"@octokit/types" "^6.7.1"
|
||||
deprecation "^2.0.0"
|
||||
"@octokit/request-error" "^2.1.0"
|
||||
"@octokit/types" "^6.16.1"
|
||||
is-plain-object "^5.0.0"
|
||||
node-fetch "^2.6.1"
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^6.0.0"
|
||||
|
||||
"@octokit/rest@16.23.2":
|
||||
@@ -5834,6 +5833,16 @@
|
||||
universal-user-agent "^2.0.0"
|
||||
url-template "^2.0.8"
|
||||
|
||||
"@octokit/rest@18.10.0", "@octokit/rest@^18.0.0":
|
||||
version "18.10.0"
|
||||
resolved "https://registry.npmjs.org/@octokit/rest/-/rest-18.10.0.tgz#8a0add9611253e0e31d3ed5b4bc941a3795a7648"
|
||||
integrity sha512-esHR5OKy38bccL/sajHqZudZCvmv4yjovMJzyXlphaUo7xykmtOdILGJ3aAm0mFHmMLmPFmDMJXf39cAjNJsrw==
|
||||
dependencies:
|
||||
"@octokit/core" "^3.5.1"
|
||||
"@octokit/plugin-paginate-rest" "^2.16.0"
|
||||
"@octokit/plugin-request-log" "^1.0.4"
|
||||
"@octokit/plugin-rest-endpoint-methods" "^5.9.0"
|
||||
|
||||
"@octokit/rest@^16.28.4":
|
||||
version "16.43.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-16.43.2.tgz#c53426f1e1d1044dee967023e3279c50993dd91b"
|
||||
@@ -5856,16 +5865,6 @@
|
||||
once "^1.4.0"
|
||||
universal-user-agent "^4.0.0"
|
||||
|
||||
"@octokit/rest@^18.0.0":
|
||||
version "18.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.3.4.tgz#8e7ab02cd509e2fe7e71917a54254a8f8b827f20"
|
||||
integrity sha512-NES0pHbwyFB1D0jrLkdnIXgEmze/gLE0JoSNgfAe4vwD77/qaQGO/lRWNuPPsoBVBjiW6mmA9CU5cYHujJTKQA==
|
||||
dependencies:
|
||||
"@octokit/core" "^3.2.3"
|
||||
"@octokit/plugin-paginate-rest" "^2.6.2"
|
||||
"@octokit/plugin-request-log" "^1.0.2"
|
||||
"@octokit/plugin-rest-endpoint-methods" "4.13.4"
|
||||
|
||||
"@octokit/types@^2.0.0", "@octokit/types@^2.0.1":
|
||||
version "2.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-2.16.2.tgz#4c5f8da3c6fecf3da1811aef678fda03edac35d2"
|
||||
@@ -5873,12 +5872,12 @@
|
||||
dependencies:
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@octokit/types@^6.0.3", "@octokit/types@^6.11.0", "@octokit/types@^6.12.0", "@octokit/types@^6.7.1":
|
||||
version "6.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.12.0.tgz#8376fd60edfd5d1eebfeedb994c6bcb5b862c7a1"
|
||||
integrity sha512-KwOf16soD7aDEEi/PgNeJlHzjZPfrmmNy+7WezSdrpnqZ7YImBJcNnX9+5RUHt1MnA4h8oISRHTqaZDGsX9DRQ==
|
||||
"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.27.1":
|
||||
version "6.27.1"
|
||||
resolved "https://registry.npmjs.org/@octokit/types/-/types-6.27.1.tgz#88ec25f0cff5fb637c475cf420a0a2e35ba564c7"
|
||||
integrity sha512-p8VR2OTO1ozxqdAvPeCDDMNmcBzkOL6sPogy2MaEQCapbeWcWNDbwZnqMT3VTZ0DLBBAO0PyHYzU8bA99zd1Fg==
|
||||
dependencies:
|
||||
"@octokit/openapi-types" "^5.3.0"
|
||||
"@octokit/openapi-types" "^10.1.4"
|
||||
|
||||
"@opentelemetry/api@0.14.0":
|
||||
version "0.14.0"
|
||||
@@ -10461,14 +10460,6 @@ after@0.8.2:
|
||||
resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f"
|
||||
integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=
|
||||
|
||||
agent-base@2:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7"
|
||||
integrity sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=
|
||||
dependencies:
|
||||
extend "~3.0.0"
|
||||
semver "~5.0.1"
|
||||
|
||||
agent-base@4, agent-base@^4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee"
|
||||
@@ -12941,10 +12932,10 @@ before-after-hook@^1.4.0:
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-1.4.0.tgz#2b6bf23dca4f32e628fd2747c10a37c74a4b484d"
|
||||
integrity sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==
|
||||
|
||||
before-after-hook@^2.0.0, before-after-hook@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.0.tgz#09c40d92e936c64777aa385c4e9b904f8147eaf0"
|
||||
integrity sha512-jH6rKQIfroBbhEXVmI7XmXe3ix5S/PgJqpzdDPnR8JGLHWNYLsYZ6tK5iWOF/Ra3oqEX0NobXGlzbiylIzVphQ==
|
||||
before-after-hook@^2.0.0, before-after-hook@^2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz#a6e8ca41028d90ee2c24222f201c90956091613e"
|
||||
integrity sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==
|
||||
|
||||
better-opn@^2.1.1:
|
||||
version "2.1.1"
|
||||
@@ -19619,7 +19610,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2:
|
||||
assign-symbols "^1.0.0"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
extend@3, extend@^3.0.0, extend@~3.0.0, extend@~3.0.2:
|
||||
extend@^3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@@ -20463,14 +20454,6 @@ folktale@2.3.2:
|
||||
resolved "https://registry.yarnpkg.com/folktale/-/folktale-2.3.2.tgz#38231b039e5ef36989920cbf805bf6b227bf4fd4"
|
||||
integrity sha512-+8GbtQBwEqutP0v3uajDDoN64K2ehmHd0cjlghhxh0WpcfPzAIjPA03e1VvHlxL02FVGR0A6lwXsNQKn3H1RNQ==
|
||||
|
||||
follow-redirects@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919"
|
||||
integrity sha1-NLkLqyqRGqNHVx2pDyK9NuzYqRk=
|
||||
dependencies:
|
||||
debug "^2.2.0"
|
||||
stream-consume "^0.1.0"
|
||||
|
||||
follow-redirects@1.5.10:
|
||||
version "1.5.10"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a"
|
||||
@@ -21286,16 +21269,6 @@ github-slugger@^1.0.0:
|
||||
dependencies:
|
||||
emoji-regex ">=6.0.0 <=6.1.1"
|
||||
|
||||
github@11.0.0:
|
||||
version "11.0.0"
|
||||
resolved "https://registry.yarnpkg.com/github/-/github-11.0.0.tgz#edb32df5efb33cad004ebf0bdd2a4b30bb63a854"
|
||||
integrity sha1-7bMt9e+zPK0ATr8L3SpLMLtjqFQ=
|
||||
dependencies:
|
||||
follow-redirects "0.0.7"
|
||||
https-proxy-agent "^1.0.0"
|
||||
mime "^1.2.11"
|
||||
netrc "^0.1.4"
|
||||
|
||||
glob-base@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
|
||||
@@ -22876,15 +22849,6 @@ https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0:
|
||||
agent-base "6"
|
||||
debug "4"
|
||||
|
||||
https-proxy-agent@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6"
|
||||
integrity sha1-NffabEjOTdv6JkiRrFk+5f+GceY=
|
||||
dependencies:
|
||||
agent-base "2"
|
||||
debug "2"
|
||||
extend "3"
|
||||
|
||||
https-proxy-agent@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b"
|
||||
@@ -27358,14 +27322,13 @@ make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0:
|
||||
dependencies:
|
||||
semver "^6.0.0"
|
||||
|
||||
make-empty-github-commit@1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/make-empty-github-commit/-/make-empty-github-commit-1.2.0.tgz#5cf1402b12d509933fb2b66355a1434c8dbeec17"
|
||||
integrity sha512-Rkme2QetJ4+C0eV32wHGW8myhYM12NL0ComCWIJhhr9fgxcHyCBpaC5Ljb2cdsi44ck20IugyUmlzBqoONtrDg==
|
||||
make-empty-github-commit@cypress-io/make-empty-github-commit#4a592aedb776ba2f4cc88979055315a53eec42ee:
|
||||
version "0.0.0-development"
|
||||
resolved "https://codeload.github.com/cypress-io/make-empty-github-commit/tar.gz/4a592aedb776ba2f4cc88979055315a53eec42ee"
|
||||
dependencies:
|
||||
"@octokit/rest" "18.10.0"
|
||||
debug "3.1.0"
|
||||
github "11.0.0"
|
||||
minimist "1.2.0"
|
||||
minimist "1.2.5"
|
||||
parse-github-repo-url "1.4.1"
|
||||
|
||||
make-error@^1, make-error@^1.1.1:
|
||||
@@ -27928,7 +27891,7 @@ mime-types@^2.1.12, mime-types@^2.1.18, mime-types@^2.1.21, mime-types@^2.1.27,
|
||||
dependencies:
|
||||
mime-db "1.49.0"
|
||||
|
||||
mime@1.6.0, mime@^1.2.11, mime@^1.3.4, mime@^1.4.1, mime@^1.6.0:
|
||||
mime@1.6.0, mime@^1.3.4, mime@^1.4.1, mime@^1.6.0:
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
|
||||
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
|
||||
@@ -28975,11 +28938,6 @@ nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0:
|
||||
resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61"
|
||||
integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==
|
||||
|
||||
netrc@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444"
|
||||
integrity sha1-a+lPysqNd63gqWcNxGCRTJRHJEQ=
|
||||
|
||||
next-tick@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
|
||||
@@ -36185,11 +36143,6 @@ semver@~2.3.1:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-2.3.2.tgz#b9848f25d6cf36333073ec9ef8856d42f1233e52"
|
||||
integrity sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI=
|
||||
|
||||
semver@~5.0.1:
|
||||
version "5.0.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a"
|
||||
integrity sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=
|
||||
|
||||
send@0.17.1:
|
||||
version "0.17.1"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
|
||||
@@ -37642,11 +37595,6 @@ stream-combiner@~0.0.4:
|
||||
dependencies:
|
||||
duplexer "~0.1.1"
|
||||
|
||||
stream-consume@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.1.tgz#d3bdb598c2bd0ae82b8cac7ac50b1107a7996c48"
|
||||
integrity sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==
|
||||
|
||||
stream-each@^1.1.0:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae"
|
||||
|
||||
Reference in New Issue
Block a user