Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support snapshots and console props within multi-domain #20949

Merged
Merged
Show file tree
Hide file tree
Changes from 65 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
50e7404
Empty commit to get a new percy nonce
ryanthemanuel Mar 28, 2022
638a36e
Implement snapshots and consoleprops within multi origin
AtofStryker Mar 30, 2022
c87a3bf
fix lint types issues on serializationKeys
AtofStryker Apr 6, 2022
31354a2
rename switchToDomain to origin (might help with failing tests... ya …
AtofStryker Apr 7, 2022
6e7a3ff
rename snapshot files to fit origin paradigm and fix misname on prima…
AtofStryker Apr 7, 2022
4064185
fix .tick() snapshot/consoleProps test (figure out the deal with cons…
AtofStryker Apr 7, 2022
b3d6515
rename multiDomainCommunicator to origin primaryDomainCommunicator
AtofStryker Apr 7, 2022
aa2d194
don't invoke functions with arguments (we need to be more explicit ab…
AtofStryker Apr 7, 2022
22441cb
opt for my explicit serialization behavior with functions, never atte…
AtofStryker Apr 7, 2022
585f6d4
move serialization to folder and change name to index
AtofStryker Apr 7, 2022
6b2e623
refactor log serialization to own file, clean up code and add comment…
AtofStryker Apr 7, 2022
2382b65
make sure to serialize functions for snapshots
AtofStryker Apr 7, 2022
42186f1
fix pause snapshot test for multi origin
AtofStryker Apr 7, 2022
96328b5
refactor postprocess snapshot into own method to handle in final stat…
AtofStryker Apr 7, 2022
be4bc19
update snapshot comments to be more accurate
AtofStryker Apr 7, 2022
c7f4abc
fix renamings within tests
AtofStryker Apr 7, 2022
1353f6c
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
AtofStryker Apr 7, 2022
0656e84
fix path in log.ts serialization
AtofStryker Apr 7, 2022
65c8e0c
revert about:blank changes in aut-iframe which was breaking session
AtofStryker Apr 7, 2022
2312ebc
move all log/snapshot serialization magic invokations into the commun…
AtofStryker Apr 11, 2022
11f29be
Merge branch 'feature-multidomain' of github.com:cypress-io/cypress i…
AtofStryker Apr 11, 2022
5237e84
update typos and fix namings of preprocess and reify
AtofStryker Apr 11, 2022
c181927
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
AtofStryker Apr 11, 2022
3290d3e
further name changes
AtofStryker Apr 11, 2022
9c54498
Merge branch 'md-support-snapshots-and-console-props' of github.com:c…
AtofStryker Apr 11, 2022
539f24a
fix snapshot generator to always reify snapshot (<body>) over attempt…
AtofStryker Apr 12, 2022
e0ab8d4
unskip test that was fixed with explicit function serialization for logs
AtofStryker Apr 12, 2022
aa66edc
fix flaky screenshot test that was screensize dependent
AtofStryker Apr 12, 2022
62a6a51
rename a few items in the log serialization file
AtofStryker Apr 12, 2022
838e091
clean up snapshot style reification to be more straightforward and re…
AtofStryker Apr 12, 2022
02c6533
Merge branch 'feature-multidomain' of github.com:cypress-io/cypress i…
AtofStryker Apr 12, 2022
f19c3c4
refactor snapshots code to be more readable
AtofStryker Apr 12, 2022
3fd2095
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
mjhenkes Apr 13, 2022
301cf72
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
mjhenkes Apr 13, 2022
9269726
update reifyDomElement docs to actually explain what hte method does
AtofStryker Apr 14, 2022
d28f924
fix typos within the log serialization file pertaining to comments
AtofStryker Apr 14, 2022
e1af413
use Cypress._ over lodash import to reduce spec bundle size
AtofStryker Apr 14, 2022
bb83fd3
remove snapshots test folder and migrate tests into commands director…
AtofStryker Apr 14, 2022
5c0588a
change removeSrcAttributeFromAUTIframe name to removeSrcAttribute as …
AtofStryker Apr 14, 2022
02cb280
update log consoleProps comment to better reflect cross origin nature
AtofStryker Apr 14, 2022
9734059
remove skipped consoleProps tests that do not have a command log to t…
AtofStryker Apr 14, 2022
9ef3f56
add createSnapshot to internal types (might need more specifics on this)
AtofStryker Apr 14, 2022
912162c
refactor multi-domain consoleProp tests to use shouldWithTimeout cust…
AtofStryker Apr 14, 2022
2561b1d
simplify DOM hydration for input based elements
AtofStryker Apr 15, 2022
45716ae
Merge branch 'feature-multidomain' of github.com:cypress-io/cypress i…
AtofStryker Apr 15, 2022
257f5e0
update preprocessedHTMLElement type
AtofStryker Apr 15, 2022
c93c220
clean up some documentation and remove TS ignores. added getStyles to…
AtofStryker Apr 18, 2022
bf94d55
add comment to aut-iframe on src attr removal for posterity
AtofStryker Apr 18, 2022
14cc07d
reverse snapshot ternary for readability
AtofStryker Apr 18, 2022
ecb6b84
add shouldWithTimeout into spec-types and refactor out of internal-types
AtofStryker Apr 18, 2022
710d93d
add getAll type to cypress spec-types
AtofStryker Apr 18, 2022
fba5cf2
compare originPolicy of top and AUT instead of just origin to make sn…
AtofStryker Apr 18, 2022
416d3c8
add comment to _storeOriginalState for future developers and to add c…
AtofStryker Apr 18, 2022
5345e10
add some basic log serialization tests that show full pre/reification…
AtofStryker Apr 18, 2022
3ad89e7
update variables to metasyntactic
AtofStryker Apr 19, 2022
3a1bc84
add renderProps assertion for cy.request
AtofStryker Apr 19, 2022
c1989ea
apply suggestions from code review to clean up log serializer
AtofStryker Apr 19, 2022
1e2dfd0
Merge branch 'feature-multidomain' of github.com:cypress-io/cypress i…
AtofStryker Apr 19, 2022
e13870f
make snapshot serialization more generic and typesafe
AtofStryker Apr 19, 2022
5349974
work around firefox 93 issues by unsetting the document in cy state a…
AtofStryker Apr 19, 2022
c264f20
clean up code and implement suggestions in code review
AtofStryker Apr 19, 2022
6926bfe
remove crossOriginLog in favor of nullish coalescing if visible on th…
AtofStryker Apr 19, 2022
af3d4cf
if get is null, return null for whole snapshot
AtofStryker Apr 20, 2022
75dfaa2
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
AtofStryker Apr 21, 2022
000c519
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
mjhenkes Apr 21, 2022
7fa02e6
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
AtofStryker Apr 21, 2022
61192b3
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
mjhenkes Apr 21, 2022
8d3ae17
Merge branch 'feature-multidomain' into md-support-snapshots-and-cons…
mjhenkes Apr 22, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions packages/driver/cypress/fixtures/dom.html
Expand Up @@ -437,8 +437,8 @@
</select>

<select name="foods">
<option value="Japanese">Ramen</option>
<option value="Ramen">Japanese</option>
<option value="Ramen">Ramen</option>
mschile marked this conversation as resolved.
Show resolved Hide resolved
<option value="Japanese">Japanese</option>
</select>

<select name="names">
Expand Down

Large diffs are not rendered by default.

@@ -1,3 +1,5 @@
import { findCrossOriginLogs } from '../../../../support/utils'

context('cy.origin aliasing', () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
Expand All @@ -10,4 +12,39 @@ context('cy.origin aliasing', () => {
cy.get('@checkbox').click().should('be.checked')
})
})

context('#consoleProps', () => {
let logs: Map<string, any>

beforeEach(() => {
logs = new Map()

cy.on('log:changed', (attrs, log) => {
logs.set(attrs.id, log)
})
})

it('.as()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.get('#button').as('buttonAlias')
})

cy.shouldWithTimeout(() => {
const { alias, aliasType, consoleProps, $el } = findCrossOriginLogs('get', logs, 'foobar.com')

// make sure $el is in fact a jquery instance to keep the logs happy
expect($el.jquery).to.be.ok

expect(alias).to.equal('buttonAlias')
expect(aliasType).to.equal('dom')
expect(consoleProps.Command).to.equal('get')
expect(consoleProps.Elements).to.equal(1)
expect(consoleProps.Selector).to.equal('#button')

// The Yielded value here SHOULD be correct as it will be reified from its props as it should not be found in the current DOM state
expect(consoleProps.Yielded.tagName).to.equal('BUTTON')
expect(consoleProps.Yielded.getAttribute('id')).to.equal('button')
})
})
})
})
@@ -1,3 +1,5 @@
import { findCrossOriginLogs } from '../../../../support/utils'

