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

fix: protocol supports body highlight element #28627

Merged
merged 4 commits into from Jan 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions cli/CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ _Released 1/2/2024 (PENDING)_
- Now 'node_modules' will not be ignored if a project path or a provided path to spec files contains it. Fixes [#23616](https://github.com/cypress-io/cypress/issues/23616).
- Updated display of assertions and commands with a URL argument to escape markdown formatting so that values are displayed as is and assertion values display as bold. Fixes [#24960](https://github.com/cypress-io/cypress/issues/24960) and [#28100](https://github.com/cypress-io/cypress/issues/28100).
- When generating assertions via Cypress Studio, the preview of the generated assertions now correctly displays the past tense of 'expected' instead of 'expect'. Fixed in [#28593](https://github.com/cypress-io/cypress/pull/28593).
- Fixed a regression in [`13.6.2`](https://docs.cypress.io/guides/references/changelog/13.6.2) where the `body` element was not highlighted correctly in Test Replay. Fixed in [#28627](https://github.com/cypress-io/cypress/pull/28627).
- Fixed an issue where some cross-origin logs, like assertions or cy.clock(), were getting too many dom snapshots. Fixes [#28609](https://github.com/cypress-io/cypress/issues/28609).

**Dependency Updates:**
Expand Down
76 changes: 58 additions & 18 deletions packages/driver/cypress/e2e/cy/snapshot.cy.js
Expand Up @@ -174,38 +174,78 @@ describe('driver/src/cy/snapshots', () => {

expect(body.get().find('iframe').css('height')).to.equal('70px')
})
})

it('captures a protocol snapshot with highlight elements', {
protocolEnabled: true,
}, function () {
context('protocol', () => {
beforeEach(() => {
// set to 0 to ensure protocol snapshots are taken
// since the driver support file sets the value to 1
Cypress.config('numTestsKeptInMemory', 0)
})

const element = $('<iframe id=\'frame-foo-bar\' src=\'generic.html\' />').appendTo(cy.$$('body'))
const ownerDoc = element[0].ownerDocument
const elWindow = ownerDoc.defaultView
it('captures a protocol snapshot with highlight elements', {
protocolEnabled: true,
}, function () {
cy.window().then((win) => {
win.__cypressProtocolMetadata = { frameId: 'test-frame-id' }

const { elementsToHighlight, name, timestamp } = cy.createSnapshot('snapshot', cy.$$('a'))

expect(elementsToHighlight?.length).to.equal(3)
expect(elementsToHighlight?.[0].selector).to.equal('a:nth-child(2)')
expect(elementsToHighlight?.[0].frameId).to.equal('test-frame-id')
expect(elementsToHighlight?.[1].selector).to.equal('#hashchange')
expect(elementsToHighlight?.[1].frameId).to.equal('test-frame-id')
expect(elementsToHighlight?.[2].selector).to.equal('#dimensions')
expect(elementsToHighlight?.[2].frameId).to.equal('test-frame-id')
expect(name).to.equal('snapshot')
expect(timestamp).to.be.a('number')
})
})

elWindow.__cypressProtocolMetadata = { frameId: 'test-frame-id' }
it('captures a protocol snapshot with an embedded iframe highlight element', {
protocolEnabled: true,
}, function () {
const iframe = $('<iframe src=\'iframe-inner.html\' />')

const { elementsToHighlight, name, timestamp } = cy.createSnapshot('snapshot', element)
iframe.on('load', () => {
const ownerDoc = iframe[0].contentDocument
const elWindow = iframe[0].contentWindow
const element = $(ownerDoc.querySelector('button'))

delete elWindow.__cypressProtocolMetadata
elWindow.__cypressProtocolMetadata = { frameId: 'test-frame-id' }

expect(elementsToHighlight?.length).to.equal(1)
expect(elementsToHighlight?.[0].selector).to.equal('#frame-foo-bar')
expect(elementsToHighlight?.[0].frameId).to.equal('test-frame-id')
expect(name).to.equal('snapshot')
expect(timestamp).to.be.a('number')
const { elementsToHighlight, name, timestamp } = cy.createSnapshot('snapshot', element)

expect(elementsToHighlight?.length).to.equal(1)
expect(elementsToHighlight?.[0].selector).to.equal('button:nth-child(1)')
expect(elementsToHighlight?.[0].frameId).to.equal('test-frame-id')
expect(name).to.equal('snapshot')
expect(timestamp).to.be.a('number')
})

iframe.appendTo(cy.$$('body'))
})

it('captures a protocol snapshot and excludes a null element', {
it('captures a protocol snapshot with a body highlight element', {
protocolEnabled: true,
}, function () {
// set to 0 to ensure protocol snapshots are taken
// since the driver support file sets the value to 1
Cypress.config('numTestsKeptInMemory', 0)
cy.window().then((win) => {
win.__cypressProtocolMetadata = { frameId: 'test-frame-id' }

const { elementsToHighlight, name, timestamp } = cy.createSnapshot('snapshot', cy.$$('body'))

expect(elementsToHighlight?.length).to.equal(1)
expect(elementsToHighlight?.[0].selector).to.equal('body:nth-child(2)')
expect(elementsToHighlight?.[0].frameId).to.equal('test-frame-id')
expect(name).to.equal('snapshot')
expect(timestamp).to.be.a('number')
})
})

it('captures a protocol snapshot and excludes a null element', {
protocolEnabled: true,
}, function () {
// create an element but don't append it to the DOM
const element = $('<div id=\'foo\' />')

Expand Down
4 changes: 3 additions & 1 deletion packages/driver/src/cy/snapshots.ts
Expand Up @@ -271,7 +271,9 @@ export const create = ($$: $Cy['$$'], state: StateFunc) => {

// finder tries to find the shortest unique selector to an element,
// but since we are more concerned with speed, we set the threshold to 1 and maxNumberOfTries to 0
const selector = finder(el, { root: ownerDoc.body, threshold: 1, maxNumberOfTries: 0 })
// @ts-expect-error because 'root' can be either Document or Element but is defined as Element
// @see https://github.com/antonmedv/finder/issues/75
const selector = finder(el, { root: ownerDoc, threshold: 1, maxNumberOfTries: 0 })
const frameId = elWindow['__cypressProtocolMetadata']?.frameId

return [{ selector, frameId }]
Expand Down