Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automation example - RedMart rescheduling or repeating groceries order #24

Closed
kensoh opened this issue Jul 5, 2019 · 15 comments
Closed
Labels

Comments

@kensoh
Copy link
Member

kensoh commented Jul 5, 2019

Whenever there is a need to reschedule or repeat our groceries delivery on RedMart.com, there is a need to manually add back all the previous items one by one to create a new order. There is no option to repeat an order (unbelievable).

My wife is very frustrated with that, because in between clicks there is so much waiting time, and the website cannot be ctrl-clicked to open new tabs to do this efficiently. So I wrote below automation script for her. Instead of wasting time doing mindless work every week, now she can double-click this Python script and automate the process herself.

PS - we have since left Singapore and no longer use RedMart, thus below code would likely not work with updates to the website. But it should give you an idea of what's possible with rpa package and how you can approach a scenario.

redmart_order

import rpa as r
r.init()

# get URL of old groceries order to re-add all items to cart
r.url(r.ask('Paste the URL of your groceries order and login to RedMart'))

# set a maximum 5-minute timeout for user to login to RedMart
r.timeout(300)

# use exist() function with XPath to check if logged in
if not r.exist('(//*[@class="order-item"])[1]//*[@class="item-pic"]'):
    r.dom('alert("Quitting as groceries order page is not detected after 5 min")')

# change back to default of 10 seconds to quit fast on error
r.timeout(10)

# get count of total items to place order for, using XPath identifier
total_items = r.count('//*[@class="order-item"]//*[@class="item-pic"]')

# to track total quantity of items to order
total_quantity = 0

# loop to add all the items and their quantity
for item in range(1, total_items + 1):
    # get count of quantity to order for item, before clicking into item
    item_quantity = int(r.read('(//*[@class="order-item"])['+ str(item) + ']//*[@class="item-quantity"]//*[@class="text"]'))
    r.click('(//*[@class="order-item"])[' + str(item) + ']//*[@class="item-pic"]')

    # first click ADD TO CART, then click + icon for subsequent quantity
    if r.exist('ADD TO CART') and not r.present('Out of stock'):

        # handle case where item is in cart, thus no ADD TO CART button
        if r.present('next-icon-add'):
            r.click('next-icon-add')
        else:
            r.click('ADD TO CART')

        for additional_quantity in range(item_quantity - 1):
            r.click('next-icon-add')

        # wait to ensure adding of item has been registered before going back
        r.wait(3)
        total_quantity = total_quantity + item_quantity

    # go back to the previous page with list of items
    r.dom('history.back()')

    # optional wait to slow down the pace of iteration in the automation
    r.wait(3)

# show popup with summary of the quantity of items added before exiting
r.dom('alert("A total quantity of ' + str(total_quantity) + ' items has been added to cart")')
r.close()
@kensoh kensoh added the query label Jul 5, 2019
@kensoh
Copy link
Member Author

kensoh commented Jul 5, 2019

Adding on, wait() is usually not necessary as there is auto-wait for UI elements to appear until timeout.

For above, it is to ensure that the click has been processed by the webapp (seems to have some lag) before proceeding, and that previous page items have been fully loaded before proceeding.

@kensoh
Copy link
Member Author

kensoh commented Jul 12, 2019

Updated above version 2 with browser prompt for URL, and handles multiple quantity per item

@kensoh kensoh changed the title Simple automation example - RedMart re-adding cancelled order Jul 12, 2019
@kensoh kensoh changed the title Simple automation example - RedMart rescheduling order (cancel & add again) Jul 12, 2019
kensoh added a commit that referenced this issue Jul 12, 2019
#31 - ask() shows the question in terminal window. This is not intuitive if automation is running on the Chrome browser and a prompt appears in terminal window to ask for user input. Raising an issue to update behaviour to show prompt in Chrome browser, if it's available. PS - similar issue exists if chrome_browser = False and visual_automation = True. The terminal may not be in the foreground during the automation flow to be visible for user inputs. However, there isn't a consistent way to show SikuliX popup with focus across platforms. Thus KIV for now.

#32 - At present, if visual automation mode is not on and `snap('page.png', 'screenshot.png')` is used, there is no error message saying that `init(visual_automation = True)` is needed to use this. Raising an issue to show error message instead of hanging waiting for SikuliX response.

#24 - readme linking to RedMart online groceries example to automate re-adding all items to cart (to reschedule delivery, need to cancel and create new order manually)
kensoh added a commit that referenced this issue Jul 12, 2019
#31 - ask() shows the question in terminal window. This is not intuitive if automation is running on the Chrome browser and a prompt appears in terminal window to ask for user input. Raising an issue to update behaviour to show prompt in Chrome browser, if it's available. PS - similar issue exists if chrome_browser = False and visual_automation = True. The terminal may not be in the foreground during the automation flow to be visible for user inputs. However, there isn't a consistent way to show SikuliX popup with focus across platforms. Thus KIV for now.

