test: percy snapshot workaround (#1111)

* Try workaround for percy snapshot

* Return our modified document

* test: some dark magic to make it possible to take screenshots of WebGL canvases

* Apply transformation directly to test DOM

* investigate: window:before:load

* Register flag in correct place; add experimental-webgl check

* Remaining canvas fixes

* Remove comment
This commit is contained in:
Danny Brown 2019-10-28 12:43:37 -04:00 committed by GitHub
parent f0519920fa
commit 70532a6cc6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 81 additions and 31 deletions

View File

@ -21,7 +21,6 @@ describe('OHIF Microscopy Extension', () => {
.should('be.eq', 1);
cy.wait(3000); //Waiting for image to render before taking the snapshot
cy.screenshot();
cy.percyCanvasSnapshot('Microscopy Extension');
});
});

View File

@ -20,7 +20,8 @@ describe('OHIF PDF Extension', () => {
.its('length')
.should('be.eq', 1);
cy.screenshot();
// This won't work unless we switch to an extension that renders using `canvas`
// Currently, we rely on the browser's built-in implementation
cy.percyCanvasSnapshot('PDF Extension');
});
});

View File

@ -22,14 +22,20 @@ describe('OHIF VTK Extension', () => {
btn.click();
}
});
//wait VTK toolbar and images to be loaded
cy.wait(3000);
cy.initVTKToolsAliases();
});
it('checks if VTK buttons are displayed on the toolbar', () => {
cy.screenshot();
cy.percyCanvasSnapshot('VTK Extension');
// Wait for start reformatting
cy.get('[data-cy="viewprt-grid"]', { timeout: 10000 }).should($grid => {
expect($grid).to.contain.text('Reform');
});
// Wait for finish reformatting
cy.get('[data-cy="viewprt-grid"]', { timeout: 30000 }).should($grid => {
expect($grid).not.to.contain.text('Reform');
});
cy.get('@crosshairsBtn')
.should('be.visible')
@ -50,5 +56,8 @@ describe('OHIF VTK Extension', () => {
cy.get('@layoutBtn')
.should('be.visible')
.contains('Layout');
cy.wait(3000);
cy.percyCanvasSnapshot('VTK Extension');
});
});

View File

@ -314,28 +314,53 @@ Cypress.Commands.add('isInViewport', element => {
*
*/
Cypress.Commands.add('percyCanvasSnapshot', (name, options = {}) => {
function convertCanvas(documentClone) {
documentClone
.querySelectorAll('canvas')
.forEach(selector => canvasToImage(selector));
cy.document().then(doc => {
convertCanvas(doc);
});
return documentClone;
}
// `domTransformation` does not appear to be working
// But modifying our immediate DOM does.
cy.percySnapshot(name, { ...options }); //, domTransformation: convertCanvas });
function canvasToImage(selectorOrEl) {
let canvas =
typeof selectorOrEl === 'object'
? selectorOrEl
: document.querySelector(selectorOrEl);
let image = document.createElement('img');
let canvasImageBase64 = canvas.toDataURL();
image.src = canvasImageBase64;
image.style = 'max-width: 100%';
canvas.setAttribute('data-percy-modified', true);
canvas.parentElement.appendChild(image);
canvas.style = 'display: none';
}
cy.percySnapshot(name, { ...options, domTransformation: convertCanvas });
cy.document().then(doc => {
unconvertCanvas(doc);
});
});
function convertCanvas(documentClone) {
documentClone
.querySelectorAll('canvas')
.forEach(selector => canvasToImage(selector));
return documentClone;
}
function unconvertCanvas(documentClone) {
// Remove previously generated images
documentClone
.querySelectorAll('[data-percy-image]')
.forEach(selector => selector.remove());
// Restore canvas visibility
documentClone.querySelectorAll('[data-percy-canvas]').forEach(selector => {
selector.removeAttribute('data-percy-canvas');
selector.style = '';
});
}
function canvasToImage(selectorOrEl) {
let canvas =
typeof selectorOrEl === 'object'
? selectorOrEl
: document.querySelector(selectorOrEl);
let image = document.createElement('img');
let canvasImageBase64 = canvas.toDataURL('image/png');
// Show Image
image.src = canvasImageBase64;
image.style = 'width: 100%';
image.setAttribute('data-percy-image', true);
// Hide Canvas
canvas.setAttribute('data-percy-canvas', true);
canvas.parentElement.appendChild(image);
canvas.style = 'display: none';
}

View File

@ -13,8 +13,23 @@
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands';
// Alternatively you can use CommonJS syntax:
// require('./commands')
Cypress.on('window:before:load', window => {
// Override our `getContext` function so all contexts that are webGl are
// Created with `preserveDrawingBuffer = true`; this is required for percy
// Snapshot
window.HTMLCanvasElement.prototype.getContext = (function(oldGetContextFn) {
return function(type, attrs) {
attrs = attrs || {};
if (
type === 'webgl' ||
type === 'webgl2' ||
type === 'experimental-webgl'
) {
attrs.preserveDrawingBuffer = true;
}
return oldGetContextFn.apply(this, [type, attrs]);
};
})(HTMLCanvasElement.prototype.getContext);
});

View File

@ -91,6 +91,7 @@ const ViewportGrid = function(props) {
return (
<div
data-cy="viewprt-grid"
style={{
display: 'grid',
gridTemplateRows: `repeat(${numRows}, ${rowSize}%)`,