简体   繁体   中英

Intercept calls to HTML5 canvas element

I have a WEB application, that renders it's entire User Interface in an HTML5 canvas. Note that I can't change the current application.

Currently, this application is being tested using Selenium. This is done by simulating a click event at a given location in the browser window. After the click has been executed, a sleep of 2 seconds is being performed to ensure that the entire UI is ready before moving to the next step.

Due to all the 'wait' statements, testing the application is very slow.

Therefore, I thought it was an idea to intercept all calls to the HTML5 canvas. That way I can rely on the triggered events to know if the UI is ready to move to the next step.

Assume that I have the following code in my application that renders the canvas.

var canvas = document.getElementById("canvasElement");
var ctx = canvas.getContext("2d");

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

Is there a way to intercept the 'fillRect' event? I tought something along the lines:

var canvasProxy = document.getElementById("canvasElement");

canvasProxy.addEventListener("getContext", function(event) {
  console.log("Hello");
});

var canvas = document.getElementById("canvasElement");
var ctx = canvas.getContext("2d");

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 100, 100);

Unforuntately this is not working.

I've created a JSFiddle to play with the example. https://jsfiddle.net/5cknym74/4/

Amy toughts?

I played a bit around with the JS API and it seems that the following might be working:

// SECTION: Store a reference to all the HTML5 'canvas' element methods.
HTMLCanvasElement.prototype._captureStream              = HTMLCanvasElement.prototype.captureStream;
HTMLCanvasElement.prototype._getContext                 = HTMLCanvasElement.prototype.getContext;
HTMLCanvasElement.prototype._toDataURL                  = HTMLCanvasElement.prototype.toDataURL;
HTMLCanvasElement.prototype._toBlob                     = HTMLCanvasElement.prototype.toBlob;
HTMLCanvasElement.prototype._transferControlToOffscreen = HTMLCanvasElement.prototype.transferControlToOffscreen;
HTMLCanvasElement.prototype._mozGetAsFile               = HTMLCanvasElement.prototype.mozGetAsFile;

// SECTION: Patch the HTML5 'canvas' element methods.
HTMLCanvasElement.prototype.captureStream = function(frameRate) {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.captureStream');

    return this._captureStream(frameRate);
}

HTMLCanvasElement.prototype.getContext = function(contextType, contextAttributes) {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.getContext');
    console.log('PROPERTIES:');
    console.log('  contextType: ' + contextType);

    return this._getContext(contextType, contextAttributes);
}

HTMLCanvasElement.prototype.toDataURL = function(type, encoderOptions) {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.toDataURL');

    return this._toDataURL(type, encoderOptions);
}

HTMLCanvasElement.prototype.toBlob = function(callback, mimeType, qualityArgument) {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.toBlob');

    return this._toBlob(callback, mimeType, qualityArgument);
}

HTMLCanvasElement.prototype.transferControlToOffscreen = function() {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.transferControlToOffscreen');

    return this._transferControlToOffscreen();
}

HTMLCanvasElement.prototype.mozGetAsFile = function(name, type) {
    console.log('INTERCEPTING: HTMLCanvasElement.prototype.mozGetAsFile');

    return this._mozGetAsFile(name, type);
}

Now that I can intercept the calls, I can find out which calls are responsible that draw a button and react accordingly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM