Clicknium Cookbook
Tags: tutorial, python, beginners, productivity
Published: 2023-03-09 12:03:45

[Clicknium](https://www.clicknium.com/documents "Clicknium") is a Python UI automation library used primarily for automating Windows desktop applications and web applications. As the documents are hard to learn the tool quickly, this article will provide a systematic guide on how to use Clicknium.

# 1. Basic Concepts

Clicknium generates a locator by recording mouse clicks on UI elements, which stores various properties of the UI element. This allows Clicknium to locate the corresponding UI element by using the Locator. Once the UI element is located, Clicknium provides various common methods for operating UI elements, such as inputting (set_text), mouse clicks (Click), etc. With these methods, Python developers can write UI automation scripts easily.

**Clicknium Development Kit**

The Clicknium Python SDK is the automation core of Clicknium. Around this core, Clicknium provides a series of plug-ins to assist in developing automation scripts:

- Clicknium VS Code plug-in: manage and debug locators, provide Python code completion and intelligent prompts.
- Clicknium browser plug-in: enhance web automation capabilities, support Chrome, Firefox, Edge, Brave, and Vivaldi.
- Clicknium Recorder: supports recording UI elements to generate locators.

[Clicknium Python SDK](https://pypi.org/project/clicknium/ "Clicknium Python SDK") can be installed via pip install clicknium. After searching for Clicknium in the VS Code extension and installing the extension, various plug-ins for Clicknium and the SDK can be managed and updated in the extension.

# 2. Development Environment Configuration

Windows 7 SP1+ is required:
Search for Clicknium in the VS Code extension and install it:
![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309150755.png)
Python module can also be installed by `pip install clicknium`.

# 3.Automation Script Development Process

## 3.1 Sample Script

First, take a look at the sample script. Open VS Code, enter Clicknium: Sample with Ctrl+Shift+P, and then select a new empty directory to store the sample project.

Now we have the following sample project. Press F5 to run and Ctrl+F5 to debug.
![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309160436.png)


The directory structure of the sample project:

/.locator: Locator information

/.locator/sample_img: snapshot of the locator

/.locator/sample.cnstore: stores the properties of this Locator

Code analysis:

-   **Part 1: Installing the browser plug-in**

```python
    if cc.edge.extension.install_or_update():
      print("Please open edge browser to enable clicknium extension, then run sample again.")
      
```

It is easy to understand that the corresponding browser plug-in needs to be installed.

-   **Part 2**：Web automation, automatically open your browser, go to bing search, enter clicknium in the input box, and click the search button.

```python
    tab = cc.edge.open("https://www.bing.com/")
    tab.find_element(locator.sample.bing.search_sb_form_q).set_text('clicknium')
    tab.find_element(locator.sample.bing.svg).click()
    sleep(3)
    tab.close()
```


Line 1: Using clicknium to call the Edge browser and open the Bing homepage, returning the corresponding browser tab.

Line 2: Calling find_element within the tab and passing in the Locator of the input box as a parameter, then using the set_text API to input the text information.

Line 3: Calling find_element within the tab and passing in the Locator of the search button as a parameter, then using the click function.

Line 4&5: Waiting for 3 seconds, then closing the corresponding tab.

Through this code snippet, one can roughly understand the logic of clicknium. Clicknium provides functions such as find_element that accept the locator parameter to obtain UI elements. It also provides some common methods for operating UI, such as set_text, click, etc., to simulate human operations.


-   **Part 3**：Windows desktop automation. Open Notepad and enter "clicknium".

```
    process = subprocess.Popen("notepad")
    ui(locator.sample.notepad.document_15).set_text("clicknium")
```


The API for Desktop Applications and Web browsers is the same.

-   **the Clicknium core: Locator**

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/87c78cad99044844a99a229119404b6f~tplv-k3u1fbpfcp-zoom-1.image)​

You might have no idea about how to create a locator since the sample is without a process. It will be introduced in the next part. 

## Developing Your Own Automation Scripts from Scratch

Starting from scratch, use the Chrome browser to search for the Clicknium website and automatically register for an account.

-   **Creating a Project**

Create a folder named ClickniumSample to store the Python Project, open the folder with VS Code, and create a Python file named Sample.py.

Open the Clicknium official website:[The best python automation module | Clicknium](https://www.clicknium.com/ "The best python automation module | Clicknium")

In VS Code, find the Capture button next to LOCATOR and launch the Clicknium Recorder.

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309180528.png)

Hold down Ctrl and click on the Sign Up button:

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309182104.png)

