Page 1 of 1

Control UI Questions

Posted: 07 Nov 2018 13:33
by robchoc
What would be the best way to accomplish each of these scenarios:

You have to click on the OK text, every few seconds or even better each time you get a new one on the screen until stop button shows up that you then click.

You only click a button if it says ready on the screen if not you click a button to try again.

Look forward to your replies.

Re: Control UI Questions

Posted: 08 Nov 2018 06:13
by Desmanto
Depends on the app and other conditions, there are basically 2 ways to do it
1. UI event, and look up for the text when it appear. This will delay up to 1 second because of the accessibility, before the clicking can start. However not every app can use this, since not every UI changes involved lookup-able UI Event. Use this if the app support it and you don't mind the 1 second latency.

2. Looped Control UI, execute the flow by other trigger (example app task started), then looped-sleep-check for that OK button to appear; while checking for the stop button too. Compatible to most app, but the looped-sleep Control UI can slow down other Control UI operation (if other flow triggered at the same time). It also wakelock the CPU, so you have to make sure the loop has some escape mechanism to stop the script after certain amount of time (timeout if the button not found).

For UI event, you can try to simulate the OK button and stop button as they appear. Go back to Automagic, at the trigger UI event and check the RECENT event and see if those button appear. If there is you can try to use that as the trigger and follow by Control UI to click that button.

For Looped Control UI, you need to use while() and put some condition to check at the inner lines. Example

Code: Select all

loop = 0;
while(getTextById("android:id/button1") != "STOP" AND loop < 100)
{
  if(getTextById("android:id/button2") == "OK")
    clickById("android:id/button2");
  sleep(1000);
  loop = loop + 1;
}
{loop} is for the escape mechanism, so your script doesn't run forever. Adjust the 100 to the value you can tolerate or expect that the script should have stopped.
It will check for the button1, if it is not "STOP" (if the button not there, it will be null), then loop the script.
The if() check for the "OK" button, if exist, click it.
sleep(1000) and increment the loop. Adjust the sleep to the latency you can tolerate. Too low value will have lower latency, but script executing too many times and loop achieved faster. Too high value will have lower execution but higher latency, the delay can sometimes be noticeably painful. So try to find the optimal value. You can check more detail at the other thread : viewtopic.php?f=5&t=7108

The same applies to the Ready and Try Again scenario. YOu have to replace it with the App element Id.

Re: Control UI Questions

Posted: 08 Nov 2018 11:14
by robchoc
What if there is no ID just click("OK") & click("STOP")

How woud this be changed?
(getTextById("android:id/button2") == "OK")
and this
while(getTextById("android:id/button1") != "STOP" AND loop < 100)

Re: Control UI Questions

Posted: 08 Nov 2018 12:28
by Helios
There is also

Code: Select all

getText("OK")
if no ID is available.
You could also do something like

Code: Select all

while(not click("OK") AND loop < 100) {
  sleep(1000);
  loop = loop + 1;
}
because all

Code: Select all

click(), clickById()
operations return a boolean whether the click was successfull or not.

Re: Control UI Questions

Posted: 08 Nov 2018 16:49
by Desmanto
@robchoc : As answered by Helios, you can use getText(). If there is no element with the label stated, getText() will give null. Or you can also use the same getText() label to check it. I use null for the STOP and same text for the OK, as example. Here is the script

Code: Select all

loop = 0;
while(getText("STOP") == null AND loop < 100)
{
  if(getText("OK") == "OK")
    click("OK");
  sleep(1000);
  loop = loop + 1;
}
@Helios : I just know that click() and its kind give true/false. Something to learn everyday. :D But I don't use that, i still use getText() method, since most of the time I don't click the checked label, it is just for element confirmation.

Re: Control UI Questions

Posted: 09 Nov 2018 19:38
by robchoc
The same question but now we have a scenario of not acting whilst a certain text is on the screen, for example:

I need to press next when the screen has stopped showing block.

All these questions are helping me understand how things work, apology if they seem a bit basic.

Once again thanks for the help in learning how to use Automagic.

Re: Control UI Questions

Posted: 10 Nov 2018 12:11
by Desmanto
Use the while() loop sleep linked from my previous post. I modify it a bit.

Code: Select all

loop = 0;
while(getText("NEXT") == null)
{
  if(loop > 100);
    1/0;
  sleep(1000);
  loop = loop + 1;
}
click("NEXT");
If after 100 loop and NEXT button is not detected, it will produce error. You need to catch the error using exception.
You can replace 1/0 to return, in case you just want to exit from the Control UI.

If the NEXT is detected within 100 loop, it will finish the loop and immediately click the NEXT.

Re: Control UI Questions

Posted: 10 Nov 2018 15:53
by robchoc
But how does this prevent it from executing when block is showing on the screen.

If the screen shows block I do not want it to press next even if next is showing.

Can you alter your code for this scenario, please?

Re: Control UI Questions

Posted: 10 Nov 2018 16:47
by Desmanto
Oh, so the NEXT is already there, it is the BLOCK you want to check. Reverse the logic and use the BLOCK as the check.

Code: Select all

loop = 0;
while(getText("BLOCK") != null)
{
  if(loop > 100);
    1/0;
  sleep(1000);
  loop = loop + 1;
}
click("NEXT");
While the BLOCK exists (not null means exists), then sleep only. As soon as it is null, then click NEXT.

Re: Control UI Questions

Posted: 28 Dec 2019 15:31
by tsolignani
I just wanted to say thank you, I used the code from Desmanto into a flow I was making. Thank you.