Generator User Guide

This document explains how to configure the UTAM generator and generate UTAM JSON page objects from HTML files.

Runner setup

Project Dependencies

The package.json file configures the dependencies for a JavaScript project.

Add a development dependency for the UTAM generator by running one of these commands:

These commands are equivalent and add utam to the devDependencies property in package.json, where x.y.z represents the installed version and is the latest version by default.

{
    "devDependencies": {
        "utam": "x.y.z"
    }
}

Set Up Generate Step in package.json

The package.json file has a script that runs the utam-generate generation CLI command. utam is installed locally in your project because you added it to the devDependencies in package.json.

{
    "scripts": {
        "build": "yarn generate:utam",
        "generate:utam": "utam-generate -c utam-generator.config.json"
    },
    "devDependencies": {
        "utam": "x.y.z"
    }
}

Use a generator configuration file

You can specify options in the generator configuration file.

Use the -c flag of the utam-generate CLI to point at the configuration file. In this example, we use utam-generator.config.json.

utam-generate -c utam-generator.config.json

Use the -p flag of the utam-generate CLI to point the generator at multiple configuration files. This approach is useful if you have a repo where you need different configuration options in different subprojects. In most scenarios, the -c flag suffices and you don't need to use the -p flag.

utam-generate -p 'path/to/project1/utam.config.json' 'path/to/project2/utam.config.json'

Note: Pass a list of whitespace-separated utam compiler configuration file paths.

The generator configuration options are explained in the next section.

Default Convention

You don't have to explicitly declare any options for the generator because all options have default values. If your project structure follows the default convention, the compiler works out of the box. In that case, set the generator configuration file to be an empty object, {}.

Here's an overview of all configuration options supported by the generator runner with their associated default values:

{
  "inputRootDir" : "./", // config file directory name
  "ignore": ["**/node_modules/**"],
  "inputFileMask" : ["**/*.html"],
  "outputDir" : "__utam__",
  "outputFileExtension" : ".utam.json",
  "overrideExisting" : true,
  "relativeOutputDir" : false,
  "generateCustomContent": false
}

There are other configuration parameters responsible for how the generator interprets HTML. Those parameters are explained in later sections.

Runner parameters

This section lists all the options supported by the generator runner. For each option, we describe its JSON type, its default value, and what it does.

inputRootDir

The relative path from the configuration file's directory that represents the root directory path. The generator looks recursively in the root directory for HTML files.

Defaults to the configuration file's directory if not specified. For instance, if your utam-generator.config.json configuration file is at the package root (the same level as the package.json file), the page object root directory defaults to the package root directory.

ignore

You can specify which folders and files should be ignored and not traversed by the generator.