Upon success, the Locator for the registration button is obtained.

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309182941.png)

Locators can be organized in a folder structure or renamed by oneself. The structure is similar to that of namespaces, so special characters such as spaces cannot appear in the locator name.

After generating the Locator, we can use the method [find_element](https://www.clicknium.com/documents/references/python/globalfunctions/find_element "find_element") to locate the corresponding UI element. There will be intelligent prompts after inputting the Locator:

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309183303.png)


When the Mouse is placed on the Locator, a locator snapshot will appear to help identify the UI element corresponding to the Locator, and validation and re-recording can also be done.

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309183401.png)

After locating the UI element, a series of operations are supported. Since the object is a button, we choose to click:

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309183423.png)


Using the same method, record the five input boxes and one button on the registration page:
![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309183443.png)

The button uses the Click method, and the input boxes use set_text. Use F5 to run and check the effect.

```python
from clicknium import clicknium as cc, Locator
from time import sleep

def main():
    cc.chrome.open("https://www.clicknium.com/")
    cc.find_element(locator.clicknium.button_sign_up).click()
    sleep(5)
    firstName = "Kay"
    lastName = "Whitlock"
    email = "youremail@youremail.com"
    password = "youpassword"
    cc.find_element(locator.clicknium.auth.text_firstname).set_text(firstName)
    cc.find_element(locator.clicknium.auth.text_lastname).set_text(lastName)
    cc.find_element(locator.clicknium.auth.text_email).set_text(email)
    cc.find_element(locator.clicknium.auth.password_password).set_text(password)
    cc.find_element(locator.clicknium.auth.password_confirmpassword).set_text(password)
    cc.find_element(locator.clicknium.button_sign_up).click()

if __name__ == "__main__":
    main()
```
# 4. Mouse and Keyboard Input

Clicknium's documentation provides a detailed description of the mouse and keyboard operations supported. Here is a brief introduction.

- **Mouse Input:**

