Browser Module

The Browser module allows you to operate web browsers. Through this module, we can navigate to a URL and interact with the web page just as a human user would: clicking on the page controls, selecting options, entering values in text fields, retrieving HTML items from the DOM, etc.

To use the Browser module in our projects, we must include the dependency:

1
2
3
4
5
<dependency>
    <groupId>com.novayre.jidoka.module</groupId>
    <artifactId>jidoka-browser-api</artifactId>
    <version>${jidoka.version}</version>
</dependency>

in the file pom.xml, where ${jidoka.version} specifies the module current version.

1
2
3
<properties>
    <jidoka.version>X.Y.Z</jidoka.version>
</properties>

This will load the dependency jidoka-browser-api-X.Y.Z.jar, thus making the Browser module available.

Browser module architecture

The Browser module requires Selenium to work properly and interact with browsers.

Appian RPA uses the Selenium WebDriver API, which contains different language specific implementations, such as Java. This Java implementation, included in the Maven dependency selenium-java, are called drivers. It is important to know this terminology to avoid confusion.

Drivers need to use the so-called servers to be able to interact with browsers. These servers, sometimes known as proxies, are necessary and are available to download as external components, since they are developed by third parties (except for Internet Explorer at the moment). We call them servers to avoid confusions.

Finally, we must talk about the last component forming this architecture, they are the browsers. The Appian RPA Browser module supports Chrome, Firefox, and Internet Explorer.

Components

To continue, we are going to analyze each of the components needed to work with the Appian RPA Browser module. Some of them are transparent for the developer, while others must be downloaded.

  • Browser module: this is the specific Appian RPA module designed to interact with different browsers.
  • Java Selenium drivers: Java implementations to handle browsers. They are included in the Browser module as part of the selenium-java Maven dependency. It is transparent to the developer, who only has to worry about calling the Browser module.
  • Servers: each of the executable programs that drivers communicate with. They are needed since they act as a bridge between a driver and a browser (and, by extension, the Browser module).
  • Browsers: each of the final browsers that are the one we are interested to use in the automation. The supported ones are Chrome, Firefox and Internet Explorer.

In the following image we can see how all these components are interconnected.

2234036.png

According to the specific browser, there are different servers available, as shown below:

Once downloaded, they must be added to robots in their section Support Files following the folder structure Appian RPA expects, as shown in the image below.

2234035.png

Note that, usually, a robotic process will only have to interact with one browser, so you don't need to upload all the files shown in the image.

Compatibility between components

Once we have defined all the necessary components for making the Browser module work properly and we know how they are connected, we have to bear in mind that not all versions of each component are compatible with each other.

Since the total number of possible combinations is too high, we recommend to always work with the most recent versions of the browsers and their bridge servers, bearing in mind that they must be compatible with the Selenium version integrated into the Appian RPA Browser module.

For instance, for the Appian RPA version 6.8.4, the Selenium version used is 3.141.59. Considering this, to know what versions of the rest of the components we can use, we must go to the links described below for each manufacturer:

  • Firefox: you can consult the supported versions for geckodriver.
  • Chrome: you can consult the supported versions for ChromeDriver.
  • Internet Explorer: in this case, since their releases are synchronized with those of the Selenium project, view the changelog for compatibility.

IWebBrowserSupport

The core interface of the Appian RPA Browser module is com.novayre.jidoka.browser.api.IWebBrowserSupport.

It enables working with the browser from the beginning and interacting with the page components.

You can obtain an instance of the interface this way:

1
2
IWebBrowserSupport browser =
    IWebBrowserSupport.getInstance(this, client);

Where client is an instance of IWindows and IJidokaRobot respectively.

Using the Browser module

Once we have obtained the instance of IWebBrowserSupport, we should properly initialize it. To do so, we will set the browser to be used and the default timeout:

1
2
3
// Set the browser to Chrome
browser.setBrowserType(EBrowsers.CHROME);
browser.setTimeoutSeconds(60);

In the previous example, we have set Google Chrome as the browser and a timeout of 60 seconds.

The enumerator type EBrowsers contains the identifiers for all the browsers supported by the module: CHROME, INTERNET_EXPLORER and FIREFOX.

To set other browsers:

1
2
3
4
5
// Set the browser to Internet Explorer
browser.setBrowserType(EBrowsers.INTERNET_EXPLORER);

// Set the browser to Mozilla Firefox
browser.setBrowserType(EBrowsers.FIREFOX);

Therefore, the full code to initialize the Browser module is:

1
2
3
4
5
6
7
8
9
10
// IClient
IClient client = IClient.getInstance(this);

// IWebBrowserSupport
IWebBrowserSupport browser =
IWebBrowserSupport.getInstance(this, client);

