From 06fe5b1b74f4ed2ee159ee1b77364760322502eb Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Wed, 11 May 2022 18:53:12 -0400 Subject: [PATCH 01/13] fix iframe performance issues in electron --- packages/app/src/main.scss | 11 ++++ packages/runner/src/iframe/iframe.scss | 10 +--- .../spec_bridge_in_viewport_spec.ts.js | 59 +++++++++++++++++++ .../e2e/cypress/e2e/spec_bridge.cy.ts | 20 +++++++ .../projects/e2e/secondary_origin.html | 1 + .../test/spec_bridge_in_viewport_spec.ts | 38 ++++++++++++ 6 files changed, 130 insertions(+), 9 deletions(-) create mode 100644 system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js create mode 100644 system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts create mode 100644 system-tests/test/spec_bridge_in_viewport_spec.ts diff --git a/packages/app/src/main.scss b/packages/app/src/main.scss index a7abe69f5266..4ee45e1195f8 100644 --- a/packages/app/src/main.scss +++ b/packages/app/src/main.scss @@ -29,3 +29,14 @@ 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%; + top: 0; + left: 0; +} diff --git a/packages/runner/src/iframe/iframe.scss b/packages/runner/src/iframe/iframe.scss index b78847792590..b37f1a04f46c 100644 --- a/packages/runner/src/iframe/iframe.scss +++ b/packages/runner/src/iframe/iframe.scss @@ -94,12 +94,4 @@ transform-origin: 50% 0; width: 100%; } -} - -.spec-bridge-iframe { - border: none; - height: 100%; - position: fixed; - visibility: hidden; - width: 100%; -} +} \ No newline at end of file diff --git a/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js b/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js new file mode 100644 index 000000000000..906eeac117b7 --- /dev/null +++ b/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js @@ -0,0 +1,59 @@ +exports['e2e spec bridge in viewport / Overlays the reporter/AUT and is not positioned off screen, leading to potential performance impacts with cy.origin'] = ` + +==================================================================================================== + + (Run Starting) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Cypress: 1.2.3 │ + │ Browser: FooBrowser 88 │ + │ Specs: 1 found (spec_bridge.cy.ts) │ + │ Searched: cypress/e2e/spec_bridge.cy.ts │ + │ Experiments: experimentalSessionAndOrigin=true │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + +──────────────────────────────────────────────────────────────────────────────────────────────────── + + Running: spec_bridge.cy.ts (1 of 1) + + + ✓ visits foobar.com and types foobar inside an input + + 1 passing + + + (Results) + + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ Tests: 1 │ + │ Passing: 1 │ + │ Failing: 0 │ + │ Pending: 0 │ + │ Skipped: 0 │ + │ Screenshots: 0 │ + │ Video: true │ + │ Duration: X seconds │ + │ Spec Ran: spec_bridge.cy.ts │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + + + (Video) + + - Started processing: Compressing to 32 CRF + - Finished processing: /XXX/XXX/XXX/cypress/videos/spec_bridge.cy.ts.mp4 (X second) + + +==================================================================================================== + + (Run Finished) + + + Spec Tests Passing Failing Pending Skipped + ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ + │ ✔ spec_bridge.cy.ts XX:XX 1 1 - - - │ + └────────────────────────────────────────────────────────────────────────────────────────────────┘ + ✔ All specs passed! XX:XX 1 1 - - - + + +` diff --git a/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts b/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts new file mode 100644 index 000000000000..1211d19d89f1 --- /dev/null +++ b/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts @@ -0,0 +1,20 @@ +it('visits foobar.com and types foobar inside an input', () => { + cy.visit('primary_origin.html') + cy.get('[data-cy="cross_origin_secondary_link"]').click() + + cy.origin('http://foobar.com:4466', () => { + cy.get('[data-cy="text-input"]').type('foobar') + }) + + // ensure stability + cy.then(() => { + const specBridgeIframe: HTMLIFrameElement = window.top.document.querySelector('.spec-bridge-iframe') + const currentBody = window.top.document.querySelector('body') + + // make sure the spec bridge overlays the reporter/AUT and is not off the screen + expect(specBridgeIframe.offsetTop).to.equal(currentBody.offsetTop) + expect(specBridgeIframe.offsetLeft).to.equal(currentBody.offsetLeft) + expect(specBridgeIframe.clientWidth).to.equal(currentBody.clientWidth) + expect(specBridgeIframe.clientHeight).to.equal(currentBody.clientHeight) + }) +}) diff --git a/system-tests/projects/e2e/secondary_origin.html b/system-tests/projects/e2e/secondary_origin.html index 2668024059d8..068ec4662065 100644 --- a/system-tests/projects/e2e/secondary_origin.html +++ b/system-tests/projects/e2e/secondary_origin.html @@ -6,6 +6,7 @@

From a secondary origin

+
diff --git a/system-tests/test/spec_bridge_in_viewport_spec.ts b/system-tests/test/spec_bridge_in_viewport_spec.ts new file mode 100644 index 000000000000..a49b8b5ccc86 --- /dev/null +++ b/system-tests/test/spec_bridge_in_viewport_spec.ts @@ -0,0 +1,38 @@ +import path from 'path' +import systemTests from '../lib/system-tests' +import Fixtures from '../lib/fixtures' + +const e2ePath = Fixtures.projectPath('e2e') + +const PORT = 3500 +const onServer = function (app) { + app.get('/secondary_origin.html', (_, res) => { + res.sendFile(path.join(e2ePath, `secondary_origin.html`)) + }) +} + +describe('e2e spec bridge in viewport', () => { + systemTests.setup({ + servers: [{ + port: 4466, + onServer, + }], + settings: { + hosts: { + '*.foobar.com': '127.0.0.1', + }, + }, + }) + + systemTests.it('Overlays the reporter/AUT and is not positioned off screen, leading to potential performance impacts with cy.origin', { + // keep the port the same to prevent issues with the snapshot + port: PORT, + spec: 'spec_bridge.cy.ts', + snapshot: true, + browser: 'electron', + expectedExitCode: 0, + config: { + experimentalSessionAndOrigin: true, + }, + }) +}) From 7e31364fb0ac6b044c6eefc919f23ae53adf0ee5 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Wed, 11 May 2022 19:21:57 -0400 Subject: [PATCH 02/13] reduce 1000ms to 300ms for cross:origin:release:html --- packages/driver/src/cy/commands/origin/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/driver/src/cy/commands/origin/index.ts b/packages/driver/src/cy/commands/origin/index.ts index df58404bc749..9d1d3b55ac81 100644 --- a/packages/driver/src/cy/commands/origin/index.ts +++ b/packages/driver/src/cy/commands/origin/index.ts @@ -48,7 +48,7 @@ export default (Commands, Cypress: Cypress.Cypress, cy: Cypress.cy, state: Cypre // not have a cy.origin for the intermediary origin. timeoutId = setTimeout(() => { Cypress.backend('cross:origin:release:html') - }, 1000) + }, 300) }) Commands.addAll({ From ec2ea6329e056bbbf291a8887b794502c32a97b3 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Wed, 11 May 2022 19:22:15 -0400 Subject: [PATCH 03/13] reduce shouldWithTimeout from 3000ms to 250ms --- packages/driver/cypress/support/utils.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/driver/cypress/support/utils.js b/packages/driver/cypress/support/utils.js index 23532721ccb4..52ba67d91a81 100644 --- a/packages/driver/cypress/support/utils.js +++ b/packages/driver/cypress/support/utils.js @@ -107,10 +107,7 @@ const getAllFn = (...aliases) => { ) } -// FIXME: currently increasing the timeout here from 250ms to 3 second -// due to some unknown performance issues with logs coming back in from the primary in the 10.0-release branch. -// this timeout should be reduced in the future once these performance issues are addressed. -const shouldWithTimeout = (cb, timeout = 3000) => { +const shouldWithTimeout = (cb, timeout = 250) => { cy.wrap({}, { timeout }).should(cb) } From cf12f0faf32a8881a2fae8814679403c168b2dc3 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Thu, 12 May 2022 10:29:09 -0400 Subject: [PATCH 04/13] Update system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts Co-authored-by: Chris Breiding --- system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts b/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts index 1211d19d89f1..124aff4191be 100644 --- a/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts +++ b/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts @@ -5,9 +5,7 @@ it('visits foobar.com and types foobar inside an input', () => { cy.origin('http://foobar.com:4466', () => { cy.get('[data-cy="text-input"]').type('foobar') }) - - // ensure stability - cy.then(() => { + .then(() => { const specBridgeIframe: HTMLIFrameElement = window.top.document.querySelector('.spec-bridge-iframe') const currentBody = window.top.document.querySelector('body') From 70e32513ae1a561f38d76e3c0e054b178f48cc33 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Thu, 12 May 2022 18:08:09 -0400 Subject: [PATCH 05/13] add some regression tests around screenshot size when taking screenshots within cy.origin --- .../cypress/e2e/cy_origin_screenshots.cy.js | 150 ++++++++++++++++++ .../test/cy_origin_screenshots_spec.js | 46 ++++++ 2 files changed, 196 insertions(+) create mode 100644 system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js create mode 100644 system-tests/test/cy_origin_screenshots_spec.js diff --git a/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js b/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js new file mode 100644 index 000000000000..f39e36c22de3 --- /dev/null +++ b/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js @@ -0,0 +1,150 @@ +const { devicePixelRatio } = window +const path = require('path') + +describe('taking screenshots within cy.origin', () => { + it('crops app captures to just app size', () => { + cy.viewport(600, 400) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/color/yellow') + cy.screenshot('crop-check', { capture: 'viewport' }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/crop-check.png`, + width: 600, + height: 400, + devicePixelRatio, + }) + }) + + it('can capture fullPage screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/fullPage') + cy.screenshot('fullPage', { capture: 'fullPage' }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/fullPage.png`, + width: 600, + height: 500, + devicePixelRatio, + }) + }) + + it('accepts subsequent same captures after multiple tries', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/fullPage-same') + cy.screenshot('fullPage-same', { capture: 'fullPage' }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/fullPage-same.png`, + width: 600, + height: 500, + devicePixelRatio, + }) + }) + + it('can capture element screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/element') + cy.get('.element').screenshot('element') + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/element.png`, + width: 400, + height: 300, + devicePixelRatio, + }) + }) + + describe('clipping', () => { + it('can clip app screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/color/yellow') + cy.screenshot('app-clip', { + capture: 'viewport', clip: { x: 10, y: 10, width: 100, height: 50 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/app-clip.png`, + width: 100, + height: 50, + devicePixelRatio, + }) + }) + + it('can clip runner screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/color/yellow') + cy.screenshot('runner-clip', { + capture: 'runner', clip: { x: 15, y: 15, width: 120, height: 60 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/runner-clip.png`, + width: 120, + height: 60, + devicePixelRatio, + }) + }) + + it('can clip fullPage screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/fullPage') + cy.screenshot('fullPage-clip', { + capture: 'fullPage', clip: { x: 20, y: 20, width: 140, height: 70 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/fullPage-clip.png`, + width: 140, + height: 70, + devicePixelRatio, + }) + }) + + it('can clip element screenshots', () => { + cy.viewport(600, 200) + + cy.visit('/') + cy.origin('http://foobar.com:3322', () => { + cy.visit('http://www.foobar.com:3322/element') + cy.get('.element').screenshot('element-clip', { + clip: { x: 25, y: 25, width: 160, height: 80 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `${path.basename(__filename)}/element-clip.png`, + width: 160, + height: 80, + devicePixelRatio, + }) + }) + }) +}) diff --git a/system-tests/test/cy_origin_screenshots_spec.js b/system-tests/test/cy_origin_screenshots_spec.js new file mode 100644 index 000000000000..939a09c33849 --- /dev/null +++ b/system-tests/test/cy_origin_screenshots_spec.js @@ -0,0 +1,46 @@ +const systemTests = require('../lib/system-tests').default + +const onServer = function (app) { + app.get('/color/:color', (req, res) => { + return systemTests.sendHtml(`\ + +
`)(req, res) + }) + + app.get('/fullPage', systemTests.sendHtml(`\ + +
+
+
\ + `)) + + app.get('/fullPage-same', systemTests.sendHtml(`\ + +
\ + `)) + + app.get('/element', systemTests.sendHtml(`\ +
\ + `)) +} + +describe('e2e cy.origin screenshots', function () { + systemTests.setup({ + servers: { + port: 3322, + onServer, + }, + }) + + systemTests.it('correctly takes screenshots from the spec bridge', { + spec: 'cy_origin_screenshots.cy.js', + expectedExitCode: 0, + timeout: 180000, + config: { + experimentalSessionAndOrigin: true, + hosts: { + '*.foobar.com': '127.0.0.1', + }, + }, + }) +}) From 0ff55b1ccab6c055f9e9fb2e31d11d1429dd8049 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 13 May 2022 13:19:32 -0400 Subject: [PATCH 06/13] move screenshot e2e tests from system-tests into the driver --- .../e2e/e2e/origin/commands/screenshot.cy.ts | 190 ++++++++++++++++-- .../cypress/fixtures/screenshot-color.html | 25 +++ .../cypress/fixtures/screenshot-element.html | 21 ++ .../fixtures/screenshot-full-page-same.html | 15 ++ .../fixtures/screenshot-full-page.html | 17 ++ packages/driver/cypress/plugins/index.js | 23 +++ packages/driver/package.json | 1 + .../cypress/e2e/cy_origin_screenshots.cy.js | 150 -------------- .../test/cy_origin_screenshots_spec.js | 46 ----- 9 files changed, 276 insertions(+), 212 deletions(-) create mode 100644 packages/driver/cypress/fixtures/screenshot-color.html create mode 100644 packages/driver/cypress/fixtures/screenshot-element.html create mode 100644 packages/driver/cypress/fixtures/screenshot-full-page-same.html create mode 100644 packages/driver/cypress/fixtures/screenshot-full-page.html delete mode 100644 system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js delete mode 100644 system-tests/test/cy_origin_screenshots_spec.js diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts index 0c074261173c..2284a183aeeb 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts @@ -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, @@ -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) @@ -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) @@ -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) @@ -60,7 +62,7 @@ context('cy.origin screenshot', () => { }) context('without setting viewport', () => { - beforeEach(() => { + beforeEach(function () { this.serverResult = { path: '/path/to/screenshot', size: 12, @@ -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) @@ -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) @@ -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) @@ -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) @@ -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() @@ -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() @@ -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() @@ -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)) @@ -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)) @@ -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') @@ -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') @@ -276,6 +278,162 @@ context('cy.origin screenshot', () => { }) }) + describe('dimensions', () => { + before(() => { + cy.task('trash:screenshot:assets') + }) + + after(() => { + cy.task('trash:screenshot:assets') + }) + + 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') + cy.screenshot('crop-check', { capture: 'viewport' }) + }) + + cy.task('check:screenshot:size', { + name: `crop-check.png`, + 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') + cy.screenshot('fullPage', { capture: 'fullPage' }) + }) + + cy.task('check:screenshot:size', { + name: `fullPage.png`, + 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') + cy.screenshot('fullPage-same', { capture: 'fullPage' }) + }) + + cy.task('check:screenshot:size', { + name: `fullPage-same.png`, + 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') + cy.get('.element').screenshot('element') + }) + + cy.task('check:screenshot:size', { + name: `element.png`, + 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') + cy.screenshot('app-clip', { + capture: 'viewport', clip: { x: 10, y: 10, width: 100, height: 50 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `app-clip.png`, + 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') + cy.screenshot('runner-clip', { + capture: 'runner', clip: { x: 15, y: 15, width: 120, height: 60 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `runner-clip.png`, + 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') + cy.screenshot('fullPage-clip', { + capture: 'fullPage', clip: { x: 20, y: 20, width: 140, height: 70 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `fullPage-clip.png`, + 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') + cy.get('.element').screenshot('element-clip', { + clip: { x: 25, y: 25, width: 160, height: 80 }, + }) + }) + + cy.task('check:screenshot:size', { + name: `element-clip.png`, + width: 160, + height: 80, + devicePixelRatio, + }) + }) + }) + }) + context('#consoleProps', () => { const { findCrossOriginLogs } = require('../../../../support/utils') let logs: Map diff --git a/packages/driver/cypress/fixtures/screenshot-color.html b/packages/driver/cypress/fixtures/screenshot-color.html new file mode 100644 index 000000000000..efd2aac37c9b --- /dev/null +++ b/packages/driver/cypress/fixtures/screenshot-color.html @@ -0,0 +1,25 @@ + + + + Screenshots Color Fixture + + + +
+ + + \ No newline at end of file diff --git a/packages/driver/cypress/fixtures/screenshot-element.html b/packages/driver/cypress/fixtures/screenshot-element.html new file mode 100644 index 000000000000..1406f6d9ebe4 --- /dev/null +++ b/packages/driver/cypress/fixtures/screenshot-element.html @@ -0,0 +1,21 @@ + + + + Screenshots Element Fixture + + + +
+ + \ No newline at end of file diff --git a/packages/driver/cypress/fixtures/screenshot-full-page-same.html b/packages/driver/cypress/fixtures/screenshot-full-page-same.html new file mode 100644 index 000000000000..038895fcb250 --- /dev/null +++ b/packages/driver/cypress/fixtures/screenshot-full-page-same.html @@ -0,0 +1,15 @@ + + + + + Screenshots Full Page Fixture + + + +
+ + \ No newline at end of file diff --git a/packages/driver/cypress/fixtures/screenshot-full-page.html b/packages/driver/cypress/fixtures/screenshot-full-page.html new file mode 100644 index 000000000000..97d64ef53602 --- /dev/null +++ b/packages/driver/cypress/fixtures/screenshot-full-page.html @@ -0,0 +1,17 @@ + + + + + Screenshots Full Page Fixture + + + +
+
+
+ + \ No newline at end of file diff --git a/packages/driver/cypress/plugins/index.js b/packages/driver/cypress/plugins/index.js index 33b2015528c4..c766dba708fa 100644 --- a/packages/driver/cypress/plugins/index.js +++ b/packages/driver/cypress/plugins/index.js @@ -6,6 +6,7 @@ const path = require('path') const fs = require('fs-extra') const Promise = require('bluebird') const wp = require('@cypress/webpack-preprocessor') +const Jimp = require('jimp') process.env.NO_LIVERELOAD = '1' const [webpackOptions] = require('@packages/runner/webpack.config.ts').default @@ -59,6 +60,28 @@ module.exports = (on, config) => { fs.outputFileSync(filePath, longText) + return null + }, + 'check:screenshot:size' ({ name, width, height, devicePixelRatio }) { + return Jimp.read(path.join(__dirname, '..', 'screenshots', name)) + .then((image) => { + width = width * devicePixelRatio + height = height * devicePixelRatio + + if (image.bitmap.width !== width || image.bitmap.height !== height) { + throw new Error(`Screenshot does not match dimensions! Expected: ${width} x ${height} but got ${image.bitmap.width} x ${image.bitmap.height}`) + } + + return null + }) + }, + 'trash:screenshot:assets' () { + const screenshotsPath = path.join(__dirname, '..', 'screenshots') + + if (fs.existsSync(screenshotsPath)) { + fs.rmdirSync(screenshotsPath, { recursive: true, force: true }) + } + return null }, }) diff --git a/packages/driver/package.json b/packages/driver/package.json index 152a38c6a34a..0d8249050a9c 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -54,6 +54,7 @@ "express": "4.17.1", "is-valid-domain": "0.0.20", "is-valid-hostname": "1.0.1", + "jimp": "0.14.0", "jquery": "3.1.1", "js-cookie": "2.2.1", "json-stable-stringify": "1.0.1", diff --git a/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js b/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js deleted file mode 100644 index f39e36c22de3..000000000000 --- a/system-tests/projects/e2e/cypress/e2e/cy_origin_screenshots.cy.js +++ /dev/null @@ -1,150 +0,0 @@ -const { devicePixelRatio } = window -const path = require('path') - -describe('taking screenshots within cy.origin', () => { - it('crops app captures to just app size', () => { - cy.viewport(600, 400) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/color/yellow') - cy.screenshot('crop-check', { capture: 'viewport' }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/crop-check.png`, - width: 600, - height: 400, - devicePixelRatio, - }) - }) - - it('can capture fullPage screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/fullPage') - cy.screenshot('fullPage', { capture: 'fullPage' }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/fullPage.png`, - width: 600, - height: 500, - devicePixelRatio, - }) - }) - - it('accepts subsequent same captures after multiple tries', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/fullPage-same') - cy.screenshot('fullPage-same', { capture: 'fullPage' }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/fullPage-same.png`, - width: 600, - height: 500, - devicePixelRatio, - }) - }) - - it('can capture element screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/element') - cy.get('.element').screenshot('element') - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/element.png`, - width: 400, - height: 300, - devicePixelRatio, - }) - }) - - describe('clipping', () => { - it('can clip app screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/color/yellow') - cy.screenshot('app-clip', { - capture: 'viewport', clip: { x: 10, y: 10, width: 100, height: 50 }, - }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/app-clip.png`, - width: 100, - height: 50, - devicePixelRatio, - }) - }) - - it('can clip runner screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/color/yellow') - cy.screenshot('runner-clip', { - capture: 'runner', clip: { x: 15, y: 15, width: 120, height: 60 }, - }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/runner-clip.png`, - width: 120, - height: 60, - devicePixelRatio, - }) - }) - - it('can clip fullPage screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/fullPage') - cy.screenshot('fullPage-clip', { - capture: 'fullPage', clip: { x: 20, y: 20, width: 140, height: 70 }, - }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/fullPage-clip.png`, - width: 140, - height: 70, - devicePixelRatio, - }) - }) - - it('can clip element screenshots', () => { - cy.viewport(600, 200) - - cy.visit('/') - cy.origin('http://foobar.com:3322', () => { - cy.visit('http://www.foobar.com:3322/element') - cy.get('.element').screenshot('element-clip', { - clip: { x: 25, y: 25, width: 160, height: 80 }, - }) - }) - - cy.task('check:screenshot:size', { - name: `${path.basename(__filename)}/element-clip.png`, - width: 160, - height: 80, - devicePixelRatio, - }) - }) - }) -}) diff --git a/system-tests/test/cy_origin_screenshots_spec.js b/system-tests/test/cy_origin_screenshots_spec.js deleted file mode 100644 index 939a09c33849..000000000000 --- a/system-tests/test/cy_origin_screenshots_spec.js +++ /dev/null @@ -1,46 +0,0 @@ -const systemTests = require('../lib/system-tests').default - -const onServer = function (app) { - app.get('/color/:color', (req, res) => { - return systemTests.sendHtml(`\ - -
`)(req, res) - }) - - app.get('/fullPage', systemTests.sendHtml(`\ - -
-
-
\ - `)) - - app.get('/fullPage-same', systemTests.sendHtml(`\ - -
\ - `)) - - app.get('/element', systemTests.sendHtml(`\ -
\ - `)) -} - -describe('e2e cy.origin screenshots', function () { - systemTests.setup({ - servers: { - port: 3322, - onServer, - }, - }) - - systemTests.it('correctly takes screenshots from the spec bridge', { - spec: 'cy_origin_screenshots.cy.js', - expectedExitCode: 0, - timeout: 180000, - config: { - experimentalSessionAndOrigin: true, - hosts: { - '*.foobar.com': '127.0.0.1', - }, - }, - }) -}) From 83b5746f772098a3104a9cfbcc5cea6f4942552f Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 13 May 2022 13:23:44 -0400 Subject: [PATCH 07/13] move spec bridge system test into driver test --- .../cypress/e2e/e2e/origin}/spec_bridge.cy.ts | 10 ++-- .../cypress/fixtures/secondary-origin.html | 1 + .../spec_bridge_in_viewport_spec.ts.js | 59 ------------------- .../projects/e2e/secondary_origin.html | 1 - .../test/spec_bridge_in_viewport_spec.ts | 38 ------------ 5 files changed, 6 insertions(+), 103 deletions(-) rename {system-tests/projects/e2e/cypress/e2e => packages/driver/cypress/e2e/e2e/origin}/spec_bridge.cy.ts (58%) delete mode 100644 system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js delete mode 100644 system-tests/test/spec_bridge_in_viewport_spec.ts diff --git a/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts b/packages/driver/cypress/e2e/e2e/origin/spec_bridge.cy.ts similarity index 58% rename from system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts rename to packages/driver/cypress/e2e/e2e/origin/spec_bridge.cy.ts index 124aff4191be..5f7f8ee12f4c 100644 --- a/system-tests/projects/e2e/cypress/e2e/spec_bridge.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/spec_bridge.cy.ts @@ -1,13 +1,13 @@ it('visits foobar.com and types foobar inside an input', () => { - cy.visit('primary_origin.html') - cy.get('[data-cy="cross_origin_secondary_link"]').click() + cy.visit('/fixtures/primary-origin.html') + cy.get('[data-cy="cross-origin-secondary-link"]').click() - cy.origin('http://foobar.com:4466', () => { + cy.origin('http://foobar.com:3500', () => { cy.get('[data-cy="text-input"]').type('foobar') }) .then(() => { - const specBridgeIframe: HTMLIFrameElement = window.top.document.querySelector('.spec-bridge-iframe') - const currentBody = window.top.document.querySelector('body') + const specBridgeIframe: HTMLIFrameElement = window?.top?.document.querySelector('.spec-bridge-iframe') || {} as HTMLIFrameElement + const currentBody = window?.top?.document.querySelector('body') || {} as HTMLBodyElement // make sure the spec bridge overlays the reporter/AUT and is not off the screen expect(specBridgeIframe.offsetTop).to.equal(currentBody.offsetTop) diff --git a/packages/driver/cypress/fixtures/secondary-origin.html b/packages/driver/cypress/fixtures/secondary-origin.html index 8ea020398034..a16836588c58 100644 --- a/packages/driver/cypress/fixtures/secondary-origin.html +++ b/packages/driver/cypress/fixtures/secondary-origin.html @@ -6,6 +6,7 @@

From a secondary origin

+
diff --git a/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js b/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js deleted file mode 100644 index 906eeac117b7..000000000000 --- a/system-tests/__snapshots__/spec_bridge_in_viewport_spec.ts.js +++ /dev/null @@ -1,59 +0,0 @@ -exports['e2e spec bridge in viewport / Overlays the reporter/AUT and is not positioned off screen, leading to potential performance impacts with cy.origin'] = ` - -==================================================================================================== - - (Run Starting) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 1 found (spec_bridge.cy.ts) │ - │ Searched: cypress/e2e/spec_bridge.cy.ts │ - │ Experiments: experimentalSessionAndOrigin=true │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: spec_bridge.cy.ts (1 of 1) - - - ✓ visits foobar.com and types foobar inside an input - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: true │ - │ Duration: X seconds │ - │ Spec Ran: spec_bridge.cy.ts │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - - (Video) - - - Started processing: Compressing to 32 CRF - - Finished processing: /XXX/XXX/XXX/cypress/videos/spec_bridge.cy.ts.mp4 (X second) - - -==================================================================================================== - - (Run Finished) - - - Spec Tests Passing Failing Pending Skipped - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ spec_bridge.cy.ts XX:XX 1 1 - - - │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 1 1 - - - - - -` diff --git a/system-tests/projects/e2e/secondary_origin.html b/system-tests/projects/e2e/secondary_origin.html index 068ec4662065..2668024059d8 100644 --- a/system-tests/projects/e2e/secondary_origin.html +++ b/system-tests/projects/e2e/secondary_origin.html @@ -6,7 +6,6 @@

From a secondary origin

-
diff --git a/system-tests/test/spec_bridge_in_viewport_spec.ts b/system-tests/test/spec_bridge_in_viewport_spec.ts deleted file mode 100644 index a49b8b5ccc86..000000000000 --- a/system-tests/test/spec_bridge_in_viewport_spec.ts +++ /dev/null @@ -1,38 +0,0 @@ -import path from 'path' -import systemTests from '../lib/system-tests' -import Fixtures from '../lib/fixtures' - -const e2ePath = Fixtures.projectPath('e2e') - -const PORT = 3500 -const onServer = function (app) { - app.get('/secondary_origin.html', (_, res) => { - res.sendFile(path.join(e2ePath, `secondary_origin.html`)) - }) -} - -describe('e2e spec bridge in viewport', () => { - systemTests.setup({ - servers: [{ - port: 4466, - onServer, - }], - settings: { - hosts: { - '*.foobar.com': '127.0.0.1', - }, - }, - }) - - systemTests.it('Overlays the reporter/AUT and is not positioned off screen, leading to potential performance impacts with cy.origin', { - // keep the port the same to prevent issues with the snapshot - port: PORT, - spec: 'spec_bridge.cy.ts', - snapshot: true, - browser: 'electron', - expectedExitCode: 0, - config: { - experimentalSessionAndOrigin: true, - }, - }) -}) From e26ae8b733ccf5ca8bab807711c7bfdd5e1511f2 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 13 May 2022 13:27:19 -0400 Subject: [PATCH 08/13] add additional comments to spec bridge iframe scss for caution --- packages/app/src/main.scss | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/app/src/main.scss b/packages/app/src/main.scss index 4ee45e1195f8..708b2a481b64 100644 --- a/packages/app/src/main.scss +++ b/packages/app/src/main.scss @@ -37,6 +37,9 @@ iframe.spec-bridge-iframe { 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; } From 7cf3afe869ff01f7ed79f62bdbd317b6dadc9a35 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 13 May 2022 15:51:33 -0400 Subject: [PATCH 09/13] resolve snapshots directory correctly in open vs run mode --- .../e2e/e2e/origin/commands/screenshot.cy.ts | 34 ++++++++++++++----- packages/driver/cypress/support/defaults.js | 3 ++ 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts index 2284a183aeeb..fc82d7a53841 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts @@ -1,3 +1,5 @@ +import path from 'path' + context('cy.origin screenshot', () => { const { devicePixelRatio } = window @@ -297,7 +299,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `crop-check.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'crop-check.png'), width: 600, height: 400, devicePixelRatio, @@ -314,7 +318,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `fullPage.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage.png'), width: 600, height: 500, devicePixelRatio, @@ -331,7 +337,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `fullPage-same.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage-same.png'), width: 600, height: 500, devicePixelRatio, @@ -348,7 +356,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `element.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'element.png'), width: 400, height: 300, devicePixelRatio, @@ -368,7 +378,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `app-clip.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'app-clip.png'), width: 100, height: 50, devicePixelRatio, @@ -387,7 +399,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `runner-clip.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'runner-clip.png'), width: 120, height: 60, devicePixelRatio, @@ -406,7 +420,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `fullPage-clip.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage-clip.png'), width: 140, height: 70, devicePixelRatio, @@ -425,7 +441,9 @@ context('cy.origin screenshot', () => { }) cy.task('check:screenshot:size', { - name: `element-clip.png`, + // if in run mode, screenshots are grouped under their spec name + // @ts-ignore + name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'element-clip.png'), width: 160, height: 80, devicePixelRatio, diff --git a/packages/driver/cypress/support/defaults.js b/packages/driver/cypress/support/defaults.js index dd5b7b030f6e..8f36469ea64f 100644 --- a/packages/driver/cypress/support/defaults.js +++ b/packages/driver/cypress/support/defaults.js @@ -21,6 +21,9 @@ beforeEach(() => { // necessary or else snapshots will not be taken // and we can't test them Cypress.config('numTestsKeptInMemory', 1) + // isCypressRunMode flag currently used as a substitute to isInteractive + // to test cy.origin snapshots to check snapshot size in correct directory, which changes from open/run mode. + Cypress.config('isCypressRunMode', true) } // remove all event listeners From 2c98438dacb1cb8a13e69a38511a27cbddd4a0f2 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Fri, 13 May 2022 16:39:26 -0400 Subject: [PATCH 10/13] revert this commit to see if assets are being tampered with or just missing in CI --- .../cypress/e2e/e2e/origin/commands/screenshot.cy.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts index fc82d7a53841..56430d0d796b 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts @@ -281,13 +281,13 @@ context('cy.origin screenshot', () => { }) describe('dimensions', () => { - before(() => { - cy.task('trash:screenshot:assets') - }) + // before(() => { + // cy.task('trash:screenshot:assets') + // }) - after(() => { - cy.task('trash:screenshot:assets') - }) + // after(() => { + // cy.task('trash:screenshot:assets') + // }) it('crops app captures to just app size', () => { cy.viewport(600, 400) From 0fe394f81d34216123cade4da521c9d1304850d7 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Mon, 16 May 2022 12:59:36 -0400 Subject: [PATCH 11/13] fix check:screenshot:size to always point to correct screenshot path --- .../e2e/e2e/origin/commands/screenshot.cy.ts | 213 +++++++++++------- packages/driver/cypress/plugins/index.js | 13 +- 2 files changed, 129 insertions(+), 97 deletions(-) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts index 56430d0d796b..ea95f227c78c 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/screenshot.cy.ts @@ -1,5 +1,3 @@ -import path from 'path' - context('cy.origin screenshot', () => { const { devicePixelRatio } = window @@ -281,30 +279,29 @@ context('cy.origin screenshot', () => { }) describe('dimensions', () => { - // before(() => { - // cy.task('trash:screenshot:assets') - // }) - - // after(() => { - // cy.task('trash:screenshot:assets') - // }) - 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') - cy.screenshot('crop-check', { capture: 'viewport' }) - }) + const screenShotPromiseWithPath = new Promise((resolve) => { + cy.screenshot('crop-check', { + capture: 'viewport', + onAfterScreenshot ($el, props) { + resolve(props.path) + }, + }) + }) - cy.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'crop-check.png'), - width: 600, - height: 400, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 600, + height: 400, + devicePixelRatio, + }) }) }) @@ -314,16 +311,23 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page.html') - cy.screenshot('fullPage', { capture: 'fullPage' }) - }) + const screenShotPromiseWithPath = new Promise((resolve) => { + cy.screenshot('fullPage', { + capture: 'fullPage', + onAfterScreenshot ($el, props) { + resolve(props.path) + }, + }) + }) - cy.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage.png'), - width: 600, - height: 500, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 600, + height: 500, + devicePixelRatio, + }) }) }) @@ -333,16 +337,24 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page-same.html') - cy.screenshot('fullPage-same', { capture: 'fullPage' }) - }) - cy.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage-same.png'), - width: 600, - height: 500, - devicePixelRatio, + 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, + }) }) }) @@ -352,16 +364,23 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-element.html') - cy.get('.element').screenshot('element') - }) - cy.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'element.png'), - width: 400, - height: 300, - devicePixelRatio, + 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, + }) }) }) @@ -372,18 +391,23 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-color.html?color=yellow') - cy.screenshot('app-clip', { - capture: 'viewport', clip: { x: 10, y: 10, width: 100, height: 50 }, + 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.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'app-clip.png'), - width: 100, - height: 50, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 100, + height: 50, + devicePixelRatio, + }) }) }) @@ -393,18 +417,24 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-color.html?color=yellow') - cy.screenshot('runner-clip', { - capture: 'runner', clip: { x: 15, y: 15, width: 120, height: 60 }, + + 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.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'runner-clip.png'), - width: 120, - height: 60, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 120, + height: 60, + devicePixelRatio, + }) }) }) @@ -414,18 +444,24 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-full-page.html') - cy.screenshot('fullPage-clip', { - capture: 'fullPage', clip: { x: 20, y: 20, width: 140, height: 70 }, + + 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.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'fullPage-clip.png'), - width: 140, - height: 70, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 140, + height: 70, + devicePixelRatio, + }) }) }) @@ -435,18 +471,23 @@ context('cy.origin screenshot', () => { cy.visit('/') cy.origin('http://foobar.com:3500', () => { cy.visit('http://www.foobar.com:3500/fixtures/screenshot-element.html') - cy.get('.element').screenshot('element-clip', { - clip: { x: 25, y: 25, width: 160, height: 80 }, + 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.task('check:screenshot:size', { - // if in run mode, screenshots are grouped under their spec name - // @ts-ignore - name: path.join(Cypress.config('isCypressRunMode') ? Cypress.spec.name : '', 'element-clip.png'), - width: 160, - height: 80, - devicePixelRatio, + cy.wrap(screenShotPromiseWithPath) + }).then((screenshotPath) => { + cy.task('check:screenshot:size', { + filePath: screenshotPath, + width: 160, + height: 80, + devicePixelRatio, + }) }) }) }) diff --git a/packages/driver/cypress/plugins/index.js b/packages/driver/cypress/plugins/index.js index c766dba708fa..8d89591011d8 100644 --- a/packages/driver/cypress/plugins/index.js +++ b/packages/driver/cypress/plugins/index.js @@ -62,8 +62,8 @@ module.exports = (on, config) => { return null }, - 'check:screenshot:size' ({ name, width, height, devicePixelRatio }) { - return Jimp.read(path.join(__dirname, '..', 'screenshots', name)) + 'check:screenshot:size' ({ filePath, width, height, devicePixelRatio }) { + return Jimp.read(filePath) .then((image) => { width = width * devicePixelRatio height = height * devicePixelRatio @@ -75,15 +75,6 @@ module.exports = (on, config) => { return null }) }, - 'trash:screenshot:assets' () { - const screenshotsPath = path.join(__dirname, '..', 'screenshots') - - if (fs.existsSync(screenshotsPath)) { - fs.rmdirSync(screenshotsPath, { recursive: true, force: true }) - } - - return null - }, }) return config From 739897fd9f18edf7879ed4febb42244aa9ce402c Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Mon, 16 May 2022 13:02:12 -0400 Subject: [PATCH 12/13] remove isCypressRunMode from cypress config as internal flag as we no longer need it --- packages/driver/cypress/support/defaults.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/driver/cypress/support/defaults.js b/packages/driver/cypress/support/defaults.js index 8f36469ea64f..dd5b7b030f6e 100644 --- a/packages/driver/cypress/support/defaults.js +++ b/packages/driver/cypress/support/defaults.js @@ -21,9 +21,6 @@ beforeEach(() => { // necessary or else snapshots will not be taken // and we can't test them Cypress.config('numTestsKeptInMemory', 1) - // isCypressRunMode flag currently used as a substitute to isInteractive - // to test cy.origin snapshots to check snapshot size in correct directory, which changes from open/run mode. - Cypress.config('isCypressRunMode', true) } // remove all event listeners From 1a89e948422ab45721851094bfbfb8a76879d296 Mon Sep 17 00:00:00 2001 From: Bill Glesias Date: Mon, 16 May 2022 13:54:42 -0400 Subject: [PATCH 13/13] add check:screenshot:size to task.cy.js registered plugin assertion --- packages/driver/cypress/e2e/commands/task.cy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/driver/cypress/e2e/commands/task.cy.js b/packages/driver/cypress/e2e/commands/task.cy.js index 3aa42f1fb6b3..85d92bdf69c0 100644 --- a/packages/driver/cypress/e2e/commands/task.cy.js +++ b/packages/driver/cypress/e2e/commands/task.cy.js @@ -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() })