#32 - At present, if visual automation mode is not on and `snap('page.png', 'screenshot.png')` is used, there is no error message saying that `init(visual_automation = True)` is needed to use this. Raising an issue to show error message instead of hanging waiting for SikuliX response.

#24 - readme linking to RedMart online groceries example to automate re-adding all items to cart (to reschedule delivery, need to cancel and create new order manually)
@kensoh
Copy link
Member Author

kensoh commented Jul 12, 2019

Closing issue as this example is now added to readme under API reference section.

@kensoh kensoh closed this as completed Jul 12, 2019
@kensoh kensoh changed the title Automation example - RedMart rescheduling order (cancel & add again) Jul 14, 2019
@kensoh kensoh changed the title Automation example - RedMart rescheduling or repeating order Jul 14, 2019
@CL545740896
Copy link

[TAGUI][ERROR] - 'utf-8' codec can't decode bytes in position 44-45: invalid continuation byte ,I think u should support utf-8 , Chinese example

@kensoh
Copy link
Member Author

kensoh commented Dec 3, 2019

Can you paste the Python code that cause this error message so that I can check?

In this issue #14 the package has switched over to use UTF-8. Not sure of the cause, it could be that webpage you are accessing has non-UTF-8 characters. Wait for your code to check further. I assume you are using new version of the package r.__version__ should be > 1.4 for UTF-8.

For eg of Chinese text that works, below goes to Baidu to search and show the first result -

import rpa as r
r.init()
r.url('http://www.baidu.com')
r.type('kw', 'tagui[enter]')
print(r.read('//*[@id="1"]'))
r.close()

The output shows correctly the Chinese and English text when I run above Python script -

kelaberetiv/TagUI_开源项目_极智能查看此网页的中文翻译,请点击 翻译此页2016年12月6日 - CLI tool for digital process automation (RPA)... To run TagUI flows in native languages or output fl...https://www.ziiai.com/project/...  - 百度快照
@sunnyhemnani
Copy link

Hey @kensoh
Can you please tell me how to set TagUI up on Production (Live Server)?
Thank you.

@kensoh
Copy link
Member Author

kensoh commented Feb 18, 2020

Hi @sunnyhemnani the setup instructions for this package are here -
https://github.com/tebelorg/RPA-Python#rpa-for-python-snake

Just pip install rpa, you will need Python installed on the server.

If you are referring to the TagUI RPA software instead of this Python package,
refer to these setup steps - https://github.com/kelaberetiv/TagUI#set-up

@sunnyhemnani
Copy link

@kensoh I want to know the basic Server specifications for TagUI RPA software?
I have a droplet on the Digital ocean!

@kensoh
Copy link
Member Author

kensoh commented Feb 18, 2020

A basic Windows, Linux or macOS operating system should be able to run TagUI or RPA for Python. No need high-powered CPU or high RAM to run it. Chrome is needed for automating websites.

@jroachgit
Copy link

jroachgit commented Nov 30, 2020

@kensoh is there a way to set an active chrome window or by title, as the working window for the RPA bot to work with?

It seems that when it launches the URL, its in a slim incognito window - If i'm working in a secured/ login page or one that is only accessible via another portal, then it requires a bit of running around to get there each time I want to use the bot.

thanks

@kensoh
Copy link
Member Author

kensoh commented May 11, 2021

Hi @yeders to do that you can use visual automation, and do a click() on the taskbar / docking bar to click on the Chrome icon to make it in the foreground. You can also try simulating [alt][tab] (Windows) or [cmd][tab] (Mac) using keyboard() and keep repeating until Chrome window is in front (use hover() to check for some unique thing on the screen to tell that it is ready).

@ringomass
Copy link

If i use href to get part of the address link, which method is used

@kensoh
Copy link
Member Author

kensoh commented Jun 5, 2021

For reading attributes of a web element, the syntax is using r.read('XPath/@href')

@ringomass
Copy link

ringomass commented Jun 6, 2021

Do I need to write the full href address here? If so, can I use a regular expression, because herf is dynamic

1622863408528

微信截图_20210606114250

微信截图_20210606114259

@kensoh
Copy link
Member Author

kensoh commented Jun 8, 2021

Hi @ringomass, I assume that you want to read the URL for use later. In that case, first find a good way to point to the item, eg some XPath. After that then do r.read('XPath/@href').

You can try google more on XPath to see how to write XPath, or try using the Chrome inspector to copy out the XPath - https://tagui.readthedocs.io/en/latest/faq.html#how-do-i-find-the-xpath-of-a-web-element

Above website doesn't look like public can access so I can't try it.

PS - and once you find how to click on it, using r.click('XPath') will do, no need use read(). See this for info on what type of inputs can be given to point to the webpage item - https://github.com/tebelorg/RPA-Python#element-identifiers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
5 participants