Skip to content

Commit

Permalink
Merge branch 'feature-multidomain' into issue-20041-multi-domain-view…
Browse files Browse the repository at this point in the history
…port
  • Loading branch information
mschile committed Feb 22, 2022
2 parents 3230304 + 5b4feaa commit 07d8255
Show file tree
Hide file tree
Showing 9 changed files with 345 additions and 14 deletions.
Expand Up @@ -27,14 +27,4 @@ context.skip('multi-domain network requests', { experimentalSessionSupport: true
cy.get('#result').should('contain', 'Added')
})
})

it('.server() and .route()', () => {
cy.switchToDomain('foobar.com', () => {
cy.server()
cy.route('POST', /post-only/, 'Added')

cy.get('#request').click()
cy.get('#result').should('contain', 'Added')
})
})
})
@@ -0,0 +1,29 @@
// @ts-ignore / session support is needed for visiting about:blank between tests
context('multi-domain unsupported commands', { experimentalSessionSupport: true, experimentalMultiDomain: true }, () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
cy.get('a[data-cy="multi-domain-secondary-link"]').click()
})

it('throws an error that the `cy.route()` method is deprecated and unsupported when attempted use is in multi-domain', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.equal('`cy.route()` has been deprecated and use is not supported in `cy.switchToDomain()`. Consider using `cy.intercept()` instead.')
done()
})

cy.switchToDomain('foobar.com', () => {
cy.route('api')
})
})

it('throws an error that the `cy.server()` method is deprecated and unsupported when attempted use is in multi-domain', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.equal('`cy.server()` has been deprecated and use is not supported in `cy.switchToDomain()`. Consider using `cy.intercept()` instead.')
done()
})

cy.switchToDomain('foobar.com', () => {
cy.server()
})
})
})
@@ -0,0 +1,247 @@
// @ts-ignore / session support is needed for visiting about:blank between tests+
describe('multi-domain Cypress API', { experimentalSessionSupport: true, experimentalMultiDomain: true }, () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
cy.get('a[data-cy="multi-domain-secondary-link"]').click()
})

// FIXME: Commands adding/overwriting should be condensed into one test with two switchToDomain tests
// once multiple switchToDomain calls are supported
context('Commands', () => {
context('add', () => {
it('adds a custom command', () => {
cy.switchToDomain('foobar.com', () => {
// @ts-ignore
Cypress.Commands.add('foo', () => 'bar')

// @ts-ignore
cy.foo().should('equal', 'bar')
})
})

it('persists defined commands through spec bridge', () => {
cy.switchToDomain('foobar.com', () => {
// @ts-ignore
cy.foo().should('equal', 'bar')
})
})
})

context('overwrite', () => {
it('overwrites an existing command in the spec bridge', () => {
cy.switchToDomain('foobar.com', () => {
// @ts-ignore
Cypress.Commands.overwrite('foo', () => 'baz')

// @ts-ignore
cy.foo().should('equal', 'baz')
})
})

it('persists overwritten command through spec bridge', () => {
cy.switchToDomain('foobar.com', () => {
// @ts-ignore
cy.foo().should('equal', 'baz')
})
})
})
})

context('Keyboard', () => {
it('does NOT sync defaults', () => {
const defaults = Cypress.Keyboard.defaults({
keystrokeDelay: 30,
})

cy.switchToDomain('foobar.com', [defaults], ([primaryKeyboardDefaults]) => {
const multiDomainKeyboardDefaults = Cypress.Keyboard.defaults({})

expect(multiDomainKeyboardDefaults).to.not.deep.equal(primaryKeyboardDefaults)
})
})

// FIXME: Commands adding/overwriting should be condensed into one test with two switchToDomain tests
// once multiple switchToDomain calls are supported
it('allows a user to configure defaults', () => {
cy.switchToDomain('foobar.com', () => {
const multiDomainKeyboardDefaults = Cypress.Keyboard.defaults({
keystrokeDelay: 60,
})

expect(multiDomainKeyboardDefaults).to.deep.include({
keystrokeDelay: 60,
})
})
})

it('persists default configuration changes through spec bridge', () => {
cy.switchToDomain('foobar.com', () => {
const multiDomainKeyboardDefaults = Cypress.Keyboard.defaults({})

expect(multiDomainKeyboardDefaults).to.deep.include({
keystrokeDelay: 60,
})
})
})
})

