简体   繁体   中英

Protractor: Wait for image to load on Canvas

In Protractor, I need to open a non-angular page that has a canvas, which will be populated with an image. I then need to manipulate the image and do a screenshot comparison. However, my problem is getting the tests to wait for the image to load. If I use the Expected Conditions to wait for element ie

browser.wait(expectedConditions.visibilityOf(element(by.tagName('canvas'), 20000);

browser.wait(expectedConditions.presenceOf(element(by.tagName('canvas'), 20000);

to be present or visible, the canvas element is present and visible, but the image is still loading into it, so the screenshot comparison fails as the image is usually half loaded when it happens. I can ensure the image is fully loaded by inserting lots of browser.sleep(20000) statements in my code, but that's just horrible.

Does anyone know of a way to make protractor wait until the image has finished loading before continuing? Or at least a slightly nicer way of doing this?

Thanks

You can solve it by having a custom Expected Condition . I think you can use the getImageData() method of a canvas and wait for it to be truthy (not tested):

function waitForCanvasToLoad(elm) {
    return function () {
        return browser.executeScript("!!arguments[0].getImageData();", elm.getWebElement());
    }
}

var canvas = element(by.tagName('canvas'));
browser.wait(waitForCanvasToLoad(elm), 5000);

You could wait for the encoded canvas to be just under the expected length:

var canvas = element(by.tagName('canvas'));
browser.wait(EC.presenceOf(canvas), 6000);

// wait for the encoded length to be over 2500 (must be adjusted depending on the canvas)
browser.wait(() => browser.executeScript(
  (e) => e.toDataURL().length > 2500
  , canvas.getWebElement()), 6000);

You could also wait for the last pixel to be set if the color is not black:

var canvas = element(by.tagName('canvas'));
browser.wait(EC.presenceOf(canvas), 6000);

// wait for the last pixel to be set (not black)
browser.wait(() => browser.executeScript(
  (e) => [].some.call(e.getContext('2d').getImageData(e.width, e.height, 1, 1), Math.abs)
  , canvas.getWebElement()), 6000);

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