Recording the steps

Before you can record or run a test, plan out the steps that you’ll be taking and start recording them. You have the option to use previous fixtures that you had made, but to make this test a more focused one it is better to create a new fixture.  If you’re using the TestCafe program, in the control panel user interface, you can create a new fixture by clicking the New Fixture button and filling up the necessary fields on the popup form and press Create button to finish.If you’ll be doing it programmatically, you’ll have to create a new JS file in your test file’s directory.

Create new fixture

In this article we’ll be using Checkout Process as the fixture’s name and the JS file will be checkout_process.test.js as the test file’s name. Open your file in your favorite text editor or simply use the built-in text editor of TestCafe in the control panel UI and check or insert these lines:

  • "@fixture Checkout Process";
  • "@page https://subject_site_url";

Note that the quotes are included. The @fixture directive is the fixture’s name that will be visible in the control panel and the @page will be the URL of the website that you’ll be doing the test. When authentication is required, you could insert @auth directive to store your account details.

  • "@auth username:password";

Life is much easier when you have the control panel UI because when the page require Windows or basic http authentication TestCafe will just show you a form to fill in your credentials and if your details are valid it’ll automatically be saved on the *.test.js file. If you’re using the UI, the authentication check only occurs after pressing the REC Button which basically means start recording. Starting the record actions process will automatically redirect you to the page you had stated in the @page directive. When the page had finished loading, you’ll see this notification and the TestCafe logo with the available recording options or menu. Now you can interact with the page and start recording the actions that you had planned to check and verify whether the behavior of the elements are as the way you had expected.

Start recording

Recording the steps are simply done by doing the test and Testcafé will record these actions automatically. The advantage of using TestCafé is that you had the option of cancelling a step which you didn’t intend to do or a step you want to skip for some reasons. Cancelling the step is easily done by clicking the Cancel button or when you want to record it then press the Add Action button. If you do a click action and added it to the steps, then it’ll bring you to the URL the link was pointing to.

Click action

If you create the steps programmatically, the basic structure is as follows:

  • "@test"["going to categories page"] = {
    • '1.Click link "CATEGORY"': function() {
      • var link = $(":containsExcludeChildren(CATEGORY)").eq(2);
      • act.click(link);
    • }
  • };

The “@test” directive initializes an individual test. The test above has only 1 step recorded and this test will only click the categories button on the main menu navigation. For multiple steps and with steps that would require user text input, using this.propertyName = value; would come in handy. After using the UI to record the basic steps you can add some spice to your steps programmatically. This will enable you to run the same steps but with different data or change the order of your steps. @mixin and @testCases are as useful as this.*.

  • "@test"["ThisTest"] = {
    • 'Type in input "s"': function() {
      • this.searchQuery = 'This is how to use this.*';
      • var input = $(".search_mini").find("[name='s']");
      • act.type(input, this.searchQuery);
    • },
    • 'Click input "s"': function() {
      • var input = $(".search_mini").find("[name='s']");
      • act.click(input);
    • },
    • "Click submit button": function() {
      • var submitButton = $("#mini-search-submit");
      • act.click(submitButton);
    • },
  • },

Mixins

If you find that a step is repetitive all trough out the test block, then you could use @mixin directive to group the steps that are redundant. This will make it re-usable and have a clean and organized code. You can declare this directive inside the *.test.js file or in another JS file and load it using @require depending on which you prefer. It has a similar structure with the common @test directive.

  • "@fixture Checkout Process";
  • "@page https://subject_site_url";
  • '@mixin'['AddItemToCart'] = {
    • 'Click link "CATEGORY"': function() {
      • var link = $(":containsExcludeChildren(CATEGORY)").eq(2);
      • act.click(link);
    • },
    • 'Click image "Category"': function() {
      • var image = $("[alt='accessories 254x203 Category'][title='Category']");
      • act.click(image);
    • },
    • 'Click image "Bolle RX Insert..."': function() {
      • var image = $(".attachment-shop_catalog.wp-post-image[alt='Bolle RX Insert for Vigilante and Parole']");
      • act.click(image);
    • },
    • 'Click submit button "Add to cart"': function() {
      • var submitButton = $("#sidebar-product-single").find(":containsExcludeChildren(Add to cart)");
      • act.click(submitButton);
    • }
  • };
  • "@test"["checkout enter customer details"] = {
    • 'Click link "CATEGORY"': function() {
      • var link = $(":containsExcludeChildren(CATEGORY)").eq(2);
      • act.click(link);
    • },
    • 'Click image "Category"': function() {
      • var image = $("[alt='accessories 254x203 Category'][title='Category']");
      • act.click(image);
    • },
    • 'Click image "Bolle RX Insert..."': function() {
      • var image = $(".attachment-shop_catalog.wp-post-image[alt='Bolle RX Insert for Vigilante and Parole']");
      • act.click(image);
    • },
    • 'Click submit button "Add to cart"': function() {
      • var submitButton = $("#sidebar-product-single").find(":containsExcludeChildren(Add to cart)");
      • act.click(submitButton);
    • },
    • 'Add Item To Cart using MixIn 1': '@mixin AddItemToCart',
    • 'Add Item To Cart using MixIn 2': '@mixin AddItemToCart',
  • };