The mouse operations supported by Clicknium can be found at [Mouse](https://www.clicknium.com/documents/references/python/mouse/ "Mouse"). Taking a single click as an example, let's take a look at the parameters supported by the click function.

```python
    def click(
        self,
        mouse_button: Literal["left", "middle", "right"] = MouseButton.Left,
        mouse_location: MouseLocation = MouseLocation(),
        by: Union[Literal["default", "mouse-emulation", "control-invocation"], MouseActionBy] = MouseActionBy.Default,
        modifier_key: Literal["nonekey", "alt", "ctrl", "shift","win"]  = ModifierKey.NoneKey,
        timeout: int = 30
    ) -> None:        
        """
            Single click the target element.
 
            Parameters:

                mouse_button: The available values are: 'left', 'right' and 'center', default is 'left'.  

                mouse_location: it is set to define the position where the element is to be clicked. The default position is the center of the element.  
 
                by: Defines the method to click the UI element.  
                    mouse-emulation: click the target UI element by simulating Mouse.  
                    control-invocation: click the target UI element by invoking its UI method. It may not be supported if it is a Windows desktop element.  
                    default: automatically choose method per element type. For Web element, use `control-invocation`; for Window element, use `mouse-emulation`.  

                modifier_key: The modifier key("alt", "ctrl", "shift", "win") to be pressed along with click, and the default is none.  

                timeout: timeout for the operation, the unit is second, and default is set to 30 seconds.  
                            
            Returns:
                None
        """
```


**mouse_button**: The left or right button of the Mouse.

**mouselocation**: Absolute or relative position.

**by**: There are two modes: mouse-emulation and control-invocation. The names may sound abstract, but the former simulates the behavior of the Mouse, moving the Mouse and clicking it, while the latter uses a system call-like method invocation. In short, mouse-emulation has a higher success rate, while control-invocation has better performance. For desktop automation, it is recommended to use mouse-emulation first, and for browser automation, try control-invocation first and use mouse-emulation if it doesn't work.

**modifier_key**: Achieve the effect of holding down special buttons like alt, ctrl, shift while clicking the Mouse.

**Keyboard Input**

There are two commonly used keyboard inputs:
- Inputting text
- Pressing special buttons
For inputting text, the set_text method is generally used:


```python
    def set_text(
        self,
        text: str,        
        by: Union[Literal["default", "set-text", "sendkey-after-click", "sendkey-after-focus"], InputTextBy]= InputTextBy.Default,
        overwrite: bool = True,
        timeout: int = 30
    ) -> None:
        """
            Set text for the target element, it can be used to input text to a system.  

            Parameters:

                text[Requried]: text string to be input.                 

                by: the method to perform the text input operation. 
                    set-text: call system method to set text to the target element. Some Windows application elements may not be supported.  
                    sendkey-after-click: simulate Mouse click to activate the element, then send keys by simulating keyboard.  
                    sendkey-after-focus: set the target element to a focused state, then send keys by simulating keyboard.  
                    default: using different methods per target element type. `set-text` for web element and `sendkey-after-click` for desktop element.  

                overwrite: whether overwrite or append the text on the target element, default is True. 

                timeout: timeout for the operation. The unit of the parameter is seconds. The default is set to 30 seconds.
                                
            Returns:
                No
```


Parameter Section:

**text**: The string to be entered.

**by**: set-text is a system call with the best performance and is generally used in browser scenarios.

**sendkey-after-click**: Simulates clicking on this UI element and then inputs by simulating the keyboard.

**sendkey-after-focus**: Sets the target UI element to focus and then inputs by simulating the keyboard.

**overwrite**: Can choose to append or overwrite directly.

Sendkey-after-click is a very commonly used option because, currently, input boxes often need to be clicked by the Mouse to become activated to receive input. They cannot receive input when in an inactive state. This is also the reason why input operations often fail in automation processes. It should be noted that this method is often hijacked by input methods, so when using this parameter, the input method should be disabled and switched to English input.

**Pressing special buttons:**
The send_hotkey method is mainly used.

```python
    def send_hotkey(hotkey: str) -> None:
        """
            Send hotkey to the cursor's current position.
 
            Parameters:
                hotkey[Requried]: hotkey string represents one key or combined keys. For example, to represent the letter A, input string "A". To represent the letters A, B, and C, input paremeter "ABC". For special keys, please refer to [hotkeys](https://docs.microsoft.com/en-au/dotnet/api/system.windows.forms.sendkeys?view=windowsdesktop-6.0#remarks).
                                
            Returns:
                None
        """
```

This method accepts a string as the hotkey code. The specific hotkey code corresponding to the keyboard button can be found in Microsoft's [hotkey list](https://learn.microsoft.com/en-au/dotnet/api/system.windows.forms.sendkeys?view=windowsdesktop-6.0#remarks "hotkey list"). For example, if you need to press the Enter key, you can find the code for Enter as {ENTER} in the table.

```python
cc.send_hotkey("{ENTER}")
```

# 5. Locator

The Locator is fundamental to locating UI elements. During the recording process, Clicknium Recorder reads various properties and structures of the UI elements, and then uses an algorithm to select the attributes that can help locate the UI element.


Returning to the directory structure in the Sample, a .locator folder will appear in the Python project directory, which stores the Locator data. VS Code reads the Locator data and displays it under the LOCATORS tab:

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309191257.png)

The above picture shows the Locator interface, where you can select the corresponding Locator under the LOCATORS tab to enter the Locator details page.

There are three buttons on the upper right side: Recapture, Validation, and Action.

**Recapture**: is mainly used to re-record the Locator after it becomes invalid. There is also an option called recapture&compare for comparison, especially when the Locator becomes invalid and needs to be re-recorded. This option can help identify which attributes have changed and caused the Locator to fail to locate the UI element.

**Validation**: is used to test whether the Locator can locate the corresponding UI element. Note that the webpage or app corresponding to the UI element needs to be open, and validation will not actively open it.

**Action**: is mainly used to test the usability of the Locator and perform some common UI operations, such as clicking (click), getting text (get_text), and setting text (set_text).


## 5.1 Locator Attributes

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301locator_atribute.png)  


Locator attributes are actually the content of the Locator. When Clicknium Recorder captures an element, it automatically obtains the element's attributes and selects which attributes to use to locate the UI element. The content in the red box below the three shortcut buttons in the Locator interface is the Locator attributes. In the example in the above picture, there are three lines of attribute content from top to bottom. Clicknium finds the corresponding UI element through the hierarchical structure, and the three lines of attributes in the Locator actually represent the hierarchical relationship. The first line is the chrome.exe application. After locating the chrome application, the second line is the browser tab, and the third line locates the button through the web attribute.

## 5.2 Modifying Locator Attributes

In most cases, the attributes automatically selected by Clicknium can successfully locate the UI element. However, in some cases, we still need to fine-tune the Locator attributes to better match the UI element: first, choose the hierarchical relationship. If it is determined that a certain level of an attribute is not needed, you can uncheck the blue box in front of the attribute to exclude it from locating the element. When you click the hierarchical attribute with the Mouse, the attribute on the right will be expanded. For the attributes within the hierarchy, you can also choose whether to participate in locating. At the same time, in order to improve the generalization ability, the attribute value matching rule supports four modes: equals, startWith, endWith, and regex.

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301attributematch.png)  


When the matching pattern is 'equals', wildcard characters are also supported. For example, name='test?_node', where '?' matches one character and * matches zero or more characters.

## 5.3  Parametric Locator:

For multiple UI elements of the same type, most locator attributes are the same, except for one or a few attribute values. In this case, creating a large number of locators is not feasible, especially when the number of elements is not fixed. This is where parametric locators are useful.

Using parameters in locators:

1. Use Mustache style by declaring a parameter with two curly braces and a variable name in the locator attribute:`{{variable}}`. The entire attribute value can be set to a variable."：

```
<Web ancestorId="{{id}}" tag="A" />
```
Or the part of the attribute value can be set as a variable：
```python
from clicknium import clicknium as cc, Locator, ui
# replace variable'id' in parametric Locator during runtime
variables = {"id":"test"}
ui(locator.chrome.bing.search_sb_form_q, variables)
```
For example:

There is a list in the sample website：[List group · Bootstrap v5.1](https://getbootstrap.com/docs/5.1/components/list-group/ "List group · Bootstrap v5.1")

![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301paraLocatorsamplesite.png)  

Use the Recorder to capture the fist item of the list, and get the Locator:
![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230309194441.png)

Modify the value of index by creating a variable: `{{indexValue}}` using double brackets, and then iterating through each item in the code with a loop.  
```python
from clicknium import clicknium as cc, Locator, ui

index = 1
driver = cc.chrome.open("https://getbootstrap.com/docs/5.1/components/list-group/")
while True:
    variables = {"indexValue":index}
    if driver.is_existing(locator.chrome.getbootstrap.li_anitem, variables):
        text = driver.find_element(locator.chrome.getbootstrap.li_anitem, variables).get_text()
        print(text)
        index += 1
    else:
        break
```
## 5.4 Get values of Locator attribute

The `get_text` method automatically retrieves the text displayed in the corresponding UI element. When we need to obtain other attribute values of the UI element, we can use the [get_property](https://www.clicknium.com/documents/references/python/uielement/get_property "get_property") method. Clicknium supports multiple automation technologies (refer to the [Automation Concepts](https://www.clicknium.com/documents/concepts/ "Automation Concepts")), and different automation technologies will generate different locators. Among them, Web corresponds to the browser, UIA and IA correspond to Windows desktop applications. For Web elements, on the Web automation page, you can find [the list of properties (Web element properties)](https://www.clicknium.com/documents/concepts/web#web-element-properties).


![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301element properties.png)  

```python
from clicknium import clicknium as cc, Locator, ui
#get the URL of currentpage
tag = ui(locator.chrome.bing.search_sb_form_q).get_property("URL") 
# get the title of the UI element
tag = ui(locator.chrome.bing.search_sb_form_q).get_property("title") 
```

## 6. Capture Similar elements

We often need to handle a large number of similar elements in web pages or applications, such as UI elements in lists and grids. Sequentially capturing these elements will generate a large number of locators, which is obviously not a good method. Some users even ask how to traverse a locator folder when the same type of Locator is placed in a folder. Of course, using parameterized locators mentioned earlier is also a way. However, on the one hand, you need to analyze which attribute and what value to traverse UI elements, and on the other hand, the range of parameters may be unknown, especially as the application becomes more and more complex and more and more dynamic loading is used, leading to the total number of UI elements to be captured cannot be predicted.

Usually, we use libraries like BeautifulSoup to parse the HTML structure of websites. As the website styles become more and more complex, the content captured is not always in the same structure. Each item may be wrapped in multiple layers of divs or other elements. Therefore, when parsing, we need to analyze the HTML structure and build an algorithm to find the smallest common node of all elements and traverse the structure. This process is indeed time-consuming but can be solved by algorithms.

Clicknium Recorder includes a feature for capturing similar elements. Users can capture two similar (same level) elements, and Clicknium's built-in algorithm automatically parses the HTML structure and calculates the minimum common node and hierarchical information to capture similar elements. If the calculated element is not what the user wants, a third capture can be performed, and the algorithm will recalculate the capture path based on the information of three UI elements.

### 6.1 how to use similar elements：

Using the [Okay Bear](https://opensea.io/collection/okay-bears) image in Opensea as an example, which is a typical Grid structure.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6vlookujin49txh879nk.png)


a.  Click the Capture button in the VS Code plug-in to start the Recorder: 


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b4wwy0n9kutxgxgk961q.png)

b. Click on Similar elements in the Recorder:


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5vd31kurx3khq95ldyg.png)


c. Ctrl + Mouse click to grab the first and second elements.：


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr1kzvezg5yrfal6l3n8.png)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95ne8byp0r4qj4iog8v1.png)