Defaults to ignore only **/node_modules/**.

inputFileMask

The file mask pattern used by the generator to find HTML input files. It tells the generator where to start scanning for the source files relative to inputRootDir. Declare the file mask as a list of glob patterns.

outputDir

The relative path from the inputRootDir directory to the target directory for generated UTAM JSON files. The generator writes the JSON page objects to this directory.

<inputRootDir>
├── utam-generator.config.json
├── __utam__
   ├── component1.utam.json
├── src/
   └── modules/
      ├── component1/
         └── component1.html

relativeOutputDir

If set to a non-empty string, the output is generated under the same folder as the source file. The path is relative to the source folder. For example, if it's set to __utam__, here's where the output is generated:

<inputRootDir>
├── utam-generator.config.json
├── src/
   └── modules/
      ├── component1/
         └── component1.html
         └── __utam__/
            └── component1.utam.json

outputFileExtension

The generated output file has the same name as the source file with .html removed and with the outputFileExtension added as a suffix. For example, a myComponent.html source file generates myComponent.utam.json.

overrideExisting

If set to true, the generator overrides an existing file with the same name. By default if myComponent.utam.json already exists, it is overridden.

generateCustomContent

When the generator processes a custom HTML tag, it can be treated as a separate HTML source to generate another UTAM page object. If this parameter is set to true and myComponent1.html contains a custom html tag such as <my-component2>some HTML here</my-component2>, the generator treats the content of the custom tag as another HTML source for generation and creates a component2.utam.json file.

<inputRootDir>
├── utam-generator.config.json
├── src/
   └── modules/
      ├── component1/
         └── component1.html
         └── __utam__/
            └── component1.utam.json
            └── component2.utam.json

Namespaces

When the generator processes a custom HTML tag such as:

<my-component2>some HTML here</my-component2>

It generates a custom element that requires type to be set to something like my-namespace/pageObjects/component2.

The generator splits a custom HTML tag by "-" and considers the first part a namespace (in our example, it's my). Then, the generator tries to find a proper type prefix for the given namespace looking at the following configuration parameters.

namespaces

First, the generator tries to find a match in the namespaces map. Let's say our config looks like this:

{
    "namespaces": {
        "my" : "my-namespace/pageObjects",
        "lightning" : "salesforce/lightning/pageObjects"
    }
}

Since the generator can find a map entry for our namespace prefix my, it picks the type and adds the name, so the type is my-namespace/pageObjects/component2.

defaultNamespace

If the namespaces map is empty or doesn't have a proper entry, the generator uses the preconfigured default namespace.

For our example, a custom element's type is then utam/pageObjects/component2.

Generated elements

When the generator parses HTML, it only creates a JSON element if the HTML element has a preconfigured tag name, attribute, or class value. It's defined by the following parameters.

includeTags

The values in this array determine which tags are processed and added to JSON. Other HTML elements are ignored except for elements that match includeAttributes or includeClasses.

When this parameter is set in the config, the value is added to the default list. The value doesn't override the default list.

For example if a configuration file has "includeTags" : ["div", "span"], it means that the div and span tags are processed in addition to the default tag list.

includeAttributes

If an HTML element with any tag name has an attribute defined in this array, the element is processed and added to JSON.

For example, if a configuration file has "includeAttributes" : ["my-data"], the following element is no longer ignored even though <p> isn't part of the includeTags.

<p my-data="something">
    <!-- content -->
</p>

When this parameter is set in the config, the value is added to the default list. The value doesn't override the default list.

includeClasses

If an HTML element's class has a partial match for one of the values in the array, the element is processed and added to JSON.

For example, if a configuration file has "includeClasses" : ["forceLookup"], the following element is no longer ignored even though <p> isn't part of the includeTags and doesn't have attributes from includeAttributes.

<p class="forceLookup something else">
    <!-- content -->
</p>

Generated description

descriptionAuthor

Each generated JSON begins with a description with the author property set from the value in the config:

{
    "description": {
        "author": "UTAM generator",
        "text": ["Page Object: <name of page object>"]
    }
}

addMethodDescription

If set to true, a compose method has the following description with the method name:

{
    "methods": [
        {
            "description": {
                "text": ["method getOptionByIndexText"]
            },
            "name": "getOptionByIndexText",
            "args": [],
            "compose": []
        }
    ]
}

Location strategy

createScopeElement

This parameter affects chaining selectors versus using scope elements. Let's take the following HTML:

<table>
    <tr>
        <td>first</td>
        <td>second</td>
    </tr>
</table>

If the createScopeElement parameter is set to true, the generator creates a table scope element:

{
    "elements": [
        {
            "name": "table",
            "type": [],
            "selector": {
                "css": "table"
            },
            "elements": [
                {
                    "public": true,
                    "name": "tableRows",
                    "type": [],
                    "selector": { "css": "tr", "returnAll": true }
                }
            ]
        }
    ]
}

If the parameter is set to false, the generator uses a chain selector table > tr:

Generates JSON:

{
    "elements": [
        {
            "public": true,
            "name": "tableRows",
            "type": [],
            "selector": {
                "css": "table > tr"
            }
        }
    ]
}

Root page object

rootSelectors

If the root tag of the HTML file is the same as one of the strings configured in rootSelectors, the JSON page object is marked as a root element. For example:

<html>
    <!-- content -->
</html>

The generated JSON contains "root": true.

{
    "root": true,
    "selector": {
        "css": "html"
    }
}

Container selector

containerSelector

This parameter defines the CSS selector that's used for a container element generated from a default slot <slot></slot>.

{
    "public": true,
    "name": "rootContainer",
    "type": "container",
    "selector": { "css": "slot > *" }
}