Problem with comparing screenshots using selenium - selenium

I want to cover ui test cases with automation and was suggested to imply compare screenshots
So the algorithm is the following:
1.I take screenshot of the page using selenium takescreenshot method and stored it in expected results folder
2.That I'm running test case which take screenshot of the same page and then compare it with expected screenshot from the step1
I was using the following method:
try {
// take buffer data from both image files //
BufferedImage biA = ImageIO.read(fileA);
DataBuffer dbA = biA.getData().getDataBuffer();
int sizeA = dbA.getSize();
BufferedImage biB = ImageIO.read(fileB);
DataBuffer dbB = biB.getData().getDataBuffer();
int sizeB = dbB.getSize();
// compare data-buffer objects //
if (sizeA == sizeB) {
for (int i = 0; i < sizeA; i++) {
if (dbA.getElem(i) != dbB.getElem(i)) {
return false;
}
}
return true;
} else {
return false;
}
} catch (Exception e) {
LOGGER.error("Failed to compare image files");
return false;
}
And previous week it was working well, but today I ran the same test and it failed, I opened images properties and see that screenshot made today is larger by 0,1 KB then the expected one.
Can't understand the reason
Can it be somehow related to chrome constant background updates and for example browser has some update during the weekend and now the screenshot is little bit different and this way of comparing is wrong?
And if yes, then how can wee do this, I tried popular library Ashot and it also tells me that the screenshot are different

Related

Selenium 4 C# Edge IEMode - WindowHandles funtion does not increase number of handles when new browser window appears

I updated Selenium to 4. I test legacy app that runs only on IE. Now IE will be closed down and I need to switch to MS Egde in capability mode.
My tests during execution need to switch to new browser windows and uses function IWebDriver.WindowHandles to do it (code below).
I had to add new options for a driver to run test on Edge like this:
var options = new InternetExplorerOptions();
options.AttachToEdgeChrome = true;
options.EdgeExecutablePath = #"\msedge.exe";
Then I use code like this to switch between browser windows:
public Context SwitchToNewIEWindow(string windowTitle, bool isEqual = true)
{
for (int i = 0; i < context.GetTimeout().Seconds; i++)
{
try
{
var ieWindowHandlers = context.GetDriver().WindowHandles;
foreach(var handler in ieWindowHandlers)
{
var window = context.GetDriver().SwitchTo().Window(handler);
bool condition = isEqual ? window.Title == windowTitle : window.Title.Contains(windowTitle);
if (condition)
{
context.SetDriver(window);
context.SetCurrentWindow(windowTitle);
return context;
}
}
}
catch (Exception)
{
context.Wait(1);
}
}
throw new Exception($"No window found with title: {windowTitle}");
}
In Selenium 3 everything works fine and WindowHandles function returns 2 handles. In Selenium 4 and IEDriver in Edge mode this function returns 1 handle.I have read https://github.com/SeleniumHQ/selenium/issues/8868 but in my case waiting a few seconds does not change anything. Even after a minute I still get only handle of first window.
Any suggestions how to make it work properly again in Selenium 4.
Libraries and its versions:

SimpleOpenNI: Multiple Kinects and enableScene()/sceneImage() in Processing

In Processing, I can successfully draw depth maps from 2 Kinects using SimpleOpenNI, but I'm now trying to draw 2 "scenes" (from enableScene() vs enableDepth()). Both Kinects are detected but when I draw the output, I see the same scene is drawn twice (whereas using enableDepth() always gave me 2 different depth images). Any ideas what I'm doing wrong? Thanks in advance.
/* --------------------------------------------------------------------------
* SimpleOpenNI Multi Camera Test
* --------------------------------------------------------------------------
*/
import SimpleOpenNI.*;
SimpleOpenNI cam1;
SimpleOpenNI cam2;
void setup()
{
size(640 * 2 + 10,480);
// start OpenNI, loads the library
SimpleOpenNI.start();
// init the cameras
cam1 = new SimpleOpenNI(0,this);
cam2 = new SimpleOpenNI(1,this);
// set the camera generators ** HAD TO REVERSE ORDER FOR BOTH KINECTS TO WORK
// enable Scene
if(cam2.enableScene() == false)
{
println("Can't open the scene for Camera 2");
exit();
return;
}
// enable depthMap generation
if(cam1.enableScene() == false)
{
println("Can't open the scene for Camera 1");
exit();
return;
}
background(10,200,20);
}
void draw()
{
// update the cams
SimpleOpenNI.updateAll();
image(cam1.sceneImage(),0,0);
image(cam2.sceneImage(),640 + 10,0);
}
I've done another text using the sceneMap() functionality but it looks like there is indeed an issue with SimpleOpenNI not updating properly internally:
/* --------------------------------------------------------------------------
* SimpleOpenNI Multi Camera Test
* --------------------------------------------------------------------------
*/
import SimpleOpenNI.*;
SimpleOpenNI cam1;
SimpleOpenNI cam2;
int numPixels = 640*480;
int[] sceneM1 = new int[numPixels];
int[] sceneM2 = new int[numPixels];
PImage scene1,scene2;
void setup()
{
size(640 * 2 + 10,480 * 2 + 10);
// start OpenNI, loads the library
SimpleOpenNI.start();
// init the cameras
cam1 = new SimpleOpenNI(0,this);
cam2 = new SimpleOpenNI(1,this);
// set the camera generators ** HAD TO REVERSE ORDER FOR BOTH KINECTS TO WORK
// enable Scene
if(cam2.enableScene() == false)
{
println("Can't open the scene for Camera 2");
exit();
return;
}
// cam2.enableDepth();//this fails when using only 1 bus
// enable depthMap generation
if(cam1.enableScene() == false)
{
println("Can't open the scene for Camera 1");
exit();
return;
}
cam1.enableDepth();
scene1 = createImage(640,480,RGB);
scene2 = createImage(640,480,RGB);
background(10,200,20);
}
void draw()
{
// update the cams
SimpleOpenNI.updateAll();
image(cam1.depthImage(),0,0);
image(cam1.sceneImage(),0,0);
cam1.sceneMap(sceneM1);
cam2.sceneMap(sceneM2);
updateSceneImage(sceneM1,scene1);
updateSceneImage(sceneM2,scene2);
image(scene1,0,490);
image(scene2,650,490);
}
void updateSceneImage(int[] sceneMap,PImage sceneImage){
for(int i = 0; i < numPixels; i++) sceneImage.pixels[i] = sceneMap[i] * 255;
sceneImage.updatePixels();
}
Using something like
cam1.update();
cam2.update();
rather than
SimpleOpenNI.updateAll();
doesn't change anything.
An issue was filed, hopefully it will be resolved.
In the meantime, try using OpenNI in a different language/framework.
OpenFrameworks has many similarities to Processing (and many differences
as well to be honest, but it's not rocket science).
Try the experimental ofxOpenNI addon to test multiple cameras, hopefully it will resolve your issue.

Best way to find out if jqGrid is loaded and ready with Selenium

How are you finding out if jqGrid is loaded and ready to be used, via selenium.
Some details :
Im using C# driver
I have a method : new WebDriverWait(driver, new TimeSpan(0, 0, 0, 30)).Until(x => loadingdissapearedcondition) which im using to wait until Loading.. element is gone.
I also sometimes use this script :
private const string script = #"return ($('#{0}').jqGrid('getGridParam', 'reccount') !=x undefined) && ($('#{0}').jqGrid('getGridParam', 'reccount') != 0) && (!$('#load_{0}').is(':visible')) && (!$('#busyIcon').is(':visible'))";
private readonly string waitScript;
waitScript = string.Format(script, jqGridId);
public void WaitUntilLoadIconDissappears()
{
driver.WaitUntil(MAXWAIT, Wait);
}
public bool Wait()
{
var executeScript = ((IJavaScriptExecutor) driver).ExecuteScript(waitScript);
bool result;
bool tryParse = bool.TryParse(executeScript.SafeToString(), out result);
return tryParse && result;
}
to find if jqGrid has records and loading done.
I require something better - as even the above two does not make driver wait until load finishes, if we are using local data for jqGrid. Im also curious what is the best way, or at the minimum, how others are dealing with this problem.
I never used Selenium before, so I'm not sure that I understood your problem correctly. jqGrid will be first initialized and then (optionally) the data can be loaded from the server. During the initializing stage the original <table id="grid"></table> element will be converted to relatively complex HTML fragment which is the grid. At the end of the initialization the DOM element of the table (the $("#grid")[0]) will get the expando grid.
So you can use the test like
if ($("#grid")[0].grid) {
// grid is initialized
}
to determine that the grid is already initialized. jqGrid uses the same test internally (see here for example).
Here is solution for Java and jqgrid.
If grid data is not loaded yet then right pager has no value, so simply check its length. Methods such as isElementPresent, isDisplayed etc. seems not to work for grid right pager object. It's always present in page code while ajax, but text value is set when dynamic data is loaded.
public void waitForGridPagerRight(String gridName) throws Exception {
for (int second = 0;; second++) {
if (second >= 15) {
fail("Timeout.");
}
try {
if (driver
.findElement(By.id("pager_" + gridName + "_right"))
.getText().length() > 2)
break;
} catch (Exception e) {
}
Thread.sleep(1000);
}
}
Not sure why #Oleg's answer didn't work for me. It seemed like grid was being populated even before the ajax call was being made. It appears there's some change in newer versions maybe. It look like the last thing to happen in the ajax call is that the "loading" block is hidden, so instead I find that element and check it's display attribute a la:
def wait_for_jqgrid(self, t=20):
def check_jqgrid(driver):
#the last thing jqgrid does after the ajax call is to turn off the loading div
#so we find it and check to see if its display attribute is no longer set to 'none'
script = 'pid = $.jgrid.jqID($(".ui-jqgrid-btable").get(0).p.id); return $("#load_"+pid).get(0).style.display == "none";'
return driver.execute_script(script)
WebDriverWait(self.driver, t).until(check_jqgrid)
When the loading div is hidden, we are done. This is python but the same javascript bit should work in Java or whatever.

Eclipse plugin: about the function --println(String) in org.eclipse.ui.console.MessageConsoleStream

Recently I am doing a eclipse plugin project with eclipse_RCP. But I encountered some issues with eclipse UI when I wanted to print a large number of messages in the console of plugin.
The messages are from a complex process which could be considered as a factory producing messages all the time and never stop (until the client stop the process of course).
When I printed the message before (the message is short), I just needed to call the function -org.eclipse.ui.console.MessageConsoleStream.println().
BUT this time ,when I tried like before at first , the runtime-EclipseApplication (launch the debug mode) stopped responding and then tell me out of memory.
It seems like that the eclipse will read all the messages in the memory and THEN print them to the console one time .So when the number of message is large ,it will out of memory.
My issue is what can I do if I want to print the message line by line in the console ?
My description may be not accurate. Below is the java code:
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
try {
while ((line = in.readLine()) != null) {
//it is correct when print in the main console
System.out.println(line);
//when print in plugin console .it is out of memory
//this is the function
//org.eclipse.ui.console.MessageConsoleStream.println()
println(line);
}
in.close();
this.flush();
this.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
Then I try to write to a file at first and let the MessageConsoleStream read from the file every 1000 messages,but it looks like the same .
public void print(Process p) {
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()),1024);
String line = "";
char []tem = new char[1024];
int i = 0 ;
try {
File temp = File.createTempFile("temp", ".tep",new File("E:/"));
FileWriter out = new FileWriter(temp);
MessageConsoleStream mcs = null;
while((line = in.readLine())!=null){
if(i<=1000){
System.out.println(line);
out.write(line+"\n", 0, line.length()+1);
i++;
}
else{
i=0 ;
out.flush();
out.close();
FileReader fr=new FileReader(temp);
mcs = CConsole.getMessageStream("consoleName", "file name");
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
fr.close();
out = new FileWriter(temp,false);
}
}
if(i!= 0){
mcs = CConsole.getMessageStream("consoleName", "file name");
out.flush();
out.close();
FileReader fr=new FileReader(temp);
while( fr.read(tem, 0, 1024)!=-1){
mcs.print(String.valueOf(tem));
}
mcs.flush();
mcs.close();
}
in.close();
p.destroy();
}
catch (IOException e) {
e.printStackTrace();
}
}
All the ways above will make the eclipse out of memory when the number of messages more than 600,000 (then I stop the process ,otherwise it will out of memory).
It looks like the ecplipse wants to print all of them one time but not line by line.So it reads and reads again until out of memory.
BTW,I find a note in the org.eclipse.ui.console.MessageConsoleMessage.java——
Clients should avoid writing large amounts of output to this stream
in the UI thread. The console needs to process the output in the UI
thread and if the client hogs the UI thread writing output to the
console, the console will not be able to process the output.
That is not the real reason ,isn't it ?
I also notice that both the cdt and jdt are ok when printing a large number of message .How did they do ?
THANKS!
You have to use the flush() method every so often to write the MessageConsoleStream out to the console.
The flush() method is part of the IOConsoleOutputStream class, in the org.eclipse.ui.console package. The flush() method is not well documented, so I can see how you might have missed it.