context('cy.origin assertions', () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
Expand All @@ -10,4 +12,45 @@ context('cy.origin assertions', () => {
.should('not.be.checked').and('not.be.disabled')
})
})

context('#consoleProps', () => {
let logs: Map<string, any>

beforeEach(() => {
logs = new Map()

cy.on('log:changed', (attrs, log) => {
logs.set(attrs.id, log)
})
})

it('.should() and .and()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.get(':checkbox[name="colors"][value="blue"]')
.should('not.be.checked').and('not.be.disabled')
})

cy.shouldWithTimeout(() => {
// in the case of some firefox browsers, the document state is left in a cross origin context when running these assertions
// set to context to undefined to run the assertions
if (Cypress.isBrowser('firefox')) {
cy.state('document', undefined)
}

const assertionLogs = findCrossOriginLogs('assert', logs, 'foobar.com')

expect(assertionLogs[0].consoleProps.Message).to.equal('expected <input> not to be checked')
expect(assertionLogs[1].consoleProps.Message).to.equal('expected <input> not to be disabled')

assertionLogs.forEach(({ $el, consoleProps }) => {
expect($el.jquery).to.be.ok

expect(consoleProps.Command).to.equal('assert')
expect(consoleProps.subject[0]).to.have.property('tagName').that.equals('INPUT')
expect(consoleProps.subject[0]).to.have.property('value').that.equals('blue')
expect(consoleProps.subject[0].getAttribute('name')).to.equal('colors')
})
})
})
})
})
@@ -1,3 +1,5 @@
import { findCrossOriginLogs } from '../../../../support/utils'

