Files
cypress/packages/server/lib/routes.ts
T
Bill Glesias ca01e29ab8 fix: re include document domain injections for spec-bridge and injection and disable origin-agent-cluster (#25013)
* Revert "chore: remove document.domain usage for cross-origin testing (#24945)"

This reverts commit a3d3074e70.

* fix: set origin-agent-cluster=?0 for the spec bridge iframe

* re apply comment that was reverted in 1fa1246b5c

* Update packages/server/lib/routes-e2e.ts

Co-authored-by: Matt Schile <mschile@cypress.io>

* chore: update document.domain immutable target from chrome 106 -> chrome 109

Co-authored-by: Matt Schile <mschile@cypress.io>
2022-12-06 17:52:48 -05:00

126 lines
3.8 KiB
TypeScript

import httpProxy from 'http-proxy'
import Debug from 'debug'
import { ErrorRequestHandler, Request, Router } from 'express'
import send from 'send'
import { getPathToDist } from '@packages/resolve-dist'
import type { NetworkProxy } from '@packages/proxy'
import type { Cfg } from './project-base'
import xhrs from './controllers/xhrs'
import { runner } from './controllers/runner'
import { iframesController } from './controllers/iframes'
import type { FoundSpec } from '@packages/types'
import { getCtx } from '@packages/data-context'
import { graphQLHTTP } from '@packages/graphql/src/makeGraphQLServer'
import type { RemoteStates } from './remote_states'
const debug = Debug('cypress:server:routes')
export interface InitializeRoutes {
config: Cfg
getSpec: () => FoundSpec | null
nodeProxy: httpProxy
networkProxy: NetworkProxy
remoteStates: RemoteStates
onError: (...args: unknown[]) => any
testingType: Cypress.TestingType
}
export const createCommonRoutes = ({
config,
networkProxy,
testingType,
getSpec,
remoteStates,
nodeProxy,
}: InitializeRoutes) => {
const router = Router()
const { clientRoute, namespace } = config
if (process.env.CYPRESS_INTERNAL_VITE_DEV) {
const proxy = httpProxy.createProxyServer({
target: `http://localhost:${process.env.CYPRESS_INTERNAL_VITE_APP_PORT}/`,
})
router.get('/__cypress/assets/*', (req, res) => {
proxy.web(req, res, {}, (e) => {})
})
} else {
router.get('/__cypress/assets/*', (req, res) => {
const pathToFile = getPathToDist('app', req.params[0])
return send(req, pathToFile).pipe(res)
})
}
router.use(`/${namespace}/graphql/*`, graphQLHTTP)
router.get(`/${namespace}/runner/*`, (req, res) => {
runner.handle(req, res)
})
router.all(`/${namespace}/xhrs/*`, (req, res, next) => {
xhrs.handle(req, res, config, next)
})
router.get(`/${namespace}/iframes/*`, (req, res) => {
if (testingType === 'e2e') {
iframesController.e2e({ config, getSpec, remoteStates }, req, res)
}
if (testingType === 'component') {
iframesController.component({ config, nodeProxy }, req, res)
}
})
if (!clientRoute) {
throw Error(`clientRoute is required. Received ${clientRoute}`)
}
router.get(clientRoute, (req: Request & { proxiedUrl?: string }, res) => {
const nonProxied = req.proxiedUrl?.startsWith('/') ?? false
// Chrome plans to make document.domain immutable in Chrome 109, with the default value
// of the Origin-Agent-Cluster header becoming 'true'. We explicitly disable this header
// so that we can continue to support tests that visit multiple subdomains in a single spec.
// https://github.com/cypress-io/cypress/issues/20147
res.setHeader('Origin-Agent-Cluster', '?0')
getCtx().html.appHtml(nonProxied)
.then((html) => res.send(html))
.catch((e) => res.status(500).send({ stack: e.stack }))
})
// serve static assets from the dist'd Vite app
router.get([
`${clientRoute}assets/*`,
`${clientRoute}shiki/*`,
], (req, res) => {
debug('proxying static assets %s, params[0] %s', req.url, req.params[0])
const pathToFile = getPathToDist('app', 'assets', req.params[0])
return send(req, pathToFile).pipe(res)
})
router.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)
}
router.use(errorHandlingMiddleware)
return router
}