// Establecer navegador
browser.setBrowserType(EBrowsers.INTERNET_EXPLORER);
browser.setTimeoutSeconds(60);

Opening the browser and loading a web page

Now that we have properly initialized the browser, we can open it and navigate to a web page, on which we want to work. For example, we will open the browser and visit the Jidoka Blog:

1
2
3
4
5
6
// Open browser
browser.initBrowser();

// Navigate to a URL
String url = "http://www.appian.com";
browser.navigate(url);

Browser example robotic process

This time we will develop a robot to perform searches with Google, taking an Excel sheet as input, with the first column containing the term to search. The robot will update the second column with the number of results found and the third one with the time consumed by the search engine to find them. We will learn to use an Excel file through the Data-Provider module. Data Provider is meant to be used when each row of an Excel file is an item to be processed. In this example, we'll use instructions (or parameters) as inputs for the robot from the Appian RPA Console.

Source Code

Description Link
Source Code robot-developmentguide-internet-search.zip
Chrome Driver 81.0.4044.69 (Compatible with Chrome version 81.0.4044.69) Download
Gecko Driver v0.26 win64 (minimum recommended Firefox version 60 or higher) Download
IE Driver Server v3.150.1 win64 (Compatible with IE version 11) Download
Input File Example internet-search.xlsx

Workflow

This is the flow of actions that will be performed by the robot:

browser-module-workflow.png

You can import this workflow using this file. To import the workflow, you have to click in the import button (2236670.png), and paste the data included in the file.

Support files and parameters

We need to create this folder structure in the support files option

browser-module-support-files.png

You need to create two input parameters:

  • File: Input file with words to search in google. If it is empty, the robot will use the file included in the support files.
  • Browser: Param to choose the browser to use. The valid values are: "chromeBrowser,ieBrowser,firefoxBrowser"

browser-module-instructions.png

Implementation

We will analyze the methods openExcel, openBrowser, search and hasMore, highlighting the use of the Excel data provider. After the robot starts, the first action that it will do is to initialize the Excel Data Provide module. Then it will open the file, which is the one passed-in as instruction, and will allow us to call the methods provided by the module.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Action 'Open Excel'.
 * 
 * @throws Exception
 */
public void openExcel() throws Exception {

    // Get an instance of the data provider
    dataProvider = IJidokaDataProvider.getInstance(this, Provider.EXCEL);
    
    // Initialize the file
    dataProvider.init(inputFile, "Hoja1", 0,
            new InternetSearchRowMapper());

    // Set the number of items
    server.setNumberOfItems(dataProvider.count());
}

In the previous code, the instantiation of the data provider is done by the method init, which receives the complete file name, the Excel sheet containing the items, the zero-based position of the row with the first item and a column mapper.

The mapper must implement the interface IRowMapper, linking the Excel with the data model structure. The methods that must be implemented are map, to map the data from the Excel to the model, update, to update the Excel from the model, and isLastRow which will return true when there are no more items in the Excel.

The model class will represent the item retrieved from the Excel. As we will see next, the class is a typical Java POJO.

InternetSearchRow.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class InternetSearchRow implements Serializable {

    /**
     * Serial
     */
    private static final long serialVersionUID = 1L;

    /**
     * Search term.
     */
    private String searchTerm;
    
    /**
     * Number of results.
     */
    private String numberOfResults;

    /**
     * Getters/Setters
     */
    ...
}

The object Mapper will use the defined model class to retrieve and store items from the Excel. Next, we show the implementation, where you can see how the different spreadsheet columns are associated with the model class attributes.

InternetSearchRowMapper.java:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public class InternetSearchRowMapper implements IRowMapper<IExcel, InternetSearchRow> {

    /**
     * Columnn with the search term.
     */
    private static final int SEARCH_TEAM_COL = 0;
    
    /**
     * Column with the number of results.
     */
    private static final int NUMBER_OF_RESULTS_COL = 1;

    /**
     * Column with the time spent in the search.
     */
    private static final int TIME_SPENT_COL = 2;
    /**
     * @see com.novayre.jidoka.data.provider.api.IRowMapper#
     * map(java.lang.Object, int)
     */
    @Override
    public InternetSearchRow map(IExcel data, int rowNum) {
        
        InternetSearchRow r = new InternetSearchRow();
        
        r.setSearchTerm(data.getCellValueAsString(
            rowNum, SEARCH_TEAM_COL));
        r.setNumberOfResults(data.getCellValueAsString(
            rowNum, NUMBER_OF_RESULTS_COL));
        r.setTimeSpent(data.getCellValueAsString(
            rowNum, TIME_SPENT_COL));
        
        return isLastRow(r) ? null : r;
    }

    /**
     * @see com.novayre.jidoka.data.provider.api.IRowMapper
     * #update(java.lang.Object, int, java.lang.Object)
     */
    @Override
    public void update(IExcel data, int rowNum, InternetSearchRow rowData)
    {

        data.setCellValueByRef(new CellReference(
                rowNum, NUMBER_OF_RESULTS_COL),
            rowData.getNumberOfResults());
        data.setCellValueByRef(new CellReference(
                rowNum, TIME_SPENT_COL),
            rowData.getTimeSpent());
    }

     /**
     * @see com.novayre.jidoka.data.provider.api.IRowMapper
     * #isLastRow(java.lang.Object)
     */
    @Override
    public boolean isLastRow(InternetSearchRow instance) {
        return instance == null ||
            StringUtils.isBlank(instance.getSearchTerm());
    }
}