context('cy.origin connectors', () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
Expand Down Expand Up @@ -43,4 +45,75 @@ context('cy.origin connectors', () => {
})
})
})

context('#consoleProps', () => {
let logs: Map<string, any>

beforeEach(() => {
logs = new Map()

cy.on('log:changed', (attrs, log) => {
logs.set(attrs.id, log)
})
})

it('.its()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.get('#by-id>input').its('length')
})

cy.shouldWithTimeout(() => {
// in the case of some firefox browsers, the document state is left in a cross origin context when running these assertions
// set to context to undefined to run the assertions
if (Cypress.isBrowser('firefox')) {
cy.state('document', undefined)
}

const { consoleProps, $el } = findCrossOriginLogs('its', logs, 'foobar.com')

expect($el.jquery).to.be.ok

expect(consoleProps.Command).to.equal('its')
expect(consoleProps.Property).to.equal('.length')
expect(consoleProps.Yielded).to.equal(3)

expect(consoleProps.Subject.length).to.equal(3)

// make sure subject elements are indexed in the correct order
expect(consoleProps.Subject[0]).to.have.property('tagName').that.equals('INPUT')
expect(consoleProps.Subject[0]).to.have.property('id').that.equals('input')

expect(consoleProps.Subject[1]).to.have.property('tagName').that.equals('INPUT')
expect(consoleProps.Subject[1]).to.have.property('id').that.equals('name')

expect(consoleProps.Subject[2]).to.have.property('tagName').that.equals('INPUT')
expect(consoleProps.Subject[2]).to.have.property('id').that.equals('age')
})
})

it('.invoke()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.get('#button').invoke('text')
})

cy.shouldWithTimeout(() => {
// in the case of some firefox browsers, the document state is left in a cross origin context when running these assertions
// set to context to undefined to run the assertions
if (Cypress.isBrowser('firefox')) {
cy.state('document', undefined)
}

const { consoleProps, $el } = findCrossOriginLogs('invoke', logs, 'foobar.com')

expect($el.jquery).to.be.ok

expect(consoleProps.Command).to.equal('invoke')
expect(consoleProps.Function).to.equal('.text()')
expect(consoleProps.Yielded).to.equal('button')

expect(consoleProps.Subject).to.have.property('tagName').that.equals('BUTTON')
expect(consoleProps.Subject).to.have.property('id').that.equals('button')
})
})
})
})
@@ -1,3 +1,5 @@
import { findCrossOriginLogs } from '../../../../support/utils'

context('cy.origin cookies', () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
Expand Down Expand Up @@ -34,4 +36,142 @@ context('cy.origin cookies', () => {
cy.getCookies().should('be.empty')
})
})

context('#consoleProps', () => {
const { _ } = Cypress
let logs: Map<string, any>

beforeEach(() => {
logs = new Map()

cy.on('log:changed', (attrs, log) => {
logs.set(attrs.id, log)
})
})

it('.getCookie()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.getCookies().should('be.empty')
cy.setCookie('foo', 'bar')
cy.getCookie('foo')
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('getCookie', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('getCookie')
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
})
})

it('.getCookies()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.getCookies().should('be.empty')

cy.setCookie('foo', 'bar')
cy.getCookies()
})

cy.shouldWithTimeout(() => {
// get the last 'getCookies' command, which is the one we care about for this test
const allGetCookieLogs = findCrossOriginLogs('getCookies', logs, 'foobar.com')

const { consoleProps } = allGetCookieLogs.pop() as any

expect(consoleProps.Command).to.equal('getCookies')
expect(consoleProps['Num Cookies']).to.equal(1)

// can't exactly assert on length() as this is a array proxy object
expect(consoleProps.Yielded.length).to.equal(1)
expect(consoleProps.Yielded[0]).to.have.property('expiry').that.is.a('number')
expect(consoleProps.Yielded[0]).to.have.property('httpOnly').that.equals(false)
expect(consoleProps.Yielded[0]).to.have.property('secure').that.equals(false)
expect(consoleProps.Yielded[0]).to.have.property('name').that.equals('foo')
expect(consoleProps.Yielded[0]).to.have.property('value').that.equals('bar')
expect(consoleProps.Yielded[0]).to.have.property('path').that.is.a('string')
})
})

