Reload your Amazon Balance ‘n’ number of times using Scala & Selenium Web Driver

I think everyone should be taught to code just like how we are taught to learn at least one language while we grow up. While a language such as English or Spanish enables an individual communicate with another, learning to code will empower an individual to better navigate this digital world powered by technology evolution. There are many compelling reasons for why this is important. Technology already plays a major role in all of our lives. And it’s reach is only going to increase and there’s no way around it. One might as well learn to code and make it work for us.

Any repeated task is ripe for automation. Repetition bores humans while Computers are immune to such boredom. AmazonBalanceReload is a simple project based in Scala that fires up a Web Browser, Logs the user in to Amazon, opens up the Balance Reload page on Amazon, fills in the balance to reload and submits it. This uses Selenium Web Driver which is a popular tool for writing Functional tests to a Web Based project. Let’s take a look at this simple implementation.

The main method in the AmazonAutoReload Scala object serves as the entry point to the application much like the main method in a Java class. This holds the necessary properties which alternatively be picked up from a property file or be passed as arguments when running the Object. But just to keep things simple, they are maintained inline in this implementation.

 def main(args: Array[String]): Unit = {

    val driver: WebDriver = new ChromeDriver()

    val n = 1 //Number of reloads
    val amountPerReload: String = "0.5" //In USD
    val email = "username" //Amazon email/phone number
    val password = "password" //Amazon password.


    val url = "https://www.amazon.com/ap/signin?_encoding=UTF8&ignoreAuthState=1&openid.assoc_handle=usflex&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.mode=checkid_setup&openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.ns.pape=http%3A%2F%2Fspecs.openid.net%2Fextensions%2Fpape%2F1.0&openid.pape.max_auth_age=0&openid.return_to=https%3A%2F%2Fwww.amazon.com%2F%3Fref_%3Dnav_custrec_signin&switch_account="
    val email_field = "email"
    val password_field = "password"
    val submitBtn_field = "signInSubmit"

    login(driver, url, email_field, password_field, submitBtn_field, email, password)
    reload(driver, n, amountPerReload)

  }

 

The main method calls the login() method first while passing in the Web Driver instance among other things.

def login(driver: WebDriver, url: String, email_field: String, password_field: String, submitBtn_field: String, email: String, password: String): Int = {

    driver.get(url)

    val username_field_ele: WebElement = driver.findElement(By.name(email_field))
    username_field_ele.sendKeys(email)

    val password_field_ele = driver.findElement(By.name(password_field))
    password_field_ele.sendKeys(password)


    val submitBtn = driver.findElement(By.id(submitBtn_field))
    submitBtn.submit()
    return 0

  }

After the login is complete synchronously, reload() is then called which is just the front for calling the reloadOnce() based on the user input

def reload(driver: WebDriver, n: Int, amountPerReload: String): Int = {

    for (i <- 1 to n) {
      reloadOnce(driver, amountPerReload)
      Thread.sleep(10000)
    }

    return 0
  }

reloadOnce()

 def reloadOnce(driver: WebDriver, amountPerReload: String): Int = {

    driver.get("https://www.amazon.com/asv/reload/order?ref=asv_re_th_ftr_d")

    val manualReloadAmt = driver.findElement(By.id("asv-manual-reload-amount"))
    manualReloadAmt.sendKeys(amountPerReload)
    Thread.sleep(2000)
    manualReloadAmt.sendKeys((Keys.TAB))
    Thread.sleep(2000)

    val confirmPayment = driver.findElements(By.className("a-alert-content"))
    if (confirmPayment.size() > 0)
      confirmPaymentDetails(driver, "xxxx")


    Thread.sleep(2000)

    driver.findElement(By.id("form-submit-button")).submit()

    return 0
  }

Sometimes, Amazon triggers a payment verification step if it senses that something is fishy (Like trying to use this script to reload multiple times within a short period of time). The confirmPaymentDetails() takes care of that. This needs to further tuned to be production ready. But since this is for fun and for learning, this should suffice for now.

  def confirmPaymentDetails(driver: WebDriver, card: String): Int = {
    driver.findElement(By.id("asv-payment-edit-link")).click()
    Thread.sleep(2000)
    driver.findElement(By.id("pmts-id-2")).click()
    Thread.sleep(2000)
    driver.findElement(By.id("pmts-id-31")).sendKeys(card)
    Thread.sleep(2000)
    driver.findElement(By.id("pmts-id-33-announce")).submit()
    Thread.sleep(2000)
    driver.findElement(By.id("pmts-id-2")).click()
    Thread.sleep(2000)
    driver.findElement(By.id("asv-form-submit")).click()
    return 0

  }

Selenium is very powerful and it can be re purposed to automate practically anything we do in a browser (With some caveats!) such as checking your bank balances, paying all of your bills while logging in to each biller (Takes time to setup but it can be done) or any other repetitive task.

Source Code

https://github.com/batchu/AmazonBalanceReload.git

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.