After crawling the Locator corresponding to the similar elements, call [find_elements](https://www.clicknium.com/documents/references/python/webdriver/browser/browsertab/webelement /find_elements) to return a UI element list ([find_element](https://www.clicknium.com/documents/references/python/webdriver/browser/browsertab /webelement/find_element) returns a single UI element.


Sample code：

Get the picture URL by [get_property](https://www.clicknium.com/documents/references/python/uielement/get_property). Download the picture using request lib, and use [send_hotkey](https://www.clicknium.com/documents/references/python/uielement/send_hotkey) to press PgDn key to scroll and load more pictures. 

```python
import requests
from time import sleep
from clicknium import clicknium as cc, Locator
def main():
    cc.chrome.open("https://opensea.io/collection/okay-bears")
    nftDic = {}

    while True:
        newDic = {}
        finish = True
        sleep(4)
        nfts = cc.find_elements(locator.sample.opensea.img_okay_bear)
        for nft in nfts:
            src = nft.get_property("src")
            name = nft.get_property("alt")
            if name not in nftDic:
                newDic[name]=src
                finish = False

        for key,value in newDic.items():
            r = requests.get(value)
            print("Downloading:"+ key)
            imagePath = ".\image\" + key + ".jpg"
            with open(imagePath,'wb') as f:
                f.write(r.content)

        nftDic = nftDic | newDic
        if finish:
            break
        else:
            print("next page")
            cc.send_hotkey("{PGDN}")

if __name__ == "__main__":
    main()
```
## 7. Get structured data

In automated scenarios, there is a great demand for obtaining structured data, especially tabular data. Capturing similar elements is only suitable for capturing one column of data. Of course, one can capture a table column by column, but this approach may lead to alignment issues between different columns, increasing the risk of errors and making the operation very cumbersome.

There are two common scenarios for structured data: 
- Tables 
- Non-tabular structured data. 

Tables are relatively easy to understand, but what is non-tabular structured data? As mentioned above, in the case of OpenSea's pages, if one needs to simultaneously capture the prices and numbers corresponding to NFT images in order to construct a table, this can be considered non-tabular structured data. Compared with obtaining similar elements, structured data adds a matching algorithm between different columns and a range of functions to facilitate table operation.

### 7.1 Capturing tabular data.

1. Start the Recorder in VS Code
2. Click data scraper in the Recorder

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8przcrswmmrxaz4fpf7a.png)

For example, let's capture the following table in [Coingecko](https://www.coingecko.com/).

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7vv78by47ae4aenikz1a.png)
3. Use Ctrl+left mouse button to click on the first row and column of data in the table.
Clicknium will automatically detect the capture object for the table, and prompt whether to capture the full table information.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqfdyxvqpes1sq8317q3.png)
Click Yes to see the data preview. On the preview page, you can modify the column name, change the column order, delete the column, and so on. You can also select No, and then select the desired data column by column.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p40dmpipgv3owle833wy.png)

