É possível simular a tela sem ter a implementação real ( canvas
/ canvas-prebuilt
)?
Gostaria de evitar que esse erro aconteça, pois a funcionalidade do canvas não é muito importante para mim:
Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
Caso alguém precise disso, aqui está como resolvi:
const utils = require("jsdom/lib/jsdom/utils");
const canvasMock = require("canvas-mock");
function Canvas () {
canvasMock(this);
this.toDataURL = function() { return ""; }
}
utils.Canvas = Canvas;
Por favor, não faça isso. Ele será interrompido em uma versão de patch futura. Em vez disso, substitua o método getContext (), ou seja, window.HTMLCanvasElement.prototype.getContext = ...
Obrigado @domenic !
@domenic Não consigo fazer isso funcionar. Meu método substituído não é chamado. Eu uso o arquivo jest e o arquivo de script de configuração da seguinte maneira:
import { jsdom } from 'jsdom';
import mockLocalStorage from './mockLocalStorage';
import jQuery from 'jquery';
import Backbone from 'backbone';
import moment from 'moment';
const dom = jsdom('<!doctype html><html><body></body></html>');
const { window } = dom.defaultView;
function copyProps(src, target) {
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
}
//Mock canvas (used by qtip)
window.HTMLCanvasElement.prototype.getContext = () => {
return {};
};
global.window = window;
global.document = window.document;
global.navigator = {
userAgent: 'node.js',
};
global.localStorage = mockLocalStorage;
global.jQuery = jQuery;
global.$ = jQuery;
global.fetch = () => Promise.resolve();
Backbone.$ = jQuery;
copyProps(window, global);
//Mock Mousetrap (only works in browser)
jest.mock('mousetrap', () => { return { bind: () => {}}});
//Set moment locale for all tests
moment.locale('sv');
Desculpe por poluir globalmente no nó, mas esta é uma base de código muito antiga e grande que tento migrar para o Jest.
Versão Jest: 21.2.1
Versão Jsdom: 9.12.0
Seria muito bom se o mocking do canvas (sem usar o pacote canvas, já que não é suportado no Windows) fosse coberto pela documentação oficial e não apenas como um comentário em um problema.
sem usar o pacote canvas, pois não é compatível com Windows
Por que a pré-configuração da tela não é uma opção para você? É isso que estamos usando em nosso projeto sem nenhum problema (Win, Mac e Linux, embora tudo tenha que ser x64).
Em geral, não planejamos adicionar documentos ou ajudar com problemas únicos de simulação. Abordamos isso em https://github.com/tmpvar/jsdom#intervening -before-parsing em geral e qualquer problema específico estará relacionado à sua base de código específica.
Esta é uma maneira simples de simular uma tela que eu criei:
//
// Mock Canvas / Context2D calls
//
function mockCanvas (window) {
window.HTMLCanvasElement.prototype.getContext = function () {
return {
fillRect: function() {},
clearRect: function(){},
getImageData: function(x, y, w, h) {
return {
data: new Array(w*h*4)
};
},
putImageData: function() {},
createImageData: function(){ return []},
setTransform: function(){},
drawImage: function(){},
save: function(){},
fillText: function(){},
restore: function(){},
beginPath: function(){},
moveTo: function(){},
lineTo: function(){},
closePath: function(){},
stroke: function(){},
translate: function(){},
scale: function(){},
rotate: function(){},
arc: function(){},
fill: function(){},
measureText: function(){
return { width: 0 };
},
transform: function(){},
rect: function(){},
clip: function(){},
};
}
window.HTMLCanvasElement.prototype.toDataURL = function () {
return "";
}
}
const document = jsdom.jsdom(undefined, {
virtualConsole: jsdom.createVirtualConsole().sendTo(console)
});
const window = document.defaultView;
mockCanvas(window);
Muito obrigado! O pacote pré-construído do canvas parece estar funcionando.
Olá @cattermo ,
Eu adicionei canvas pré-construídas aos meus deps, preciso alterar minha configuração de jest? Eu não consigo fazer funcionar, isso me dá
Not implemented: HTMLCanvasElement.prototype.toBlob (without installing the canvas npm package)
@micabe
Não fiz nenhuma alteração na configuração. Jsdom pegará a tela pré-construída se estiver presente em node_modules.
Talvez essa função específica não seja compatível?
Agora está funcionando depois de yarn cache clean
Desculpe incomodá-lo! obrigado @cattermo
Talvez jest-canvas-mock possa ajudar.
A solução é simples, basta instalar canvas
como um devDependency e executar novamente seus testes de jest.
ref: https://github.com/jsdom/jsdom#canvas -support
Isso ainda não está funcionando devido à maneira como o jsdom verifica os módulos do canvas em lib / jsdom / utils.js:
exports.Canvas = require(moduleName);
if (typeof exports.Canvas !== "function") {
// In browserify, the require will succeed but return an empty object
exports.Canvas = null;
}
Fazer require ('canvas') retorna um objeto que tem a função Canvas. Ele não retorna a função Canvas imediatamente. Ou estou errado neste assunto? Funcionou bem quando eu estava usando o módulo canvas pré-construído, mas parece que o módulo canvas tem uma API diferente. Estou usando a versão mais recente do canvas, 2.0.1.
Editar
Testei a versão principal anterior (1.6.x) e funciona bem, é uma alteração da API que o JSDOM não está tratando.
Você pode apenas fazer:
HTMLCanvasElement.prototype.getContext = jest.fn()
se a implementação real não for importante para você
Isso ainda não está funcionando devido à maneira como o jsdom verifica os módulos do canvas em lib / jsdom / utils.js:
exports.Canvas = require(moduleName); if (typeof exports.Canvas !== "function") { // In browserify, the require will succeed but return an empty object exports.Canvas = null; }
Fazer require ('canvas') retorna um objeto que tem a função Canvas. Ele não retorna a função Canvas imediatamente. Ou estou errado neste assunto? Funcionou bem quando eu estava usando o módulo canvas pré-construído, mas parece que o módulo canvas tem uma API diferente. Estou usando a versão mais recente do canvas, 2.0.1.
Editar
Testei a versão principal anterior (1.6.x) e funciona bem, é uma alteração da API que o JSDOM não está tratando.
Eu tenho o mesmo problema. Parece que o problema não é com jsdom, pois a correção foi mesclada um tempo atrás em https://github.com/jsdom/jsdom/pull/1964 e está disponível desde a versão 13
.
No entanto, a versão jsdom
em jest-environment-jsdom
ainda está presa em ^11.5.1
e acredito que isso esteja causando o problema:
https://github.com/facebook/jest/blob/2e2d2c8dedb76e71c0dfa85ed36b81d1f89e0d87/packages/jest-environment-jsdom/package.json#L14
Sem instalar o canvas , ou canvas pré-construídas foram capazes de se livrar dos erros relacionados ao HTMLCanvasElement, bem como quaisquer outros métodos de canvas bem propostos por @endel como um hack para contornar este problema. Como @hustcc propôs, usou jest-canvas-mock para encontrar uma solução bastante limpa. Para detalhes técnicos, dê uma olhada neste comentário .
Eu estava vendo mensagens como "Cannot read webkitBackingStorePixelRatio of null", bem como "
Não implementado: HTMLCanvasElement.prototype.getContext (sem instalar o pacote npm do canvas) ", e instalar o canvas (-prebuilt) não foi suficiente. Entrei no package-lock.json, consertei o jest-environment-jsdom para apontar para jsdom 13 , jogou fora node_modules e reran npm install. As mensagens de erro foram embora. Acho que @paradite está certo e abriu um tíquete contra jest:
Tenho feedback. Está relacionado ao fato de o gracejo ficar preso a versões de nós mais antigas. Se precisar de suporte para o nó mais recente, veja aqui: https://www.npmjs.com/package/jest-environment-jsdom-thirteen. No entanto, isso é específico para uma brincadeira, então talvez um pouco fora do assunto aqui. Compartilhando de qualquer maneira para a posteridade ..
@grtjn - verifiquei a dependência jest-environment-jsdom-treze , mas no meu caso ainda
Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
TypeError: Cannot read property 'fillRect' of null
Mantendo minha solução mencionada anteriormente, sobre a versão do Node eu não diria que a 10.15 está obsoleta, pois tenho os problemas para tal ambiente
Angular CLI: 7.2.4
Node: 10.15.0
OS: win32 x64
Angular: 7.2.4
Para sua informação: Tive que acrescentar "testEnvironment": "jest-environment-jsdom-thirteen"
à minha configuração de brincadeira e instalar o pacote canvas, bem como o conjunto de ferramentas do Cairo OS. canvas pré-construídas não parecem funcionar para mim. Estou usando o Vue.
Link para a dependência do conjunto de ferramentas do Cairo OS? Não foi possível encontrar esse.
@danieldanielecki Veja a página principal do pacote 'canvas': https://www.npmjs.com/package/canvas#compiling
@grtjn obrigado por isso - talvez em algum momento tire vantagem disso. Eu estava sentindo falta, mas parece mais complicado do que a minha solução, então mantendo o projeto como está.
Desculpe por necropost, mas a sugestão @grtjn de instalar jest-environment-jsdom-treze (usei quatorze apenas porque é mais recente) corrigiu meu problema. Eu tentei usar jest-canvas-mock, mas fizemos algumas coisas estranhas onde fingimos criarImageBitmap usando node-canvas quando OffscreenCanvas não está disponível, o que não está em muitos navegadores, e jest-canvas-mock ficou muito confuso com isso. Talvez outro dia vamos fazer isso funcionar ... é uma biblioteca simulada legal.
Comentários muito úteis
Esta é uma maneira simples de simular uma tela que eu criei: