Jsdom: Nachgeahmte Leinwand

Erstellt am 22. MĂ€rz 2017  Â·  25Kommentare  Â·  Quelle: jsdom/jsdom

Ist es möglich, Canvas zu simulieren, ohne die tatsÀchliche Implementierung zu haben ( canvas / canvas-prebuilt )?

Ich möchte diesen Fehler verhindern, da die Canvas-FunktionalitĂ€t fĂŒr mich nicht wirklich wichtig ist:

Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)

Hilfreichster Kommentar

Hier ist eine einfache Möglichkeit, eine Leinwand zu simulieren, die ich mir ausgedacht habe:

//
// 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);

Alle 25 Kommentare

Falls das jemand braucht, so habe ich es gelöst:

const utils = require("jsdom/lib/jsdom/utils");
const canvasMock = require("canvas-mock");

function Canvas () {
    canvasMock(this);
    this.toDataURL = function() { return ""; }
}
utils.Canvas = Canvas;

Bitte tu das nicht. Es wird in einer zukĂŒnftigen Patch-Version kaputt gehen. Überschreiben Sie stattdessen die Methode getContext(), dh window.HTMLCanvasElement.prototype.getContext = ...

Danke @domenic !

@domenic Ich kann das nicht zum

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');

Entschuldigung fĂŒr die Verschmutzung von global in node, aber dies ist eine sehr alte und große Codebasis, die ich versuche, auf Jest zu migrieren.
Scherzversion: 21.2.1
Jsdom-Version: 9.12.0

WĂ€re sehr schön, wenn das Verspotten von Canvas (ohne das Canvas-Paket zu verwenden, da es in Windows nicht unterstĂŒtzt wird) in offiziellen Dokumenten behandelt wĂŒrde und nicht nur als Kommentar in einem Problem.

ohne Canvas-Paket zu verwenden, da in Windows nicht unterstĂŒtzt

Warum ist Canvas-Prebuild keine Option fĂŒr Sie? Das verwenden wir in unserem Projekt ohne Probleme (Win, Mac und Linux, obwohl alles x64 sein muss).

Im Allgemeinen planen wir nicht, Dokumente hinzuzufĂŒgen oder bei einmaligen Spottproblemen zu helfen. Wir haben dies in https://github.com/tmpvar/jsdom#intervening -before-parsing im Allgemeinen behandelt und alle spezifischen Probleme werden mit Ihrer spezifischen Codebasis zusammenhĂ€ngen.

Hier ist eine einfache Möglichkeit, eine Leinwand zu simulieren, die ich mir ausgedacht habe:

//
// 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);

Danke vielmals! Das vorgefertigte Canvas-Paket scheint zu funktionieren.

Hallo @cattermo ,
Ich habe Canvas-Prebuilt zu meinen Deps hinzugefĂŒgt, muss ich meine Jest-Konfiguration Ă€ndern? Ich kann es nicht schaffen, es gibt mir
Not implemented: HTMLCanvasElement.prototype.toBlob (without installing the canvas npm package)

@micabe
Ich habe keine KonfigurationsÀnderungen vorgenommen. Jsdom greift vorgefertigte Canvas auf, wenn sie in node_modules vorhanden ist.

Vielleicht wird diese spezielle Funktion nicht unterstĂŒtzt?

Es funktioniert jetzt nach yarn cache clean Entschuldigung fĂŒr die Störung! danke @cattermo

Vielleicht kann Scherz-Leinwand-Mock helfen.

Die Lösung ist einfach, installieren Sie einfach canvas als devDependency und fĂŒhren Sie Ihre Scherztests erneut aus.

Referenz: https://github.com/jsdom/jsdom#canvas -support

Das funktioniert immer noch nicht, weil jsdom unter lib/jsdom/utils.js nach den Canvas-Modulen sucht:

  exports.Canvas = require(moduleName);
  if (typeof exports.Canvas !== "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = null;
  }

Das AusfĂŒhren von require('canvas') gibt ein Objekt zurĂŒck, das die Canvas-Funktion hat. Es gibt die Canvas-Funktion nicht sofort zurĂŒck. Oder liege ich in dieser Frage falsch? Es hat gut funktioniert, als ich das vorgefertigte Canvas-Modul verwendet habe, aber es scheint, dass das Canvas-Modul eine andere API hat. Ich verwende die neueste Version von Canvas, 2.0.1.
Bearbeiten
Ich habe die vorherige Hauptversion (1.6.x) getestet und sie funktioniert einwandfrei, es handelt sich um eine API-Änderung, die JSDOM nicht behandelt.

Sie können einfach tun:

HTMLCanvasElement.prototype.getContext = jest.fn()

wenn die tatsĂ€chliche Umsetzung fĂŒr Sie nicht wichtig ist

Das funktioniert immer noch nicht, weil jsdom unter lib/jsdom/utils.js nach den Canvas-Modulen sucht:

  exports.Canvas = require(moduleName);
  if (typeof exports.Canvas !== "function") {
    // In browserify, the require will succeed but return an empty object
    exports.Canvas = null;
  }

