Filling in the sales form

The eagle has landed! 🦅

Our robot logged in to the intranet! On the page, there is a form where Maria can fill in the sales data for one sales representative.

Sales form

Here's the form HTML markup for reference (this is what a web browser sees before it renders a nice-looking website for you):

<form id="sales-form"> <div class="form-group"> <label for="firstname">First name</label ><input type="text" id="firstname" name="firstname" required="" class="form-control" /> </div> <div class="form-group"> <label for="lastname">Last name</label ><input type="text" id="lastname" name="lastname" required="" class="form-control" /> </div> <div class="form-group"> <label for="salestarget">Sales target ($)</label ><select id="salestarget" required="" class="custom-select"> <option value="5000">$5,000</option> <option value="10000">$10,000</option> <option value="15000">$15,000</option> <option value="20000">$20,000</option> <option value="25000">$25,000</option> <option value="30000">$30,000</option> <option value="35000">$35,000</option> <option value="40000">$40,000</option> <option value="45000">$45,000</option> <option value="50000">$50,000</option> <option value="55000">$55,000</option> <option value="60000">$60,000</option> <option value="65000">$65,000</option> <option value="70000">$70,000</option> <option value="75000">$75,000</option> <option value="80000">$80,000</option> <option value="85000">$85,000</option> <option value="90000">$90,000</option> <option value="95000">$95,000</option> <option value="100000">$100,000</option> </select> </div> <div class="form-group"> <label for="salesresult">Sales result ($)</label ><input type="number" id="salesresult" name="salesresult" required="" class="form-control" /> </div> <button type="submit" class="btn btn-primary">Submit</button> </form>

The next logical step in our task, using plain English, will be Fill and submit the sales form, which we translate to fill_and_submit_sales_form().

You can use any language you want when naming your functions, although many libraries provide functions written mainly in English. Keep in mind, the syntax is case-sensitive.

This is a valid function name: DEjLigT_at_mødE_dig() but when called, it needs to be exactly the same.
Use auto-complete so you get it right!

Modify your task function like this:

from robocorp.tasks import task from robocorp import browser @task def robot_spare_bin_python(): """Insert the sales data for the week and export it as a PDF""" browser.configure( slowmo=100, ) open_the_intranet_website() log_in() fill_and_submit_sales_form()

As we have learned, we need to implement the function so that our robot knows what to do. Let's define this new function at the end of our code (also by adding the docstrings):

def fill_and_submit_sales_form() """Fills in the sales data and click the 'Submit' button"""

Eating an elephant 🐘

The form is composed of three text input fields and one field where one can not type in. Looks complicated! 🤯

Breathing intensifies, beads of sweat appear on the software robot developer's forehead.

Out of nowhere, a deep voice rumbles:

There is only one way to eat an elephant: a bite at a time.

Right. We can tackle any challenge by taking small steps. Try the simplest thing you can think of first. We do not have to get everything done properly on the first try. Iterating is the key to success!

Let's start our "simplest possible solution" experiment by just submitting the form without worrying about inputting anything to it. That's right! We only want to see what happens.

The robocorp.browser library provides a click function. Let's use that one here! This will need a way to identify the correct element in the page, so we will provide thhe text of the button - text=Submit. But before any clicking, we need to make sure our robot has the correct context of the new page.

def fill_and_submit_sales_form(): """Fills in the sales data and click the 'Submit' button""" page = browser.page() page.click("text=Submit")

Ok, that should do the trick. Using the Command Palette (Shift-Command-P (macOS) or Ctrl+Shift+P (Windows)), we run the robot from the very beginning and celebrate our success! We see that an error is displayed in the form, but our test passes gracefully.

Progress! We ate a small piece of the elephant and can continue devouring the beast, a bite at a time.

The evolution of a solution, Part I 🥚

In the spirit of taking small steps towards our ultimate goal, we will cut some corners. We'll be hard coding our sales data for now. That is, we are not concerned about using real data just yet. That is perfectly acceptable at this point. We want to see that our general flow works. This way, we can find possible technical blockers as soon as possible. We will create a crude solution first and polish it to production quality later.

Using our previous knowledge of the page.fill() function, we can easily fill the First Name, Last Name and Sales Results fields of this new form. We just need to use the id of each field as the locator:

def fill_and_submit_sales_form(): """Fills in the sales data and click the 'Submit' button""" page = browser.page() page.fill("#firstname", "John") page.fill("#lastname", "Smith") page.fill("#salesresult", "123") page.click("text=Submit")

However, the sales target is not a simple text field but a select HTML element. We need to use a different keyword to select a value from the ones that the field allows. page.select_option() comes to the rescue! The keyword takes a selector and a value as arguments:

def fill_and_submit_sales_form(): """Fills in the sales data and click the 'Submit' button""" page = browser.page() page.fill("#firstname", "John") page.fill("#lastname", "Smith") page.fill("#salesresult", "123") page.select_option("#salestarget", "10000") page.click("text=Submit")

Save time and money with auto-completion!

Here's how our complete robot looks like now:

from robocorp.tasks import task from robocorp import browser @task def robot_spare_bin_python(): """Insert the sales data for the week and export it as a PDF""" browser.configure( slowmo=100, ) open_the_intranet_website() log_in() fill_and_submit_sales_form() def open_the_intranet_website(): """Navigates to the given URL""" browser.goto("https://robotsparebinindustries.com/") def log_in(): """Fills in the login form and clicks the 'Log in' button""" page = browser.page() page.fill("#username", "maria") page.fill("#password", "thoushallnotpass") page.click("button:text('Log in')") def fill_and_submit_sales_form(): """Fills in the sales data and click the 'Submit' button""" page = browser.page() page.fill("#firstname", "John") page.fill("#lastname", "Smith") page.fill("#salesresult", "123") page.select_option("#salestarget", "10000") page.click("text=Submit")

We try running our robot again.

Success! Poor "John Smith" has his horrible performance entered in the intranet.

Hard-coded data submitted

We now have the basic outline of our form filling keyword done! Next, we need to figure out how to read real data from the Excel file and how to enter the data for multiple people in sequence.

What we learned

  • There is only one way to eat an elephant: a bite at a time.
  • The page.click() function can click on buttons using the label as the locator (other locators work, too).
  • Hard coding data is an acceptable practice for making progress and finding potential technical blockers faster.
  • Take small steps. Iterate often.