diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 26cbc3f07f9c..b35b84c42a67 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -3112,7 +3112,11 @@ declare namespace Cypress { * @default null */ experimentalSkipDomainInjection: string[] | null - // TODO: document + /** + * Enables setting document.domain to the superdomain on code injection. This option is + * disabled by default. Enabling this option allows for navigating between subdomains in + * the same test without the use of cy.origin(). + */ injectDocumentDomain: boolean /** * Enables AST-based JS/HTML rewriting. This may fix issues caused by the existing regex-based JS/HTML replacement algorithm. diff --git a/npm/vite-dev-server/src/plugins/cypress.ts b/npm/vite-dev-server/src/plugins/cypress.ts index 92d770b64c07..7d85fdd07b97 100644 --- a/npm/vite-dev-server/src/plugins/cypress.ts +++ b/npm/vite-dev-server/src/plugins/cypress.ts @@ -99,7 +99,7 @@ export const Cypress = ( }, configureServer: async (server: ViteDevServer) => { server.middlewares.use(`${base}index.html`, async (req, res) => { - let transformedIndexHtml = await server.transformIndexHtml(base, '') + const transformedIndexHtml = await server.transformIndexHtml(base, '') return res.end(transformedIndexHtml) }) diff --git a/packages/config/test/index.spec.ts b/packages/config/test/index.spec.ts index d5c29784b578..60ee518fd2fd 100644 --- a/packages/config/test/index.spec.ts +++ b/packages/config/test/index.spec.ts @@ -247,15 +247,12 @@ describe('config/src/index', () => { describe('.validateNeedToRestartOnChange', () => { it('returns the need to restart if given key has changed', () => { - let result = configUtil.validateNeedToRestartOnChange({ blockHosts: [] }, { blockHosts: ['https://example.com'] }) - - expect(result).to.eql({ + expect(configUtil.validateNeedToRestartOnChange({ blockHosts: [] }, { blockHosts: ['https://example.com'] })).to.eql({ server: true, browser: false, }) - result = configUtil.validateNeedToRestartOnChange({ injectDocumentDomain: true }, {}) - expect(result).to.eql({ + expect(configUtil.validateNeedToRestartOnChange({ injectDocumentDomain: true }, {})).to.eql({ server: true, browser: false, }) diff --git a/packages/driver/cypress.config.ts b/packages/driver/cypress.config.ts index 2d79495144a1..12f6a552ed72 100644 --- a/packages/driver/cypress.config.ts +++ b/packages/driver/cypress.config.ts @@ -19,7 +19,6 @@ export default defineConfig({ configFile: '../../mocha-reporter-config.json', }, e2e: { - excludeSpecPattern: 'cypress/**/with-inject-document-domain/**/*.cy.{js,ts}', experimentalOriginDependencies: true, experimentalModifyObstructiveThirdPartyCode: true, setupNodeEvents: (on, config) => { diff --git a/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts b/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts index fcdfdaff16f6..ac42d31e690c 100644 --- a/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/cookie_behavior.cy.ts @@ -1286,7 +1286,7 @@ describe('Cookie Behavior', { browser: '!webkit' }, () => { describe('misc', () => { describe('domains', () => { // NOTE: tested in ./with-inject-document-domain/cookie_behavior - it.skip('attaches subdomain and TLD cookies when making subdomain requests', () => { + it('attaches subdomain and TLD cookies when making subdomain requests', () => { cy.intercept(`${scheme}://app.foobar.com:${crossOriginPort}/test-request`, (req) => { expect(req['headers']['cookie']).to.equal('foo=bar; bar=baz') diff --git a/packages/driver/cypress/e2e/e2e/privileged_commands.cy.ts b/packages/driver/cypress/e2e/e2e/privileged_commands.cy.ts index f134d463309d..6dc09d2bcceb 100644 --- a/packages/driver/cypress/e2e/e2e/privileged_commands.cy.ts +++ b/packages/driver/cypress/e2e/e2e/privileged_commands.cy.ts @@ -221,8 +221,8 @@ describe('privileged commands', () => { } strategies.forEach((strategy) => { - describe(`strategy: ${strategy}`, () => { - commands.forEach((command) => { + commands.forEach((command) => { + describe(`strategy: ${strategy}`, () => { describe(`command: ${command}`, () => { it('fails in html script', (done) => { cy.on('fail', (err) => { diff --git a/packages/driver/src/cy/commands/sessions/index.ts b/packages/driver/src/cy/commands/sessions/index.ts index 5360d4a02472..8c116c8870ed 100644 --- a/packages/driver/src/cy/commands/sessions/index.ts +++ b/packages/driver/src/cy/commands/sessions/index.ts @@ -254,7 +254,6 @@ export default function (Commands, Cypress, cy) { const userInvocationStack = $errUtils.getUserInvocationStack(err, Cypress.state) - //console.log('enhancingStack from session', { err, userInvocationStack }) err = $errUtils.enhanceStack({ err, userInvocationStack, diff --git a/packages/driver/src/cypress/cy.ts b/packages/driver/src/cypress/cy.ts index d862986b4e71..8f82d49b298f 100644 --- a/packages/driver/src/cypress/cy.ts +++ b/packages/driver/src/cypress/cy.ts @@ -390,7 +390,6 @@ export class $Cy extends EventEmitter2 implements ITimeouts, IStability, IAssert const userInvocationStack = $errUtils.getUserInvocationStack(err, this.state) - //console.log('enhancing stack', { errStack: err.stack, userInvocationStack }) err = $errUtils.enhanceStack({ err, userInvocationStack, diff --git a/packages/driver/src/cypress/error_utils.ts b/packages/driver/src/cypress/error_utils.ts index d9265a6f5411..4512f0565772 100644 --- a/packages/driver/src/cypress/error_utils.ts +++ b/packages/driver/src/cypress/error_utils.ts @@ -431,17 +431,12 @@ const createUncaughtException = ({ frameType, handlerType, state, err }) => { // but the stack points to cypress internals. here we replace the internal // cypress stack with the invocation stack, which points to the user's code const stackAndCodeFrameIndex = (err, userInvocationStack): StackAndCodeFrameIndex => { - //console.log('stackAndCodeFrameIndex', { isCypressErr: isCypressErr(err), isChai: isChaiValidationErr(err) }) if (!userInvocationStack) return { stack: err.stack } if (isCypressErr(err) || isChaiValidationErr(err)) { - //console.log('splicing userInvocationStack') - return $stackUtils.stackWithUserInvocationStackSpliced(err, userInvocationStack) } - //console.log('returning new stack from userInvocationStack') - return { stack: $stackUtils.replacedStack(err, userInvocationStack) || '' } } diff --git a/packages/driver/src/cypress/stack_utils.ts b/packages/driver/src/cypress/stack_utils.ts index 2164f0e79e83..c28049d262bc 100644 --- a/packages/driver/src/cypress/stack_utils.ts +++ b/packages/driver/src/cypress/stack_utils.ts @@ -31,10 +31,11 @@ const hasCrossFrameStacks = (specWindow) => { return topStack === specStack } -const stackWithContentAppended = (err, stack: string = '') => { +const stackWithContentAppended = (err, stack: string | undefined) => { + const usableStack = stack ?? '' const appendToStack = err.appendToStack - if (!appendToStack || !appendToStack.content) return stack + if (!appendToStack || !appendToStack.content) return usableStack delete err.appendToStack @@ -43,7 +44,7 @@ const stackWithContentAppended = (err, stack: string = '') => { const normalizedContent = normalizeStackIndentation(appendToStack.content) const content = $utils.indent(normalizedContent, 2) - return `${stack}\n\n${appendToStack.title}:\n${content}` + return `${usableStack}\n\n${appendToStack.title}:\n${content}` } const stackWithLinesRemoved = (stack, cb) => { diff --git a/packages/network/lib/document-domain-injection.ts b/packages/network/lib/document-domain-injection.ts index 18b11484088f..c141b1c7a0a5 100644 --- a/packages/network/lib/document-domain-injection.ts +++ b/packages/network/lib/document-domain-injection.ts @@ -17,6 +17,30 @@ import type { ParsedHostWithProtocolAndHost } from './types' const debug = Debug('cypress:network:document-domain-injection') +export abstract class DocumentDomainInjection { + public static InjectionBehavior (config: { injectDocumentDomain?: boolean, testingType?: 'e2e' | 'component'}): DocumentDomainInjection { + debug('Determining injection behavior for config values: %o', { + injectDocumentDomain: config.injectDocumentDomain, + testingType: config.testingType, + }) + + if (config.injectDocumentDomain && config.testingType !== 'component') { + debug('Returning document domain injection behavior') + + return new DocumentDomainBehavior() + } + + debug('Returning origin behavior - no document domain injection') + + return new OriginBehavior() + } + + public abstract getOrigin (url: string): string + public abstract getHostname (url: string): string + public abstract urlsMatch (frameUrl: string | ParsedHostWithProtocolAndHost, topUrl: string | ParsedHostWithProtocolAndHost): boolean + public abstract shouldInjectDocumentDomain (url: string | undefined): boolean +} + export class DocumentDomainBehavior implements DocumentDomainInjection { public getOrigin (url: string) { return getSuperDomainOrigin(url) @@ -59,29 +83,3 @@ export class OriginBehavior implements DocumentDomainInjection { return false } } - -export abstract class DocumentDomainInjection { - public static InjectionBehavior (config: { injectDocumentDomain?: boolean, testingType?: 'e2e' | 'component'}): DocumentDomainInjection { - debug('Determining injection behavior for config values: %o', { - injectDocumentDomain: config.injectDocumentDomain, - testingType: config.testingType, - }) - - debug('called from', new Error().stack) - - if (config.injectDocumentDomain && config.testingType !== 'component') { - debug('Returning document domain injection behavior') - - return new DocumentDomainBehavior() - } - - debug('Returning origin behavior - no document domain injection') - - return new OriginBehavior() - } - - public abstract getOrigin (url: string): string - public abstract getHostname (url: string): string - public abstract urlsMatch (frameUrl: string | ParsedHostWithProtocolAndHost, topUrl: string | ParsedHostWithProtocolAndHost): boolean - public abstract shouldInjectDocumentDomain (url: string | undefined): boolean -} diff --git a/packages/proxy/lib/http/util/rewriter.ts b/packages/proxy/lib/http/util/rewriter.ts index 69993ab01ffc..de4d286a771f 100644 --- a/packages/proxy/lib/http/util/rewriter.ts +++ b/packages/proxy/lib/http/util/rewriter.ts @@ -3,9 +3,6 @@ import * as astRewriter from './ast-rewriter' import * as regexRewriter from './regex-rewriter' import type { CypressWantsInjection } from '../../types' import type { SerializableAutomationCookie } from '@packages/server/lib/util/cookies' -import Debug from 'debug' - -const debug = Debug('cypress:proxy:http:rewriter') export type SecurityOpts = { isNotJavascript?: boolean @@ -35,7 +32,6 @@ function getRewriter (useAstSourceRewriting: boolean) { } function getHtmlToInject (opts: InjectionOpts & SecurityOpts) { - debug('getting html to inject from opts %O', opts) const { cspNonce, domainName, diff --git a/packages/proxy/test/unit/http/response-middleware.spec.ts b/packages/proxy/test/unit/http/response-middleware.spec.ts index c4776d325d7d..5f749f4eb231 100644 --- a/packages/proxy/test/unit/http/response-middleware.spec.ts +++ b/packages/proxy/test/unit/http/response-middleware.spec.ts @@ -2127,7 +2127,7 @@ describe('http/response-middleware', function () { htmlStub.restore() }) - ;[true].forEach((injectDocumentDomain) => { + ;[true, false].forEach((injectDocumentDomain) => { describe(`when injectDocumentDomain is ${injectDocumentDomain}`, () => { const config = { modifyObstructiveCode: true, diff --git a/packages/server/lib/privileged-commands/privileged-channel.js b/packages/server/lib/privileged-commands/privileged-channel.js index a5bac3d05c11..da9771ceebb8 100644 --- a/packages/server/lib/privileged-commands/privileged-channel.js +++ b/packages/server/lib/privileged-commands/privileged-channel.js @@ -68,8 +68,6 @@ ) }) - //console.log('hasSpecFrameStackLines? ', err.stack, stackLines, filteredLines, filteredLines.length) - return filteredLines.length > 0 } @@ -82,8 +80,6 @@ return isInCallback(err) && hasValidCallbackContext } - //console.log('hasCallbackInsideEval', isInCallback(err), stringIncludes.call(err.stack, '> eval line')) - return isInCallback(err) && stringIncludes.call(err.stack, '> eval line') } @@ -99,8 +95,6 @@ return stringIncludes.call(err.stack, script) }) - //console.log('hasStackLinesFromSpecOrSupportFile?', scripts, filteredLines) - return filteredLines.length > 0 } @@ -129,10 +123,7 @@ return hasSpecBridgeInvocation(err) } - //console.log('should check special case?', { browserFamily, documentDomainContext }, browserFamily && documentDomainContext) if (browserFamily === 'chromium' && documentDomainContext) { - //console.log('checking special case', browserFamily, documentDomainContext, browserFamily && documentDomainContext) - return hasStackLinesFromSpecOrSupportFile(err) || hasSpecFrameStackLines(err) } diff --git a/packages/server/lib/remote_states.ts b/packages/server/lib/remote_states.ts index ceec9e3e3fd8..79304916ee85 100644 --- a/packages/server/lib/remote_states.ts +++ b/packages/server/lib/remote_states.ts @@ -62,8 +62,6 @@ interface RemoteStatesServerPorts { * } */ export class RemoteStates { - // Cypress.RemoteState was coming from the namespace declared in @packages/net-stubbing, somehow - // now it's defined (for a second time) in `./remote_states_abs.ts private remoteStates: Map = new Map() private primaryOriginKey: string = '' private currentOriginKey: string = '' diff --git a/packages/server/lib/server-base.ts b/packages/server/lib/server-base.ts index deb11fe2443a..adb78406d702 100644 --- a/packages/server/lib/server-base.ts +++ b/packages/server/lib/server-base.ts @@ -15,7 +15,6 @@ import la from 'lazy-ass' import httpsProxy from '@packages/https-proxy' import { getRoutesForRequest, netStubbingState, NetStubbingState } from '@packages/net-stubbing' import { agent, clientCertificates, cors, httpUtils, uri, concatStream, DocumentDomainInjection } from '@packages/network' -import type { Policy } from '@packages/network/lib/cors' import { NetworkProxy, BrowserPreRequest } from '@packages/proxy' import type { SocketCt } from './socket-ct' import * as errors from './errors' @@ -159,10 +158,8 @@ export class ServerBase { protected _eventBus: EventEmitter protected _remoteStates: RemoteStates private getCurrentBrowser: undefined | (() => Browser) - private _originPolicy: Policy = 'same-origin' private _urlResolver: Bluebird> | null = null private testingType?: TestingType - private _config: Cfg private _documentDomainInjection: DocumentDomainInjection constructor (config: Cfg) { @@ -176,8 +173,6 @@ export class ServerBase { this._fileServer = null this._documentDomainInjection = DocumentDomainInjection.InjectionBehavior(config) - // TODO: maybe dont need to keep this around anymore - this._config = config const remoteStatePorts = () => { return { @@ -248,13 +243,10 @@ export class ServerBase { onWarning: unknown, ): Bluebird<[number, WarningErr?]> { return new Bluebird((resolve, reject) => { - const { port, fileServerFolder, socketIoRoute, baseUrl, injectDocumentDomain } = config + const { port, fileServerFolder, socketIoRoute, baseUrl } = config this._server = this._createHttpServer(app) - debug('inject document domain?', injectDocumentDomain) - this._originPolicy = injectDocumentDomain ? 'same-super-domain-origin' : 'same-origin' - const onError = (err) => { // if the server bombs before starting // and the err no is EADDRINUSE