Behat Automation Scenarios for e-Commerce

Tags: Behat, eCommerce, quality assurance


eCommerce sites are gaining in popularity with each day. With the increase in demand, it has become extremely important to ensure the availability of each and every feature on these sites. If the site is multi-linguistic, then testing it manually becomes even more tedious. Testing on various browsers and for responsiveness adds to the work further.

In this blog, we will be discussing the most common and important features of these sites which can be automated. Functional regression tests become necessary when the site starts growing larger with each new function being added to the site. In this blog, we will consider http://automationpractice.com/index.php our demo test site.

Functional scenarios that can be automated for any eCommerce site are as below:

Checkout using various delivery types & payment options

1. Checkout is the most important feature of any eCommerce site, since it directly impacts the business of the site. Hence, it is extremely important to automate all possible combinations of delivery type (Home Delivery, Collect from Store) and payment types (Cash on Delivery, Pay through Card, etc.)

2. Ensure that a test is written for each combination on all supported languages too.

3. Ensure that checkout works for guests, authenticated users and returning customers (someone who logs in after populating the cart).

4. While checking out, write tests to ensure that the user is able to select from multiple addresses, if available. Also, the user should be able to add a new address while checking out, and check out using the newly added address.

Search

Search is the next most important feature of these sites, because it lets users quickly find what they are looking for:

1. Ensure the test verifies that the search term is present in any of the indexed fields in all the search results displayed. Indexing can be done on any field, either the title, small description, long description, or all of them. Gherkin statements for search would be as below:

Given I am on homepage

And I wait for the page to load

When I fill in "search_query" with "summer dress"

And I press "submit_search"

Then I should see Search results page for "summer dress"


Below is a small piece of code that validates whether either of the search terms is present in the title of the results displayed:

public function iShouldSeeSearchResultsPageFor($arg1)

{

  $page = $this->getSession()->getPage();

  $page->hasContent("search results for " . $arg1);


  $expected_text = explode(' ', $arg1);

  $actual_text = $page->findAll('css', '.product-name');

  $flag = FALSE;


  if (!empty($actual_text)) {

      foreach ($actual_text as $text) {

          $actual_values1 = $text->find('css', 'a')->getText();

          foreach ($expected_text as $a) {

              if (stripos($actual_values1, $a) !== FALSE) {

                  $flag = TRUE;

              }

          }

          if (!$flag) {

              throw new Exception('Search results are not correct');

          }

      }

  } else {

      echo 'Search passed. But, Search term did not yield any results';

  }

}

2. Users should be able to narrow down their search results using the sorting options. Ensure tests are written to test all types of sorting options. Verify whether all the available filters are working as expected. The Gherkin scenario would be similar to the one below:

Given I am on homepage

And I wait for the page to load

When I fill in "search_query" with "black"

And I press "submit_search"

And I wait for the page to load

When I select "name:asc" from "selectProductSort"

And I wait for the page to load

Then I should see results sorted in ascending order

The sorting function below can be used to check low and high price order too. The code to check all sorts of sorting options is as below:

public function iShouldSeeResultsSortedInAscendingOrder() {

$page = $this->getSession()->getPage();

$elements = $page->findAll('css', '.product-name');

if ($elements == NULL) {

  echo 'No search results found';

}

foreach ($elements as $element) {

  if ($element !== NULL) {

    $value = $element->find('css', 'a')->getText();

    $actual_values[] = $value;

  }

  else {

    throw new Exception('Element is returning null');

  }

}

if (!$this->is_array_ordered($actual_values, ORDER_ASC)) {

  throw new Exception('Search results list is not sorted in ascending order');

}

}



public function is_array_ordered($array, $sort_order) {

$i = 0;

$total_elements = count($array);


if ($sort_order == ORDER_ASC) {

  //Check for ascending order

  while ($total_elements > 1) {

    if (strtolower($array[$i]) <= strtolower($array[$i + 1])) {

      $i++;

      $total_elements--;

    }

    else {

      var_dump($array[$i]);

      var_dump($array[$i+1]);

      return FALSE;

    }

  }

}

elseif ($sort_order == ORDER_DSC) {

  //Check for descending order

  while ($total_elements > 1) {

    if (strtolower($array[$i]) >= strtolower($array[$i + 1])) {

      $i++;

      $total_elements--;

    }

    else {

      var_dump($array[$i]);

      var_dump($array[$i+1]);

      return FALSE;

    }

  }

}


return TRUE;

}

NOTE: The sorting function above handles any special characters and uppercase characters to give appropriate results.

3. Ensure the user is able to search terms, add items to the cart and complete the checkout journey. In this condition, you would have to write a script that clicks on the product that is in stock and then adds it to the cart.

4. Lastly, ensure the user is able to search for terms in the language of the site. Search results displayed should also be in the same language and not the default one, for example, say English.

My account section: For signed up users

1. User should be able to view and update account details like address, contact number, etc.

2. User should be able to view past orders.

3. User should be able to sort orders based on the order status.

Products listing page

1. Ensure filters and sorting options are displayed and functioning as expected.

2. Some sites present the option of adding products to the cart from the listing page when the user hovers over a product. Ensure that the user cannot add out-of-stock products to cart. The Gherkin syntax and the corresponding code snippet would look like this:

Given I select a product in stock from product category

