Protractor:等待画布上的图片加载完成

4
在Protractor中,我需要打开一个非Angular页面,其中包含一个画布,该画布将被填充图像。然后我需要操作该图像并进行屏幕截图比较。但是我的问题是如何让测试等待图像加载完成。如果使用Expected Conditions来等待元素,则无法正常工作。
browser.wait(expectedConditions.visibilityOf(element(by.tagName('canvas'), 20000);

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

为了展现或显示,canvas元素已经出现和可见,但是图像仍在加载中,因此当它发生时,截图比较失败,因为图像通常只有一半被加载。我可以通过在代码中插入大量的browser.sleep(20000)语句来确保图像完全加载,但这太糟糕了。
有人知道一种方法可以使protractor等待图像完成加载才继续吗?或者至少有一种稍微好一点的方法吗?
谢谢

尝试监听你正在加载的画布图像(onload),而不是画布元素本身... [HTML5 Canvas Image Tutorial](http://www.html5canvastutorials.com/tutorials/html5-canvas-images/) - DIEGO CARRASCAL
好的,那听起来不错,但是教程并没有真正帮助我从protractor中连接到画布图像,我该怎么做呢?似乎没有找到任何抓取它的方法? - user3075259
你可以尝试比较直到变量 c=document.getElementById("myCanvas"); c.toDataURL(); 返回相同的2或3次,这只是一个想法,可能是一种解决方法,或者更好地为您提供思路...我现在还没有确定的答案。 - DIEGO CARRASCAL
所以,只是为了澄清一下,因为我对JavaScript和Protractor还很陌生。所以我会像下面这样通过browser.executeScript将它们传递给浏览器,并且我认为我可以在此过程中传递一个冗长的脚本?我会试试看的。谢谢。 - user3075259
2个回答

1
你可以通过使用自定义的预期条件来解决它。我认为你可以使用画布的getImageData()方法并等待其变为真(未经测试):
function waitForCanvasToLoad(elm) {
    return function () {
        return browser.executeScript("!!arguments[0].getImageData();", elm.getWebElement());
    }
}

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

很酷,看起来可能会起作用,但它给了我一个内存不足的错误,我会在谷歌上搜索一下,但如果你有任何建议,将不胜感激,谢谢。 - user3075259
@user3075259 我已经对代码进行了修复(忘记调用 getWebElement()),看看是否有帮助。此外,可以尝试在画布元素上调用不同的方法 - 例如,尝试使用 data 而不是 getImageData() - alecxe
那个效果更好,我现在没有看到任何内存问题,但它也没有返回任何东西,只是超时了。我已经尝试返回几乎所有可以返回的东西了。 - user3075259
@user3075259 好的,谢谢。你确定你正在定位正确的“canvas”元素吗? - alecxe
是的,肯定获取了正确的画布元素。它似乎工作正常,但只是超时了,即使图像已经完全加载完成。当我逐步执行它时,它总是返回null(我已经添加了一个then到executeScript函数来解决promise)。 - user3075259

0

你可以等待编码后的画布长度略低于预期长度:

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

如果颜色不是黑色,您也可以等待最后一个像素被设置:

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

谢谢,那看起来差不多能行,但最后却没成功,真是令人烦恼。画布在完成绘制之前就获取了完整的数据URL。看来我只能使用browser.sleep了。 - user3075259
在测试环境中,我会计算画布的哈希码,并等待返回预期的哈希码或直到超时。 - Florent B.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接