context('Screenshot', () => {
it('does NOT sync defaults', () => {
Cypress.Screenshot.defaults({
blackout: ['foo'],
overwrite: true,
onBeforeScreenshot: () => undefined,
onAfterScreenshot: () => undefined,
})

cy.switchToDomain('foobar.com', () => {
const multiDomainScreenshotDefaults = Cypress.Screenshot.defaults({})

expect(multiDomainScreenshotDefaults).to.not.deep.include({
blackout: ['foo'],
overwrite: true,
onBeforeScreenshot: () => undefined,
onAfterScreenshot: () => undefined,
})
})
})

// FIXME: Commands adding/overwriting should be condensed into one test with two switchToDomain tests
// once multiple switchToDomain calls are supported
it('allows a user to configure defaults', () => {
cy.switchToDomain('foobar.com', () => {
const multiDomainScreenshotDefaults = Cypress.Screenshot.defaults({
blackout: ['foo'],
overwrite: true,
})

expect(multiDomainScreenshotDefaults).to.deep.include({
blackout: ['foo'],
overwrite: true,
})
})
})

it('persists default configuration changes through spec bridge', () => {
cy.switchToDomain('foobar.com', () => {
const multiDomainScreenshotDefaults = Cypress.Screenshot.defaults({})

expect(multiDomainScreenshotDefaults).to.deep.include({
blackout: ['foo'],
overwrite: true,
})
})
})
})

context('dom', () => {
it('provides a sanity check that the dom API exists on Cypress.*', () => {
cy.switchToDomain('foobar.com', () => {
cy.get('[data-cy="dom-check"]').then(($el) => {
expect(Cypress.dom.isAttached($el)).to.be.true
})
})
})
})

// TODO: Before implementing, understand how Cypress.session.* and cy.session() are supposed to function within the context of multi-domain
context.skip('session', () => {
it('clearAllSavedSessions() functions as expected', () => {
cy.switchToDomain('foobar.com', () => {
Cypress.session.clearAllSavedSessions()
})
})
})

context('properties', () => {
it('has arch property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.arch], ([theArch]) => {
expect(Cypress.arch).to.equal(theArch)
})
})

it('has browser property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.browser], ([theBrowser]) => {
expect(Cypress.browser).to.deep.equal(theBrowser)
})
})

it('has currentTest property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.currentTest], ([theCurrentTest]) => {
expect(Cypress.currentTest).to.deep.equal(theCurrentTest)
})
})

it('has platform property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.platform], ([thePlatform]) => {
expect(Cypress.platform).to.equal(thePlatform)
})
})

it('has testingType property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.testingType], ([theTestingType]) => {
expect(Cypress.testingType).to.deep.equal(theTestingType)
})
})

it('has spec property synced from primary', () => {
cy.switchToDomain('foobar.com', [Cypress.spec], ([theSpec]) => {
expect(Cypress.spec).to.deep.equal(theSpec)
})
})
})

context('methods', () => {
it('isCy()', () => {
cy.switchToDomain('foobar.com', () => {
expect(Cypress.isCy(cy)).to.be.true
})
})

it('isBrowser()', () => {
cy.switchToDomain('foobar.com', [Cypress.browser], ([theBrowser]) => {
expect(Cypress.isBrowser(theBrowser.name)).to.equal(true)
})
})

it('log()', (done) => {
cy.on('log:changed', (changedLog) => {
if (changedLog?.message === 'test log' && changedLog.ended) {
// just make sure Big Cypress logs make their way back to the primary
done()
}
})

cy.switchToDomain('foobar.com', () => {
Cypress.log({
message: 'test log',
})
})
})
})

context('not supported', () => {
it('throws an error when a user attempts to configure Cypress.Server.defaults() inside of multi-domain', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.equal('`Cypress.Server.*` has been deprecated and use is not supported in `cy.switchToDomain()`. Consider using `cy.intercept()` instead.')
done()
})

cy.switchToDomain('foobar.com', () => {
Cypress.Server.defaults({})
})
})

