Code Example
Process data to ERP
An example how to use Aiviro to create a story, which at first reads emails from a mailbox and extracts the data from the email’s attachment, then it continues by adding this data into the ERP. In the end, all opened windows are closed by robot and a report is sent.
Main Story
An example how to use Aiviro, which handles the main loop with all the required actions and steps. To see more information about used classes, please see
BaseScenario
, ShellCommands
, InvoiceReader
.Download here
main_story_example.py
from pathlib import Path
from typing import Generator, Tuple
import aiviro
from aiviro.modules.config import YAMLConfig
from aiviro.modules.pdf import create_pdf_robot
from aiviro.modules.powershell import ShellCommands
from aiviro.modules.reader import InvoiceData, InvoiceReader
from docs.code_examples.erp_handler_example import ERPHandler
class MainStoryXX(aiviro.BaseScenario):
"""
This class inherits from BaseScenario and implements the main logic of the story.
This class handles a process of parsing attachments from an email and adding this
data to an ERP system. In the end, all opened windows are closed by a shell command
and a report is generated and sent to the list of recipients defined in the config file.
"""
def __init__(self, config: YAMLConfig):
super().__init__(config)
self.pdf_robot = create_pdf_robot()
# name of the robot is set in the config file
self.r = self.robot(robot_name="rdp_robot")
self.erp_handler = ERPHandler(
rdp_robot=self.r, export_folder=self.tmp_folder.unique_folder
)
self.invoice_reader = InvoiceReader(self.pdf_robot)
self.shell_commands = ShellCommands(self.r)
self.notifier = self.email_notifier()
def _before_run(self) -> None:
"""
e.g. wait until robot is connected to the RDP machine
"""
self.r.wait_until_ready()
def _after_run(self) -> None:
"""
e.g. close all opened applications, send a report etc.
"""
self.shell_commands.close_all_open_windows().execute()
self.notifier.send_report()
def _run(self):
"""
This method handles the main loop of the story
"""
for parsed_data, pdf_path in self._get_data_from_emails_pdf():
try:
self.erp_handler.handle_story_xx(data=parsed_data, pdf_path=pdf_path)
except Exception as e:
self.notifier.error(
f"An error occurred when processing PDF file {pdf_path} - {e}"
)
else:
self.notifier.successful(
f"Data from PDF file {pdf_path} was successfully added to ERP"
)
@aiviro.step
def _get_data_from_emails_pdf(
self,
) -> Generator[Tuple[InvoiceData, Path], None, None]:
"""
All the required parameters for email extractor can be set in the
.yaml config file , for example:
- maximum number of emails to be processed by setting variable
'max_valid_emails'
- conditions for email attachments by setting variable 'attachment_conditions',
e.g. if email contains pdf files within its attachments, then each
attachment is checked if it is a pdf file, otherwise it is skipped
"""
for _email, attachments in self.email_extractor().extract_all():
for one_attachment in attachments:
if one_attachment.suffix != ".pdf":
continue
data = self._parse_file(one_attachment)
yield data, one_attachment
@aiviro.step
def _parse_file(self, one_attachment: Path) -> InvoiceData:
# set required pdf file as a source for the pdf robot
self.pdf_robot.parse(one_attachment)
return self.invoice_reader.parse()
ERP Handler
An example how to use Aiviro to handle actions in ERP system. In this case, Aiviro robot is used to add parsed data from the pdf file to the ERP system.
Download here
erp_handler_example.py
import datetime
import pathlib
import aiviro
from aiviro.modules.reader import InvoiceData
class ERPHandler:
def __init__(self, rdp_robot: "aiviro.RDPRobot", export_folder: pathlib.Path):
self.r = rdp_robot
self._export_folder = export_folder
@aiviro.step
def handle_story_xx(self, data: InvoiceData, pdf_path: pathlib.Path) -> None:
"""Method called to handle whole process of adding data to ERP"""
self._start_erp()
self._open_invoices_with_new_record()
self._write_to_new_record(data)
self._attach_pdf(pdf_path)
self._save_new_record()
self._close_erp()
@aiviro.step
def _start_erp(self) -> None:
"""Method to start ERP program via WIN+R shortcut"""
self.r.start_process(r"path\to\your\erp\program.exe")
@aiviro.step
def _open_invoices_with_new_record(self) -> None:
"""Method to open invoices tab in ERP"""
self.r.double_click(aiviro.Text("Přijaté faktury", element_index=0))
self.r.click(aiviro.Text("Nový záznam", element_index=0))
@aiviro.step
def _write_to_new_record(self, data: InvoiceData) -> None:
"""Method to write provided data to new record"""
self.r.type_text(
element=aiviro.Input("Číslo dokladu", element_index=0),
text_to_type=data.invoice_id.value,
)
self.r.type_text(
element=aiviro.Input("Celková částka", element_index=0),
text_to_type=str(data.total_amount.value),
)
self.r.type_text(
element=aiviro.Input("Celková částka bez DPH", element_index=0),
text_to_type=str(data.total_amount_without_tax.value),
)
self.r.type_text(
element=aiviro.Input("Daňový doklad", element_index=0),
text_to_type=datetime.date.strftime(data.tax_date.value, "%d.%m.%Y"),
)
@aiviro.step
def _attach_pdf(self, pdf_path: pathlib.Path) -> None:
"""Method to attach pdf to the new record"""
self.r.transfer_files_to_guests_clipboard(pdf_path)
self.r.click(aiviro.Button("Připojit ze schránky", element_index=0))
@aiviro.step
def _save_new_record(self) -> None:
"""Method to save new record simply by clicking on the Save button.
And transfer generated files from guest clipboard to the export folder on the host machine.
"""
self.r.click(aiviro.Button("Uložit", element_index=0))
self.r.click(aiviro.Text("Nový záznam", element_index=0))
self.r.transfer_files_from_guests_clipboard(self._export_folder, copy=True)
@aiviro.step
def _close_erp(self) -> None:
"""Method to close ERP program"""
self.r.click(aiviro.Button("Zavřít", element_index=0))
self.r.click(aiviro.Button("Ano", element_index=0))
Simple scripts
Example how to automate login testing.
Download here
simplehq_login.py
import aiviro
if __name__ == "__main__":
# init aiviro logger
aiviro.init_logging()
#################
# Test case
#################
# create web-robot
r = aiviro.create_web_robot(headless=False) # only works in non-headless mode
r.go_to_url("https://app.simplehq.co/login.html")
# wait until page is fully loaded
r.wait_for(aiviro.Text("Hello!"))
# type login credentials & click log-in button
r.type_text(aiviro.Input("Email"), "jelenovi.pivo.nelej@wtf.com")
r.type_text(aiviro.Input("Password"), "123456789")
r.click(aiviro.Button("Log In"))
# check that the log-in was invalid
r.wait_for(aiviro.Text("Information provided is incorrect."), timeout=10)
# close the web-robot
r.close()
Example how to check the alignment of elements.
Download here
todo_mvc_alignment.py
import aiviro
URLS = [
"http://todomvc.com/examples/vanillajs/",
"http://todomvc.com/examples/backbone/",
"http://todomvc.com/examples/angularjs/#/",
"http://todomvc.com/examples/emberjs/",
"http://todomvc.com/examples/knockoutjs/",
"http://todomvc.com/examples/dojo/",
"http://todomvc.com/examples/knockback/",
"http://todomvc.com/examples/canjs/",
"http://todomvc.com/examples/polymer/index.html",
"http://todomvc.com/examples/react/#/",
"http://todomvc.com/examples/mithril/#/",
"http://todomvc.com/examples/vue/",
"http://todomvc.com/examples/backbone_marionette/",
]
if __name__ == "__main__":
# init aiviro logger
aiviro.init_logging()
#################
# Test case
#################
# create web-robot
r = aiviro.create_web_robot(headless=True)
for url in URLS:
r.go_to_url_in_new_tab(url)
# create Input search-object & wait until it appears on the website
input_object = aiviro.Or(
aiviro.Button("What needs to be done?", element_index=0),
aiviro.Input("What needs to be done?", element_index=0),
)
input_box = r.wait_for(input_object, timeout=15)
# add 3 tasks into list
r.type_text(input_box, "Do the laundry\n")
r.type_text(input_box, "Go shopping\n")
r.type_text(input_box, "Pay the bills\n")
# wait until the last task appears in the list
r.wait_for(aiviro.Text("Pay the bills"), timeout=10)
do_the_laundry_label = aiviro.Text("Do the laundry")
go_shopping_label = aiviro.Text("Go shopping")
pay_the_bills_label = aiviro.Text("Pay the bills")
# check different alignment of the elements
r.check_are_in_column(
do_the_laundry_label,
go_shopping_label,
pay_the_bills_label,
anchor=aiviro.layout_anchor.LEFT,
tolerance=10,
)
r.check_is_positioned(
do_the_laundry_label,
go_shopping_label,
direction_type=aiviro.layout_positions.IS_ABOVE,
)
r.check_is_positioned(
pay_the_bills_label,
go_shopping_label,
direction_type=aiviro.layout_positions.IS_BELOW,
)
# close the web-robot
r.close()
Example of filling up the registration forms.
Download here
eshop_registration.py
import aiviro
if __name__ == "__main__":
aiviro.init_logging()
r = aiviro.create_web_robot(headless=True)
r.set_animation_timeout(5)
FIRST_NAME = "Aiviro"
LAST_NAME = "Test"
EMAIL = "aiviro@test.cz"
PHONE_NUMBER = "777189234"
# e-shop Nazuby
r.go_to_url("https://www.nazuby.cz/")
r.click(aiviro.Icon("Prihlasit"), aiviro.Text("Registrace"))
r.type_text(aiviro.Input("Jmeno"), FIRST_NAME + " " + LAST_NAME)
r.type_text(aiviro.Input("Vas e-mail"), EMAIL)
# e-shop MALL
r.go_to_url("https://www.mall.cz")
r.move(aiviro.Text("Muj ucet"))
box_button = r.wait_for(aiviro.Button("Zaregistrovat"))
r.click(box_button)
r.type_text(aiviro.Input("Jmeno"), FIRST_NAME)
r.type_text(aiviro.Input("Prijmeni"), LAST_NAME)
r.type_text(aiviro.Input("Vas e-mail"), EMAIL)
r.type_text(aiviro.Input("Telefon"), PHONE_NUMBER)