Write automated UI tests for an Oracle JET web app

Introduction

This tutorial shows you how to create tests that automate the Create and Delete functionality in the Oracle JET web app that that you developed over the course of the previous learning paths in this series of learning paths.

Objectives

In this tutorial, you will learn how to write test scripts that create and delete activity items using the REST service used by the Oracle JET web app that you created.

Prerequisites

Task 1: Prepare Your Oracle JET Web App for Testing

Prior to executing the Selenium WebDriver tests that you create in the CommonJS-based app, you must install Chai as a dev dependency in the Oracle JET web app that you want to test.

If you have not completed earlier learning paths and, as a result, don’t have an Oracle JET web app that uses Oracle JET’s RESTDataProvider to manage activity items in the backend REST service, download and restore the app. Once you have downloaded it, install the Chai NPM package.

In the following steps, we demonstrate this for the virtual DOM learning path’s Oracle JET web app, but the same steps apply to the MVVM learning path’s app.

  1. Download the JET-Virtual-DOM-app-final.zip file to your computer and extract its content to a directory.

  2. In the directory where you extracted the content of the ZIP file, open a terminal window and run the following command to restore the dependencies that the Oracle JET web app requires to run.

    npm install
    
  3. In the terminal window, run the following command to determine the version of the Oracle JET web app.

    npm list --depth=0
    

    The terminal window displays the NPM packages and version numbers that the Oracle JET web app uses. Verify that the version number returned for the @oracle/oraclejet package matches the version number of the @oracle/oraclejet-webdriver package that you installed in the CommonJS-based app where you write tests. That is, if the Oracle JET web app uses @oracle/oraclejet@15.1.2, the entry in the CommonJS-based app must be @oracle/oraclejet-webdriver@15.1.2.

  4. In the terminal window, enter the following command to install Chai’s NPM package and its supported types as a dev dependency in your Oracle JET web app.

    npm i -D chai@4.3.10
    
  5. Open the path_mapping.json file and verify that it includes an entry for the Chai library, liked the following that appears at the end of the file.

    "chai": {
      "cwd": "node_modules/chai/",
      "debug": {
        "src": "chai.js",
        "path": "libs/chai/chai.js"
      },
      "release": {
        "src": "chai.js",
        "path": "libs/chai/chai.js"
        }
      }
     }
    }
    

    In the MVVM-based jet_rest_crud_application_final app, the path_mapping.json file is in the ./jet_rest_crud_application_final/src/js/ folder. In the virtual DOM-based JET-Virtual-DOM-app-final app, the path_mapping.json file is in the ./JET-Virtual-DOM-app-final folder.

  6. In the terminal window, in the directory where you extracted the content of the ZIP file, run the following command to serve the Oracle JET web app.

    npx ojet serve
    

    The Oracle JET web app appears in the browser and is ready to test.

Task 2: Gather the Data to Create a Test Script

The end-to-end tests that you write emulate what users do with your web app. This type of testing differs to unit testing, where you write tests for units of your own code, be it a function, a class, or a component. So, to create an end-to-end test, you need to think about the flow of actions that users perform to accomplish a task. For example, in the learning path apps (both MVVM and VDOM), users who create a new activity item select an activity (for example, Soccer), and then click the Create button to open the Create Item dialog where they enter values for the new activity item (name, description, price, and so on). Finally, they click Submit to submit the newly-created activity item and close the Create Item dialog.

To emulate this task in a Selenium WebDriver test, we need to interact with the relevant Oracle JET components in the Oracle JET web app. We’ll use Chrome’s developer tools (DevTools) to retrieve the element IDs for each component. You could, as an alternative, inspect the source files that you download, but given that we run our tests against a deployed Oracle JET web app, and a successful test requires knowing what elements appear in the DOM, it is a better practice to retrieve these values from the running Oracle JET web app.

  1. In your Google Chrome browser where you deployed the Oracle JET web app to http://localhost:8000/, press Ctrl+Shift+I to display the developer tools window. Chrome DevTools displays the source code.

  2. In the Elements tab of Chrome DevTools, click in the source HTML and press Ctrl+F, then enter oj-list-view in the input field that appears at the bottom of the Chrome DevTools window.

    If you have not selected an item in the Activities list, this search returns a single result. When you select the instance in Chrome DevTools’ Elements tab, you will notice that the Activities list is highlighted in the browser view, indicating that the instance of oj-list-view corresponds to the Activities list. For our test, we need the ID value of the Activities list, so we retrieve and save this value (activitiesList), as is demonstrated in the following composite image where we see a part of our Oracle JET web app in the Chrome browser, and the corresponding source view in the Elements tab of the Chrome DevTools.

    "Retrieve the element ID for the Activities list view component

  3. Repeat the previous step for each of the UI components that you need to interact with to create and submit an activity item.

    You need to click these UI components in the browser, so that the relevant UI component element loads in the browser DOM, and you can then select the ID attribute value. That is, select an Activity, such as Soccer, click Create, and use the Element tab in Chrome DevTools to retrieve the values of the Create button, the Dialog component, and the Input Text components.

    On completion of this step, you should have the following element IDs:

    • Activities List View component with an element ID value of activitiesList
    • Create Button component with an element ID value of createButton
    • Dialog component with an element ID value of createDialog
    • Input Text components that appear in the Create New Item dialog with the following values:
      • “Name” with an element ID of name
      • “Price” with an element ID of price
      • “Description” with an element ID of short_desc
      • “Quantity: In Stock” with with an element ID of quantity_instock
      • “Quantity: Shipped” with with an element ID of quantity_shipped
    • Submit Button component with an element ID of submitBtn

    Now that we have gathered the data that we need for the test, we can write the test.

