Reputation: 325
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
Upvotes: 4
Views: 1454
Reputation: 42518
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);
Upvotes: 0
Reputation: 473833
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);
Upvotes: 1