Metadata-Version: 2.4
Name: robo-appian
Version: 0.1.35
Summary: Reusable automation components for Appian applications.
License-Expression: MIT
License-File: LICENSE
Author: Dinil Mithra
Maintainer: Dinil Mithra
Requires-Python: >=3.12,<3.13
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Requires-Dist: playwright (==1.63.0)
Requires-Dist: pytest (==9.1.1)
Requires-Dist: robo-automation (==0.1.19)
Project-URL: Documentation, https://dinilmithra.github.io/robo-appian/
Project-URL: Developer, https://www.linkedin.com/in/dinilmithra/
Project-URL: Issues, https://github.com/dinilmithra/robo-appian/issues
Project-URL: Repository, https://github.com/dinilmithra/robo-appian
Description-Content-Type: text/markdown

# robo-appian

`robo-appian` (robo appian / `robo_appian`) by Dinil Mithra makes Appian pages easier to automate with readable Python. It is a Python automation and testing library for Appian applications.

It is designed for people who know their web application and only need basic Python to start writing automation.

## Quick example

```python
from robo_appian import AppianPage


def test_update_item(page: AppianPage) -> None:
    page.textbox(label="Description").fill("Example item")
    page.date(label="Start Date").fill("10/15/2026")
    page.radio(label="Priority").select("High")
    page.button(name="Submit").click()
```

The goal is to describe the page using the same text a user sees.

## Install

```bash
pip install robo-appian
robo-appian install-browser firefox
```

Python 3.12 is required. `robo-appian` uses `robo-automation` for generic browser and pytest infrastructure.

## Common controls

```python
page.textbox(label="Description").fill("Example item")
page.textbox(placeholder="example@example.com").fill("user@example.com")
page.textbox("Employee").select(search_text="John", value="John Smith")
page.date(label="Start Date").fill("10/15/2026")
page.radio(label="Priority").select("High")
page.button(name="Next").click()
```

Textboxes, dates, and selection components automatically move focus out after a value changes so Appian can process it.

## What belongs where?

```text
Your application tests
        ↓
robo-appian       Appian controls and Appian behavior
        ↓
robo-automation   Browser and pytest infrastructure
        ↓
Playwright
```

Your application project should own application URLs, login policy, business workflows, assertions, and test data.

## Documentation

Start with the beginner guides:

- Installation
- Quick Start
- Your First Test
- Choosing a Component
- Troubleshooting

Advanced architecture and pytest integration are documented separately for framework maintainers.

Full documentation:

**https://dinilmithra.github.io/robo-appian/**

## License

`robo-appian` is licensed under the [MIT License](LICENSE).
## Error handling

Appian-specific library failures use `RoboAppianError`, which is also a `RoboAutomationError`. Normal tests should usually let pytest report these errors. If you need recovery or diagnostic handling, see **[How to use RoboAppianError](docs/getting-started/error-handling.md)** for examples using `code`, `details`, `to_dict()`, and exception chaining.


## Runtime boundary for application projects

Application projects should normally import automation APIs only from
`robo_appian`.

```python
from robo_appian import AppianPage, AppianRuntime, RoboAppianError
```

`AppianRuntime` provides the Appian-facing browser/session lifecycle used by
advanced consumer fixtures. It intentionally hides lower browser and
performance implementation classes. Normal test authors usually only need the
`page` fixture and component APIs shown above.

## Semantic browser recorder

The library now includes `robo_appian.recorder`: live semantic inspection,
recording normalization, explicit step review and deterministic pytest generation.
Use the sibling `robo-recorder` project's README for installation, the local demo,
supported mappings and live-browser validation steps. Recorder mechanics stay in
this library; generated tests do not depend on CORE testcase patterns.

### Recorder commands

The recorder CLI and demo are owned by this library; no `robo-recorder` package
is required to capture, review or generate tests.

```powershell
robo-appian recorder record --url "https://your-appian-host/suite/sites/your-site" --output .\recordings\request
robo-appian recorder review .\recordings\request\recording.json
robo-appian recorder validate .\recordings\request\recording.json
robo-appian recorder generate .\recordings\request\recording.json --output .\tests\generated\test_request.py
```

Use `python -m robo_appian.cli recorder --help` if the console command is not on
PATH. `robo-appian recorder demo` opens the library-bundled local example.
Playback requires consumer page fixtures for browser lifecycle and cleanup;
see the sibling `robo-recorder` project for an example. Existing browser-install
commands remain available. The old `robo-recorder` CLI forwards to these same
library functions.

### Exact keyed grid rows

`grid.row_matching(column_name="Vendor #", value="549")` returns a live row
matched by normalized exact text in the named column. With its default `wait=True`,
it requires one matching grid and one matching row; duplicates fail rather than
selecting the first match. `timeout`, tri-state `visible`, and `wait=False` are
available. Existing positional/named row, column, cell and counting APIs are
unchanged. This lookup only searches rendered rows and does not paginate.

The semantic recorder prefers `grid.row(name=..., exact=True, unique=True)`
and named columns. If an exact unique row/column name is unavailable, it uses
recorded one-based row/column numbers independently. `unique=True` is optional
and preserves the existing default row behavior when omitted; it verifies one
grid and one matching row when enabled. The recorded grid, row and column mapping
remain subject to explicit human approval. Numbered rows are positional and do
not remain bound to the same business record after sorting/filtering.
Recording browser viewports now follow window resizing (`no_viewport=True`).

### Dialog-scoped recorder fields

`AppianDialog` now exposes `textbox(...)`, `date(...)` and `grid(...)` using the
existing component constructors with dialog scope. `dialog.grid(..., wait=False)`
supports optional lookup; default grid/row/cell/component synchronization remains
in place. Grid cell actions retain the original AppianPage as their owner.
Recorder calendar selections are normalized to the uniquely associated date field
when that relationship is available; unresolved historical calendar clicks require
re-recording and are not automatically approved or assigned to a guessed field.

## Headless execution

Pytest browsers default to visible (`HEAD_LESS=N`) in this workspace. Use
`HEAD_LESS=Y` for headless execution. See the [Headless execution guide](docs/guides/headless-execution.md)
for project `.env`, shell, CI and VS Code examples, configuration precedence, and
the proposed fixture override. Interactive recorder browsers remain visible.

## Feature documentation

Start with the [Feature guide](docs/features.md) for components, recorder,
configuration, evidence, verification, runtime APIs and current limitations.
The [Semantic recorder guide](docs/guides/recorder.md) covers the complete
capture-to-execution workflow.

Repository-only [Component identification requirements](technical-requirements/component-identification.md)
describe how RoboAppian recognizes buttons and other components. This technical
reference is kept outside the GitHub Pages documentation source.

