Skip to content

Commit

Permalink
fix: electron slowness within cy origin (#21445)
Browse files Browse the repository at this point in the history
* fix iframe performance issues in electron

* reduce 1000ms to 300ms for cross:origin:release:html

* reduce shouldWithTimeout from 3000ms to 250ms

* Update system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts

Co-authored-by: Chris Breiding <[email protected]>

* add some regression tests around screenshot size when taking screenshots within cy.origin

* move screenshot e2e tests from system-tests into the driver

* move spec bridge system test into driver test

* add additional comments to spec bridge iframe scss for caution

* resolve snapshots directory correctly in open vs run mode

* revert this commit to see if assets are being tampered with or just missing in CI

* fix check:screenshot:size to always point to correct screenshot path

* remove isCypressRunMode from cypress config as internal flag as we no longer need it

* add check:screenshot:size to task.cy.js registered plugin assertion

Co-authored-by: Chris Breiding <[email protected]>
  • Loading branch information
AtofStryker and chrisbreiding authored May 17, 2022
1 parent 3055c79 commit 045ad04
Show file tree
Hide file tree
Showing 14 changed files with 363 additions and 31 deletions.
14 changes: 14 additions & 0 deletions packages/app/src/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,17 @@ html {
height: 0;
}
}

// used to style the spec bridge needed for cy.origin.
iframe.spec-bridge-iframe {
border: none;
height: 100%;
position: fixed;
visibility: hidden;
width: 100%;
// NOTE: Please do NOT remove top/left styles from the .spec-bridge-iframe.
// This is needed to overlay the spec bridge on top of the AUT/Reporter to avoid performance issues in Electron when the iframe is outside the viewport.
// Full size of the iframe is needed for cy.screenshot to work properly
top: 0;
left: 0;
}
2 changes: 1 addition & 1 deletion packages/driver/cypress/e2e/commands/task.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ describe('src/cy/commands/task', () => {
expect(lastLog.get('error')).to.eq(err)
expect(lastLog.get('state')).to.eq('failed')

expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the setupNodeEvents method. The following tasks are registered: return:arg, cypress:env, arg:is:undefined, wait, create:long:file\n\nFix this in your setupNodeEvents method here:\n${Cypress.config('configFile')}`)
expect(err.message).to.eq(`\`cy.task('bar')\` failed with the following error:\n\nThe task 'bar' was not handled in the setupNodeEvents method. The following tasks are registered: return:arg, cypress:env, arg:is:undefined, wait, create:long:file, check:screenshot:size\n\nFix this in your setupNodeEvents method here:\n${Cypress.config('configFile')}`)

done()
})
Expand Down
249 changes: 233 additions & 16 deletions packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
context('cy.origin screenshot', () => {
const { devicePixelRatio } = window

context('set viewport', () => {
beforeEach(() => {
beforeEach(function () {
this.serverResult = {
path: '/path/to/screenshot',
size: 12,
Expand All @@ -20,7 +22,7 @@ context('cy.origin screenshot', () => {
cy.get('a[data-cy="screenshots-link"]').click()
})

it('captures the fullPage', () => {
it('captures the fullPage', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -34,7 +36,7 @@ context('cy.origin screenshot', () => {
})
})

it('captures the runner', () => {
it('captures the runner', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -46,7 +48,7 @@ context('cy.origin screenshot', () => {
})
})

it('captures the viewport', () => {
it('captures the viewport', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -60,7 +62,7 @@ context('cy.origin screenshot', () => {
})

context('without setting viewport', () => {
beforeEach(() => {
beforeEach(function () {
this.serverResult = {
path: '/path/to/screenshot',
size: 12,
Expand All @@ -78,7 +80,7 @@ context('cy.origin screenshot', () => {
cy.get('a[data-cy="screenshots-link"]').click()
})

it('supports multiple titles', () => {
it('supports multiple titles', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -89,7 +91,7 @@ context('cy.origin screenshot', () => {
})
})

it('supports the blackout option', () => {
it('supports the blackout option', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -107,7 +109,7 @@ context('cy.origin screenshot', () => {
})
})

it('supports element screenshots', () => {
it('supports element screenshots', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -119,7 +121,7 @@ context('cy.origin screenshot', () => {
})
})

it('supports screenshot retrying with appropriate naming', () => {
it('supports screenshot retrying with appropriate naming', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
const automationStub = cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)

Expand All @@ -132,7 +134,7 @@ context('cy.origin screenshot', () => {
})
})

it('calls the onBeforeScreenshot callback', () => {
it('calls the onBeforeScreenshot callback', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)
const onBeforeScreenshot = cy.stub()
Expand All @@ -142,7 +144,7 @@ context('cy.origin screenshot', () => {
})
})

it('calls the onAfterScreenshot callback', () => {
it('calls the onAfterScreenshot callback', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)
const onAfterScreenshot = cy.stub()
Expand All @@ -152,7 +154,7 @@ context('cy.origin screenshot', () => {
})
})

it('supports the Cypress.screenshot callbacks', () => {
it('supports the Cypress.screenshot callbacks', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').resolves(serverResult)
const onAfterScreenshot = cy.stub()
Expand All @@ -169,7 +171,7 @@ context('cy.origin screenshot', () => {
})
})

it('supports pausing timers', () => {
it('supports pausing timers', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').returns(Cypress.Promise.delay(500, serverResult))

Expand Down Expand Up @@ -202,7 +204,7 @@ context('cy.origin screenshot', () => {
})
})

it('does not pause timers when disableTimersAndAnimations is false', () => {
it('does not pause timers when disableTimersAndAnimations is false', function () {
cy.origin('http://foobar.com:3500', { args: this.serverResult }, (serverResult) => {
cy.stub(Cypress, 'automation').withArgs('take:screenshot').returns(Cypress.Promise.delay(500, serverResult))

Expand All @@ -227,7 +229,7 @@ context('cy.origin screenshot', () => {
})
})

it('handles errors thrown from setTimeout after the timer is paused', () => {
it('handles errors thrown from setTimeout after the timer is paused', function () {
cy.on('fail', (err) => {
expect(err.name).to.eq('Error')
expect(err.message).to.include('setTimeout error after screenshot')
Expand All @@ -250,7 +252,7 @@ context('cy.origin screenshot', () => {
})
})

it('handles errors thrown from setTimeout when the timer is NOT paused', () => {
it('handles errors thrown from setTimeout when the timer is NOT paused', function () {
cy.on('fail', (err) => {
expect(err.name).to.eq('Error')
expect(err.message).to.include('setTimeout error during screenshot')
Expand All @@ -276,6 +278,221 @@ context('cy.origin screenshot', () => {
})
})

describe('dimensions', () => {
it('crops app captures to just app size', () => {
cy.viewport(600, 400)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-color.html?color=yellow')
const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('crop-check', {
capture: 'viewport',
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 600,
height: 400,
devicePixelRatio,
})
})
})

it('can capture fullPage screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page.html')
const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('fullPage', {
capture: 'fullPage',
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 600,
height: 500,
devicePixelRatio,
})
})
})

it('accepts subsequent same captures after multiple tries', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page-same.html')

const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('fullPage-same', {
capture: 'fullPage',
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 600,
height: 500,
devicePixelRatio,
})
})
})

it('can capture element screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-element.html')

const screenShotPromiseWithPath = new Promise((resolve) => {
cy.get('.element').screenshot('element', {
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 400,
height: 300,
devicePixelRatio,
})
})
})

describe('clipping', () => {
it('can clip app screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-color.html?color=yellow')
const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('app-clip', {
capture: 'viewport', clip: { x: 10, y: 10, width: 100, height: 50 },
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 100,
height: 50,
devicePixelRatio,
})
})
})

it('can clip runner screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-color.html?color=yellow')

const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('runner-clip', {
capture: 'runner', clip: { x: 15, y: 15, width: 120, height: 60 },
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 120,
height: 60,
devicePixelRatio,
})
})
})

it('can clip fullPage screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page.html')

const screenShotPromiseWithPath = new Promise((resolve) => {
cy.screenshot('fullPage-clip', {
capture: 'fullPage', clip: { x: 20, y: 20, width: 140, height: 70 },
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 140,
height: 70,
devicePixelRatio,
})
})
})

it('can clip element screenshots', () => {
cy.viewport(600, 200)

cy.visit('/')
cy.origin('http://foobar.com:3500', () => {
cy.visit('http://www.foobar.com:3500/fixtures/screenshot-element.html')
const screenShotPromiseWithPath = new Promise((resolve) => {
cy.get('.element').screenshot('element-clip', {
clip: { x: 25, y: 25, width: 160, height: 80 },
onAfterScreenshot ($el, props) {
resolve(props.path)
},
})
})

cy.wrap(screenShotPromiseWithPath)
}).then((screenshotPath) => {
cy.task('check:screenshot:size', {
filePath: screenshotPath,
width: 160,
height: 80,
devicePixelRatio,
})
})
})
})
})

context('#consoleProps', () => {
const { findCrossOriginLogs } = require('../../../../support/utils')
let logs: Map<string, any>
Expand Down
Loading

2 comments on commit 045ad04

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 045ad04 May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/linux-x64/10.0-release-045ad04cbd3d4892741664290935b6b98d498377/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 045ad04 May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/win32-x64/10.0-release-045ad04cbd3d4892741664290935b6b98d498377/cypress.tgz

Please sign in to comment.