Task 3: Create an Activity Item in the Backend REST Service

The high-level steps to create a Selenium WebDriver script are the same, regardless of the type of script that you are creating.

After you create your test script file, import the modules that you need, including a driver to connect to the browser where you run the test, the Oracle JET Component WebElements UI automation library to access the Oracle JET components, and other additional libraries to assist with test execution.

Once you have imported the required code, write the first entry in the script file: a describe statement where you provide a description for the suite of one or more tests that you will write. You then create an instance of the browser driver to connect to the URL where you deployed your Oracle JET web app.

After completing these steps, you are ready to interact with the Oracle JET component elements to automate user actions and test the UI. The following example shows how to access the element for the Oracle JET List View component that renders the Activities list and select the Soccer activity.

The final script file that you can download here includes the remaining tests to access the Create Button component, open the Create New Item Dialog component, and complete the input fields, before submitting the new activity item. Finally, you release the driver connection to the Oracle JET web app that you created at the start of the script.

import { expect } from "chai";
. . .
import { ojListView } from "@oracle/oraclejet-webdriver/elements";

describe("Create an Activity Item", () => {
    let driver: WebDriver;

    before(async () => {
        driver = await dm.getDriver();
        await ojwd.get(driver, "http://localhost:8000");
    });

    it("Select an Activity", async () => {
        await driver
            .wait(
                until.elementLocated(By.id("activitiesList")),
                20000,
                "Timed out after 20 seconds waiting for Activities List",
                2000
            )
        const activitiesList = await ojListView(
            driver,
            By.id("activitiesList")
        );
        await activitiesList.changeSelected([4]);
        . . .
    });

    after(() => dm.releaseDriver(driver));
});

