@craft-native/ios 0.0.214 → 0.0.215
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/README.md
CHANGED
|
@@ -192,6 +192,14 @@ wrong screen. `systemtap` targets the system button around a Live Activity rathe
|
|
|
192
192
|
than its remotely hosted text. The [Live Activity layout fixture](./fixtures/live-activity)
|
|
193
193
|
exercises long names and timer alignment using the production widget.
|
|
194
194
|
|
|
195
|
+
Use `universallink https://example.com/profile` to test an associated HTTPS
|
|
196
|
+
link after a fresh install. The driver host uses Apple's public
|
|
197
|
+
`universalLinksOnly` option and waits up to 60 seconds for iOS to accept the
|
|
198
|
+
association downloaded from Apple's CDN. A rejected association fails the
|
|
199
|
+
journey; it cannot fall back to Safari. This operation does not launch the app
|
|
200
|
+
under test directly, so a preceding `terminate` still tests a cold handoff.
|
|
201
|
+
Use `openurl` for browser fallback checks and custom URL schemes.
|
|
202
|
+
|
|
195
203
|
The iOS host uses the shared tree-layout ABI for eligible definite-size,
|
|
196
204
|
non-grid, non-wrapped containers and retains a local fallback for older
|
|
197
205
|
runtimes or unsupported styles. Both paths implement wrapped-line and grid
|
package/dist/index.js
CHANGED
|
@@ -156,8 +156,11 @@ function serializeSimulatorSteps(steps) {
|
|
|
156
156
|
}
|
|
157
157
|
} else if ("name" in step)
|
|
158
158
|
arg = token(step.name);
|
|
159
|
-
else if ("url" in step)
|
|
159
|
+
else if ("url" in step) {
|
|
160
|
+
if (step.command === "universallink" && new URL(step.url).protocol !== "https:")
|
|
161
|
+
throw new Error("Universal Links require an HTTPS URL");
|
|
160
162
|
arg = step.url;
|
|
163
|
+
}
|
|
161
164
|
if (/[\r\n]/.test(arg))
|
|
162
165
|
throw new Error("Simulator arguments cannot contain newlines");
|
|
163
166
|
return `${step.command}${arg ? ` ${arg}` : ""}`;
|
package/dist/testing.d.ts
CHANGED
|
@@ -60,6 +60,11 @@ export type SimulatorStep = {
|
|
|
60
60
|
command: 'openurl';
|
|
61
61
|
url: string;
|
|
62
62
|
}
|
|
63
|
+
/** Use Apple's universalLinksOnly API, allowing association downloads up to 60 seconds. */
|
|
64
|
+
| {
|
|
65
|
+
command: 'universallink';
|
|
66
|
+
url: string;
|
|
67
|
+
}
|
|
63
68
|
/** Runs `step` only when the element with this identifier is there (a screen shown the first time). */
|
|
64
69
|
| {
|
|
65
70
|
command: 'ifid';
|
package/package.json
CHANGED
|
@@ -14,6 +14,7 @@ import XCTest
|
|
|
14
14
|
/// delay <ms> every proxied request waits this long (0 = off)
|
|
15
15
|
/// exec <hook> runs the switch's HOOKS/<hook>.sh on the Mac (restart the API, …)
|
|
16
16
|
/// openurl <url> opens a link through the system, answering "Open in the app?"
|
|
17
|
+
/// universallink <https-url> waits up to 60s for an OS-verified link; never opens a browser
|
|
17
18
|
/// shot <name> screenshot → shots/<name>.png
|
|
18
19
|
/// tree <name> accessibility tree → shots/<name>.txt
|
|
19
20
|
/// tap <text> first hittable element whose label contains text
|
|
@@ -253,6 +254,21 @@ final class DriverTests: XCTestCase {
|
|
|
253
254
|
answerOpenPrompt()
|
|
254
255
|
note("openurl \(arg)")
|
|
255
256
|
}
|
|
257
|
+
case "universallink":
|
|
258
|
+
guard let url = URL(string: arg), url.scheme == "https" else {
|
|
259
|
+
check(false, "universallink requires an HTTPS URL")
|
|
260
|
+
return
|
|
261
|
+
}
|
|
262
|
+
let host = XCUIApplication(bundleIdentifier: "{{BUNDLE_PREFIX}}.host")
|
|
263
|
+
host.launchArguments = ["--craft-universal-link", url.absoluteString]
|
|
264
|
+
host.launch()
|
|
265
|
+
let opened = app.wait(for: .runningForeground, timeout: 75)
|
|
266
|
+
if !opened {
|
|
267
|
+
post("/save?name=universal-link-host.txt", Data(host.debugDescription.utf8))
|
|
268
|
+
post("/save?name=universal-link-app.txt", Data(app.debugDescription.utf8))
|
|
269
|
+
}
|
|
270
|
+
check(opened, "universallink \(arg) opened the target app")
|
|
271
|
+
host.terminate()
|
|
256
272
|
case "shot":
|
|
257
273
|
let shot = XCUIScreen.main.screenshot()
|
|
258
274
|
post("/save?name=\(arg).png", shot.pngRepresentation)
|
|
@@ -1,6 +1,36 @@
|
|
|
1
1
|
import SwiftUI
|
|
2
|
+
import UIKit
|
|
2
3
|
|
|
3
4
|
@main
|
|
4
5
|
struct HostApp: App {
|
|
5
|
-
|
|
6
|
+
@State private var status = "Craft simulator driver"
|
|
7
|
+
|
|
8
|
+
var body: some Scene {
|
|
9
|
+
WindowGroup {
|
|
10
|
+
Text(status).accessibilityIdentifier("craft-driver-status")
|
|
11
|
+
.task { await openUniversalLinkIfRequested() }
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
@MainActor
|
|
16
|
+
private func openUniversalLinkIfRequested() async {
|
|
17
|
+
let arguments = ProcessInfo.processInfo.arguments
|
|
18
|
+
guard let index = arguments.firstIndex(of: "--craft-universal-link"),
|
|
19
|
+
arguments.indices.contains(index + 1),
|
|
20
|
+
let url = URL(string: arguments[index + 1]), url.scheme == "https" else { return }
|
|
21
|
+
// Installation returns before iOS finishes downloading the AASA from
|
|
22
|
+
// Apple's CDN. Ask the public API until the OS accepts the association;
|
|
23
|
+
// universalLinksOnly prevents a failed attempt from opening Safari.
|
|
24
|
+
let deadline = Date().addingTimeInterval(60)
|
|
25
|
+
while Date() < deadline && !Task.isCancelled {
|
|
26
|
+
let opened = await UIApplication.shared.open(url, options: [.universalLinksOnly: true])
|
|
27
|
+
if opened {
|
|
28
|
+
status = "Universal Link accepted"
|
|
29
|
+
return
|
|
30
|
+
}
|
|
31
|
+
status = "Waiting for Universal Link association"
|
|
32
|
+
try? await Task.sleep(nanoseconds: 1_000_000_000)
|
|
33
|
+
}
|
|
34
|
+
status = "Universal Link was not accepted within 60 seconds"
|
|
35
|
+
}
|
|
6
36
|
}
|