it('throws an error when a user attempts to configure Cypress.Cookies.preserveOnce() inside of multi-domain', (done) => {
cy.on('fail', (err) => {
expect(err.message).to.equal('`Cypress.Cookies.preserveOnce` use is not supported in `cy.switchToDomain()`. Consider using `cy.session()` instead.')
done()
})

cy.switchToDomain('foobar.com', () => {
// @ts-ignore
Cypress.Cookies.preserveOnce({})
})
})
})
})
Expand Up @@ -29,14 +29,22 @@ describe('multi-domain', { experimentalSessionSupport: true, experimentalMultiDo
_currentRetry: runnable._currentRetry,
type: 'test',
title: 'passes runnable state to the secondary domain',
titlePath: [
'multi-domain',
'passes runnable state to the secondary domain',
],
parent: {
id: runnable.parent.id,
type: 'suite',
title: 'multi-domain',
titlePath: [
'multi-domain',
],
parent: {
id: runnable.parent.parent.id,
type: 'suite',
title: '',
titlePath: undefined,
ctx: {},
},
ctx: {},
Expand All @@ -53,6 +61,9 @@ describe('multi-domain', { experimentalSessionSupport: true, experimentalMultiDo
expectedRunnable.resetTimeout = actualRunnable.resetTimeout
expectedRunnable.timeout = actualRunnable.timeout

expect(actualRunnable.titlePath()).to.deep.equal(expectedRunnable.titlePath)
expectedRunnable.titlePath = actualRunnable.titlePath

expect(actualRunnable).to.deep.equal(expectedRunnable)
})
})
Expand Down
5 changes: 4 additions & 1 deletion packages/driver/src/cy/multi-domain/util.ts
Expand Up @@ -21,13 +21,16 @@ export const correctStackForCrossDomainError = (serializedError: any, userInvoca
export const serializeRunnable = (runnable) => {
if (!runnable) return undefined

const fields = _.pick(runnable, ['id', '_currentRetry', 'type', 'title', 'parent', 'ctx'])
const fields = _.pick(runnable, ['id', '_currentRetry', 'type', 'title', 'parent', 'ctx', 'titlePath'])

fields.ctx = _.pick(runnable.ctx, ['currentTest.id', 'currentTest._currentRetry', 'currentTest.type', 'currentTest.title'])

// recursively call serializeRunnable for the parent field
if (fields.parent) {
fields.titlePath = fields.titlePath()
fields.parent = serializeRunnable(fields.parent)
} else {
fields.titlePath = undefined
}

return fields
Expand Down
27 changes: 27 additions & 0 deletions packages/driver/src/cypress/error_messages.ts
Expand Up @@ -1736,6 +1736,33 @@ export default {
message: stripIndent`\
${cmd('switchToDomain')} could not serialize the subject due to symbols not being supported by the structured clone algorithm.`,
},
// TODO: These deprecation warnings and forbidden use errors need to be audited before releasing multi-domain
route: {
unsupported: {
message: `${cmd('route')} has been deprecated and use is not supported in ${cmd('switchToDomain')}. Consider using ${cmd('intercept')} instead.`,
docsUrl: 'https://on.cypress.io/intercept',
},
},
server: {
unsupported: {
message: `${cmd('server')} has been deprecated and use is not supported in ${cmd('switchToDomain')}. Consider using ${cmd('intercept')} instead.`,
docsUrl: 'https://on.cypress.io/intercept',
},
},
Server: {
unsupported: {
message: `\`Cypress.Server.*\` has been deprecated and use is not supported in ${cmd('switchToDomain')}. Consider using ${cmd('intercept')} instead.`,
docsUrl: 'https://on.cypress.io/intercept',
},
},
Cookies: {
preserveOnce: {
unsupported: {
message: `\`Cypress.Cookies.preserveOnce\` use is not supported in ${cmd('switchToDomain')}. Consider using ${cmd('session')} instead.`,
docsUrl: 'https://on.cypress.io/session',
},
},
},
},

task: {
Expand Down

0 comments on commit 07d8255

Please sign in to comment.