craft-native 0.0.487 → 0.0.491

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.
@@ -354,6 +354,30 @@ final class DriverTests: XCTestCase {
354
354
  lastTappedInput = input
355
355
  }
356
356
 
357
+ /// `target`'s frame once it has stopped moving, or its last reading at
358
+ /// the deadline. This only ever waits — it never taps.
359
+ ///
360
+ /// A journey that flicks the page before touching a control leaves the
361
+ /// scroll view decelerating, and a touch that lands on a decelerating
362
+ /// scroll view stops the scroll instead of reaching the control. HQ's
363
+ /// agreement journey does exactly that: `swipe up`, then `tapid` the
364
+ /// first switch, which stayed off while the second one — tapped seconds
365
+ /// later — turned on (#449). `scrollto` and `drag` both end with a hold
366
+ /// that leaves the content at rest; `swipe` is a flick and does not.
367
+ ///
368
+ /// Waiting before the one gesture is not a second gesture.
369
+ func settledFrame(_ target: XCUIElement, within seconds: TimeInterval = 1.0) -> CGRect {
370
+ var frame = target.frame
371
+ let deadline = Date().addingTimeInterval(seconds)
372
+ while Date() < deadline {
373
+ Thread.sleep(forTimeInterval: 0.1)
374
+ let next = target.frame
375
+ if next.equalTo(frame) { return frame }
376
+ frame = next
377
+ }
378
+ return frame
379
+ }
380
+
357
381
  func answerOpenPrompt() {
358
382
  // A direct app link has already arrived. Querying an invisible
359
383
  // SpringBoard here can stall its accessibility snapshot on iOS 27.
@@ -517,7 +541,7 @@ final class DriverTests: XCTestCase {
517
541
  // renderer or hit-testing failure (HQ agreement job 7570).
518
542
  let before = target.value as? String
519
543
  let enabledBefore = target.isEnabled
520
- let frameBefore = target.frame
544
+ let frameBefore = settledFrame(target)
521
545
  press(target)
522
546
  let settle = Date().addingTimeInterval(1.5)
523
547
  var flipped = false
@@ -525,11 +549,17 @@ final class DriverTests: XCTestCase {
525
549
  flipped = switchFlipped(from: before, to: target.value as? String)
526
550
  if !flipped { Thread.sleep(forTimeInterval: 0.25) }
527
551
  } while !flipped && Date() < settle
552
+ let frameAfter = target.frame
528
553
  let observation: [String: Any] = [
529
554
  "id": arg, "gestures": 1, "flipped": flipped,
530
555
  "enabledBefore": enabledBefore, "enabledAfter": target.isEnabled,
531
556
  "valueBefore": before ?? "unknown", "valueAfter": target.value as? String ?? "unknown",
532
557
  "frameBefore": [frameBefore.origin.x, frameBefore.origin.y, frameBefore.width, frameBefore.height],
558
+ // Without this a control that was still moving when it
559
+ // was tapped looks exactly like one that sat still and
560
+ // ignored the tap, which is where #449 ran out of
561
+ // evidence.
562
+ "frameAfter": [frameAfter.origin.x, frameAfter.origin.y, frameAfter.width, frameAfter.height],
533
563
  ]
534
564
  lastBooleanTap = observation
535
565
  if let data = try? JSONSerialization.data(withJSONObject: observation, options: [.sortedKeys]),
package/dist/mobile.js CHANGED
@@ -1510,7 +1510,7 @@ function postHybrid(message) {
1510
1510
  }
1511
1511
  }
1512
1512
  function isSnapshotName(name) {
1513
- return typeof name === "string" && /^[A-Za-z0-9_-][\w.-]{0,127}$/.test(name);
1513
+ return typeof name === "string" && /^[A-Za-z0-9_:-][\w.:-]{0,127}$/.test(name);
1514
1514
  }
1515
1515
  var snapshots = {
1516
1516
  isAvailable() {
@@ -1518,7 +1518,7 @@ var snapshots = {
1518
1518
  },
1519
1519
  set(name, value) {
1520
1520
  if (!isSnapshotName(name))
1521
- throw new TypeError(`Snapshot names are letters, digits, ".", "_" and "-": ${String(name)}`);
1521
+ throw new TypeError(`Snapshot names are letters, digits, ".", "_", "-" and ":": ${String(name)}`);
1522
1522
  const json = JSON.stringify(value);
1523
1523
  if (json === undefined)
1524
1524
  throw new TypeError(`Snapshot ${name} is not JSON`);
package/dist/package.d.ts CHANGED
@@ -298,6 +298,11 @@ export declare function detachDiskImage(mount: string, options?: {
298
298
  error: string;
299
299
  attempts: DiskImageDetachAttempt[];
300
300
  }>;
301
+ /**
302
+ * The whole-disk device `hdiutil attach` reports for the image it mounted
303
+ * ("/dev/disk4" from its first line), or null when the output names none.
304
+ */
305
+ export declare function attachedDevice(attachOutput: string): string | null;
301
306
  /**
302
307
  * Helper: Create DMG from app bundle
303
308
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craft-native",
3
- "version": "0.0.487",
3
+ "version": "0.0.491",
4
4
  "type": "module",
5
5
  "description": "Build desktop apps with web languages - TypeScript SDK for Craft",
6
6
  "author": "Chris Breuer <chris@stacksjs.org>",