### App Termination

Whenever the testers.ai CLI completes, it will return an exit code to indicate
success or an error.  This allows the CLI to be used in a typical processing
pipeline. The return codes are as follows:

Success             0
Invalid Auth        1  - Invalid or expired activation code
Setup Failed        2  - Bug/Issue loading and configuring command
Command Failed      3  - There was a problem running the command
Unexpected Failure  4

In addition to the exit code, running certain commands that can be used as
part of a processing pipeline will output meaningful information as the last
line of the console log. These commands will document the final line format
and what data will be returned.  The same data will be written to file in
JSON format depending on the pipeline methods used.

The testers.ai app has built in help subsystem where anyone can find the list of support commands and each commands
set of options.

```
List commands:
    testers --help

List given command's options:
    testers {command} --help
```

*NOTE: By default, if there is no command provided then the standard checks ("sc") command is run.



### General Options

**base**
```
--activation-code  [Default: None]  Provided activation code; required.
--cfg              [Default: None]  Path to JSON file containing configuration for this run.
--debug            [Default: None]  Prints additional logging information.
--print            [Default: None]  Prints logging information to the console in addition to log file.
--team             [Default: None]  Team identifier used for activation and organizing results (default: "TEAM")
```


**ai**
Currently testers.ai CLI only supports:
- Anthropic
- Gemini (Google AI Platform)
- OpenAI
- AzureOpenAI

```
--ai-model                      [Default: None]  The name of the model to use (defaults: gemini-2.5-flash)
--ai-temp                       [Default: None]  AI temperature (float) [0.0, 2.0] (default: AI api default)
--api-keys-path                 [Default: None]  Path to a JSON file containing LLM API keys.
--anthropic-key                 [Default: None]  Anthropic API_KEY; or from ENV
--azure-openai-api-version      [Default: None]  Azure OpenAI version
--azure-openai-deployment-name  [Default: None]  Azure OpenAI deployment name; or from ENV
--azure-openai-endpoint         [Default: None]  Azure OpenAI endpoint; i.e. url endpoint.  Only accepts endpoints within the
                                                 azure.com domain.
--azure-openai-key              [Default: None]  Azure OpenAI API_KEY; or from ENV
--gemini-key                    [Default: None]  Google Gemini API_KEY; or from ENV
--google-application-credentials[Default: None]  Path to a file containing VertexAI credentials
--openai-key                    [Default: None]  OpenAI API_KEY; or from ENV
--print-ai-stats                [Default: False] Print AI info and token usage.
```

**Notes:
*If one doesn't supply their own key then we provide access to Google Gemini through the testers.ai account.
*API_KEY can also be provided through the standard environment variables instead of as an argument.
*If an API_KEY is provided but the model is not provided then the default model for that LLM is used.

              DEFAULT MODEL NAME         ENV KEY NAME
-Anthropic:   claude-3-7-sonnet-latest   ANTHROPIC_API_KEY
-AzureOpenAI: gpt-4o                     AZURE_OPENAI_API_KEY, AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_VERSION,
                                         AZURE_OPENAI_DEPLOYMENT_NAME
-Gemini:      gemini-2.5-flash           GEMINI_API_KEY
                                         GOOGLE_APPLICATION_CREDENTIALS
-OpenAI:      gpt-4o                     OPENAI_API_KEY


**browser configuration**
These are the common browser flags used to configure the browser during the execution of the run.

```
--as-device {device_name}             [Default: None] Use device-like configuration; ignores browser option.
--browser {browser_name}              [Default: chromium]
--browser-install-path {directory}    [Default: <testers_binary_path>/playwright-browsers]
--disable-video-recording             [Default: False]
--header                              [Default: None] Allows zero or more of this flag.  All entries are composed into
                                                      a dictionary of headers that will be applied to all sites.
--user-agent {string}                 [Default: None] *Uses default value
--user-data {directory}               [Default: None]
--viewport-dims {width},{height}      [Default: 1920,1080]
--window-pos {x},{y}                  [Default: None] *Does not work with WebKit / Firefox
```


**Run Configuration**
--app-name       [Default: "APP"]  Name of the application being tested (default: "APP")
--custom-prompt  [Default: None]   A custom prompt to guide AI testing agents in this phase.
                                   (currently second of two custom prompts)