The above code is a complete test fixture that will repetitively add 1 quantity of the same item three times to your cart. Without @mixin directive, this test will have more lines than what you see above.

Using Parameters in Tests

The @testCases enables you to specify a set of data like user’s complete name, login name, password and other user details. This directive is initialized inside the @test block and its data could be assigned using a JSON format object or from an external JSON file.

  • "@test"["ThisTest"] = {
    • '@testCases': [
      • {'@name': 'Bag', brand: 'Wilson'},
      • {'@name': 'Shoes', brand: 'Prince'},
      • {'@name': 'Racket', brand: 'Head'}
    • ],
    • 'Type in input "s"': function() {
      • var input = $(".search_mini").find("[name='s']");
      • act.type(input, this.brand);
    • },
    • 'Click input "s"': function() {
      • var input = $(".search_mini").find("[name='s']");
      • act.click(input);
    • },
    • "Click submit button": function() {
      • var submitButton = $("#mini-search-submit");
      • act.click(submitButton);
    • }
  • };

In the above code, the @name will be the name to enable you tell apart from the other array of details and will be the text that you’ll see in the UI.

Data driven style=

Using Close and Open  to close and open and choose one from the list to run or simply press  to run all data groups in the list.

Checkout Process Test

Now that you have learned some tricks in making texts and modifying the codes, let’s apply it in testing the checkout process of a site. Note that in declaring the value of our @page derivative, since most checkout processes are done securely hence it is safer to use https to avoid unexpected errors while running the test.

  • "@fixture Checkout Process";
  • "@page https://subject_site_url";
  • '@mixin'['AddItemToCart'] = {
    • 'Click link "CATEGORY"': function() {
      • var link = $(":containsExcludeChildren(CATEGORY)").eq(2);
      • act.click(link);
    • },
    • 'Click image "Category"': function() {
      • var image = $("[alt='accessories 254x203 Category'][title='Category']");
      • act.click(image);
    • },
    • 'Click image "Bolle RX Insert..."': function() {
      • var image = $(".attachment-shop_catalog.wp-post-image[alt='Bolle RX Insert for Vigilante and Parole']");
      • act.click(image);
    • },
    • "Select in input": function() {
      • var input = $(".cart").find("[name='quantity']");
      • act.select(input, 1, 0);
    • },
    • "Type in input": function() {
      • var input = $(".cart").find("[name='quantity']");
      • act.type(input, "2", {
        • caretPos: 0
      • });
    • },
    • 'Click submit button "Add to cart"': function() {
      • var submitButton = $("#sidebar-product-single").find(":containsExcludeChildren(Add to cart)");
      • act.click(submitButton);
    • },
  • };
  • '@mixin'['CartAndCheckout'] = {
    • 'Click link "View Cart"': function() {
      • var link = $(".cart_control");
      • act.click(link);
    • },
    • 'Click submit button "Proceed to..."': function() {
      • var submitButton = $("#cart-table").find("[name='proceed']");
      • act.click(submitButton);
    • },
  • };
  • '@mixin'['FillInForm'] = {
    • 'Type in input "First Name *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_first_name']");
      • act.type(input, this.firstname);
    • },
    • 'Type in input "Last Name *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_last_name']");
      • act.type(input, this.lastname);
    • },
    • 'Type in input "Address *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_address_1']");
      • act.type(input, this.address);
    • },
    • 'Type in input "Town / City *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_city']");
      • act.type(input, this.city);
    • },
    • 'Click span "Select an option…"': function() {
      • var span = $("#billing_state_chosen").find(":containsExcludeChildren(Select an option)");
      • act.click(span);
    • },
    • 'Click list item "Louisiana"': function() {
      • var listItem = $("#billing_state_chosen").find(":containsExcludeChildren(Louisiana)");
      • act.click(listItem);
    • },
    • 'Type in input "Zip *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_postcode']");
      • act.type(input, this.zip);
    • },
    • 'Type in input "Email Address *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_email']");
      • act.type(input, this.email);
    • },
    • 'Type in input "Phone *"': function() {
      • var input = $("[name='checkout'].checkout").find("[name='billing_phone']");
      • act.type(input, this.phone);
    • },
    • 'Type in password input "Account password *"': function() {
      • var passwordInput = $("[name='checkout'].checkout").find("[name='account_password']");
      • act.type(passwordInput, this.password);
    • },
    • 'Click check box "Ship to different..."': function() {
      • var checkBox = $("[name='checkout'].checkout").find("[name='ship_to_different_address']");
      • act.click(checkBox);
    • },
    • 'Type in text area "Order Notes"': function() {
      • var textArea = $("#order_comments");
      • act.type(textArea, "This is a test checkout for TestCafe");
    • }
  • };
  • '@mixin'['PlaceOrder'] = {
    • 'Click submit button "Place order"': function() {
      • var submitButton = $(".checkout").find("[name='woocommerce_checkout_place_order']");
      • act.click(submitButton);
    • },
  • };
  • "@test"["Checkout enter customer details"] = {
    • '@testCases': [
      • {'@name': 'Empty', firstname:'', lastname:'', address:'', city:'', zip:'', email:'', phone:'', password:''},
      • {'@name': 'Missing Some Fields 1', firstname:'', lastname:'', address:'MyAdress', city:'MyCity', zip:'', email:'', phone:'', password:''},
      • {'@name': 'Missing Some Fields 2', firstname:'FirstName', lastname:'LastName', address:'', city:'', zip:'', email:'', phone:'', password:'mypassword'},
      • {'@name': 'Wrong Email Format', firstname:'FirstName', lastname:'LastName', address:'MyAdress', city:'MyCity', zip:'1000', email:'myWrongEmailFormat.com', phone:'1234567890', password:'mypassword'},
      • {'@name': 'Wrong Zip Format', firstname:'FirstName', lastname:'LastName', address:'MyAdress', city:'MyCity', zip:'wrongZipFormat', email:'myEmail@mail.com', phone:'1234567890', password:'mypassword'},
      • {'@name': 'Wrong Phone Format', firstname:'FirstName', lastname:'LastName', address:'MyAdress', city:'MyCity', zip:'1000', email:'myEmail@mail.com', phone:'WrongPhoneFormat', password:'mypassword'},
      • {'@name': 'Complete', firstname:'FirstName', lastname:'LastName', address:'MyAdress', city:'MyCity', zip:'8000', email:'myEmail@mail.com', phone:'1234567890', password:'mypassword'},
    • ],
    • 'Add Item to Cart': '@mixin AddItemToCart',
    • 'View Cart ad Proceed to Checkout': '@mixin CartAndCheckout',
    • 'Filling up the Form': '@mixin FillInForm',
    • 'Place your order': '@mixin PlaceOrder',
  • };

Note that the navigation on every site depends on the developer’s preference and every site’s structure might differ from one another. The code above might not work on your site. In this example, it will start from the homepage of the subject site’s URL. The steps on the @test code block only have 4 steps on it thanks to @mixin directive. The idea in the @testCases is scenario’s on which you would like your subject site to test. In the example above, we test the site for instances that the user might place their order completely without filling the shipping details, missed some details or have wrong formats like on the email and zip and then lastly a completely filled form with the correct detail format.

There are endless ways of having fun with testing your site and look for issues such as cross browser bugs, or navigation problems. You can formulate your own approaches in creating the tests or the steps inside your test. For more information, please refer to the Test Fixture API Reference.