---
title: Testing & Build
aliases: [build, test, Jest, CI/CD, sf mdl, modeler build]
sources: [sources/sessions/2026-02-18-testing-and-build.md]
last_updated: 2026-04-19
status: seed
---

# Testing & Build

Build commands, test framework, CI/CD pipeline, and common build errors for the CG Mobile App modeler contracts.

## Build Commands

```bash
# cd to your workspace root

sf mdl build         # Compile all contracts
sf mdl simulate      # Start local dev server (http://localhost:3000)
sf mdl clean         # Clean build artifacts
sf mdl package       # Create distributable package
```

## Build Output

```
appl/build/app/clockwork/
├── dataSource/          # Compiled datasources
├── businessObject/      # Compiled BOs and LOs
├── processFlow/         # Compiled processes
├── userInterface/       # Compiled UIs
├── rtas.json            # Runtime artifact (~10MB, all metadata)
└── localization/        # Localized labels (~601KB)
```

## Jest Testing

Tests live in `test/unitTests/{Module}/{BO}/`:

```javascript
describe('BoVisit', function () {
    describe('reschedule', function () {
        it('should update planned dates when valid', function () {
            var bo = BoFactory.instantiate('BoVisit');
            bo.setPKey('V001');
            bo.setPlannedStartDate('2026-02-18');

            bo.reschedule('2026-02-19', '10:00', null, null);

            expect(bo.getPlannedStartDate()).toBe('2026-02-19');
            expect(bo.getPlannedStartTime()).toBe('10:00');
        });
    });
});
```

**Coverage thresholds** (from `jest.config.js`):

-   Statements: 70%
-   Branches: 65%
-   Functions: 70%
-   Lines: 70%

## CI/CD Pipeline (SFCI)

```
init → install → prepare → build → genManifest → package → publish
```

## Common Build Errors & Fixes

### CONFIRM Action: `messageId` not allowed as attribute

```xml
<!-- WRONG -->
<Action name="Confirm" actionType="CONFIRM" confirmType="YesNo"
        messageId="ConfirmMsg">

<!-- CORRECT -->
<Action name="Confirm" actionType="CONFIRM" confirmType="YesNo">
  <Message messageId="ConfirmMsg" />
  <Cases>
    <Case value="Yes" action="DoAction" />
    <Case value="No" action="Cancel" />
  </Cases>
</Action>
```

### SAVE Action: `object` not allowed as attribute

```xml
<!-- WRONG -->
<Action name="Save" actionType="SAVE" object="ProcessContext::MyBo">

<!-- CORRECT -->
<Action name="Save" actionType="SAVE">
  <Parameters>
    <Input name="boMyItem" value="ProcessContext::MyBo" />
  </Parameters>
</Action>
```

### ProcessFlow reference could not be resolved

Referenced process doesn't exist. Verify the process name and module prefix.

### ContextMenu: `name` / `dataSource` not allowed as attributes

```xml
<!-- WRONG -->
<ContextMenu name="MyMenu" dataSource="ProcessContext::MenuList.Items[]">

<!-- CORRECT -->
<ContextMenu>
  <Bindings>
    <Binding target="DataSource"
             binding="ProcessContext::MenuList.Items[]"
             bindingMode="ONE_WAY" />
  </Bindings>
  <Items name="ContextMenuItems">
    <Bindings>
      <Binding target="Icon" type="Image" binding=".actionImg" />
      <Binding target="Text" type="Label" binding=".actionId" />
      <Binding type="Editable" target="Editable" binding=".actionEnabled" />
    </Bindings>
  </Items>
</ContextMenu>
```

### Card Not Visible in Cockpit

See [[cockpit-cards#Troubleshooting Card Visibility]].

## End-to-End Implementation Checklist

-   [ ] **Salesforce object** exists with required fields
-   [ ] **DataSource(s)** map SF fields to DS attributes
-   [ ] **BO/LO/LI definitions** map DS attributes to typed properties
-   [ ] **Business logic** implements rules in `.bl.js` files (with `@namespace CUSTOM`)
-   [ ] **Process** loads BOs/LOs in EntryActions, handles events, orchestrates flow
-   [ ] **UI bindings** connect to ProcessContext variables
-   [ ] **Responsive layouts** defined for Phone, Tablet, and Default
-   [ ] **Localization** added for all labels (`<Resource>` with `id`)
-   [ ] **Validation** implemented in BO `afterDoValidateAsync`
-   [ ] **Tests** cover business logic methods
-   [ ] **Build passes** (`sf mdl build`)
-   [ ] **Server test** (`sf mdl simulate`)

## Cross-References

-   [[modeler-setup]] — Plugin installation and workspace setup
-   [[architecture-overview]] — Overall system context
-   [[cockpit-cards]] — Additional checklist for card implementations
