Elastic Path Commerce Development

Testing Commerce Manager Functionality

Testing Commerce Manager Functionality

When extending or altering existing Commerce Manager functionality, Elastic Path provides a suite of automated unit tests to ensure that new functionality does not cause existing functionality to fail.

Testing Framework

Commerce Manager is rendered in the browser by RAP as <div> elements with automatically generated ids attached. The ids are sequential, and change based on the interactions a user takes within the UI. Based on a user's interaction with an UI element, in-line CSS sets a <div>'s visibility to visible or hidden. The nature of how RAP renders UI elements makes automated testing difficult to achieve out of the box.

The testing framework uses JavaScript to assign consistent IDs to specific UI elements, like tabs, and indicates an element's visibility to the user. This allows you to consistently test different user interaction scenarios without accidentally selecting invisible or incorrect UI elements.

Running Tests

Prerequisites
  • Ensure that the settings.xml file with database information.
  • Ensure that the POM file is updated with cortex.baseurl.
  • Ensure that the api-platform and ep-commerce modules are built successfully before building the ep-commerce/extensions/cortex/system-test module.
  • Ensure that the commerce/ep-commerce/extensions/cm/ext-cm-modules/system-tests/selenium module is deployed.
  • Ensure that the ActiveMQ, search, Cortex and Commerce Manager client servers are started.

Procedure

  1. In the ext-cm-webapp-runner module, run the following:
    mvn clean tomcat8:run-war -Dorg.eclipse.rap.rwt.enableUITests=true
  2. In the commerce/ep-commerce/extensions/cm/ext-cm-modules/system-tests/selenium module, run the following command:
    mvn clean install -Dcucumber.options=“--tags @smokeTest”
You can use the following optional arguments to run a specific test:
Table 1. Maven Arguments
Option Description
-Dcucumber.options="--tags @example" Specifies that you can replace the tag with a tag that you define.
-Dfailsafe.fork.count="1" Specifies the number of tests that can be run at the same time. The default value is 1. You can change this value depending on number of TestsIT classes.
-Premote -Dremote.web.driver.url="<REMOTE DRIVER IP>" Specifies that the tests are executed using a remote VM. The remote.web.driver.url attribute specifies the URL of the remote VM. For example, http://<Remote machine's IP>/wd/hub.
Note: You must set up selenium grid on your system to use this feature. For more information, see Selenium Grid Documentation.

Enabling and Disabling Tests

The testing framework is implemented as a standalone plugin, /commerce-manager-client/cm-plugins/test-util . It is included in Commerce Manager's out of the box feature.xml by default, and only needs to be enabled.

To enable the test-util bundle, rebuild Commerce Manager from cm/ext-cm-modules/ext-cm-webapp-runner, adding -Dorg.eclipse.rap.rwt.enableUITests=true to your maven call:
mvn clean tomcat7:run-war -Dorg.eclipse.rap.rwt.enableUITests=true

Adding Test IDs to Your UI Elements

To add Test IDs to your UI elements, you must extend com.elasticpath.cmclient.core.ui.AbstractEpUiPlugin and implement AbstractEpUiPlugin.loadLocalizedMessages().

public class CustomUIPlugin extends AbstractUIPlugin {
  @Override
  protected void loadLocalizedMessages() {
    CustomMessages.load();
  }
}
      

This should delegate to a Messages class, which then calls LocalizedMessagePostProcessor.getUTF8Encoded() to process the messages:

public static CustomMessages load() {
  return LocalizedMessagePostProcessor.getUTF8Encoded(BUNDLE_NAME, CustomMessages.class);
}
      

Writing Your Own Unit Tests

If you wish to create your own unit tests for custom UI elements, you can use Elastic Path's automation IDs to write Selenium tests against.

The following are all the automation IDs attached to UI elements by the test-util plugin.

Table 2.
Test identifier Status Notes
automation-id current, ideal Highest priority for testing. Use this ID for testing if it is present.
widget-id current Locale dependant; use automation-id if possible. (See tables section). Data created at runtime is assigned a widget-id corresponding to the text/title of the widget. Assigned via the EpWidgetIdUtil class.
seeable current Used in conjunction with other IDs to uniquely identify HTML elements. Used to disambiguate currently viewable components with same IDs (generally superseded by automation-id).
wid current Dynamic (non-deterministic) internal RAP widget ID, used at runtime by automation-id. Should not be used for testing.
widget-type current Identifies the type of the widget in RCP. The value is generated by Java. The value may be slightly different from appearance-id.
appearance-id current, to be removed Identifies the type of the widget in RWT. The value is generated by JavaScript. Helps identify the type of the widget.
row-id legacy - to be deprecated Same as the text of the first text-containing column in that row. Use if automation-id is not there or is undefined.
column-id legacy - to be deprecated Same as the text for that column. Use if automation-id is not there or is undefined.
row-num legacy - to be deprecated Identifies the row number in the table, starting with 0.
column-num legacy - to be deprecated Identifies the column number in the row, starting with 0.

Writing Tests Against Automation IDs

In general, write all tests against automation-id if it is available and its value is not undefined. Tests should next be written against widget-id if required.

In addition, you can use the following automation IDs in conjunction with autiomation-id and widget-id to disambiguate between UI elements:

  1. seeable
  2. appearance-id
  3. widget-type

Assigning Automation IDs to Tables

The following automation IDs are automatically assigned to all tables created through EpControlFactory to assist in identifying specific rows and columns of a table:

  • row-id
  • column-id
  • row-num
  • column-num