Selenium Workbook #45: Shopping Cart

Testing a common eBusiness feature

Courtney Zhan
4 min readSep 7, 2024

This article is one of the “Web Test Automation Workbook” series, a set of bite-sized exercises (typically 15–20 mins). A practical and satisfying way to learn web test automation with Selenium WebDriver.

Learning Objectives

  • contains in XPath expressions
    (a bit like a partial check-in XPath)
  • Tip: Use simple locators whenever possible
  • Review: refresh the page
  • Tip: Be aware of elements with the same ID

Test Case 45

Continue from #34: adding non-time-based service.

Test Design

  • Log in as a business
  • Create several service (i.e. billing) items
  • Log out
  • Log in as a client
  • Visit the business’ store URL /biz/wise-pool/store
  • Select a billing item and quantity (multiple)
  • Verify the total amount in the shopping cart
  • Refresh the page
  • Click the cart icon and verify the total amount
    This is to verify the session, don’t forget to test this for session-related test cases

Test Data (Login) :

Site URL: https://whenwise.agileway.net
Login (Business): pool@biz.com
Login (Customer): james@client.com
Password: test01

Tasks

Task 1. Select Quantity for a Billing Item (dropdown)

WhenWise Shopping Cart screen

The quantity selection is a drop down box.

Even though the ID locator is recommended in the general case, experienced test engineers would NOT use ID locator this time, like below.

driver.find_element(:id, "quantity-33")

Why? The id’s 33 might change in the next release.

One way to use XPath locator. The statements below select quantity “2” for the first billing item.

qty_elem = driver.find_element(:xpath, "//select[contains(@name, 'quantity_')]")
Selenium::WebDriver::Support::Select.new(qty_elem).select_by(:text, "2")

Please note the use //select[contains(@name, 'quantity_')] , which means “finding the first <select>element matching: its name attribute contains the text quantity_2 ”.

Task 2. Select the Quantity for a specific Billing Item

How about the quantity drop down for a specific billing item. Remember the ‘XPath go back the parent and come back’ trick?

qty2_elem = driver.find_element(:xpath,
"//tr/td/span[text()='Half-year Maintenance']/../../td/select[contains(@name, 'quantity_')]")
Selenium::WebDriver::Support::Select.new(qty2_elem).select_by(:text, "4")

Task 3. Click the ‘Add’ button

The HTML for the ‘Add’ button:

<a href="#" id="add_service_33" onclick="add_service_fee(33); return false;" class="btn btn-default btn-xs no-uppercase  add_invoice_item">Add</a>

It looks like a button, but in fact, is a hyperlink. Some might want to reuse the approach in Task 1. It works, but complex unnecessarily. The standard Link locator works fine, :-).

driver.find_element(:link, "Add").click

Task 4. Refresh the page

We used this a few times before: driver.navigate.refresh.

Here I want to talk about why we need to ‘Refresh’ in Test Design. A key concept of a Shopping Cart is a Session. During a session, the user can always see the goods count in the shopping cart. Refreshing the page (in automated test scripts) is to verify that we don’t lose the shopping cart’s contents by navigating to another page.

Task 5. Assert the total amount in the modal dialogue

This seems simple, just as you have done many times before, driver.find_element(:id, 'cart_total_price').text. However, this one is slightly trickier. There are two #cart_total_priceelements (the same ID)

puts  driver.find_elements(:id, "cart_total_price").count # => 2

One solution is to use find_elements , then refer to the one by index, such as driver.find_elements(:id, 'cart_total_price').last.text

A more reliable way is to use XPath locator, specifying the modal and the ID in the XPath expression.

driver.find_element(:xpath, "//div[@id='cart-modal']//strong[@id='cart_total_price']").text

Full Test Script

load File.dirname(__FILE__) + "/../test_helper.rb"

describe "Shopping cart" do
include TestHelper

before(:all) do
# browser_type, browser_options, site_url are defined in test_helper.rb
@driver = $driver = Selenium::WebDriver.for(browser_type, browser_options)
driver.manage().window().resize_to(1280, 856)
driver.get(site_url + "/reset")
driver.get(site_url)
sign_in("pool@biz.com", "test01")

visit("/services")

service_list_page = ServiceListPage.new(driver)
driver.find_elements(:partial_link_text, "NEW SERVICE").last.click

new_service_page = NewServicePage.new(driver)
new_service_page.enter_name("Maintaining - 6 months")
new_service_page.enter_price(99)
new_service_page.toggle_is_time_based
new_service_page.click_create
sign_out

end

after(:all) do
driver.quit unless debugging?
end

it "Shopping Cart" do
sign_in("james@client.com", "test01")
visit("/biz/wise-pool/store")
qty_elem = driver.find_element(:xpath, "//select[contains(@name, 'quantity_')]")
Selenium::WebDriver::Support::Select.new(qty_elem).select_by(:text, "2")

driver.find_element(:link_text, "Add").click
sleep 0.5
expect(driver.find_element(:id, "cart_total_price").text).to eq("A$217.80")
driver.navigate.refresh
driver.find_element(:id, "cart-link").click
sleep 1
expect( driver.find_element(:xpath, "//div[@id='cart-modal']//strong[@id='cart_total_price']").text).to eq("A$217.80")
end
end

For all testing challenges on the WhenWise practice site (like this one), TestWise customers receive free complimentary coaching services. That is, Customers who purchased a TestWise license ($30/month) can raise tickets on Agileway’s support site (attaching your TestWise project, in a zip format), and a test coach will provide you reviews, suggestions, and solutions, for free!

--

--