### 7.2 Capture non-tabular structured data.
Let's use an example：[Gaming chairs in Amazon website](https://www.amazon.com/s?k=gaming+chairs&pd_rd_r=071a746f-f709-4a1c-9131-c355b4cc70db&pd_rd_w=b4pJC&pd_rd_wg=gLsyP&pf_rd_p=12129333-2117-4490-9c17-6d31baf0582a&pf_rd_r=5R8Z3Y5NF2J8G0DQ66PC&ref=pd_gw_unk)

In this example, we need to fetch the product name, price and image. The operation is similar to capturing similar elements, where two elements determine a column.

a. Capture the first cell in the first column: the first product name.

b. Capture the second cell in the first column: the second product name.

c. The first column is captured successfully, click Add column to start capturing the second column elements.

d. Capture the second column, the first element: the first product price.
......

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3xtbbxjx5dpa9me4vkm7.png)

After capturing, Clicknium will organize the data into tables.
![](https://raw.githubusercontent.com/kayYOLO/pichost/main/pic/zh20230301/20230310155948.png)
On the preview page, you can also change the column names, and column order and select different attributes as column values.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g1cuuo9ivodk8f72dtkz.png)

Sample Code:
For structured data, Clicknium provides the [scrape_data](https://www.clicknium.com/documents/references/python/globalfunctions/scrape_data) method, which returns text in JSON format. Not only this function supports passing in the Locator of the page flip button to achieve automatic page flip, but page flip also supports setting controls and simulating the Mouse, etc., waiting for the page to load, grabbing the number of data bars, control and timeout.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dehy1r7rdwj0au9avjhw.png)


```python
from clicknium import clicknium as cc, Locator
import pandas as pd

row = cc.scrape_data(locator.jd.phone)
df = pd.json_normalize(row)
print(df.head(10))
```
## 8. Automation Technology

By default, Clicknium will automatically select the appropriate automation technology. However, when automating desktop applications, sometimes it is necessary to choose a different automation technology, and different automation technologies are thought to have different locator attributes.

Clicknium includes automation technologies：

-   [Web Automation](https://www.clicknium.com/documents/concepts/web)
-   [UIA](https://www.clicknium.com/documents/concepts/uia)
-   [IA](https://www.clicknium.com/documents/concepts/ia)
-   [Image Recognition](https://www.clicknium.com/documents/concepts/image)
-   [Java](https://www.clicknium.com/documents/concepts/java)
-   [SAP Automation](https://www.clicknium.com/documents/concepts/sap)

Note that the Locator recorded by different automation technologies has different Locator attributes and Element properties. For Element properties, you can check the documentation of the corresponding technology above and get the value of the property through the get_property method.

The following table provides a summary of the automation technologies supported by Clicknium.

| Automation Technology    | Scenario                          | Introduction                                                                                 |
| -------- | --------------------------- | ---------------------------------------------------------------------------------- |
| Browser Automation   | Chrome/Edge/IE/Firefox etc. | Chrome DevTools Protocol/ Web elements are controlled using Clicknium browser plug-in with injected JavaScript scripts.             |
| UIA      | Windows desktop application                | Based on Microsoft UI Automation, it has richer method and property information than IA, and is specially optimized for WPF.                             |
| IA       | Windows desktop application        | Based on Microsoft Active Accessibility (MSAA), it exposes some of the interface properties and APIs using the COM interface. Better support for software that is older in development. |
| Image Recognition     | try with other automation tech failed               | Based on Open CV, it is also the reason why the Clicknium Python SDK is relatively large                                           |
| JAVA automation | automate Java GUI Application                   | Based on the Java Access Bridge and enhanced with AWT components and more, you need to rely on the Clicknium Java plug-in.                         |
| SAP automation   | SAP WinGUI API              | Based on SAP GUI Scripting.                                                              |

In the Recorder, the default options can be modified to select the automation techniques you need:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g7zvwhd2ojo7uaqgwz90.png)

## 9. Pack the Clicknium project as an executable file

The user of an automation script is not necessarily the Python programmer himself. When automation scripts need to be handed off to different users, there are a variety of issues that need to be addressed. It is possible that the other party does not have a Python environment, lacks a particular Python library, or has a version conflict, or even that the other party is a business person and not a programmer. Packaging scripts into human-running exe executables can be a good solution to these problems.

Packing method：

-   Clicknium Project
-   PyInstaller

### 9.1 Packed by Clicknium Project 

Clicknium Package is Clicknium's built-in project management approach, designed to ensure that automation scripts are developed, debugged, executed and distributed in a way that guarantees the same operational results.

a. Create Clicknium Project

In VS Code, press Ctrl+Shift+P to bring up the Command Palette, select Clicknium: Create Project, and specify a path to save the project. During the project creation process, a virtual environment will be created for the project at the same time. You can see the environment information displayed next to the Python interpreter in the bottom right corner of VS Code.

Unlike a normal Python project, several files are automatically created in this Project.

- app.py: Python source file
- logo.icon: the Icon of the packaged executable
- clicknium.yaml: the configuration file for the Clicknium Project

clicknium.yaml, which contains basic information about the project, including entry and dependencies, log paths, etc. The logo.icon can be replaced with the icon file you want.

b. run and debug Clicknium Project

Similarly, in VS Code, press Ctrl+Shift+P to bring up the Command Palette, and select Clicknium: Run Project. clicknium will run the project with the configuration in clicknium.yaml. When you run the file directly from F5, you will not see the configuration in yaml for deployment and execution.

c. Clicknium Project package

In VS Code, press Ctrl+Shift+P to bring up the Command Palette, select Clicknium: Package Project, then select a path to store the executable, then select console, if the script contains a graphical interface, please select GUI, otherwise the graphical interface may not be displayed properly. Clicknium will package the script according to the information in clicknium.yaml.

The following is an example of a clicknium.yaml file.

```
startUp: app
ignoreFiles: .gitignore
log:
  folder: 
  type: File
type: project
requirements:
  python: 3.9.13
  pip: 
  packages:
  - package: clicknium
    version: 
  - package: pandas
    version: 1.5.3
  locators: []
```

In the above example：

app:the entry point file of the Python program

log: The default log path is C:\Users\{currentUser}\AppData\Local\Clicknium\Log. It can be modified to other paths. For example, the current path is .\\

python: the version of the Python interpreter to be packaged into the executable file. 

Clicknium will automatically scan for Python libraries used in the script and automatically add the corresponding library name and version number. If there are problems with the automatic addition, you can modify this section manually.

### 9.2 Package by PyInstaller

In addition to the built-in packaging method, a more common practice in Python development is to use the Pyinstaller: [PyInstaller Manual](https://pyinstaller.org/en/stable/).

To keep the project clean, it is still recommended to use a Python virtual environment for development. Typically, the Python virtual environment used for a project can be found by opening the settings.json file in the .vscode folder of the project file.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kmxzahxphu9lqj7vovhs.png)

a. Go to the directory of the virtual environment and use `pip install pyinstaller` to install pyinstaller. use the `pip list` to see what pyinstaller is included and the specific version information.


b. Edit publish.spec


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5xs5wkz774di7fjwu9vo.png)


Configuration description：

-   **Project location**：{$"project app.py full path"}，input the full address of the project app.py, such as 'c:\\Users\\{Username}\\Desktop\\Sample\\app.py'
-   **Clicknium SDK address**：($'clicknium .lib automation full path', 'clicknium\\.lib\\automation')，input Python virtual environment site-packages folder clicknium under.lib\\automation，such as：binaries=[('C:\\Users\\{Username}\\AppData\\Local\\Clicknium\\Envs\\Sample_17aea73e4ca65262\\.virtualEnv\\Lib\\site-packages\\clicknium\\.lib\\automation', 'clicknium\\.lib\\automation')]
-   **Locator address**：datas=[($'project .locator full path', '.locator')]，input the .locator address of project, such as, datas=[('c:\\Users\\YanZhiwei\\Desktop\\Sample\\.locator', '.locator')]
-   **Executable file name**：name=$'project name', Fill in the package to generate exe name. You can fill in your own

The following is an example.：

```
# -*- mode: python ; coding: utf-8 -*-


block_cipher = None


a = Analysis(
    ['c:\Users\KayYOLO\Desktop\Sample\app.py'],
    pathex=[],
    binaries=[('C:\Users\KayYOLO\AppData\Local\Clicknium\Envs\Sample_17aea73e4ca65262\.virtualEnv\Lib\site-packages\clicknium\.lib\automation', 'clicknium\.lib\automation')],
    datas=[('c:\Users\KayYOLO\Desktop\Sample\.locator', '.locator')],
    hiddenimports=[],
    hookspath=[],
    hooksconfig={},
    runtime_hooks=[],
    excludes=[],
    win_no_prefer_redirects=False,
    win_private_assemblies=False,
    cipher=block_cipher,
    noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='Sample',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None
)
```

## 10. Frequently Asked Questions：

### 5.1 How to launch a Windows application

You can launch desktop applications using Python's subprocess module 
```python
import subprocess

process_notpad = subprocess.Popen("notepad")
process_feishu = subprocess.Popen("C:\Users\kay\AppData\Local\Feishu\Feishu.exe")  
```

### 10.2 How to set a timer to run

a. Search for Task Scheduler in the taskbar

b. Create a Task or Create a basic Task


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/876al9nqmpmfe26hi19j.png)


c. Task Config：

-  Task name
-  Trigger：Select trigger conditions, daily, weekly or monthly, at startup, at login, etc.
-  Action： Select Launcher, Program or Script: Fill in the address of python.exe. Add parameter: the address of the automation script.

### 10.3 For the same website, if you open multiple browsers to log in to different accounts

With the browser automation extension, attach method is the choice. If you don't need to mouse and keyboard simulation, it is recommended to use Chrome and Edge browsers to call the CDP interface and bind the tab object to the corresponding browser tab. To make web browser instances not share cookies between them and to be able to log into different accounts on the same website, different User profiles can be used.

According to [open method](https://www.clicknium.com/documents/references/python/webdriver/open) method：

```
def open(
        self,
        url: str,
        is_maximize: bool = True,
        is_wait_complete: bool = True,
        userdata_folder_mode: Literal["automatic", "default", "custom"] = WebUserDataMode.Automatic,
        userdata_folder_path: str = "",
        timeout: int = 30
    ) -> BrowserTab 
```

set `userdata_folder_mode` to 'custom', and pass different folder paths to `userdata_folder_path`，as different addresses to store the user profile. For different browser tab, use differnet path, instant multi-account login is available.

### 10.4 Why sometimes the script will be stuck in the main for a long time? How to check the log？

Most scripts get stuck because they cannot find the UI element corresponding to the Locator. Clicknium has a default timeout of 30 seconds for locator operations. You can check the API documentation for the timeout time of the method. If you get stuck, first use `Validation` to make sure that the Locator can recognize the UI element.
If it didn't work, use `Recapture&Compare` to check the difference for the current UI element attribute and the old locator attribute.
The default path to the logs：C:\Users\{currentUser}\AppData\Local\Clicknium\Log

### 10.5 Why did the Locator fail after a while
There are many reasons why a locator may fail, such as dynamic loading, version updates, and context changes. First, you can use the `Recapture&Compare` function on the locator page to re-record and compare the differences between the old and new locators. Different properties will be highlighted.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7xhq81mmkejfbddu9v6j.png)

To make the Locator more stable, it is recommended to use wildcards, regular expressions, parameterized Locator, and other features to improve the Locator's robustness.

### 10.6 Why Mouse click and type text has no effect

Toggles between the system call method and the simulated mouse method. In some cases, when recording a button, it may record the logo inside the button or the outer border. For system calls, only the button has the click property. Some input boxes also have a click or focus state to be activated, so you can choose to click or focus parameters before input. Since there is no return value after the system call is triggered, Clicknium cannot throw an error. In such cases, it is recommended to click the button in a simulated mouse way.