# Changelog Source: https://docs.qalti.com/changelog ## Release Notes Stay up to date with the latest Qalti releases, features, and improvements. ### Version 0.5.7 Read the full release notes: [Qalti Release 0.5.7](https://qalti.com/blog/qalti-release-0-5-7) ### Version 0.5.3 Read the full release notes: [Qalti Release 0.5.3](https://qalti.com/blog/qalti-release-0-5-3) # Writing Tests - Best Practices Source: https://docs.qalti.com/getting-started/best-practices You can write Qalti tests in many different ways, using more general instructions, and they will work. However, based on our experience and feedback from our clients, we've identified practices that make tests more reliable and consistent. Think of it this way: these guidelines are similar to what you'd follow when outsourcing manual testing. You need clear, detailed documentation for each test case—written for someone who may be seeing your app for the first time. The same principle applies here. Below we break down the specific details to help you write effective Qalti tests. ## Test File Format A Qalti test is a plain text file with a `.test` extension containing one step per line. We use `//` at the beginning of a line for comments that provide context rather than actionable instructions. ## Start with Context Begin each test with comment lines explaining what you're testing: ```text theme={null} // SyncUps is a meeting management app that helps teams organize daily sync-up meetings. // This test verifies that a past meeting appears in the history list. ``` We recommend using `//` to mark lines as comments. Use comments to provide additional contextual information that helps Qalti Agent understand the app's purpose, test objective, or any other background information. While the Agent reads all lines, comments are typically used for context and guidance rather than actionable test steps. ## Write Clear Actions Combine the action and expected outcome in a single line: ```text theme={null} Tap the "Design" sync-up card. The Design sync-up detail screen opens showing "SYNC-UP INFO" section. ``` **Good examples:** * `Open the SyncUps app. When app loads you will see "Daily Sync-ups" screen with a list of sync-ups.` * `Tap "Start Meeting" button. The meeting timer screen appears with "Time Elapsed" and "Time Remaining" displayed.` * `Tap "Save and end". You return to the Design sync-up detail screen.` **Avoid vague instructions:** * ❌ `Go to the main screen` * ✅ `Tap "Daily Sync-ups". The main screen appears with a list of sync-ups.` ## Be Specific Always use exact element names in quotes and specify what should happen: * Quote exact text: `"Start Meeting"`, `"Design"`, `"Save and end"` * Specify locations when needed: `"End meeting" button at the top left` * Describe visible elements: `"Time Elapsed" and "Time Remaining" displayed` ## Assume First-Time Use Write as if Qalti is seeing your app for the first time: * Don't use internal team jargon or abbreviations * Explain what each screen shows * State expected outcomes explicitly * Describe the full context of actions **Example:** ```text theme={null} Tap the "End meeting" button at the top left. A dialog appears with the question "End meeting?" and three options: "Save and end", "Discard", and "Resume". ``` ## Handle Edge Cases Account for optional dialogs or permissions: ```text theme={null} If a speech recognition permission dialog appears, dismiss it by not allowing. ``` ## Use Verification Steps Add explicit verification lines for critical checks: ```text theme={null} Verify that a new meeting entry with today's date and current time appears in the "PAST MEETINGS" section. ``` Verification steps should: * State what to check clearly * Include specific element names or values * Focus on test objectives ## Complete Test Example ```text theme={null} // SyncUps is a meeting management app that helps teams organize daily sync-up meetings. // This test verifies that a past meeting appears in the history list. Open the SyncUps app. When app loads you will see "Daily Sync-ups" screen with a list of sync-ups. Tap the "Design" sync-up card. The Design sync-up detail screen opens showing "SYNC-UP INFO" section. Tap the "Start Meeting" button. The meeting timer screen appears with "Time Elapsed" and "Time Remaining" displayed. If a speech recognition permission dialog appears, dismiss it by not allowing. Tap the "End meeting" button at the top left. A dialog appears with the question "End meeting?" and three options: "Save and end", "Discard", and "Resume". Tap "Save and end". You return to the Design sync-up detail screen. Wait for the screen to update with the new meeting entry. Verify that a new meeting entry with today's date and current time appears in the "PAST MEETINGS" section. Swipe the newly created meeting row fully to the left starting from the right edge (near the ">" arrow). The meeting is removed from the "PAST MEETINGS" list. ``` ## Using Comments You can add comments anywhere in your test file using `//` at the beginning of a line: ```text theme={null} // This is a comment providing context about the app or test Open the app. The home screen appears. // The next step handles an optional permission dialog If a notification permission dialog appears, tap "Allow". // Now we verify the main functionality Verify that the dashboard shows today's date. ``` Comments are useful for: * Explaining the app's domain or purpose at the start of the test * Describing why a particular test step is important * Noting edge cases or conditional behavior * Adding context that helps the Agent make better decisions * Documenting assumptions or prerequisites **Tip:** While the Agent reads all lines including comments, we recommend using them primarily for context and background information. This keeps your actionable test steps clear and easy to follow. ## Common Action Patterns * **Opening apps**: `Open the [App Name] app. The [screen name] appears.` * **Tapping elements**: `Tap "[Element]". The [expected screen/state] appears.` * **Input text**: `Input "[text]". [Expected result] appears.` * **Scrolling**: `Move finger on the middle of the screen down. New content appears below.` * **Waiting**: `Wait for the screen to update with the new meeting entry.` * **Verifying**: `Verify that "[element]" [condition].` ## Key Principles 1. **Specificity over brevity** — Better to be clear than concise 2. **Explicit outcomes** — Always state what should happen 3. **No assumptions** — Don't assume Qalti knows your app 4. **One step, one line** — Keep each action on its own line 5. **Test like a human** — Write instructions as you'd explain to a new team member Following these practices will make your tests more reliable and reproducible. # CI Quickstart Source: https://docs.qalti.com/getting-started/ci-quickstart This guide shows how to run the Qalti CLI in a CI pipeline (GitHub Actions). It includes parallel simulator runs and an example of running a test on a real iOS device. You can check out the full repository here: [github.com/qalti/qalti](https://github.com/qalti/qalti). It includes source code, CI examples, and demo tests. Below is how a real CI run looks like under the hood with 4 workers: ![Qalti demo](https://raw.githubusercontent.com/qalti/qalti/main/imgs/ci-4-tests-demo.gif) ## What you can do * Parallel simulator execution * Run tests on a real device * Produce Allure-formatted reports that you can upload to any QA system ## Authentication for CI Qalti requires your OpenRouter API key for test execution. Set it in your CI environment: ```bash theme={null} export OPENROUTER_API_KEY="sk-or-v1-..." ``` Or pass it explicitly with `--token`. ## Install Qalti in CI Qalti is a macOS app, and the CLI is included in the bundle. You can download and install it in your CI pipeline with this bash script: ```bash theme={null} curl -L -o Qalti.dmg https://app.qalti.com/releases/Qalti.dmg hdiutil attach Qalti.dmg -nobrowse -quiet -mountpoint /Volumes/Qalti cp -R /Volumes/Qalti/Qalti.app /Applications/Qalti.app hdiutil detach /Volumes/Qalti -quiet # Run the CLI directly from the app bundle /Applications/Qalti.app/Contents/MacOS/Qalti cli --help /Applications/Qalti.app/Contents/Resources/QaltiScheduler --help ``` ## Minimal CLI example This is the easiest way to run your test: ```bash theme={null} export OPENROUTER_API_KEY="sk-or-v1-..." /Applications/Qalti.app/Contents/MacOS/Qalti cli change_appearance.test --token "$OPENROUTER_API_KEY" ``` where `change_appearance.test` is a test file with steps in English: ```text theme={null} Open Settings Scroll down to find Display & Brightness Tap it Change Appearance Verify Appearance is changed ``` To learn more, run `/Applications/Qalti.app/Contents/MacOS/Qalti cli --help` ```text theme={null} Qalti CLI - Run iOS tests from command line USAGE: qalti cli --token OPENROUTER_API_KEY [options] ARGUMENTS: Path to test file (.test, .txt, or .json) OPTIONS: --token, -t OpenRouter API key (or set OPENROUTER_API_KEY env var) --model AI model to use (default: gpt-4.1) Available: gpt-5, gpt-5-mini, gpt-5-nano, gpt-4.1, gemini-2.5-pro, claude-4-sonnet, claude-3.5-sonnet --prompts-dir Custom prompts directory --report-path Output report path (default: ./reports/test_TIMESTAMP.json) --allure-dir Generate Allure report files in specified directory DEVICE SELECTION: --udid Device UDID (takes precedence) --device-name Device name (e.g., "iPhone 16") --os OS version (e.g., "iOS 18.2") --type Device type: simulator (default) or real OTHER OPTIONS: --app-path App bundle to install before testing (.app or .ipa) --iterations Max test iterations (default: 50) --verbose, -v Enable verbose output --help, -h Show this help EXAMPLES: # Basic usage qalti cli ./tests/login.test --token sk-or-v1-xxx # Specific device and model qalti cli ./tests/login.test --token sk-or-v1-xxx --device-name "iPhone 16" --model claude-4-sonnet # Using UDID with app install qalti cli ./tests/app.test --udid 12345-67890 --app-path ./MyApp.app --verbose # Custom prompts and report location qalti cli ./tests/checkout.test --prompts-dir ./custom-prompts --report-path ./reports/checkout-run.json ``` ## Parallel simulator runs (QaltiScheduler) Use `QaltiScheduler` to execute tests in parallel: ```bash theme={null} /Applications/Qalti.app/Contents/Resources/QaltiScheduler \ --tests "./tests" \ --device-name "iPhone 16" \ --os "18.3" \ --workers 4 \ --model "gpt-4.1" \ --token "$OPENROUTER_API_KEY" \ --app-path "./SyncUps-simulator.zip" \ --allure-dir "./reports/allure" ``` ## CI example (GitHub Actions) This workflow example shows how you can use Qalti in your CI pipelines: [`.github/workflows/qalti.yml`](https://github.com/qalti/qalti/blob/main/.github/workflows/qalti.yml) — it's short, commented, and shows how to: * Set up Qalti * Run tests on simulators and on a real device * Export Allure results and upload artifacts You can check recent runs in the [Qalti Actions dashboard](https://github.com/qalti/qalti/actions) to see it in action. ## Allure reports Qalti outputs results in Allure format if you set the `--allure-dir` flag. You can upload them to your QA system of choice. As an example, we use TestOps Cloud and upload via `allurectl`. ![Allure report in TestOps Cloud](https://raw.githubusercontent.com/qalti/qalti/main/imgs/qalti-allure-report-in-testsops.png) ## Contact * Questions and support: [hi@qalti.com](mailto:hi@qalti.com) * Qalti website: [qalti.com](https://qalti.com/) # Your First Test Source: https://docs.qalti.com/getting-started/first-test The easiest way to run your first test is on an iOS Simulator with an app build compiled for the simulator. Don't worry—**your app build never leaves your computer**. We don't have access to it. All we receive are screenshots and the test flow itself, similar to test management systems like [qase.io](https://qase.io) or [qameta.io](https://qameta.io). ## Prerequisites Before running your first test, ensure you have: * [Qalti installed](/getting-started/install) on your Mac * Your app bundle available as `.app` built for simulator * Your OpenRouter API key (from [openrouter.ai/keys](https://openrouter.ai/keys)) If you don't have your own app build available yet, you can [download our demo app (SyncUps)](https://app.qalti.com/SyncUps/SyncUps-simulator.zip). However, we recommend trying Qalti with your own app to see how it works with your specific use case. ## Running Your First Test in Qalti UI