it('.setCookie()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.getCookies().should('be.empty')

cy.setCookie('foo', 'bar')
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('setCookie', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('setCookie')
expect(consoleProps.Yielded).to.have.property('domain').that.includes('foobar.com')
expect(consoleProps.Yielded).to.have.property('expiry').that.is.a('number')
expect(consoleProps.Yielded).to.have.property('httpOnly').that.equals(false)
expect(consoleProps.Yielded).to.have.property('secure').that.equals(false)
expect(consoleProps.Yielded).to.have.property('name').that.equals('foo')
expect(consoleProps.Yielded).to.have.property('value').that.equals('bar')
expect(consoleProps.Yielded).to.have.property('path').that.is.a('string')
})
})

it('.clearCookie()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.setCookie('foo', 'bar')
cy.getCookie('foo').should('not.be.null')
cy.clearCookie('foo')
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('clearCookie', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('clearCookie')
expect(consoleProps.Yielded).to.equal('null')
expect(consoleProps['Cleared Cookie']).to.have.property('domain').that.includes('foobar.com')
expect(consoleProps['Cleared Cookie']).to.have.property('expiry').that.is.a('number')
expect(consoleProps['Cleared Cookie']).to.have.property('httpOnly').that.equals(false)
expect(consoleProps['Cleared Cookie']).to.have.property('secure').that.equals(false)
expect(consoleProps['Cleared Cookie']).to.have.property('name').that.equals('foo')
expect(consoleProps['Cleared Cookie']).to.have.property('value').that.equals('bar')
expect(consoleProps['Cleared Cookie']).to.have.property('path').that.is.a('string')
})
})

it('.clearCookies()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.setCookie('foo', 'bar')
cy.setCookie('faz', 'baz')

cy.getCookies().should('have.length', 2)
cy.clearCookies()
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('clearCookies', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('clearCookies')
expect(consoleProps['Num Cookies']).to.equal(2)

expect(consoleProps.Yielded).to.equal('null')

expect(consoleProps['Cleared Cookies'].length).to.equal(2)

expect(consoleProps['Cleared Cookies'][0]).to.have.property('name').that.equals('foo')
expect(consoleProps['Cleared Cookies'][0]).to.have.property('value').that.equals('bar')

expect(consoleProps['Cleared Cookies'][1]).to.have.property('name').that.equals('faz')
expect(consoleProps['Cleared Cookies'][1]).to.have.property('value').that.equals('baz')

_.forEach(consoleProps['Cleared Cookies'], (clearedCookie) => {
expect(clearedCookie).to.have.property('httpOnly').that.equals(false)
expect(clearedCookie).to.have.property('secure').that.equals(false)
expect(clearedCookie).to.have.property('path').that.is.a('string')
})
})
})
})
})
@@ -1,3 +1,5 @@
import { findCrossOriginLogs } from '../../../../support/utils'

context('cy.origin files', () => {
beforeEach(() => {
cy.visit('/fixtures/multi-domain.html')
Expand Down Expand Up @@ -44,4 +46,51 @@ context('cy.origin files', () => {
})
})
})

context('#consoleProps', () => {
let logs: Map<string, any>

beforeEach(() => {
logs = new Map()

cy.on('log:changed', (attrs, log) => {
logs.set(attrs.id, log)
})
})

it('.readFile()', () => {
cy.origin('http://foobar.com:3500', () => {
cy.readFile('cypress/fixtures/example.json')
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('readFile', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('readFile')
expect(consoleProps['File Path']).to.include('cypress/fixtures/example.json')
expect(consoleProps.Contents).to.deep.equal({ example: true })
})
})

it('.writeFile()', () => {
cy.origin('http://foobar.com:3500', () => {
const contents = JSON.stringify({ foo: 'bar' })

cy.stub(Cypress, 'backend').resolves({
contents,
filePath: 'foo.json',
})

cy.writeFile('foo.json', contents)
})

cy.shouldWithTimeout(() => {
const { consoleProps } = findCrossOriginLogs('writeFile', logs, 'foobar.com')

expect(consoleProps.Command).to.equal('writeFile')
expect(consoleProps['File Path']).to.equal('foo.json')
expect(consoleProps.Contents).to.equal('{"foo":"bar"}')
})
})
})
})