> For the complete documentation index, see [llms.txt](https://docs.drizz.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.drizz.dev/writing-tests/memory-and-blockers.md).

# Memory & Blockers

**Memory** is org-level context attached to a registered app. **Blocker rules** are its main content — a condition and one recovery action, written once, applied to every run.

|                |                                                                               |
| -------------- | ----------------------------------------------------------------------------- |
| **Platforms**  | Android · iOS                                                                 |
| **Scope**      | The app, org-wide. Every test everyone runs against that package              |
| **Linked to**  | A registered app. Multiple package names can map to one entry                 |
| **Hard limit** | **One action per rule.** A rule cannot do X then Y                            |
| **Watch out**  | A rule that dismisses something a test is meant to check will hide a real bug |

## Prerequisites

* Drizz desktop app installed and signed in
* An app registered through the web app
* The exact on-screen text of the popup being dismissed

## Copy this

Blocker rules for ShopEase. Each is a condition and a single recovery action.

```
blocker: A promotional or upsell bottom sheet is visible unexpectedly.
recovery: Tap the Close ("X") CTA.

blocker: "Your internet is a little wonky" with a Retry button.
recovery: Tap on Retry

blocker: Permission prompt for location or notifications is visible.
recovery: Tap "While using the app"

blocker: "Rate ShopEase" bottom sheet is visible over the home or order screen.
recovery: Tap "Not Now".

blocker: First time user experience flow with a "Continue to [section]" button (e.g. "Continue to Deals").
recovery: Tap on the "Continue to [section]" button
```

With those five in Memory, no ShopEase test needs an `IF` block for any of them.

## What Memory holds

Memory holds context about an app that makes Vision AI more accurate on it: blocker rules, plus app-specific hints.

| Property        | Detail                                                                                                            |
| --------------- | ----------------------------------------------------------------------------------------------------------------- |
| Scope           | An app, not a test. Everything in it applies to every run against that package                                    |
| Link            | A registered app — one uploaded through the web app                                                               |
| Package mapping | Multiple package names can map to one entry, which covers debug, staging and production builds with different IDs |
| Sharing         | Shared across the whole organization. Every member's tests get it                                                 |
| Lifetime        | Until it is changed                                                                                               |

## Memory v/s Variables

|                                 | What it is                                               | Where it lives                                | How long it lasts   |
| ------------------------------- | -------------------------------------------------------- | --------------------------------------------- | ------------------- |
| **Memory** (this page)          | Org-level context about an app — blocker rules and hints | The Memory area, attached to a registered app | Until you change it |
| **Variables** (`Store` / `SET`) | Values a test captures or assigns while it runs          | Inside one test run                           | That run only       |

These docs say **Memory** for the app context and **variables** for the other. `Store the Order Total as total` belongs to [Store & SET](/writing-tests/which-variable/store-and-set.md).

## Blocker rules

Each rule is a **condition** and a **single recovery action**. Drizz applies it during any run, with no step in any script.

```
blocker: A half card with a close (X) button offering size or color variants of the item.
recovery: Tap on "Add Item" CTA

blocker: Popup with "Replace cart item?"
recovery: Tap on "Yes"

blocker: "Select Delivery Address" sheet is open, dimming the address dropdown at the top.
recovery: Tap the first visible address

blocker: in-app notification with a "Got it" button is visible
recovery: Tap on "Got it"
```

A rule fires only when Drizz decides the screen is blocked. It isn't a background clicker — a matching popup that isn't in the way is left alone.

### Constraints on a rule

<table data-search="false"><thead><tr><th>Constraint</th><th>Detail</th></tr></thead><tbody><tr><td>One action per rule</td><td>Hard limit. A rule cannot do X and then Y. Recovery that needs two steps belongs in an <code>IF</code> block in the script</td></tr><tr><td>Appending a wait</td><td>The one accepted extension of a single action: <code>recovery: Tap "Add separately" CTA and wait for 2 seconds.</code></td></tr><tr><td>Exact text</td><td>Quote the exact on-screen text in the condition. Vague conditions over-match and dismiss things they shouldn't</td></tr><tr><td>Nothing under test</td><td>A rule that closes a dialog a test validates — "Payment failed" — turns a real bug into a green run</td></tr><tr><td>Org-wide effect</td><td>A rule affects every test the whole organization runs against that package. A popup that appears in one flow only belongs in an <code>IF</code> block</td></tr><tr><td>No duplication</td><td>A blocker in Memory must not also be an <code>IF</code> block in scripts. One fires, the other's condition is false, and the script reads as if Memory isn't working</td></tr><tr><td>Generic over specific</td><td>One pattern rule replaces five near-identical rules</td></tr></tbody></table>

| Don't                         | Do                                                                       |
| ----------------------------- | ------------------------------------------------------------------------ |
| `blocker: a popup is visible` | `blocker: "Rate ShopEase" bottom sheet is visible over the home screen.` |
| `blocker: an error appears`   | `blocker: "Your internet is a little wonky" with a Retry button.`        |

A generic pattern rule:

```
blocker: First time user experience flow with a "Continue to [section]" button (e.g. "Continue to Deals/Grocery/Fashion").
recovery: Tap on the "Continue to [section]" button
```

## Memory rule v/s IF block

{% tabs %}
{% tab title="Memory blocker rule" %}
**Use when** the popup can appear in any test, at any point.

```
blocker: "Rate ShopEase" bottom sheet is visible over the home or order screen.
recovery: Tap "Not Now".
```

|                     |                                                               |
| ------------------- | ------------------------------------------------------------- |
| Written in          | The Memory area, against a registered app                     |
| Applies to          | Every test in the organization that runs against that package |
| Actions allowed     | One                                                           |
| Steps in the script | None                                                          |
| {% endtab %}        |                                                               |

{% tab title="Inline IF block" %}
**Use when** the state is tied to one screen or one scenario.

```
IF Address Suggestion dropdown is visible
{
    Tap on the first suggestion
}

IF minimum order value popup is visible
{
    Tap on OK
    Wait Until 1 Seconds
}

IF maximise button is visible
{
    Tap on maximise button
    Wait Until 2 Seconds
}
```

|                     |                               |
| ------------------- | ----------------------------- |
| Written in          | The test script               |
| Applies to          | That test only                |
| Actions allowed     | Any number                    |
| Steps in the script | One block per popup, per test |

The `maximise button` block belongs in every test that runs on tablets. Parallel runs can reset orientation to portrait.
{% endtab %}
{% endtabs %}

## Common mistakes

<table data-search="false"><thead><tr><th>What you write</th><th>What happens</th></tr></thead><tbody><tr><td><code>recovery: Tap Close then tap Continue</code></td><td>Two actions. One action per rule — this is a hard limit</td></tr><tr><td><code>blocker: a bottom sheet is visible</code></td><td>Over-matches. It starts dismissing sheets your tests need</td></tr><tr><td>A rule that closes the "Payment failed" dialog</td><td>The test that checks for that error passes forever</td></tr><tr><td>The same popup in Memory <em>and</em> in an <code>IF</code> block</td><td>Confusing to read, and hides whether Memory is working</td></tr><tr><td>A rule for a popup only your one test sees</td><td>Every test in the org now pays for a check it doesn't need</td></tr><tr><td>Expecting Memory to fix a flaky tap</td><td>Memory dismisses blockers. It doesn't improve targeting — fix the description</td></tr><tr><td>Confusing Memory with <code>Store</code></td><td>Different features, same word. See the table above</td></tr></tbody></table>

## Next

* [Conditionals](/writing-tests/conditionals.md)
* [Store & SET](/writing-tests/which-variable/store-and-set.md)
* [Authoring rules](/writing-tests/authoring-rules.md)

***

*Last updated: 6 August 2026*
