---
schema_version: "1"
id: 51117a4c53a12b48361ebafe6310f30b13086b2ec47ba1d2800c31ec77d54eb7
title: Linting
collection: developer
version: current
locale: en-us
portal_url: https://docs.salesforce.com/developer/current/en-us/lwc/utam/guide/linting.md
canonical_url: https://developer.salesforce.com/docs/platform/utam/guide/linting.html
source_site: developer.salesforce.com
content_type: documentation
content_hash: 18836c2a80a1983232fa8a2cfb1c65a89d9534224f44ed64da47bebbca79734e
products:
  - UI Test Automation Model
  - lwc
---
# Linting

UTAM provides the ability to statically analyze JSON files to prevent common bad practices, such as duplication of page objects or violations of the encapsulation pattern.

We encourage you not to disable any linting rules and to make sure that your page objects comply with recommended best practices.

**note:** This documentation is relevant for UTAM Java versions after 2.0.4 and UTAM JavaScript versions after 2.1.2. Prior to these versions UTAM also produced console output from the linter, this is no longer the case.

## Run linting

Linting is run during the page object compilation process. All warnings and errors are printed into a Static Analysis Results Interchange Format ([SARIF](https://sarifweb.azurewebsites.net/)) report generated after compilation.
SARIF is a common format to store linting results. UTAM creates `utam-lint.sarif` in the SARIF JSON format, which looks like this:

```json
{
  "$schema": "https://json.schemastore.org/sarif-2.1.0.json",
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "UTAM",
          "semanticVersion": "2.1.0",
          "informationUri": "https://github.com/salesforce/utam-java",
          "rules": [
            {
              "id": "ULR01",
              "name": "Unique local selectors",
              "shortDescription": {
                "text": "Check for unique selectors inside the same file. By default, this is a warning because a list element can have the same selector."
              }
            }
            // other rules
          ]
        }
      },
      // all page objects being analyzed
      "artifacts": [
        {
          "description": {
            "text": "page object utam/pageObjects/test"
          },
          "location": {
            "uri": "src/test/resources/lint/changeDefaultConfig/test.utam.json",
            "uriBaseId": "%srcroot%",
            "index": 0
          }
        }
      ],
      // violations
      "results": [
        {
          "ruleId": "ULR02",
          "message": {
            "text": "root description is missing",
            "id": "2002"
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "src/test/resources/lint/changeDefaultConfig/test.utam.json",
                  "uriBaseId": "%srcroot%",
                  "index": 0
                },
                "region": {
                  "startLine": 2
                }
              }
            }
          ],
          "fixes": [
            {
              "description": {
                "text": "add \"author\" property to the root description"
              }
            }
          ]
        }
      ]
    }
  ]
}
```

## Linting report

The SARIF file is in JSON format. To view (pretty print) SARIF files in a terminal or in your IDE, use available tools, such as [sarif-fmt](https://lib.rs/crates/sarif-fmt) or [Sarif VSCode extension](https://github.com/microsoft/sarif-vscode-extension).

If at least one linting violation of level `error` occurs and the `throwError` configuration parameter is set to `true` (see the next section), the page object compiler throws an exception.

A file in SARIF format can be integrated with development tools such as GitHub to show linting rule violations:
![SARIF GitHub](https://developer.salesforce.com/docs/media/utam/sarif-github.png)

GitHub documentation is [here](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/uploading-a-sarif-file-to-github).

## Configuring linting rules and violations

All linting rules and violation types (error or warning) are configurable as `lint` properties in the compiler configuration.
If a compiler configuration doesn't have a `lint` section, default values are applied.

```json
{
  "lint": {
    "lintingOutputFile": "utam-lint.sarif",
    "disable": false,
    "throwError": false,
    "<name of the rule>": {
      "violation": "error",
      "exclude": []
    },
    "<name of the rule>": {
      "violation": "error",
      "exclude": ["my/test/component1", "my/test/component2"]
    },
    "<name of the rule>": {
      "violation": "warning"
    }
  }
}
```

- **`lintingOutputFile`**
  String, default is `"utam-lint.sarif"`. This parameter sets the path for a [SARIF](https://sarifweb.azurewebsites.net/) log file generated by the UTAM linter. The path is relative to the root of the project.

- **`disable`**
  Boolean, default is `false`. If set to `true`, linting rules are not applied after the compilation.

- **`throwError`**
  Boolean, default is `false`. If set to `true`, the linting process throws an error after reporting errors to the log.

- **`<name of the rule>`** is one of the rules listed in the next section.
  - **`violation`**
    The violation type. Possible values are: `warning`, `error`, or `disabled` (disable the rule). Starting from compiler versions 2.0.3 (utam-js) and 2.0.2 (utam-java), **the default is always `warning`.**
  - **`exclude`**
    Is an array of strings that are excluded from the rule. Each string value is a page object URI.
  - **`additionalConfiguration`**
    Is an object containing additional configuration data for the rule, if any applies. See the rule description for information
    about what additional configuration the rule supports.

## Linting rules

**note:** Rules with error codes that start with 2 are applicable for one page object only. Rules with error codes that start with 3 are relevant for multiple page objects only, such as detecting duplicates from the earlier example.

### duplicateSelectors

- Rule: page object elements in the same scope (with the same immediate parent) can't have duplicate selectors except if one of the elements is a list.
- How to fix: remove one or more duplicate elements.
- Error code: 2001
- Default violation type: `warning`

Example:

```json
{
  "elements": [
    {
      "name": "element1",
      "selector": {
        "css": "css"
      }
    },
    {
      // violation - same selector as element1
      "name": "element2",
      "selector": {
        "css": "css"
      },
      "elements": [
        {
          // not a violation - element has a different parent
          "name": "element3",
          "selector": {
            "css": "css"
          }
        },
        {
          // not a violation - element is a list
          "name": "element4",
          "selector": {
            "css": "css",
            "returnAll": true
          }
        }
      ]
    }
  ]
}
```

### requiredRootDescription

- Rule: it's a good practice to provide a description at the page object root level to explain the intended usage of the page object.
- How to fix: add a [page object description](/docs/platform/utam/references/utam-grammar/descriptions-metadata.html#page-object-description).
- Error code: 2002
- Default violation type: `warning`

Example:

```json
{
  // violation - description is empty
  "elements": []
}
```

### requiredAuthor

- Rule: The page object description should include an author.
- How to fix: add an [author](/docs/platform/utam/references/utam-grammar/descriptions-metadata.html#page-object-description) property to the description.
- Error code: 2005
- Default violation type: `warning`

Example:

```json
{
  // violation - description has no author
  "description": "description is a string"
}
```

```json
{
  // not a violation - author is provided
  "description": {
    "text": ["description is a string"],
    "author": "myTeam"
  }
}
```

### requiredMethodDescription

- Rule: it's a good practice to provide a description at the method level that explains the use cases. This rule isn't applied to elements; it's for compose methods only.
- How to fix: add a [method description](/docs/platform/utam/references/utam-grammar/methods.html#method-description).
- Error code: 2003
- Default violation type: `warning`

Example:

```json
{
  "description": "root description here",
  "methods": [
    {
      // violation - description is empty
      "name": "doSomething",
      "compose": []
    }
  ]
}
```

### duplicateRootSelectors

- Rule: two page objects with the same root selector usually means a violation of the encapsulation rule (1:1 mapping between a component and a page object).
- How to fix: remove the duplicate page object. Make sure that you keep all functionality.
- Error code: 3001
- Default violation type: `warning`

Example:

```json
{
  // first page object
  "root": true,
  "selector": {
    "css": "my-root"
  }
}
```

```json
{
  // second page object
  "root": true,
  "selector": {
    // violation - same root selector
    "css": "my-root"
  }
}
```

### elementCantHaveRootSelector

- Rule: if an element has the same selector as the root selector of a different page object, it should have the same type as the given page object.
- How to fix: add the proper type, which is the type of the page object with the root selector.
- Error code: 3002
- Default violation type: `warning`

Example:

```json
{
  // first page object my/test/Component
  "root": true,
  "selector": {
    "css": "my-root"
  }
}
```

```json
{
  // second page object
  "elements": [
    {
      // violation - element should have the proper type
      "name": "element1",
      "selector": {
        "css": "my-root"
      }
    },
    {
      // not a violation - element has the proper type
      "name": "element2",
      "type": "my/test/Component",
      "selector": {
        "css": "my-root"
      }
    }
  ]
}
```

### duplicateCustomSelectors

- Rule: if an element in one page object has a custom type and a custom selector (with "-"), any element with the same selector in a different page object should have the same custom type.
- How to fix: change the element type to custom.
- Error code: 3003
- Default violation type: `warning`

Example:

```json
{
  // first page object
  "elements": [
    {
      "name": "customElement",
      "type": "my/test/Component",
      "selector": {
        "css": "my-test-component"
      }
    },
    {
      "name": "basicElement",
      "selector": {
        "css": ".myClass"
      }
    }
  ]
}
```

```json
{
  // second page object
  "elements": [
    {
      // violation - set type to "my/test/Component"
      "name": "basicElement1",
      "selector": {
        "css": "my-test-component"
      }
    },
    {
      // not a violation - basic elements can have the same selectors
      "name": "basicElement2",
      "selector": {
        "css": ".myClass"
      }
    }
  ]
}
```

### requiredMetadata

- Rule: if a page object does not contain a `metadata` property, or the object value of the `metadata` property does not contain
  the specified values.
- How to fix: add a [metadata](/docs/platform/utam/references/utam-grammar/descriptions-metadata.html) object containing mandatory fields (if any) to the page object.
- Error code: 2006
- Default violation type: `disabled`
- Note: `additionalConfiguration` should contain a `requiredProperties` array, which will contain objects defining the
  required properties in the metadata.

Example:

```json
{
  // Compiler configuration lint section
  "lint": {
    "lintingOutputFile": "utam-lint.sarif",
    "disable": false,
    "throwError": false,
    "requiredMetadata": {
      "violation": "warning",
      "exclude": [],
      "additionalConfiguration": {
        "requiredProperties": [
          {
            "name": "firstRequiredProperty"
          },
          {
            "name": "secondRequiredProperty",
            "values": ["allowedValue1", "allowedValue2", "allowedValue3"]
          }
        ]
      }
    }
  }
}
```

```json
{
  //  violation: page object has no metadata property
  "elements": [
    {
      "name": "basicElement1",
      "selector": {
        "css": ".my-test-component"
      }
    }
  ]
}
```

```json
{
  "metadata": {
    // violation: metadata object does not contain "firstRequiredProperty"
    // property with a non-empty value

    // violation: "secondRequiredProperty" value is not one of the acceptable
    // values for the property
    "secondRequiredProperty": "invalidValue"
  },
  "elements": [
    {
      "name": "basicElement1",
      "selector": {
        "css": ".my-test-component"
      }
    }
  ]
}
```