/**

* @Given /^I select a product in stock from a product category$/

*/

public function iSelectAProductInStockFromAProductCategory() {

$page = $this->getSession()->getPage();

$all_products = $page->findById('locator of the results block');

if ($all_products !== NULL) {

  $all_products = $all_products->findAll('css', 'locator_of_individual_results');

  $total_products = count($all_products);

} else {

  throw new Exception('No products are listed on PLP');

}

foreach ($all_products as $item) {

  $item_status = count($item->find('css', 'class_for_out_of_stock'));

  if ($item_status) {

    $total_products--;

    if (!$total_products) {

      throw new Exception('All products are out of stock on PLP');

    }

    continue;

  }

  $this->product = $item->find('css', 'locator_of_title_of_individual_items')->getText();

  $page->clickLink($this->product);

  break;

}

}


Product display page

1. Write scripts to select quantity, select available size and color, and then add to cart.

2. Verify logged in user is able to add the product to wishlist and add review comments.

3. Verify adding to wishlist and writing review comments is not available for Guests, and the user is prompted to login upon clicking those links.

4. Ensure all the links open and point to their corresponding target pages.

Basket/Cart page

1. Verify whether all the added products are visible on the cart page.

2. For each product, verify whether description, correct quantity and unit price is displayed.

3. Verify whether user is able to add, delete and update products from the cart page.

Order confirmation page

1. Verify the confirmation message is displayed along with an order number.

2. Verify all the products added to the cart with the selected quantity are displayed on order confirmation.

3. Verify the address is displayed correctly.

4. Verify links like ‘Continue shopping’ and ‘Proceed to checkout’ work as expected.

Promotions

1. Verify user can apply a promo code and the discounted value is reflected in the total cart value.

2. Verify auto promotions are applied without applying any promo code and when the conditions are met.

Sample code to check “buy x and get y free” would be as below:

public function iShouldGetProductsFreeOnBuying($free, $buy)

{

$page = $this->getSession()->getPage();

$sub_total = (float)$page->find('css',' ')->getText();

$per_item_price = $sub_total / $buy;

$expected_discount = $sub_total - ($per_item_price * $free);

$discount = (float)$page->find('css','locator_of_discount')->getText();

$actual_discount = $sub_total + $discount;

if($expected_discount !== $actual_discount){

  throw new Exception('Discount did not work for buy '.$buy. 'and get '.$free);

}

}

General features

1. Verify user subscription works as expected. You might want to write a function to generate a random email so that the test passes on every run. Below is the piece of code to generate a random email every time:

When I enter a valid Email ID in field "email"

And I press "submitNewsletter"

And I wait for the page to load

Then I should see “Newsletter : You have successfully subscribed to this newsletter.”

 

public function iEnterAValidEmailID($field) {

$randomString = 'randemail' . rand(2, getrandmax());

$email_id = $randomString . '@gmail.com';

$this->getSession()->getPage()->fillField($field, $email_id);

}

2. Verify breadcrumbs throughout the site.

3. Verify header and footer consistency throughout the site.

4. Ensure negative scenarios are covered throughout the site.

5. Verify all the social media links are functioning throughout the site, like entering incorrect card details, subscribing with a pre-subscribed email ID, trying to log in with an incorrect email ID, etc.

6. Verify user can select a value from the autocomplete results. Below is a code snippet to select the first value from autocomplete from the search field. This function can be used to test autocomplete throughout the site for any field by changing the parameters:

Given I am on "http://automationpractice.com/"

And I wait for the page to load

When I select the first autocomplete option for "dress" on the "search_query" field

And I wait for AJAX to finish

And I wait 5 seconds

Then I should see "Printed Summer Dress"

/**

* @Given I select the first autocomplete option for :prefix on the :field field

*/

public function iSelectFirstAutocomplete($prefix, $field) {

$field = str_replace('\\"', '"', $field);

$session = $this->getSession();

$page = $session->getPage();

$element = $page->findField($field);

if (!$element) {

  throw new ElementNotFoundException($session, NULL, 'named', $field);

}

$page->fillField($field, $prefix);

$this->iWaitSeconds(2);

$xpath = $element->getXpath();

$driver = $session->getDriver();

$prefix = str_replace('\\"', '"', $prefix);

$chars = str_split($prefix);

$last_char = array_pop($chars);

// autocomplete.js uses key down/up events directly.

$driver->keyDown($xpath, 8);

$driver->keyUp($xpath, 8);

$driver->keyDown($xpath, $last_char);

$driver->keyUp($xpath, $last_char);

// Wait for AJAX to finish.

$this->getSession()

  ->wait(10000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');

// Press the down arrow to select the first option.

$driver->keyDown($xpath, 40);

$driver->keyUp($xpath, 40);

// Press the Enter key to confirm selection, copying the value into the field.

$driver->keyDown($xpath, 13);

$driver->keyUp($xpath, 13);

// Wait for AJAX to finish.

$this->getSession()

  ->wait(10000, '(typeof(jQuery)=="undefined" || (0 === jQuery.active && 0 === jQuery(\':animated\').length))');

}

If you found this helpful, or if you have any questions, let us know in the comments below!

Shweta Sharma, QA Lead
Posted by

Shweta Sharma, QA Lead

When Shweta isn't at work, she's either on a family road trip across the country or she's dancing with her kids—it's a great combination.