> For the complete documentation index, see [llms.txt](https://docs.bugbug.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.bugbug.io/export-import-and-backup/yaml-schema.md).

# YAML schema

The BugBug YAML file format, field by field: tests, groups, steps, selectors, components, suites and folders, plus the JSON Schema for validation and editor autocomplete.

Every YAML file BugBug exports or imports has the same three-key envelope. This page is the field reference for those files. For what can be exported and imported and how conflicts are resolved, see the [Overview](/export-import-and-backup/import-export.md) and [Importing](/export-import-and-backup/importing.md).

{% hint style="info" %}
**Quick facts**

* Schema version: `1.0` (the only accepted version).
* JSON Schema: `https://api.bugbug.io/v2/schema/yaml/v1/` (draft-07, no authentication).
* Keys are `snake_case`. Action names and enum values are `camelCase` (`dblClick`, `textContent`).
* Unknown keys are rejected. A typo such as `selectr:` fails the import instead of being ignored.
* A selector must start with `xpath=` or `css=`.
* A test's folder is not a YAML field. It comes from the file's directory inside a ZIP, or from the folder you import into.
  {% endhint %}

### The envelope

BugBug writes a short header comment, then three top-level keys:

```yaml
# yaml-language-server: $schema=https://api.bugbug.io/v2/schema/yaml/v1/
# BugBug YAML Format
# Schema Version: 1.0
# Documentation: https://docs.bugbug.io/yaml-schema
schema_version: '1.0'
schema_type: component
data:
  component_name: GOTO BugBug.io
  slug: goto-bugbugio
  steps:
  - action: goto
    action_details:
      url: https://bugbug.io/
```

| Key              | Meaning                                                                       |
| ---------------- | ----------------------------------------------------------------------------- |
| `schema_version` | Which version of the format this file follows. Write it as a string: `'1.0'`. |
| `schema_type`    | What kind of thing the file describes.                                        |
| `data`           | The thing itself. Its shape depends on `schema_type`.                         |

The header comment is informational. The importer only reads the three keys.

| `schema_type` | Describes                                                                      | Imported                                    |
| ------------- | ------------------------------------------------------------------------------ | ------------------------------------------- |
| `test`        | A test: its groups, steps, screen size and tags.                               | As a YAML file, or in a test or project ZIP |
| `component`   | A reusable group of steps.                                                     | In a test or project ZIP                    |
| `suite`       | A set of tests to run together, and how to run them.                           | In a project ZIP                            |
| `profile`     | A named set of variables, typically one per environment.                       | In a project ZIP                            |
| `project`     | Project settings: selectors, waiting conditions, screen sizes, timeouts, tags. | In a project ZIP                            |
| `folder`      | A folder description, in a `.folder.yaml` marker.                              | In a test or project ZIP                    |

***

### A complete test

This test opens a login page through a component, fills in the form with profile variables, clicks a button found by XPath, and checks the result:

```yaml
# yaml-language-server: $schema=https://api.bugbug.io/v2/schema/yaml/v1/
schema_version: '1.0'
schema_type: test
data:
  name: Login with valid credentials
  slug: login-with-valid-credentials
  runtime: browser
  screen_size: desktop
  tags:
  - smoke
  groups:
  - component_source: open-login-page
  - group_name: Log in
    slug: log-in
    steps:
    - action: type
      action_details:
        selector: css=input[name="email"]
        value: '{{email}}'
    - action: type
      action_details:
        selector: css=input[type="password"]
        value: '{{password}}'
    - action: click
      name: Submit the form
      action_details:
        selector: xpath=//BUTTON[normalize-space(text())="Log in"]
    - action: assert
      action_details:
        selector: css=h1
        assertion_property: textContent
        assertion_type: contain
        assertion_expected_value: Dashboard
```

The `open-login-page` component lives in its own file:

```yaml
schema_version: '1.0'
schema_type: component
data:
  component_name: Open login page
  slug: open-login-page
  steps:
  - action: goto
    action_details:
      url: '{{homepage}}/login'
```

`{{email}}`, `{{password}}` and `{{homepage}}` are [variables](/editing-tests/variables.md). Quote any value that starts with `{{`, otherwise YAML reads it as a map.

***

### Test fields (`schema_type: test`)

| Field         | Required | Value                                                                                                                                   |
| ------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `name`        | yes      | Display name of the test.                                                                                                               |
| `slug`        | no       | Identity of the test in the project. If omitted, BugBug takes it from the filename (see [File names and slugs](#file-names-and-slugs)). |
| `runtime`     | yes      | `browser`. This is the only supported value; `api` is reserved for the future.                                                          |
| `screen_size` | yes      | `desktop` or `mobile`. The sizes themselves are set in the project settings. `custom` is reserved for the future.                       |
| `notes`       | no       | Free text.                                                                                                                              |
| `tags`        | no       | List of tag names. Missing tags are created on import with a default color.                                                             |
| `groups`      | no       | Ordered list of groups. Each item is an inline group or a component reference.                                                          |

The field is `name`, not `test_name`. Each document type has its own name field: `name` for a test, `group_name` for an inline group, `component_name` for a component, `suite_name` for a suite.

### Groups

A test is a list of groups. Each group is one of two shapes.

**Inline group** — steps that belong to this test only:

| Field        | Required | Value                                                                 |
| ------------ | -------- | --------------------------------------------------------------------- |
| `group_name` | yes      | Display name of the group.                                            |
| `slug`       | yes      | Identifies the group inside the test. Must be unique within the test. |
| `steps`      | no       | Ordered list of [steps](#steps).                                      |

**Component reference** — a link to a [component](/editing-tests/components.md), by its slug:

| Field              | Required | Value                 |
| ------------------ | -------- | --------------------- |
| `component_source` | yes      | The component's slug. |

A component reference has no `group_name`, `slug` or `steps`. The steps live in the component's own file.

The slug has to resolve when you import: either the component already exists in the target project, or its YAML is in the same ZIP. Otherwise the import stops with a "component not found" error, unless you choose to skip missing components (see [Importing](/export-import-and-backup/importing.md)). Slugs aren't shown in the app. To find a component's slug, export a test that uses it and read `component_source`, or list components through the [Public API](/integrations/public-api.md) or [MCP server](/ai-testing/mcp.md).

### Steps

Every step has the same outer shape:

```yaml
- action: click                 # required: the action name
  name: Open the menu           # optional: custom step name
  is_active: true               # optional, default true; false skips the step
  notes: Opens the burger menu  # optional
  action_details:               # required: action-specific fields, plus the selector
    selector: css=button.menu
    interaction_position: smart
  execution:                    # optional
    continue_on_failure: false
    sleep: 2
    run_timeout: 30
  waiting_conditions:           # optional: overrides the project defaults for this step
  - condition: networkIdle
    is_active: false
```

| Field                           | Value                                                                                                                                                     |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `action`                        | The action name, in camelCase. See [Action details by action](#action-details-by-action).                                                                 |
| `action_details`                | A flat map: the action's own fields plus `selector` (and `drop_selector` for drag and drop). Use `{}` for an action that needs nothing, such as `goBack`. |
| `execution.continue_on_failure` | `true` makes a failure here soft: the run continues and the step is marked "Step failed but the issue was ignored".                                       |
| `execution.sleep`               | Delay before the step, in whole seconds, up to 300. Maps to [Delay / Sleep](/preventing-failed-tests/delay-sleep.md) in the app.                          |
| `execution.run_timeout`         | Step timeout, in seconds, up to 300. If omitted, the project default applies. See [Timeout](/preventing-failed-tests/timeout.md).                         |
| `waiting_conditions`            | Per-step overrides of the project's [waiting conditions](/preventing-failed-tests/waiting-conditions.md).                                                 |
| `conditional_steps`             | Only on `ifCondition`. See [If conditions](#if-conditions).                                                                                               |

Exports leave out fields that hold their default value. When you import, a missing field means the default.

### Selectors

`selector` is a string that starts with a strategy prefix:

| Prefix   | Meaning        | Example                                          |
| -------- | -------------- | ------------------------------------------------ |
| `xpath=` | XPath selector | `xpath=//BUTTON[normalize-space(text())="Save"]` |
| `css=`   | CSS selector   | `css=form#login input[name="email"]`             |

A selector without a prefix, such as `//button` or `#save`, fails validation.

You can chain selectors, the same as **Then find its parent / child / sibling** in the app's selector editor. Each part starts with its own prefix, and parts are joined by an operator with a space on each side:

| Operator | In the app | Next part is searched among…                     | Example                                                          |
| -------- | ---------- | ------------------------------------------------ | ---------------------------------------------------------------- |
| `>>`     | child      | the previous match's descendants                 | `xpath=//section[@id="pricing"] >> css=.card >> xpath=.//BUTTON` |
| `<<`     | parent     | the previous match's ancestors                   | `xpath=//SPAN[text()="Name"] << xpath=.//DIV`                    |
| `~`      | sibling    | elements on the same level as the previous match | `css=li.active ~ css=li`                                         |

{% hint style="warning" %}
Inside a single CSS selector, write the CSS sibling combinator without spaces (`css=li.active~li`). With spaces, `~` is read as the chain operator.
{% endhint %}

### Waiting conditions

`waiting_conditions` lists conditions to switch on or off for one step. Conditions you leave out keep the project setting.

```yaml
waiting_conditions:
- condition: elementIsNotAnimating
- condition: networkIdle
  expected: 0
- condition: elementHasAttribute
  expected: data-state="ready"
- condition: documentComplete
  is_active: false
```

| Field       | Value                                                                                                                                                                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | `documentComplete`, `elementHasAttribute`, `elementHasFocus`, `elementIsNotAnimating`, `elementIsNotCovered`, `elementIsNotDisabled`, `elementIsVisible`, `networkIdle`, `pageNavigationAfterExecution` |
| `is_active` | `true` (default) or `false`.                                                                                                                                                                            |
| `expected`  | Only for the two conditions below. Other conditions take no value.                                                                                                                                      |

| Condition             | `expected`                                                                                                                                                                                                       |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `networkIdle`         | An integer: the maximum number of pending network requests, default `2` (**Max. pending requests** in Project Settings). The step runs once pending requests stay at or below this number for at least 1 second. |
| `elementHasAttribute` | A string: the attribute and value to wait for, written as `attribute="value"`, for example `aria-expanded="true"`.                                                                                               |

Project-wide defaults use the same shape under `data.settings.waiting_conditions` in the project file.

### If conditions

An `ifCondition` step checks something and runs its `conditional_steps` only when the check passes. It uses the same fields as an assertion:

```yaml
- action: ifCondition
  action_details:
    selector: css=#cookie-banner
    assertion_property: exist
    assertion_type: equal
  conditional_steps:
  - action: click
    action_details:
      selector: css=#cookie-banner button.accept
```

`conditional_steps` cannot contain another `ifCondition`, and cannot contain a component. See [Conditional logic (if/else)](/editing-tests/conditional-logic-if-else.md) for the patterns that work around this.

***

### Action details by action

The table lists the keys each action accepts in `action_details`, apart from `selector`. For what each action does, see [Actions](/editing-tests/actions.md). The JSON Schema has the full list of allowed values.

| `action`                                                                       | Keys in `action_details`                                                                                                                                                               |
| ------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `goto`, `newTab`                                                               | `url` (required), `username`, `password` (HTTP basic auth)                                                                                                                             |
| `click`, `dblClick`, `rightClick`, `hover`, `mouseDown`, `mouseUp`             | `interaction_position` (default `smart`), `modifier_keys`                                                                                                                              |
| `mouseMove`                                                                    | `interaction_position`, `is_target_document`, `client_x`, `client_y` (both required when `is_target_document: true`), `mouse_move_steps`, `mouse_buttons`                              |
| `type`, `change`                                                               | `value`, `has_secret_value`                                                                                                                                                            |
| `select`                                                                       | `select_type` (`text`, `value` or `index`, required), `value` (required), `select_is_multiple`                                                                                         |
| `scroll`                                                                       | `scroll_inside` (`window` or `element`), `scroll_to` (`coords`, `edge`, `untilNextStepElementIsVisible`, `elementIntoView`), `scroll_x`, `scroll_y`, `scroll_edge`, `scroll_direction` |
| `dragAndDrop`                                                                  | `dnd_drag_on`, `interaction_position`, `dnd_drag_x`, `dnd_drag_y`, `dnd_drop_on`, `dnd_drop_interaction_position`, `dnd_drop_x`, `dnd_drop_y`, plus `drop_selector` next to `selector` |
| `assert`                                                                       | See [Assertion fields](#assertion-fields)                                                                                                                                              |
| `ifCondition`                                                                  | Assertion fields, without `interaction_position`                                                                                                                                       |
| `execute`                                                                      | `code` (required)                                                                                                                                                                      |
| `setLocalVariable`                                                             | `local_variable_name` (required), `local_variable_source` (`element`, `value` or `evaluate`, required), `value`, `code`                                                                |
| `switchContext`                                                                | `value` (`topFrame` or `iframe`), `tab_no`, `window_no`, `frame_src`                                                                                                                   |
| `uploadFile`                                                                   | `file_source`. See [Upload files](#upload-files)                                                                                                                                       |
| `openInbox`                                                                    | `value` (required)                                                                                                                                                                     |
| `answerPrompt`                                                                 | `value` (required)                                                                                                                                                                     |
| `elementVisualRegression`, `pageVisualRegression`                              | `visual_regression_max_diff`, `visual_regression_ref_screenshots`                                                                                                                      |
| `goBack`, `goForward`, `reloadPage`, `closeTab`, `clear`, `pasteFromClipboard` | none                                                                                                                                                                                   |

All `value` fields are strings. Quote numbers you want to type, such as `value: '0042'`, so YAML keeps the leading zeros.

`interaction_position` accepts `smart`, `custom`, `topLeft`, `topCenter`, `topRight`, `middleLeft`, `middleCenter`, `middleRight`, `bottomLeft`, `bottomCenter` or `bottomRight`.

### Assertion fields

| Key                          | Required | Value                                                                                               |
| ---------------------------- | -------- | --------------------------------------------------------------------------------------------------- |
| `assertion_property`         | yes      | What to check. See the list below.                                                                  |
| `assertion_type`             | yes      | `equal`, `notEqual`, `contain`, `notContain`, `match`, `notMatch`, `greaterThan`, `lessThan`, `any` |
| `assertion_expected_value`   | no       | The expected value: a string, number or boolean. An empty string `''` is kept as a value.           |
| `assertion_case_insensitive` | no       | See [Assertion case sensitivity](#assertion-case-sensitivity).                                      |
| `assertion_attribute_name`   | no       | The attribute to check, for `hasAttribute` and `hasNotAttribute`.                                   |
| `assertion_java_script`      | no       | The function body, for `customJavaScript`. It must return `true` or `false`.                        |
| `assertion_variable_name`    | no       | The variable to check, for `variableValue`.                                                         |
| `interaction_position`       | no       | `assert` only.                                                                                      |

`assertion_property` accepts:

* Element: `exist`, `notExist`, `visible`, `notVisible`, `textContent`, `value`, `count`, `checked`, `notChecked`, `disabled`, `notDisabled`, `hasAttribute`, `hasNotAttribute`, `customJavaScript`
* Page: `pageTitle`, `pageUrlIs`, `pageShowsText`, `pageDoesNotShowText`, `downloadStarted`
* Data: `variableValue`, `clipboardValue`

Element properties need a `selector`. For what each check does, see [Assertions](/editing-tests/assertions.md).

A custom JavaScript assertion:

```yaml
- action: assert
  action_details:
    selector: css=.cart-total
    assertion_property: customJavaScript
    assertion_type: equal
    assertion_expected_value: 'true'
    assertion_java_script: |-
      return parseFloat(element.textContent.replace('$', '')) > 0;
```

### Upload files

`file_source` points at a file inside the same ZIP, by its path from the ZIP root. Exports use `artifacts/<8-character id>/<file name>`:

```yaml
- action: uploadFile
  action_details:
    selector: css=input[type="file"]
    file_source: artifacts/3f9a1c2e/invoice.pdf
```

When you write a ZIP yourself, any path under `artifacts/` works, as long as `file_source` matches it exactly, for example `artifacts/invoice.pdf`. Each artifact can be up to 50 MB.

Uploads only resolve when you import a ZIP. A standalone YAML file carries no attachments, so an `uploadFile` step imported that way has no file attached until you add one in the app.

***

### Component fields (`schema_type: component`)

| Field            | Required | Value                                          |
| ---------------- | -------- | ---------------------------------------------- |
| `component_name` | yes      | Display name.                                  |
| `slug`           | no       | Identity. If omitted, taken from the filename. |
| `steps`          | no       | Ordered list of [steps](#steps).               |

### Suite fields (`schema_type: suite`)

```yaml
schema_version: '1.0'
schema_type: suite
data:
  suite_name: Selected Staging Parallel
  suite_settings:
    run_in_parallel: true
    auto_retry: 0
    auto_add_new_tests: false
    before_after_all_enabled: false
  tests:
  - test_source: bugbugio-simple-test
  - test_source: bugbug-ifs
    is_deactivated: true
```

| Field                                 | Value                                                                                                                                                                  |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `suite_name`                          | Display name (required).                                                                                                                                               |
| `slug`, `notes`, `tags`               | As for tests.                                                                                                                                                          |
| `suite_settings`                      | Required. `run_in_parallel`, `auto_retry` and `auto_add_new_tests` are required; `before_after_all_enabled` defaults to `false`.                                       |
| `tests`                               | Tests in the suite, by `test_source` (the test's slug). `is_deactivated: true` keeps the test in the suite but switched off.                                           |
| `before_all_tests`, `after_all_tests` | Same shape as `tests`. Run only when `before_after_all_enabled` is `true`. See [Before all / After all tests](/organizing-tests/suites.md#before-all-after-all-tests). |

Suites are imported only as part of a project ZIP, which always creates a new project. A `test_source` that doesn't match any test in the ZIP is left out of the suite.

### Profile, project and folder files

* **Profile** (`schema_type: profile`): `name`, `slug`, `is_default`, and `variables`, a list of `name`, `key`, `type`, `value`, `description`, `has_secret_value`.
* **Project** (`schema_type: project`): `name`, `slug`, `homepage_url`, `tags` and `settings`. `settings.initial_run_profile` references a profile by slug; omitting it uses the base profile. The other settings (`general`, `browser`, `screen_sizes`, `selectors`, `visual_regression`, `waiting_conditions`) mirror Project Settings in the app.
* **Folder marker** (`schema_type: folder`): a single optional `description`. It sits in a `.folder.yaml` file inside the folder it describes.

A project document lists every tag in the project with its color. A test or suite document only lists tag names:

```yaml
schema_version: '1.0'
schema_type: project
data:
  tags:
  - name: flaky
    color: '#D1242F'
  - name: 'Version:1.23'
    color: '#2684FF'
```

Importing a project ZIP creates the tag definitions first, so every test and suite assignment resolves. In a standalone test YAML, a tag that doesn't exist yet is created with a default color, which you can change in Project Settings. See [Tags](/organizing-tests/tags.md).

***

### File names and slugs

Slugs identify items. They exist only for export and import and aren't shown in the app. They decide whether an import creates a new item or updates an existing one. See [How imports identify items](/export-import-and-backup/import-export.md#how-imports-identify-items).

If a file has no `slug`, BugBug takes it from the file name: the name without `.yaml` and `.bugbug`, and for tests without the `test_` prefix. `test_login.bugbug.yaml`, `login.bugbug.yaml` and `login.yaml` all give the slug `login`.

| File                           | Name BugBug uses          |
| ------------------------------ | ------------------------- |
| Single test YAML download      | `test_<slug>.bugbug.yaml` |
| Test or component inside a ZIP | `<slug>.bugbug.yaml`      |
| Project settings inside a ZIP  | `project.bugbug.yaml`     |

Import accepts any name that ends in `.yaml`. The `.bugbug.yaml` suffix helps editors recognise BugBug files.

### Folders and ZIP layout

There is no folder field in a test or component file. Inside a ZIP, the directory under `tests/` or `components/` is the folder:

```
my-test/
├── tests/
│   └── Auth/
│       └── Login/
│           └── login-with-valid-credentials.bugbug.yaml   → folder Auth / Login
├── components/
│   └── open-login-page.bugbug.yaml
└── artifacts/
    └── invoice.pdf
```

* A test ZIP contains exactly one test, plus the components it uses and its artifacts. A project ZIP can contain any number of each, plus `suites/`, `profiles/` and `project.bugbug.yaml`. See [Project ZIP contents](/export-import-and-backup/import-export.md#project-zip-contents).
* The whole content may sit in one top-level directory, as in exports (`my-test/` above), or directly at the ZIP root.
* Missing folders are created on import.
* When you import through the API with a `folderId`, that folder wins over the directory in the ZIP. A standalone YAML file lands in the folder you import into, or at the top level.

Limits for an imported ZIP: 1000 entries, 100 MB uncompressed in total, 20 MB per YAML file, 50 MB per artifact.

***

### Importing over an existing test

When the slug matches an existing test, the import reports a conflict and shows both versions. If you overwrite:

* The existing test is updated in place. It keeps its ID and its run history.
* Name, screen size, notes and tags are replaced by the file's values.
* Inline groups are matched by `slug`. Steps in a matched group are compared with the existing ones, so unchanged steps stay as they are.
* Groups and component references missing from the file are removed from the test. A removed component reference only unlinks the component; the component itself stays in the project.

If you skip, nothing changes. See [Importing](/export-import-and-backup/importing.md).

***

### Validation and autocomplete in your editor

Every exported file points at the schema on its first line:

```yaml
# yaml-language-server: $schema=https://api.bugbug.io/v2/schema/yaml/v1/
```

Most editors with YAML support pick this up and offer autocomplete for actions and fields, and flag invalid values as you type. Add the same line to files you write yourself.

### Validating in CI

The schema works with standard JSON Schema validators. For example, with [`check-jsonschema`](https://github.com/python-jsonschema/check-jsonschema):

```bash
check-jsonschema \
  --schemafile https://api.bugbug.io/v2/schema/yaml/v1/ \
  tests/**/*.yaml
```

Schema validation catches most mistakes. Import also checks things the schema can't see, such as whether a `component_source` resolves and whether a ZIP contains exactly one test.

***

### Assertion case sensitivity

For `assert` and `ifCondition` steps, the optional `assertion_case_insensitive` field controls letter case:

* `true` ignores letter case in supported text comparisons.
* `false` requires matching letter case.
* `null` or an omitted field uses the [historical defaults](/editing-tests/assertions.md#case-insensitive-text-comparisons): ordinary `contain`/`notContain` comparisons ignore case; `equal`/`notEqual`, `match`/`notMatch`, and whole-page text comparisons respect case.

```yaml
action: assert
action_details:
  assertion_property: pageTitle
  assertion_type: equal
  assertion_expected_value: Welcome
  assertion_case_insensitive: true
```

Exports omit values that match the historical default, such as `equal` with `false` or ordinary `contain` with `true`. When importing over an existing test, omitting the flag restores the historical default. In an API PATCH, omission keeps the current setting.

### Versioning

The current version is `1.0`, and it is the only version accepted today. All YAML files in one ZIP must use the same version.

{% hint style="warning" %}
**Schema v1 may change.** Re-export files after a BugBug update and fetch the schema again instead of relying on an older export or a pinned copy.
{% endhint %}

***

### FAQ

<details>

<summary>Which field sets a test's folder?</summary>

None. In a ZIP, the folder is the directory the file sits in under `tests/`, for example `tests/Auth/Login/`. When importing a single YAML file, pick the folder in the app or pass `folderId` to the API.

</details>

<details>

<summary>Why does my selector fail validation?</summary>

Every selector, and every part of a chained selector, must start with `xpath=` or `css=`. `//button` and `#save` are rejected; `xpath=//button` and `css=#save` work.

</details>

<details>

<summary>What happens when I import a test whose slug already exists?</summary>

BugBug reports a conflict and shows the current and incoming YAML. Overwrite updates the existing test in place and keeps its run history. Skip leaves it unchanged. To create a separate copy, change the `slug` in the file.

</details>

<details>

<summary>Do inline groups need a slug?</summary>

Yes. Inline groups need `group_name` and `slug`. Component references only have `component_source`.

</details>

<details>

<summary>Can I import a component, suite or profile on its own?</summary>

No. Components are imported with a test ZIP or a project ZIP. Suites, profiles and project settings are imported with a project ZIP.

</details>


---

# 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.bugbug.io/export-import-and-backup/yaml-schema.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.
