@aarwitz/tapp 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +123 -0
- package/Harness/OCQAHarness/AppDelegate.swift +21 -0
- package/Harness/OCQAHarness/Info.plist +26 -0
- package/Harness/OCQAHarness.xcodeproj/project.pbxproj +199 -0
- package/Harness/OCQAHarness.xcodeproj/xcshareddata/xcschemes/OCQAHarnessUITests.xcscheme +22 -0
- package/Harness/OCQAHarnessUITests/ExplorerTests.swift +4526 -0
- package/Harness/OCQAHarnessUITests/Info.plist +22 -0
- package/Harness/generate-harness-xcodeproj.rb +254 -0
- package/LICENSE +21 -0
- package/README.md +374 -0
- package/bin/tapp.js +1382 -0
- package/browser/app.css +227 -0
- package/browser/app.js +675 -0
- package/browser/index.html +195 -0
- package/browser/product-contract.js +25 -0
- package/browser/view-model.js +16 -0
- package/docs/BROWSER-PRODUCT.md +72 -0
- package/docs/PRODUCT-ENGINE.md +102 -0
- package/docs/application-model.md +276 -0
- package/docs/scenarios.md +95 -0
- package/mcp-server/src/android-driver.js +287 -0
- package/mcp-server/src/android-explorer.js +197 -0
- package/mcp-server/src/android-flow.js +89 -0
- package/mcp-server/src/application-model.js +1597 -0
- package/mcp-server/src/browser-product.js +659 -0
- package/mcp-server/src/browser-workspaces.js +234 -0
- package/mcp-server/src/ci-report.js +557 -0
- package/mcp-server/src/ci-setup.js +359 -0
- package/mcp-server/src/contract-authoring.js +10 -0
- package/mcp-server/src/enrich.js +57 -0
- package/mcp-server/src/flow-runtime.js +127 -0
- package/mcp-server/src/html-report.js +124 -0
- package/mcp-server/src/index.js +3775 -0
- package/mcp-server/src/maintenance-proposal.js +178 -0
- package/mcp-server/src/managed-operation.js +61 -0
- package/mcp-server/src/pr-selection.js +841 -0
- package/mcp-server/src/product-execution.js +155 -0
- package/mcp-server/src/product-operations.js +526 -0
- package/mcp-server/src/project-config.js +101 -0
- package/mcp-server/src/release-contract.d.ts +81 -0
- package/mcp-server/src/release-contract.js +226 -0
- package/mcp-server/src/report.js +363 -0
- package/mcp-server/src/scenario-runtime.js +139 -0
- package/mcp-server/src/static-server.js +44 -0
- package/mcp-server/src/task-runtime.js +266 -0
- package/mcp-server/src/ui-map.js +661 -0
- package/mcp-server/src/web-explorer.js +493 -0
- package/mcp-server/src/web-flow.js +238 -0
- package/package.json +82 -0
- package/scripts/android-corpus-e2e.sh +30 -0
- package/scripts/ci-gate.sh +323 -0
- package/scripts/cleanup-xcode.sh +157 -0
- package/scripts/compile-contract.js +27 -0
- package/scripts/compile-flow.js +18 -0
- package/scripts/corpus-apps.txt +9 -0
- package/scripts/corpus-sweep.sh +121 -0
- package/scripts/coverage-eval.sh +92 -0
- package/scripts/coverage_eval_parse.py +95 -0
- package/scripts/deploy-and-build.sh +99 -0
- package/scripts/flow-platform.js +18 -0
- package/scripts/flow_ai_judge.py +102 -0
- package/scripts/flow_lib.py +154 -0
- package/scripts/mutation-recall-desktop.sh +186 -0
- package/scripts/mutation-recall.sh +121 -0
- package/scripts/mutation_lib.py +128 -0
- package/scripts/mutation_operators.py +144 -0
- package/scripts/platform-gate.js +186 -0
- package/scripts/pr-plan.js +68 -0
- package/scripts/quick-capture.sh +419 -0
- package/scripts/run-android-flow.js +27 -0
- package/scripts/run-flow.sh +90 -0
- package/scripts/run-web-flow.js +28 -0
- package/scripts/run-web-scenario.js +23 -0
- package/scripts/validation-matrix.sh +146 -0
- package/scripts/vision-fp-eval.sh +206 -0
- package/scripts/vision_escalation_responder.py +147 -0
- package/scripts/vision_fp_probe.py +221 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Tapp agent playbook
|
|
2
|
+
|
|
3
|
+
You (the agent) have Tapp: hands, eyes, and judgment on real app surfaces — iOS simulators,
|
|
4
|
+
Android emulators/devices, plus (beta) web apps in a real browser.
|
|
5
|
+
|
|
6
|
+
## No MCP connected? Just run the CLI
|
|
7
|
+
|
|
8
|
+
Every core capability works as a plain command — no server, no config. `[target]` is
|
|
9
|
+
optional: with nothing, tapp finds + builds the Xcode project in the cwd (or falls back to
|
|
10
|
+
the app already on the simulator); it also accepts a repo dir, a `path/to/App.app`, a
|
|
11
|
+
bundle id, or (qa only) an http(s) URL. You never need to know a bundle id up front.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx -y @aarwitz/tapp qa [target] # autonomous QA → ship/no-ship verdict + findings (≈ tapp_run_qa)
|
|
15
|
+
npx -y @aarwitz/tapp open [target] # launch + screen summary + screenshot saved to a file (≈ tapp_open_app)
|
|
16
|
+
npx -y @aarwitz/tapp tree [target] # accessibility tree, --json for every element (≈ tapp_ui_tree)
|
|
17
|
+
npx -y @aarwitz/tapp shot # screenshot the booted sim → file path (≈ tapp_screenshot)
|
|
18
|
+
npx -y @aarwitz/tapp apps # what's installed on the simulator, with bundle ids
|
|
19
|
+
npx -y @aarwitz/tapp build [dir] # build the app in an Xcode repo + install it (≈ tapp_build)
|
|
20
|
+
npx -y @aarwitz/tapp qa app.apk --platform android --app-id com.acme.app
|
|
21
|
+
npx -y @aarwitz/tapp flow run .autotap/flows/smoke.yml # committed, keyless E2E replay
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
**Seeing the screen, per client:** if you can read image files into your context (Claude
|
|
25
|
+
Code's Read tool, Codex's view-image), open the saved screenshot path the CLI prints —
|
|
26
|
+
that IS the screen. If you cannot (Cursor, VS Code Copilot), connect the MCP server
|
|
27
|
+
instead: its tool results carry the screenshot inline. Screen *recordings* are for the
|
|
28
|
+
human: `tapp qa` records the full exploration and embeds it in the report.html evidence
|
|
29
|
+
page — tell the user the report path so they can watch it.
|
|
30
|
+
|
|
31
|
+
The interactive session/record loop is MCP-only (it needs a long-lived process). Flow replay is
|
|
32
|
+
also available in the CLI. The rest of this playbook assumes the `tapp_*` MCP tools are connected. With
|
|
33
|
+
MCP, the no-bundle-id path is: `tapp_build {projectDir}` (auto-detects + builds +
|
|
34
|
+
installs, returns the bundle id) → `tapp_run_qa {appBundleId}`.
|
|
35
|
+
|
|
36
|
+
## Pick the right tool for the job
|
|
37
|
+
|
|
38
|
+
| The user wants… | Use | NOT |
|
|
39
|
+
|---|---|---|
|
|
40
|
+
| "Show me / screenshot a screen" | `tapp_open_app` (launch + screenshot + tree, ~15s) | `tapp_run_qa` (a full multi-minute QA exploration) |
|
|
41
|
+
| "Tap through / drive / fill a form / log in" | `tapp_session_start` → `session_act` loop | repeated `open_app` calls (cold relaunch each time) |
|
|
42
|
+
| "Is my app broken? Is it ship-ready? Find bugs" | `tapp_run_qa` — `appBundleId` for iOS, `androidAppId` for Android, `url` for owned web apps | a manual session (QA exploration is autonomous) |
|
|
43
|
+
| "Make this flow a repeatable test" | drive it in a session, then `tapp_flow_save`; replay with `tapp_flow_run` | re-driving it by hand every time |
|
|
44
|
+
| "What's on screen right now?" | `tapp_screenshot` / `tapp_ui_tree` | relaunching the app |
|
|
45
|
+
|
|
46
|
+
## Session driving (the Playwright loop)
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
tapp_session_start { appBundleId: "com.acme.app" } → fresh launch + initial tree
|
|
50
|
+
tapp_session_act { action: "tap", id: "Email" } → tap by a11y id OR visible label
|
|
51
|
+
tapp_session_act { action: "type", text: "qa@x.com" } → types into the focused field
|
|
52
|
+
tapp_session_act { action: "tap", id: "Sign In" }
|
|
53
|
+
tapp_session_act { action: "wait", text: "Home", timeoutMs: 10000 } → block until it appears
|
|
54
|
+
tapp_screenshot → see it
|
|
55
|
+
tapp_session_end
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Android uses the same loop with `tapp_session_start { androidAppId: "com.acme.app", apkPath:
|
|
59
|
+
"path/to/app.apk" }`. Android selectors prefer resource id, then content description, exact text,
|
|
60
|
+
and text contains. The APK/app id replace the iOS bundle/simulator build inputs.
|
|
61
|
+
|
|
62
|
+
Rules that prevent 90% of failures:
|
|
63
|
+
|
|
64
|
+
1. **Read `elements[]` from the previous result before tapping.** Ids and labels shift between
|
|
65
|
+
builds — never tap from memory. `tap` matches accessibility id, exact label, or a forgiving
|
|
66
|
+
case-insensitive contains; `{x, y}` coordinates are the last resort.
|
|
67
|
+
2. **Check `hittable`.** A disabled control shows `hittable: false` — a Submit button that won't
|
|
68
|
+
tap usually means the form isn't validly filled, not that the button is missing. Fill the
|
|
69
|
+
fields first.
|
|
70
|
+
3. **`wait` after anything async** (navigation, network loads): `{action: "wait", id|text, timeoutMs}`.
|
|
71
|
+
Never assume the next screen is instantly there.
|
|
72
|
+
4. **Tap the field before typing** — `type` goes to the focused field. Tap email → type email →
|
|
73
|
+
tap password → type password.
|
|
74
|
+
5. Tap results: `ok` (landed), `not_hittable` (exists but disabled/covered — the harness
|
|
75
|
+
auto-dismisses keyboards and retries), `not_found` (nothing matches — re-read the tree).
|
|
76
|
+
6. One session at a time. `session_start` always begins from a fresh app launch.
|
|
77
|
+
|
|
78
|
+
## Autonomous QA (`tapp_run_qa`)
|
|
79
|
+
|
|
80
|
+
Returns `{verdict, confidence, headline, screensExplored, actionsPerformed, findings[]}`.
|
|
81
|
+
|
|
82
|
+
- `verdict`: `ready` | `caution` | `blocked`. **Trust it — it's deterministic.** Report it to the
|
|
83
|
+
user as-is; never soften a `blocked` or inflate a `caution`.
|
|
84
|
+
- `inconclusive: true` means the run couldn't see enough (crash on launch, login wall). That is
|
|
85
|
+
**not a pass** — tell the user what blocked exploration and what would unblock it.
|
|
86
|
+
- Login walls: pass `testEmail`/`testPassword` (auto-typed into login forms), `appLaunchArgs`
|
|
87
|
+
(e.g. `["--uitesting"]` if the app has a test bypass), and/or `appLaunchEnv` (e.g. a staging
|
|
88
|
+
backend URL). If the result shows `inputFieldsEncountered` and you have no credentials, **ask
|
|
89
|
+
the user** for them rather than re-running blind.
|
|
90
|
+
- Diff two runs: pass the previous run's `findings` as `baselineFindings` → you get a
|
|
91
|
+
`regression` block (`new` / `persisting` / `resolved`, plus a CI `gate` signal).
|
|
92
|
+
|
|
93
|
+
## Flows (deterministic E2E tests)
|
|
94
|
+
|
|
95
|
+
Flow YAML is repository-native test code. Commit it under `.autotap/flows/`; CI can replay it
|
|
96
|
+
without a coding agent, model, subscription, or API key. AI generation and `assert_ai` are optional.
|
|
97
|
+
|
|
98
|
+
- **Record:** every successful `session_act` is recorded. After driving a flow, call
|
|
99
|
+
`tapp_flow_save { name: "checkout" }` → writes `.autotap/flows/checkout.yml` with waits and
|
|
100
|
+
a final screen assertion auto-inserted; typed credentials are templated to `$TEST_EMAIL`/`$TEST_PASSWORD`.
|
|
101
|
+
- **Replay:** `tapp_flow_run { flowPath: ".autotap/flows/checkout.yml" }` — exact steps,
|
|
102
|
+
deterministic assertions, same result every time. A failed assertion is a finding.
|
|
103
|
+
- **Generate:** `tapp_flow_generate { goal: "log in and add the first item to cart" }` —
|
|
104
|
+
grounded in the app's actually-explored screens, so it can't invent steps.
|
|
105
|
+
|
|
106
|
+
## Setup facts (tell the user when relevant)
|
|
107
|
+
|
|
108
|
+
- iOS runs locally on a Mac with Xcode + a simulator. Android needs `adb` and a connected
|
|
109
|
+
emulator/device. Web needs Playwright + Chromium. `tapp doctor` reports each capability.
|
|
110
|
+
- First tool call builds the test harness once (~2 min, cached in `~/.tapp`). `tapp install`
|
|
111
|
+
prebuilds it. Switching simulators triggers an automatic rebuild.
|
|
112
|
+
- The app under test must be **installed on the booted simulator** (`tapp_install_app` builds
|
|
113
|
+
and installs from an Xcode project/workspace; or the user's normal build).
|
|
114
|
+
- A simulator must be booted (`tapp_list_simulators` → `tapp_boot_simulator`).
|
|
115
|
+
- Screenshots/captures land in `~/.tapp/captures/`.
|
|
116
|
+
|
|
117
|
+
## Honesty rules
|
|
118
|
+
|
|
119
|
+
- Never claim a screen/flow works without having actually driven or seen it via these tools.
|
|
120
|
+
- If a tool call fails twice for the same reason, stop and tell the user what's failing instead
|
|
121
|
+
of retrying variations.
|
|
122
|
+
- When you show a screenshot as proof, say what it proves and what it doesn't ("login works;
|
|
123
|
+
I haven't verified checkout").
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
|
|
3
|
+
@main
|
|
4
|
+
class AppDelegate: UIResponder, UIApplicationDelegate {
|
|
5
|
+
var window: UIWindow?
|
|
6
|
+
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
|
7
|
+
window = UIWindow(frame: UIScreen.main.bounds)
|
|
8
|
+
let vc = UIViewController()
|
|
9
|
+
vc.view.backgroundColor = .black
|
|
10
|
+
let label = UILabel()
|
|
11
|
+
label.text = "AutoTap Harness"
|
|
12
|
+
label.textColor = .white
|
|
13
|
+
label.textAlignment = .center
|
|
14
|
+
label.frame = vc.view.bounds
|
|
15
|
+
label.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
16
|
+
vc.view.addSubview(label)
|
|
17
|
+
window?.rootViewController = vc
|
|
18
|
+
window?.makeKeyAndVisible()
|
|
19
|
+
return true
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
3
|
+
<plist version="1.0">
|
|
4
|
+
<dict>
|
|
5
|
+
<key>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>en</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>APPL</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>1</string>
|
|
21
|
+
<key>LSRequiresIPhoneOS</key>
|
|
22
|
+
<true/>
|
|
23
|
+
<key>UILaunchStoryboardName</key>
|
|
24
|
+
<string></string>
|
|
25
|
+
</dict>
|
|
26
|
+
</plist>
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// !$*UTF8*$!
|
|
2
|
+
{
|
|
3
|
+
archiveVersion = 1;
|
|
4
|
+
classes = {};
|
|
5
|
+
objectVersion = 56;
|
|
6
|
+
objects = {
|
|
7
|
+
5D7C13C377373C4980FC8162 /* Project object */ = {
|
|
8
|
+
isa = PBXProject;
|
|
9
|
+
buildConfigurationList = C03EC97124C7DA0EE83E045B;
|
|
10
|
+
compatibilityVersion = "Xcode 14.0";
|
|
11
|
+
developmentRegion = en;
|
|
12
|
+
hasScannedForEncodings = 0;
|
|
13
|
+
knownRegions = (en, Base);
|
|
14
|
+
mainGroup = 97B474EE87109F337A5EDB45;
|
|
15
|
+
productRefGroup = 9A2A24D8F8E06032696AC411;
|
|
16
|
+
projectDirPath = "";
|
|
17
|
+
projectRoot = "";
|
|
18
|
+
targets = (
|
|
19
|
+
EAC02A5E44291747D888CAF7,
|
|
20
|
+
8FD0002A75D948EE79C4FDEB,
|
|
21
|
+
);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/* Main Group */
|
|
25
|
+
97B474EE87109F337A5EDB45 = {
|
|
26
|
+
isa = PBXGroup;
|
|
27
|
+
children = (
|
|
28
|
+
D5E75DDC871BCC9FA4AEB33A,
|
|
29
|
+
F1804B339745969BC4D5BD0E,
|
|
30
|
+
9A2A24D8F8E06032696AC411,
|
|
31
|
+
);
|
|
32
|
+
sourceTree = "<group>";
|
|
33
|
+
};
|
|
34
|
+
9A2A24D8F8E06032696AC411 = {
|
|
35
|
+
isa = PBXGroup;
|
|
36
|
+
children = (
|
|
37
|
+
9CEBAC16BBBB2096CF6736B7,
|
|
38
|
+
4596C27A89AAB1291984CE15,
|
|
39
|
+
);
|
|
40
|
+
name = Products;
|
|
41
|
+
sourceTree = "<group>";
|
|
42
|
+
};
|
|
43
|
+
D5E75DDC871BCC9FA4AEB33A = {
|
|
44
|
+
isa = PBXGroup;
|
|
45
|
+
children = (
|
|
46
|
+
EC2E72351C49E8A03B62A7E4,
|
|
47
|
+
C4EFB6D8BCD48E1E7CF4723F,
|
|
48
|
+
);
|
|
49
|
+
path = OCQAHarness;
|
|
50
|
+
sourceTree = "<group>";
|
|
51
|
+
};
|
|
52
|
+
F1804B339745969BC4D5BD0E = {
|
|
53
|
+
isa = PBXGroup;
|
|
54
|
+
children = (
|
|
55
|
+
02DDFAC1CE151BA9E8F1F2B0,
|
|
56
|
+
6C52E22A95C5BC114BD89C1D,
|
|
57
|
+
);
|
|
58
|
+
path = OCQAHarnessUITests;
|
|
59
|
+
sourceTree = "<group>";
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/* File References */
|
|
63
|
+
EC2E72351C49E8A03B62A7E4 = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>";};
|
|
64
|
+
C4EFB6D8BCD48E1E7CF4723F = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>";};
|
|
65
|
+
02DDFAC1CE151BA9E8F1F2B0 = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExplorerTests.swift; sourceTree = "<group>";};
|
|
66
|
+
6C52E22A95C5BC114BD89C1D = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>";};
|
|
67
|
+
9CEBAC16BBBB2096CF6736B7 = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OCQAHarness.app; sourceTree = BUILT_PRODUCTS_DIR;};
|
|
68
|
+
4596C27A89AAB1291984CE15 = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OCQAHarnessUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR;};
|
|
69
|
+
|
|
70
|
+
/* Build Files */
|
|
71
|
+
F58B8DB8FD10B48DA02F1FFE = {isa = PBXBuildFile; fileRef = EC2E72351C49E8A03B62A7E4;};
|
|
72
|
+
A66AE9116198ABFF81B3301F = {isa = PBXBuildFile; fileRef = 02DDFAC1CE151BA9E8F1F2B0;};
|
|
73
|
+
|
|
74
|
+
/* Source Build Phases */
|
|
75
|
+
3720DF3EB78B382E01A0C583 = {
|
|
76
|
+
isa = PBXSourcesBuildPhase;
|
|
77
|
+
buildActionMask = 2147483647;
|
|
78
|
+
files = (F58B8DB8FD10B48DA02F1FFE,);
|
|
79
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
80
|
+
};
|
|
81
|
+
40E8D5BE7C3857702461130C = {
|
|
82
|
+
isa = PBXSourcesBuildPhase;
|
|
83
|
+
buildActionMask = 2147483647;
|
|
84
|
+
files = (A66AE9116198ABFF81B3301F,);
|
|
85
|
+
runOnlyForDeploymentPostprocessing = 0;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/* Frameworks Build Phases */
|
|
89
|
+
6946B0A403DA0818C6E59688 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0;};
|
|
90
|
+
EC7DD5037A711664C61227B4 = {isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = (); runOnlyForDeploymentPostprocessing = 0;};
|
|
91
|
+
|
|
92
|
+
/* App Target */
|
|
93
|
+
EAC02A5E44291747D888CAF7 = {
|
|
94
|
+
isa = PBXNativeTarget;
|
|
95
|
+
buildConfigurationList = 941C8F0B572C7E6F731288EB;
|
|
96
|
+
buildPhases = (3720DF3EB78B382E01A0C583, 6946B0A403DA0818C6E59688,);
|
|
97
|
+
buildRules = ();
|
|
98
|
+
dependencies = ();
|
|
99
|
+
name = OCQAHarness;
|
|
100
|
+
productName = OCQAHarness;
|
|
101
|
+
productReference = 9CEBAC16BBBB2096CF6736B7;
|
|
102
|
+
productType = "com.apple.product-type.application";
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/* Test Target */
|
|
106
|
+
8FD0002A75D948EE79C4FDEB = {
|
|
107
|
+
isa = PBXNativeTarget;
|
|
108
|
+
buildConfigurationList = E7719FBBADD636B07F6C0F19;
|
|
109
|
+
buildPhases = (40E8D5BE7C3857702461130C, EC7DD5037A711664C61227B4,);
|
|
110
|
+
buildRules = ();
|
|
111
|
+
dependencies = (F61C75ED91EE51D617FF76C2,);
|
|
112
|
+
name = OCQAHarnessUITests;
|
|
113
|
+
productName = OCQAHarnessUITests;
|
|
114
|
+
productReference = 4596C27A89AAB1291984CE15;
|
|
115
|
+
productType = "com.apple.product-type.bundle.ui-testing";
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/* Target Dependency */
|
|
119
|
+
F61C75ED91EE51D617FF76C2 = {
|
|
120
|
+
isa = PBXTargetDependency;
|
|
121
|
+
target = EAC02A5E44291747D888CAF7;
|
|
122
|
+
targetProxy = 7BC3CFD1F9B18D721886DD65;
|
|
123
|
+
};
|
|
124
|
+
7BC3CFD1F9B18D721886DD65 = {
|
|
125
|
+
isa = PBXContainerItemProxy;
|
|
126
|
+
containerPortal = 5D7C13C377373C4980FC8162;
|
|
127
|
+
proxyType = 1;
|
|
128
|
+
remoteGlobalIDString = EAC02A5E44291747D888CAF7;
|
|
129
|
+
remoteInfo = OCQAHarness;
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
/* Build Configurations */
|
|
133
|
+
C03EC97124C7DA0EE83E045B = {
|
|
134
|
+
isa = XCConfigurationList;
|
|
135
|
+
buildConfigurations = (1BF3C243D6F4582A4C00E8E6,);
|
|
136
|
+
defaultConfigurationIsVisible = 0;
|
|
137
|
+
defaultConfigurationName = Debug;
|
|
138
|
+
};
|
|
139
|
+
1BF3C243D6F4582A4C00E8E6 = {
|
|
140
|
+
isa = XCBuildConfiguration;
|
|
141
|
+
buildSettings = {
|
|
142
|
+
ALWAYS_SEARCH_USER_PATHS = NO;
|
|
143
|
+
CLANG_ENABLE_MODULES = YES;
|
|
144
|
+
CODE_SIGN_IDENTITY = "-";
|
|
145
|
+
CODE_SIGN_STYLE = Automatic;
|
|
146
|
+
DEVELOPMENT_TEAM = "";
|
|
147
|
+
ENABLE_TESTABILITY = YES;
|
|
148
|
+
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
|
149
|
+
SDKROOT = iphoneos;
|
|
150
|
+
SWIFT_VERSION = 5.0;
|
|
151
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
|
152
|
+
};
|
|
153
|
+
name = Debug;
|
|
154
|
+
};
|
|
155
|
+
941C8F0B572C7E6F731288EB = {
|
|
156
|
+
isa = XCConfigurationList;
|
|
157
|
+
buildConfigurations = (426B4A04FEDF3507EE7B512F,);
|
|
158
|
+
defaultConfigurationIsVisible = 0;
|
|
159
|
+
defaultConfigurationName = Debug;
|
|
160
|
+
};
|
|
161
|
+
426B4A04FEDF3507EE7B512F = {
|
|
162
|
+
isa = XCBuildConfiguration;
|
|
163
|
+
buildSettings = {
|
|
164
|
+
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
|
165
|
+
CODE_SIGN_IDENTITY = "-";
|
|
166
|
+
CODE_SIGN_STYLE = Automatic;
|
|
167
|
+
DEVELOPMENT_TEAM = "";
|
|
168
|
+
INFOPLIST_FILE = OCQAHarness/Info.plist;
|
|
169
|
+
PRODUCT_BUNDLE_IDENTIFIER = ai.autotap.harness;
|
|
170
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
171
|
+
SWIFT_VERSION = 5.0;
|
|
172
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
|
173
|
+
};
|
|
174
|
+
name = Debug;
|
|
175
|
+
};
|
|
176
|
+
E7719FBBADD636B07F6C0F19 = {
|
|
177
|
+
isa = XCConfigurationList;
|
|
178
|
+
buildConfigurations = (BF02330ED7194B20B63DC653,);
|
|
179
|
+
defaultConfigurationIsVisible = 0;
|
|
180
|
+
defaultConfigurationName = Debug;
|
|
181
|
+
};
|
|
182
|
+
BF02330ED7194B20B63DC653 = {
|
|
183
|
+
isa = XCBuildConfiguration;
|
|
184
|
+
buildSettings = {
|
|
185
|
+
CODE_SIGN_IDENTITY = "-";
|
|
186
|
+
CODE_SIGN_STYLE = Automatic;
|
|
187
|
+
DEVELOPMENT_TEAM = "";
|
|
188
|
+
INFOPLIST_FILE = OCQAHarnessUITests/Info.plist;
|
|
189
|
+
PRODUCT_BUNDLE_IDENTIFIER = ai.autotap.harness.uitests;
|
|
190
|
+
PRODUCT_NAME = "$(TARGET_NAME)";
|
|
191
|
+
SWIFT_VERSION = 5.0;
|
|
192
|
+
TARGETED_DEVICE_FAMILY = "1,2";
|
|
193
|
+
TEST_TARGET_NAME = OCQAHarness;
|
|
194
|
+
};
|
|
195
|
+
name = Debug;
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
rootObject = 5D7C13C377373C4980FC8162;
|
|
199
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<Scheme LastUpgradeVersion = "1620" version = "1.7">
|
|
3
|
+
<BuildAction parallelizeBuildables = "YES" buildImplicitDependencies = "YES">
|
|
4
|
+
<BuildActionEntries>
|
|
5
|
+
<BuildActionEntry buildForTesting = "YES" buildForRunning = "YES" buildForProfiling = "YES" buildForArchiving = "YES" buildForAnalyzing = "YES">
|
|
6
|
+
<BuildableReference BuildableIdentifier = "primary" BlueprintIdentifier = "8FD0002A75D948EE79C4FDEB" BuildableName = "OCQAHarnessUITests.xctest" BlueprintName = "OCQAHarnessUITests" ReferencedContainer = "container:OCQAHarness.xcodeproj"/>
|
|
7
|
+
</BuildActionEntry>
|
|
8
|
+
</BuildActionEntries>
|
|
9
|
+
</BuildAction>
|
|
10
|
+
<TestAction buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES">
|
|
11
|
+
<Testables>
|
|
12
|
+
<TestableReference skipped = "NO">
|
|
13
|
+
<BuildableReference BuildableIdentifier = "primary" BlueprintIdentifier = "8FD0002A75D948EE79C4FDEB" BuildableName = "OCQAHarnessUITests.xctest" BlueprintName = "OCQAHarnessUITests" ReferencedContainer = "container:OCQAHarness.xcodeproj"/>
|
|
14
|
+
</TestableReference>
|
|
15
|
+
</Testables>
|
|
16
|
+
</TestAction>
|
|
17
|
+
<LaunchAction buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" debugDocumentVersioning = "YES" debugServiceExtension = "internal" allowLocationSimulation = "YES">
|
|
18
|
+
<BuildableProductRunnable runnableDebuggingMode = "0">
|
|
19
|
+
<BuildableReference BuildableIdentifier = "primary" BlueprintIdentifier = "EAC02A5E44291747D888CAF7" BuildableName = "OCQAHarness.app" BlueprintName = "OCQAHarness" ReferencedContainer = "container:OCQAHarness.xcodeproj"/>
|
|
20
|
+
</BuildableProductRunnable>
|
|
21
|
+
</LaunchAction>
|
|
22
|
+
</Scheme>
|