Problem with wait(Pattern)

Asked by Sahil Doshi on 2019-05-29

Some time wait() will find a match but for the same screen has() will return false.

I have a code like :

screen.wait(image, 60);

if (!screen.has(image)) {
 throw new FindFailed(FindFailed.createErrorMessage(this, image.getImage()));
}

above code sometimes throws FindFailed exception. This is happening randomly.

I am working with Sikuli build: 270 on CentOS 7

Question information

Language:
English Edit question
Status:
Answered
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Last query:
2019-05-29
Last reply:
2019-05-29
RaiMan (raimund-hocke) said : #1

IMHO, if the image is not found, the FindFailed will already be thrown by the

screen.wait(image, 60);

Sahil Doshi (sahil13) said : #2

but in my case wait() will not throwing FindFailed error but has() returns false

RaiMan (raimund-hocke) said : #3

--- but in my case wait() will not throwing FindFailed
I cannot see from the snippet how you can be sure.

no try...catch

Sahil Doshi (sahil13) said : #4

I have a wrapper over method.

public Match custWaitForImage(final Pattern image, final double waitInMinute)
   throws FindFailed, InterruptedException {
  try {
   double endTime = System.currentTimeMillis() + (waitInMinute * 60 * 1000);

   screen.saveScreenCapture(loggingFolder, "log_before");

   screen.wait(image, waitInMinute * 60);

   while (System.currentTimeMillis() <= endTime && !screen.has(image)) {
    TimeUnit.SECONDS.sleep(1);
   }

   if (!screen.has(image)) { // at this line has returns false
    throw new FindFailed(FindFailed.createErrorMessage(this, image.getImage()));
   }

   return screen.getLastMatch();
  } finally {
   screen.saveScreenCapture(loggingFolder, "log_after");
  }
 }

RaiMan (raimund-hocke) said : #5

ok, thanks.
as far as I understand your logic:

example: waitInMinute = 1

double endTime = System.currentTimeMillis() + (waitInMinute * 60 * 1000);
endTime will be now + 1 Minute

screen.wait(image, waitInMinute * 60);
since you do not get a FindFailed here the image gets visible within 1 minute.

   while (System.currentTimeMillis() <= endTime && !screen.has(image)) {
    TimeUnit.SECONDS.sleep(1);
   }
now you you wait until now reaches endTime if Image is not visible
... but the image should be visible in that moment (the wait before succeeded), hence the loop is skipped.

... but if has() would return false (being a bug), then you would wait here until endtime is reached or has() does not return false anymore.

conclusion in case of has() works correctly (what I checked and IMHO it does):

at this time:
if (!screen.has(image))

the image is no longer visible.

... ok, all this simply makes no sense.

I guess, you never see a failing wait, because you do not have a catch(FindFailed), but only a try...finally.

Sahil Doshi (sahil13) said : #6

I have throws for FindFailed

RaiMan (raimund-hocke) said : #7

But only if the has() returns false!

So if has() returns false and works correctly, then before the wait has already thrown a FindFailed, which is not handled!

Sahil Doshi (sahil13) said : #8

That's a problem wait is not throwing error but at has() it is returning false

RaiMan (raimund-hocke) said : #9

Then I come back to my simulation above:

at this time:
if (!screen.has(image))

the image is no longer visible.

... in those cases.

Sahil Doshi (sahil13) said : #10

No I have confirmed using save(). Image is visible.

Can you help with this problem?

Provide an answer of your own, or ask Sahil Doshi for more information if necessary.

To post a message you must log in.