Note the script’s use of the .wait() pattern. To interact with the elements for the Oracle JET components, your test script needs to wait until these elements are available in the browser DOM. Therefore, using this pattern ensures that a test does not proceed until the element is located. The .wait() method includes three parameters: a timeout of 10 seconds, a timeout error message, and a polling value of four seconds. This polling value tells Selenium to try every four seconds to find the element with an id value of activitiesList.

  1. Create and open a test script file named EndToEndActivity.spec.ts in the JET-WebDriver-Tests/src/__tests__ directory.

  2. Copy and paste the code from the attached file into your newly-created ./src/__tests__/EndToEndActivity.spec.ts file, and then save and close the file.

  3. In the terminal window, change to the JET-WebDriver-Tests directory and run the test to create an activity item.

    npm test ./src/__tests__/EndToEndActivity.spec.ts
    

    Be patient. The test takes time to start, execute, and complete. During test execution, a new instance of the Chrome browser launches, and the steps in the test script execute. That is, the Activities list is selected, the Create button is clicked, the Create New Item dialog opens, and so on. On completion of the test, refresh the view in the Chrome browser instance that displays the Oracle JET web app that you ran the test script against (http://localhost:8000/). You’ll see a new activity item under the Soccer activity category.

    "Activity Item Created by the Selenium WebDriver Test Script

    In the terminal window where you executed the text, you’ll see a summary of the test execution, similar to the following:

    oracle-PC /c/JET-WebDriver-Tests
    $ npm test ./src/__tests__/EndToEndActivity.spec.ts
    
    > JET-WebDriver-Tests@1.0.0 test
    > node node_modules/mocha/bin/mocha --require ts-node/register --timeout=0 ./src/__tests__/EndToEndActivity.spec.ts
    
    Create an Activity Item
    
    DevTools listening on ws://127.0.0.1:59951/devtools/browser/8525c4fd-b40f-48ba-b8cf-bc3d22d1b66e
        ✔ Select an activity (2561ms)
        ✔ Open the Create New Item dialog (209ms)
        ✔ Create New Activity Item (2916ms)
        ✔ Get Instance of Submit Button
        ✔ Close the Create New Item Dialog (45ms)
    
    5 passing (2m)
    oracle-PC /c/JET-WebDriver-Tests
    $
    

Task 4: Delete an Activity Item from the Backend REST Service

To expand our end-to-end testing of the Oracle JET web app, we’ll add test steps to our test script that delete the activity item that we created in the previous task.

The Oracle JET web app uses the browser’s native dialog to display a confirmation message to delete the selected activity item. Therefore, the steps that we’ll write use a Selenium WebDriver API to access the browser’s native dialog, in addition to the oraclejet-webdriver APIs to access the Oracle JET components that we interact with to automate the delete activity item task (oj-list-view, oj-button, and so on).

Successful execution of the delete steps depends on the existence of one activity item with a matching name (WebDriver-Created Activity Item) under the Soccer Activities list. If no activity item name is found, or the Soccer Activities list includes more than one activity item with the specified name, the fetchKeyByFilter function that we use throws an error.

  1. In your browser, navigate to (http://localhost:8000/) where the Oracle JET web app is running and select Soccer under the Actitivies list, then delete the WebDriver-Created Activity Item activity item that our previous test execution created.

  2. In the JET-WebDriver-Tests/src/__tests__EndToEndActivity.spec.ts file that we created previously, update the import statement to include the fetchKeyByFilter from "@oracle/oraclejet-webdriver" and the ListViewElement from "ojs/ojlistview.

    import ojwd, { DriverManager as dm, fetchKeyByFilter } from "@oracle/oraclejet-webdriver";
    . . .
    import { ListViewElement } from "ojs/ojlistview";
    
  3. Copy and paste the code from the attached file into the ./src/__tests__/EndToEndActivity.spec.ts file, and then save and close the ./src/__tests__/EndToEndActivity.spec.ts file.

    You can add the additional steps at the end of the file, before the line that releases the WebDriver, or you can overwrite all the content of the the ./src/__tests__/EndToEndActivity.spec.ts file with the content from the attached file, as it includes our final end-to-end working test script.

    These additional steps are similar to the previous steps that create the activity item in that they make use of APIs from "@oracle/oraclejet-webdriver";. One difference to note is that we use a Seleniumn WebDriver API to interact with the browser’s native dialog.

    . . .
    it("Click OK in the browser's confirmation dialog to confirm deletion ", async () => {
        await driver
            .wait(until.alertIsPresent())
        // Switch to the alert and accept the alert (click OK)
        const alert = driver.switchTo().alert();
        alert.accept();
     });
    
  4. In the terminal window, change to the JET-WebDriver-Tests directory and run the test to create and delete an activity item.

    npm test ./src/__tests__/EndToEndActivity.spec.ts
    

    During test execution, a new instance of the Chrome browser launches, and the test script steps execute. That is, an activity item is created and then deleted. On test completion, in the terminal window where you executed the test script, you’ll see a summary of the test execution, similar to the following:

    oracle-PC /c/JET-WebDriver-Tests
    $ npm test ./src/__tests__/EndToEndActivity.spec.ts
    
    > JET-WebDriver-Tests@1.0.0 test
    > node node_modules/mocha/bin/mocha --require ts-node/register --timeout=0 ./src/__tests__/EndToEndActivity.spec.ts
    
    Create and Delete an Activity Item in the Soccer activities of the Web App
    
    oracle-PC /c/JET-WebDriver-Tests
    $
     ✔ Select an activity (2691ms)
    ✔ Open the Create New Item dialog (213ms)
    ✔ Create New Activity Item (2979ms)
    ✔ Get Instance of Submit Button
    ✔ Close the Create New Item Dialog
    ✔ Select an Activity to delete an activity item (812ms)
    ✔ Select the activity item to delete from the Activity Items list (1073ms)
    ✔ Click the Delete button (1157ms)
    ✔ Click OK in the browser's confirmation dialog to confirm deletion  (209ms)
    
    9 passing (2m)
    

Task 5: (Optional) Run a Web App and a WebDriver Test from a Restored App

If you want to run the completed Selenium WebDriver tests against the Oracle JET web apps from the supplied code, you can restore the apps from the downloaded archive file. To work with a “stripped and zipped” Oracle JET web app, you must restore project dependencies, including Oracle JET tooling and the required libraries and modules, within the extracted app.

  1. Download the jet-end-to-end-testing-final.zip file and extract the contents of the completed app to the jet-end-to-end-testing-final folder.

  2. In the terminal window, navigate to the jet-end-to-end-testing-final folder and restore the apps by installing the required NPM packages from the app sub-folder of each app.

    npm install
    

    For example, if you want to run the test scripts against the Oracle JET MVVM web app, navigate to the ./jet-end-to-end-testing-final/jet_rest_crud_application_final and ./jet-end-to-end-testing-final/JET-WebDriver-Tests folder and run the npm install command in each sub-folder.

  3. Wait for a confirmation message similar to the following.

    added 284 packages in 59s
    

    The app is ready to run.

  4. Run the web app.

    For example, to run the Oracle JET MVVM web app:

    cd ./jet-end-to-end-testing-final/jet_rest_crud_application_final
    npx ojet serve
    
  5. In a new terminal window, navigate to the ./jet-end-to-end-testing-final/JET-WebDriver-Tests folder and execute the end-to-end test.

    cd ./jet-end-to-end-testing-final/jet_rest_crud_application_final
    npm test ./src/__tests__/EndToEndActivity.spec.ts
    

More Learning Resources

Explore other labs on docs.oracle.com/learn or access more free learning content on the Oracle Learning YouTube channel. Additionally, visit education.oracle.com/learning-explorer to become an Oracle Learning Explorer.

For product documentation, visit Oracle Help Center.