--data-dir       [Default: *]      A root directory for storing data (default: "{default_data_dir}")
--global-prompt  [Default: None]   A custom prompt to guide AI agents across phases
                                   (currently first of two custom prompts)
--label          [Default: "HOME"] Label for the page(s) being tested
--run-id         [Default: None]   An id used to relate data across multiple phases.  When used with the "sc"
                                   command it is appended to crawl time.  When used with scoped commands such
                                   as "scrape" it will used as the directory for the output relative the <data_dir>.
                                   Regardless, it is also an identifier.



### Commands

**browsers**

In order to provide control over what browsers are installed, testers.ai app provides the browsers command.

```
testers browsers install {browser_name} [--force]
testers browsers list
testers browsers uninstall

Common options:

--browser-install-path {directory}    [Default: <testers_binary_path>/playwright-browsers]
```

*The uninstall command uninstalls ALL "managed" browsers; does not include Chrome / MS Edge.

*The install command allows one of these browsers to be installed:

    ```chromium,firefox,webkit,chrome,chrome-beta,msedge,msedge-beta,msedge-dev``

There are occasions where a newer version is available but it is already installed.  In those instances, the --force
option can be used to force it to install even if the "browser" is "already installed".  This most often occurs when
the testers.ai app is updated.


**custom-tests**
Executes the provided custom tests and associates output with the given run_id.

GENERAL ARGS: base, ai, browser, and run config

```
--max-actions        [Default: 20]    Maximum number of actions that can be taken.
--setup-script-file  [Default: None]  A file containing the setup script to use to setup scrape.
--setup-prompt       [Default: None]  A prompt used to setup the browser prior to scrape.
--tests-file         [Default: None]  A file containing one or more tests to execute (dict[key, test]).
--test-key           [Default: None]  A file containing one or more tests to execute.
url                  [Required]       URL of the website to test

Example: ./testers custom-tests {url} --team {team} --activation-code {code} --run-id HOME --data-dir data/TEAM/APP/{timestamp}/pages --debug --print --tests-file custom_tests.json
```


**gen-setup-test**

Convert a string into an AI script that can be used to put a browser into the
state necessary to perform actions such as scrape or execute a test case. The
input can vary from a simple plain text string to the JSON dump of a test case
from a tool such as JIRA. The output should contain a sequence of steps to
take by the browser action execution model. It may also contain data that will
be injected into the test steps.


**launch**

In order to provide the ability to perform stateful tests, testers.ai app provides the launch function.  The command
lets one launch and manually use a browser in a stateless or stateful fashion; stateless by default.  The browser state
can be used to allow manually configuring a url or set of urls prior to testing.  For example, one may desire a url to
be in a logged in state prior to performing a test.

```
testers launch {url}

Options:

--as-device {device_name}             [Default: None] Use device-like configuration; ignores browser option.
--browser {browser_name}              [Default: chromium]
--browser-install-path {directory}    [Default: <testers_binary_path>/playwright-browsers]
--disable-video-recording             [Default: False]
--header                              [Default: None] Allows zero or more of this flag.  All entries are composed into
                                                      a dictionary of headers that will be applied to all sites.
--save-video-dir {directory}          [Default: None]
--user-agent {string}                 [Default: None] *Uses default value
--user-data {directory}               [Default: None]
--viewport-dims {width},{height}      [Default: 1420,1080]
--window-pos {x},{y}                  [Default: None] *Does not work with WebKit / Firefox
```

The user-data option determines whether or not the browser is in stateless mode.  If a directory is provided then
the browser will save relevant browser state such as cookies to this directory.  When the browser is
launched again with the same directory, the browser will load the provided state.  This can also be used with the
check and test commands to allow the browser to launch in the given state.


**scrape**

Launches the browser and scapes the DOM from the provided url and setup steps.
The scrape will also include the standard logs and timing information
expected for the static checks and feedback portion of the "sc" command.  The
intention is to use the final page data as the data source for the static
checks and feedback part of a pipeline.

LOG FORMAT: run_id: <string>

JSON OUTPUT: <data_dir>/meta.json
{
    "app_name": <string>,
    "label": <string>,
    "run_id": <string> - user provided or uuid,
    "team": <string>,
    "version": <string> - testers.ai CLI version,
    "created": <float> - UTC timestamp,
    "last_updated": <float> - UTC timestamp
    "scrape_time": <float> - UTC timestamp
}

