This content applies solely to Appian RPA, which must be purchased separately from the Appian base platform. |
The following content is based on the previous version of the Robotic Task Designer.
In this example, we will develop a basic robotic task, which will be able to use the notepad for typing text. We will see several ways to make our robotic task wait for an application to open.
Description | Link |
---|---|
Source Code | robot-tutorial-notepad.zip |
You must import the Eclipse project included in the zip file attached at the beginning of this tutorial. After importing the project, it is very important to modify the pom.xml file. You have to fill in the parent tag with the version of Appian RPA you are using, and change the profile tag with the configuration of your repository.
In essence, the workflow of this robotic task is identical to the previous ones. Initializing, opening the application, performing operations and ending the execution by closing the application.
You must to create a new Workflow with this structure.
You can import this workflow using
this file. To import the workflow,
you have to click in the import button
(), and paste the data included in the
file.
The main class of this robotic task, called NotepadRobot, declares the typical attributes that we have seen so far, including the specific items for this example.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Robot
public class NotepadRobot implements IRobot {
/**
* Regular expression to search the window for the application Notepad. It
* changes depending on the platform language.
*/
private static final String NOTEPAD_REGEXP = ".*(Bloc de notas|Notepad)";
/**
* Default pause between actions imitating human behavior.
*/
private static final int PAUSE = 500;
/**
* Items to process.
*/
private static final String[] ITEMS = new String[] {
"This is the "Hello World!" Appian RPA robotic task",
"It shows how to write into the notepad"
};
/**
* Server.
*/
private IJidokaServer< ? > server;
/**
* Windows module.
*/
private IWindows windows;
/**
* Current item index. The first one is the number '1'.
*/
private int currentItemIndex = 1;
The method startUp and init are similar to the previous robotic tasks.
Now, we will focus on the method openNotepad, of which we will show two different ways to make the robotic task wait for the notepad to open.
Let's see the code for the first one:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/**
* Action 'Open Notepad'.
*
* First way to open Notepad.
*/
public void openNotepadAlt1() {
try {
// Win+R
client.keyboard().windows("r").pause().type("notepad").enter().pause();
// Wait during 10 seconds until the application window is present
if (client.waitFor(this).window(10, NOTEPAD_REGEXP) == null) {
/*
* If the window is not present at the end of the wait, the robotic task must fail.
*/
throw new JidokaFatalException("Notepad could not be opened");
}
// Maximize the window
client.showWindow(client.getWindow(NOTEPAD_REGEXP).getId(), EClientShowWindowType.MAXIMIZE);
} catch (Exception e) {
throw new JidokaFatalException("Error opening notepad");
}
}
The first way uses the method waitFor of the instance windows, which is an alias of getWaitFor, and receives an IRobot type parameter. Our robotic task, like every Appian RPA robotic task, is an instance of this type, so we will pass this as an argument. It will return an instance of type IWaitFor, which includes some predefined methods for waiting. This is the case of the method window, which receives as parameters the maximum waiting time in seconds and a regular expression. The method will try to match this regular expression with the title of the opened windows available and will return the regular expression itself in case the window is found, or null otherwise. We decide to throw an exception of type JidokaFatalException in case the application cannot open, though by implementing the wait in this way, we have the advantage of handling the situation with any other strategy, without throwing exceptions.
Now, we will see the code of the second way to open the notepad:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* Action 'Open Notepad'.
*
* Second way to open Notepad.
*
* @throws JidokaUnsatisfiedConditionException if some conditions are not met
*/
public void openNotepadAlt2() throws JidokaUnsatisfiedConditionException {
try {
// Win+R
client.keyboard().windows("r").pause().type("notepad").enter().pause();
// Using a custom condition for waiting
client.waitCondition(10, 1000, "Wait for Notepad to be opened", null, true,
(i, c) -> client.getWindow(NOTEPAD_REGEXP) != null);
// Maximize the window
client.showWindow(client.getWindow(NOTEPAD_REGEXP).getId(), EClientShowWindowType.MAXIMIZE);
} catch (Exception e) {
throw new JidokaFatalException("Error opening notepad");
}
}
We accomplish it by using waitCondition, but instead of writing the condition from scratch, we use the functional interface ICondition. This way, we aim to obtain an existing opened window which matches the regular expression received as an argument, following the same logic as in the previous alternative.
The functional interface ICondition includes the implementation of the method satisfied, which can be called by using lambda expressions.
We will throw an exception or not, depending on the value of the corresponding parameter of the method waitCondition (true or false).
Finally, in both alternatives the notepad is maximized through the method showWindow of the instance windows, to which we will pass as parameters the window's reference, of type HWND, and the way in which we want it to show itself, SW_MAXIMIZE in our case.
The next method shown below is processItem, responsible for performing the action "Process line" defined in the workflow. It will be called while there are items to process within the constant ITEMS.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Action 'Process line'.
*/
public void processItem() {
try {
// Get the current item
String item = ITEMS[currentItemIndex - 1];
/*
* Notify the server the item treatment starts. Important to calculate
* statistics and execution times. The second parameter is used to make it
* easier to find registers in the execution log.
*/
server.setCurrentItem(currentItemIndex, item);
// Type the string into de Notepad and press Enter
client.keyboard().type(item).pause().enter();
/*
* Notify the item result. In this case, a the detail message is not specified.
*/
server.setCurrentItemResultToOK();
} catch (Exception e) {
throw new JidokaItemException("Error processing the item");
}
}
Here, we will highlight that, through the method keyboard of IWindows, we get access to the instance IKeyboard, to write the text with the method type.
As in the robotic tasks of the previous tutorials, there will be a method to check whether there are items left to process. Depending on this, we will process the next items or end the robotic task's execution.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Action 'More?'.
*
* @return the wire name
*/
public String hasMoreItems() {
if (currentItemIndex == ITEMS.length) {
// All items have been processed
return "no";
}
// There are more items to process
currentItemIndex++;
return "yes";
}
The method end, as in the other robotic tasks, is an empty method once again, which represents only the last action of our robotic task.
1
2
3
4
5
6
/**
* Action 'End'.
*/
public void end() {
// Continue the process. At this step, the robotic task ends its execution
}
Finally, just like in the previous robotic task, we close Notepad to leave the robot in the same status as it was before the beginning of our robotic task execution. To do so, remember that we can use the method cleanUp, where we will use the method killAllProcesses of IWindows.
1
2
3
4
5
6
7
8
9
10
11
/**
* @see com.novayre.jidoka.client.api.IRobot#cleanUp()
*/
@Override
public String[] cleanUp() throws Exception {
// Close all Notepad instances
windows.killAllProcesses("notepad.exe", 500);
return new String[0];
}
Follow the same steps as Calculator Tutorial.