Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test canvas drawings with Protractor

Is there a way to test if a drawing was made on a canvas using Protractor?

i.e. I draw a rectangle based on user clicks:

var shape = new createjs.Shape();
shape.graphics.beginStroke("black");
shape.graphics.drawRect(crd.x, crd.y, crd.width, crd.height);
stage.addChild(shape)
stage.update()

Now I want to make a spec to test if a rectangle was drawn on the specified coordinates and, as a plus, to test if its borders are of color black.

Is this possible using Protractor/WebDriverJS API?

like image 854
Tomas Romero Avatar asked May 25 '14 04:05

Tomas Romero


2 Answers

The way that we test our canvas in protractor is as follows:

We set up a "well known" base64 image string that represents what we want our canvas to be after we draw on it. Then we use browser.executeScript to get the dataUrl of the canvas. We then compare string to string and that tells us if the drawing was correct or not.

var base64ImageString = "data:image/png;base64,iVBORw0KGgoAA...snipped for brevity";

describe("The Canvas", function () {
    browser.get('/#'));

       /* 
       .
       do your drawing
       .
        */

    it("should contain the right drawings", function(){
        browser.executeScript("return document.getElementsByTagName('canvas')[0].toDataURL()").then(function (result) {
            expect(result).toBe(base64ImageString);
        });
    });
});

Works like a champ for us. We're experimenting with getting the Uint8ClampedArray to see if it's any easier - but so far this method is great except for a subtle gotcha.

In our experience, the image string that we get back from the toDataUrl method only represents the visible area of the canvas - not the entire canvas. It's good enough for us - but your mileage may vary. It's also why we're experimenting with thy byte array because it allows you to specify a specific X x Y area of the canvas.

like image 111
Scott Davis Avatar answered Sep 22 '22 22:09

Scott Davis


This might be possible but you would have to create a dummy canvas with the desired output. you could compare the Imagedata from the dummyCanvas to the imagedata from the browser objects canvas. It should look something along the lines of:

      describe('Canvas Test', function() {
      it('should have a title', function() {
        browser.get('http://whenthetestShouldrun.com');
        var dummyCanvas= document.createElement('canvas');
        //some code to edit the canvas to what you want
        expect(browser.By.id('canvas').getImageData(imageX, imageY, imageWidth, imageHeight)).toEqual(dummyCanvas.getImageData(imageX, imageY, imageWidth, imageHeight));
      });
    });
like image 2
McLoving Avatar answered Sep 22 '22 22:09

McLoving