The next method to be executed by the robot will open the browser. Through setBrowserType we will set the browser to be used, and finally we will call initBrowser to open the browser.

Remember that you need to have the dependency with the Appian RPA Browser module resolved in the robot's POM file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
 * Action 'Open Browser'.
 * 
 * @throws Exception
 */
public void openBrowser() throws Exception {

    // Get an instance of Browser module
    browser = IWebBrowserSupport.getInstance(this, windows);
    
    // Set the browser to use
    setBrowserType();
    
    // Initialize the browser
    browser.initBrowser();
}

If you analyze the method above, you can see that the Browser module is instantiated similarly to how it was done with the Data-Provider module.

Through setBrowserType we will set the browser to be used, and finally we will call initBrowser to open the browser.

With the browser ready, the robot will begin processing the items from the Excel using the data provider until there are no more items left.

In the private method setBrowserType, we are selecting the browser to use, specified in the section "Instructions" of the robot configuration page in the console.

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/**
 * Action 'Search'.
 * 
 * @throws Exception
 */
public void search() throws Exception {
    
    InternetSearchRow item = dataProvider.getCurrentItem();
    
    server.setCurrentItem(dataProvider.getCurrentItemNumber(),
            item.getSearchTerm());
    
    String url = MessageFormat.format(SEARCH_URL,
            URLEncoder.encode(item.getSearchTerm(), "UTF-8"));
    
    browser.navigate(url);
    
    // Wait until the browser loads the page.
    windows.pause(1000); // To avoid StaleElementReferenceException
    
    if (!windows.waitCondition(10, 1000, "Waiting for query results",
        null, (i, c) -> browser.getElement(
            By.cssSelector("#resultStats")) != null)) {
    
    // Result not found.
        server.setCurrentItemResultToWarn("Result not found (wait)");
        return;
    }
    
    WebElement element = browser.getElement(
        By.cssSelector("#resultStats"));
    
    if (element == null) {
        // Result not found.
        server.setCurrentItemResultToWarn("Result not found");
        return;
    }
    
    String text = element.getText();
    item.setNumberOfResults(text);
    
    WebElement nobr = element.findElement(By.cssSelector("nobr"));

    if (nobr == null) {
        // Result not found.
        server.setCurrentItemResultToWarn("Result not found (nobr)");
        return;
    }
    
    text = nobr.getText();
    item.setTimeSpent(text);
    
    dataProvider.updateItem(item);
    server.setCurrentItemResultToOK();
}

In this code snippet, the method getCurrentItem uses the instance of the data provider to retrieve the first item mapped on the model class. Data providers simplify the process task when we have a direct link between the Excel row and the item to be processed.

The robot is commanded to navigate to the URL, formed by concatenating the Google search engine address with the text parameter used in the search. The robot will wait for the response and will analyze the page to retrieve the number of results and the time consumed by Google to find them.

Finally, we use again the data provider to update the processed item, adding the values retrieved from the search result, which were previously saved in the model, to the Excel sheet.

The robot will perform this operation for each row in the Excel sheet. To accomplish this behavior, the decision-making method's implementation will also use the data provider. As we mentioned, this provider will be very helpful to perform processes where the items have a direct link to the Excel rows.

1
2
3
4
5
6
7
8
9
/**
 * Action 'More?'.
 * 
 * @return the wire name
 * @throws Exception
 */
public String hasMore() throws Exception {
    return dataProvider.nextRow() ? "yes" : "no";
}

In the previous code, we can see that it evaluates whether there are more rows to process. The method nextRow also places the current item on the next Excel row.

Once the process has ended, the robot will upload the file to the server, so that it can be checked from the console.

As we have seen in other examples, the convention is to make the method cleanUpreturn a list of local paths of the files the robot will send to the server.

Use these tutorials to learn more about the Browser module:

Open in Github Built: Fri, Nov 12, 2021 (02:39:09 PM)

On This Page

FEEDBACK