My test needs to interact with the image loaded in canvas.
But I have no idea how to implement the wait of loading the image. If I expect only canvas tests are beginning to interact with it, while the image is still loaded.
I have to use driver.sleep(), but this is a bad and unreliable solution. There are a part of page code with canvas:
<canvas class='ol-unselectable' width='816' height='400' style='width: 100%; height: 100%;'></canvas>
Also, the application is written in Angular.
The Network tab in the developer console in the browser shows that at the time of loading images is Img request.
I think, it is possible to write some code to check the load the image into canvas in the browser and use it via js executor.
But I have not idea how do it. Help me please.
UPD. I try build custom waiting condition:
exports.isAllImageLoad = function isAllImageLoad(driver) {
return new Condition('image loading', function(driver) {
return driver.executeScript(
'var img = new Image();' +
'img.onload = function() { return true; };' +
'img.onload()'
).then(function(result) {
console.log('image loading: ' + result);
return result;
});
});
};
and use it with:
return driver.wait(isAllImageLoad(driver), waitTimeOut);
But console show me thah result of img.onload()
is null
.
UPD.i try use this code:
exports.isAllImageLoad = function isAllImageLoad(driver) {
return new Condition('image loading', function(driver) {
return driver.executeScript(
'var image = new Image();' +
'function mainLoop(){' +
'if(imageplete){' +
'return true;' +
'}else{' +
'return false;' +
'}' +
'}' +
'mainLoop();'
).then(function(result) {
console.log('image loading: ' + result);
return result;
});
});
};
But the same returns null
.
My test needs to interact with the image loaded in canvas.
But I have no idea how to implement the wait of loading the image. If I expect only canvas tests are beginning to interact with it, while the image is still loaded.
I have to use driver.sleep(), but this is a bad and unreliable solution. There are a part of page code with canvas:
<canvas class='ol-unselectable' width='816' height='400' style='width: 100%; height: 100%;'></canvas>
Also, the application is written in Angular.
The Network tab in the developer console in the browser shows that at the time of loading images is Img request.
I think, it is possible to write some code to check the load the image into canvas in the browser and use it via js executor.
But I have not idea how do it. Help me please.
UPD. I try build custom waiting condition:
exports.isAllImageLoad = function isAllImageLoad(driver) {
return new Condition('image loading', function(driver) {
return driver.executeScript(
'var img = new Image();' +
'img.onload = function() { return true; };' +
'img.onload()'
).then(function(result) {
console.log('image loading: ' + result);
return result;
});
});
};
and use it with:
return driver.wait(isAllImageLoad(driver), waitTimeOut);
But console show me thah result of img.onload()
is null
.
UPD.i try use this code:
exports.isAllImageLoad = function isAllImageLoad(driver) {
return new Condition('image loading', function(driver) {
return driver.executeScript(
'var image = new Image();' +
'function mainLoop(){' +
'if(image.plete){' +
'return true;' +
'}else{' +
'return false;' +
'}' +
'}' +
'mainLoop();'
).then(function(result) {
console.log('image loading: ' + result);
return result;
});
});
};
But the same returns null
.
- Thanks for the replies. All solutions propose to use the image url, but the fact is that the images load is different, depending on the previous actions of the user. – Valentina Commented Mar 1, 2017 at 2:55
-
I try build custom waiting condition:
exports.isAllImageLoad = function isAllImageLoad(driver) { return new Condition('image loading', function(driver) { return driver.executeScript( 'var img = new Image();' + 'img.onload = function() { return true; };' + 'img.onload()' ).then(function(result) { console.log('image loading: ' + result); return result; }); }); };
and use it with:return driver.wait(isAllImageLoad(driver), waitTimeOut);
But console show me thah result isnull
. – Valentina Commented Mar 1, 2017 at 2:57
2 Answers
Reset to default 1The is an alternative approch to waiting for the onload.
When the DOM has done all it can with the image and it has loaded, or the image has failed to load it sets the semaphore image.plete
to true.
You can use that semaphore to determine whether or not it is safe to render the image.
var image = new Image();
image.src = "imageURI";
function mainLoop(){
if(image.plete){
ctx.drawImage(image,0,0,100,100);
}else{
ctx.fillRect(0,0,100,100); // image placeholder
}
requestAnimationFrame(mainLoop);
}
mainLoop();
This allows you to continue rendering while images are loading.
Though you can not tell directly if the image has loaded or there is an error.
An alternative is to attach your own semaphore.
var image = new Image();
image.src = "imageURI";
image.onload = function(){this.ready=true}
And use the ready semaphore to indicate that the image is ready to render.
You can place all your code inside the image
onload event that you wanna process after the image has been successfully loaded.
DEMO (drawing an image on canvas after its been loaded successfully)
var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'black';
ctx.font="50px Arial";
ctx.fillText('Loading...', 300, 200);
var image = new Image();
image.src = 'https://s-media-cache-ak0.pinimg./originals/e9/dc/10/e9dc10141d0b4e5c9e360cc5669e65ed.jpg';
image.onload = function() {
ctx.clearRect(0, 0, 816, 480)
ctx.drawImage(image, 0, 0);
}
#canvas {
background-color: lightgrey;
}
<canvas id="canvas" class="ol-unselectable" width="816" height="400" style="width: 100%; height: 100%;"></canvas>