Das AusfĂŒhren von require('canvas') gibt ein Objekt zurĂŒck, das die Canvas-Funktion hat. Es gibt die Canvas-Funktion nicht sofort zurĂŒck. Oder liege ich in dieser Frage falsch? Es hat gut funktioniert, als ich das vorgefertigte Canvas-Modul verwendet habe, aber es scheint, dass das Canvas-Modul eine andere API hat. Ich verwende die neueste Version von Canvas, 2.0.1.
Bearbeiten
Ich habe die vorherige Hauptversion (1.6.x) getestet und sie funktioniert einwandfrei, es handelt sich um eine API-Änderung, die JSDOM nicht behandelt.

Ich habe das gleiche Problem. Sieht so aus, als ob das Problem nicht bei jsdom liegt, da der Fix vor einiger Zeit in https://github.com/jsdom/jsdom/pull/1964 zusammengefĂŒhrt wurde und seit Version 13 verfĂŒgbar ist.
Die jsdom Version in jest-environment-jsdom hÀngt jedoch immer noch bei ^11.5.1 und ich glaube, dass dies das Problem verursacht:
https://github.com/facebook/jest/blob/2e2d2c8dedb76e71c0dfa85ed36b81d1f89e0d87/packages/jest-environment-jsdom/package.json#L14

Ohne die Installation von canvas oder canvas-prebuilt konnten Fehler im Zusammenhang mit HTMLCanvasElement sowie alle anderen von @endel als Hack vorgeschlagenen Canvas-Methoden umgehen . Wie von @hustcc vorgeschlagen, habe jest-canvas-mock verwendet, um eine ziemlich saubere Lösung zu finden. FĂŒr technische Details werfen Sie bitte einen Blick auf diesen Kommentar .

Ich habe Meldungen wie "WebkitBackingStorePixelRatio von null kann nicht gelesen werden" sowie "
Nicht implementiert: HTMLCanvasElement.prototype.getContext (ohne das canvas npm-Paket zu installieren)" und die Installation von canvas(-prebuilt) war nicht genug. Ich ging in package-lock.json, reparierte das jest-environment-jsdom so, dass es auf jsdom 13 zeigt , warf node_modules weg und fĂŒhrte npm install erneut aus. Die Fehlermeldungen gingen. Ich denke, @paradite hat Recht und öffnete ein Ticket gegen Scherz:

https://github.com/facebook/jest/issues/8016

Feedback bekommen. Es hĂ€ngt damit zusammen, dass Witze mit Ă€lteren Knotenversionen hĂ€ngen bleiben. Wenn Sie UnterstĂŒtzung fĂŒr den neuesten Knoten benötigen, schauen Sie hier: https://www.npmjs.com/package/jest-environment-jsdom-thirteen. Dies ist jedoch nur ein Scherz, also vielleicht ein wenig vom Thema hier ab. Teilen trotzdem fĂŒr die Nachwelt..

@grtjn - habe die AbhĂ€ngigkeit von jest-environment-jsdom-thirteen ĂŒberprĂŒft, aber in meinem Fall habe ich immer noch diese 2 genau die gleichen Fehler erhalten

Error: Not implemented: HTMLCanvasElement.prototype.getContext (without installing the canvas npm package)
TypeError: Cannot read property 'fillRect' of null

Wenn ich meine zuvor erwĂ€hnte Lösung behalte, wĂŒrde ich bezĂŒglich der Node-Version nicht sagen, dass 10.15 eine veraltete ist, da ich die Probleme fĂŒr eine solche Umgebung habe

Angular CLI: 7.2.4
Node: 10.15.0
OS: win32 x64
Angular: 7.2.4

Zu Ihrer Information: Ich musste "testEnvironment": "jest-environment-jsdom-thirteen" an meine jest-Konfiguration anhÀngen und das Canvas-Paket sowie das Cairo OS-Toolset installieren. Canvas-Prebuilt schien bei mir nicht zu funktionieren. Ich benutze Vue.

Link zur AbhÀngigkeit vom Kairo OS-Toolset? Konnte das nicht finden.

@danieldanielecki Siehe Hauptseite des ' https://www.npmjs.com/package/canvas#compiling

@grtjn danke dafĂŒr - vielleicht nutzt man es irgendwann aus. Ich habe es vermisst, sieht aber komplizierter aus als meine Lösung, sodass das Projekt so bleibt, wie es ist.

Entschuldigung fĂŒr den Necropost, aber der Vorschlag von @grtjn , jest-environment-jsdom-thirteen zu installieren (ich habe vierzehn verwendet, da es neuer ist), hat mein Problem behoben. Ich habe versucht, jest-canvas-mock zu verwenden, aber wir haben einige seltsame Dinge gemacht, bei denen wir createImageBitmap mit Node-Canvas vortĂ€uschen, wenn OffscreenCanvas nicht verfĂŒgbar ist, was in vielen Browsern nicht der Fall ist, und jest-canvas-mock wurde dadurch ziemlich verwirrt. Vielleicht bringen wir das an einem anderen Tag zum Laufen ... es ist eine coole Scheinbibliothek.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen