@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.
Files changed (77) hide show
  1. package/AGENTS.md +123 -0
  2. package/Harness/OCQAHarness/AppDelegate.swift +21 -0
  3. package/Harness/OCQAHarness/Info.plist +26 -0
  4. package/Harness/OCQAHarness.xcodeproj/project.pbxproj +199 -0
  5. package/Harness/OCQAHarness.xcodeproj/xcshareddata/xcschemes/OCQAHarnessUITests.xcscheme +22 -0
  6. package/Harness/OCQAHarnessUITests/ExplorerTests.swift +4526 -0
  7. package/Harness/OCQAHarnessUITests/Info.plist +22 -0
  8. package/Harness/generate-harness-xcodeproj.rb +254 -0
  9. package/LICENSE +21 -0
  10. package/README.md +374 -0
  11. package/bin/tapp.js +1382 -0
  12. package/browser/app.css +227 -0
  13. package/browser/app.js +675 -0
  14. package/browser/index.html +195 -0
  15. package/browser/product-contract.js +25 -0
  16. package/browser/view-model.js +16 -0
  17. package/docs/BROWSER-PRODUCT.md +72 -0
  18. package/docs/PRODUCT-ENGINE.md +102 -0
  19. package/docs/application-model.md +276 -0
  20. package/docs/scenarios.md +95 -0
  21. package/mcp-server/src/android-driver.js +287 -0
  22. package/mcp-server/src/android-explorer.js +197 -0
  23. package/mcp-server/src/android-flow.js +89 -0
  24. package/mcp-server/src/application-model.js +1597 -0
  25. package/mcp-server/src/browser-product.js +659 -0
  26. package/mcp-server/src/browser-workspaces.js +234 -0
  27. package/mcp-server/src/ci-report.js +557 -0
  28. package/mcp-server/src/ci-setup.js +359 -0
  29. package/mcp-server/src/contract-authoring.js +10 -0
  30. package/mcp-server/src/enrich.js +57 -0
  31. package/mcp-server/src/flow-runtime.js +127 -0
  32. package/mcp-server/src/html-report.js +124 -0
  33. package/mcp-server/src/index.js +3775 -0
  34. package/mcp-server/src/maintenance-proposal.js +178 -0
  35. package/mcp-server/src/managed-operation.js +61 -0
  36. package/mcp-server/src/pr-selection.js +841 -0
  37. package/mcp-server/src/product-execution.js +155 -0
  38. package/mcp-server/src/product-operations.js +526 -0
  39. package/mcp-server/src/project-config.js +101 -0
  40. package/mcp-server/src/release-contract.d.ts +81 -0
  41. package/mcp-server/src/release-contract.js +226 -0
  42. package/mcp-server/src/report.js +363 -0
  43. package/mcp-server/src/scenario-runtime.js +139 -0
  44. package/mcp-server/src/static-server.js +44 -0
  45. package/mcp-server/src/task-runtime.js +266 -0
  46. package/mcp-server/src/ui-map.js +661 -0
  47. package/mcp-server/src/web-explorer.js +493 -0
  48. package/mcp-server/src/web-flow.js +238 -0
  49. package/package.json +82 -0
  50. package/scripts/android-corpus-e2e.sh +30 -0
  51. package/scripts/ci-gate.sh +323 -0
  52. package/scripts/cleanup-xcode.sh +157 -0
  53. package/scripts/compile-contract.js +27 -0
  54. package/scripts/compile-flow.js +18 -0
  55. package/scripts/corpus-apps.txt +9 -0
  56. package/scripts/corpus-sweep.sh +121 -0
  57. package/scripts/coverage-eval.sh +92 -0
  58. package/scripts/coverage_eval_parse.py +95 -0
  59. package/scripts/deploy-and-build.sh +99 -0
  60. package/scripts/flow-platform.js +18 -0
  61. package/scripts/flow_ai_judge.py +102 -0
  62. package/scripts/flow_lib.py +154 -0
  63. package/scripts/mutation-recall-desktop.sh +186 -0
  64. package/scripts/mutation-recall.sh +121 -0
  65. package/scripts/mutation_lib.py +128 -0
  66. package/scripts/mutation_operators.py +144 -0
  67. package/scripts/platform-gate.js +186 -0
  68. package/scripts/pr-plan.js +68 -0
  69. package/scripts/quick-capture.sh +419 -0
  70. package/scripts/run-android-flow.js +27 -0
  71. package/scripts/run-flow.sh +90 -0
  72. package/scripts/run-web-flow.js +28 -0
  73. package/scripts/run-web-scenario.js +23 -0
  74. package/scripts/validation-matrix.sh +146 -0
  75. package/scripts/vision-fp-eval.sh +206 -0
  76. package/scripts/vision_escalation_responder.py +147 -0
  77. 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>