> For the complete documentation index, see [llms.txt](https://docs.mozark.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mozark.ai/no-code-studio/authoring-tests/modules.md).

# Modules

A module is a named, reusable group of steps: *Login*, *Search for a movie*, *Complete payment*. Record it once, use it in every test that needs it.

Modules are the difference between a suite you can maintain and forty test cases that each contain their own copy of the login flow.

## Create a module

1. In the Step Builder, select the steps you want to group.
2. Click **Create module**.
3. Give it a name, an optional description, and optional tags.

The selected steps are replaced in your test by a single **module block**: one card that stands for the whole group.

<figure><img src="https://952269762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRBaaAIJoDzwDclOOVa8Z%2Fuploads%2FMqbZ6Y3VnvIPW1eLct2z%2F28-create-module.png?alt=media&amp;token=4095e7e2-d25c-4f24-b64e-383e1ca81268" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
Name modules after what they achieve, not how. *Login* ages better than *Tap email, type, tap password, type, tap submit*.
{% endhint %}

## Insert a module into another test

In the Step Builder, use **Add → Module** and pick from the library. The block is inserted at the end of your steps; drag it where you need it. Everything inside a module runs in order, exactly as recorded.

<figure><img src="https://952269762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRBaaAIJoDzwDclOOVa8Z%2Fuploads%2FEE2evN5DsWs3XMERWTuG%2F04-modules.png?alt=media&amp;token=270c20ce-0152-4bd9-8c19-501fb3e6624f" alt=""><figcaption></figcaption></figure>

## Versions

Modules are **versioned and append-only**. This is the part worth understanding, because it is what stops a shared module from breaking tests behind your back.

* The first save is version **1.0**.
* Editing the steps creates **1.1**, then **1.2**, and so on. The old version is never changed and never deleted.
* Reverting to an old version creates a **new** version that restores that snapshot. History stays intact.

Every test that uses a module **pins** the exact version it was built against. Improving a module does not change any existing test until you choose to move it.

| Change type | When it happens                                 |
| ----------- | ----------------------------------------------- |
| create      | The module was created                          |
| edit        | Its steps were changed                          |
| revert      | An older snapshot was restored as a new version |

### When a newer version exists

Open a test whose module block is pinned to an older version and App Studio tells you. You choose:

* **Update**: re-pin this block to the newest version.
* **Keep current**: stay on the pinned version. You will not be asked again for that version.

Nothing updates silently in either direction.

## The module detail page

Click a module in the library to open it. Three tabs:

<figure><img src="https://952269762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRBaaAIJoDzwDclOOVa8Z%2Fuploads%2F8YW8sKZrqZ7q0E90Q6eF%2F21-module-detail.png?alt=media&amp;token=f004694a-7d9f-410a-a2db-1a690475a230" alt=""><figcaption></figcaption></figure>

| Tab               | What it shows                                                                                                              |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------- |
| Steps             | The steps in the current version                                                                                           |
| History           | Every version, who saved it and when, with the change type. Select two versions to see a step-by-step diff of what changed |
| Linked test cases | Every test using this module, and which version each one pins                                                              |

**Linked test cases** is also the delete guard: a module in use cannot be deleted. Remove its blocks from those tests first.

<figure><img src="https://952269762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRBaaAIJoDzwDclOOVa8Z%2Fuploads%2FIgyPN6u4W3cfjQrF5gI3%2F22-module-history.png?alt=media&amp;token=5c8316cb-0ba5-4d7a-ba27-3c09e547c0c2" alt=""><figcaption></figcaption></figure>

<figure><img src="https://952269762-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FRBaaAIJoDzwDclOOVa8Z%2Fuploads%2F4WjcG68qMeGaRmqjuEsv%2F23-module-linked.png?alt=media&amp;token=6cc13a0b-1813-4aeb-9267-9aeda267421a" alt=""><figcaption></figcaption></figure>

## Editing a module on a real device

Editing a module's steps blind is a good way to write a broken module. Instead, open the module on a live device and edit it against the real screen:

1. Open the module from the Modules library, or click a module block inside a test.
2. Start a device session.
3. Record, delete and reorder steps as usual, with **Run all** to verify them.
4. Click **Save version**.

Module edits are **not** autosaved, unlike test cases. Saving mints a new immutable version, so it is always an explicit action. If you opened the module from inside a test, saving hands you straight back to that test.

## Variables inside modules

Modules have scoping rules, because a module has to make sense wherever it is dropped in.

| Rule                                                             | Meaning                                                                                           |
| ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| Project variables work everywhere                                | Static variables, data-set lookups and the reserved context names are available inside any module |
| A variable captured inside a module is available after its block | Extract an OTP inside *Login* and later steps in the test can read it                             |
| A variable captured outside a module is not available inside it  | A module cannot depend on something a specific test happened to capture earlier                   |

The third rule is what keeps modules portable. If a module needs a value from its caller, put that value in a [data set](https://docs.mozark.ai/no-code-studio/authoring-tests/test-data) or a static variable instead of capturing it outside.

Violations show as an amber **variable scope** badge on the step, listing which names are missing. The **Create module** dialog warns you at the point of extraction if the steps you selected read outer variables.

## Worked example

A streaming app suite:

```
Modules
├── Launch and sign in          1.3
├── Navigate to watchlist       1.0
└── Search for a movie          1.2      ← reads ${movie_name}

Test cases
├── Add a movie to the watchlist
│     Launch and sign in     (pinned 1.3)
│     Search for a movie     (pinned 1.2)
│     Press Element  "Add to list"
│     Assert Presence  "Added to your list"
│
└── Remove a movie from the watchlist
      Launch and sign in     (pinned 1.3)
      Navigate to watchlist  (pinned 1.0)
      Press Element  "Remove"
      Assert Presence  "Your list is empty"
```

The sign-in flow is recorded once. When the login screen gets a new consent checkbox, you edit *Launch and sign in* on a device, save version 1.4, and update both tests, deliberately, when you are ready.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.mozark.ai/no-code-studio/authoring-tests/modules.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