Application crashes when lots of images are displayed

In my WP7 application I have downloaded 200 images from Web and saved in isolated storage .When debug all the images are loaded in panorama view by queue method and I can view when it is connected to pc. after disconnect it from pc when i open the application and navigate the images it shows some images and terminated.
if (i < 150)
{
WebClient m_webClient = new WebClient();
Uri m_uri = new Uri("http://d1mu9ule1cy7bp.cloudfront.net/2012//pages/p_" + i + "/mobile_high.jpg");
m_webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
m_webClient.OpenReadAsync(m_uri);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
int count;
try
{
Stream stream = e.Result;
byte[] buffer = new byte[1024];
using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
{
//isf.Remove();
using (System.IO.IsolatedStorage.IsolatedStorageFileStream isfs = new IsolatedStorageFileStream("IMAGES" + loop2(k) + ".jpg", FileMode.Create, isf))
{
count = 0;
while (0 < (count = stream.Read(buffer, 0, buffer.Length)))
{
isfs.Write(buffer, 0, count);
}
stream.Close();
isfs.Close();
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
I think that your problem is that if you load too many images at once in a loop the moment you go out of the loop and give focus back to the UI thread all the Garbage Collection on the bitmap images is done.
This article explains it a bit better and provides with a solution.
I also had this problem and came up with my own solution. I had a dictonairy with image url that needed to be loaded, but you can easily alter this for your scenario.
This SO question is also about this problem (loading multiple images and crash (Exception)). It also has Microsofts response to it, I based my solution on their response.
In my solution I use the dispatcher to return to the UI thread and thus making sure the garbage of the image and bitmaps used was cleaned.
private void LoadImages(List<string> sources)
{
List<string>.Enumerator iterator = sources.GetEnumerator();
this.Dispatcher.BeginInvoke(() => { LoadImage(iterator); });
}
private void LoadImage(List<string>.Enumerator iterator)
{
if (iterator.MoveNext())
{
//TODO: Load the image from iterator.Current
//Now load the next image
this.Dispatcher.BeginInvoke(() => { LoadImage(iterator); });
}
else
{
//Done loading images
}
}
After talking on Skype I reviewed his code and found out his problem was with his Isolated Storage Explorer. It couldnt connect to his pc so it gave an error. Had nothing to do with the image loading.
I'd be very wary of the memory implications of loading 200 images at once. Have you been profiling the memory usage? Using too much memory could cause your application to be terminated.