craft-native 0.0.415 → 0.0.417

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/dist/cli.js CHANGED
@@ -3047,7 +3047,7 @@ function pinCraftNativeDependency(packagePath, craftVersion) {
3047
3047
  `);
3048
3048
  }
3049
3049
  // package.json
3050
- var version = "0.0.415";
3050
+ var version = "0.0.417";
3051
3051
 
3052
3052
  // bin/cli.ts
3053
3053
  var spawnedFrom = process6.env[CRAFT_CLI_SPAWN_MARKER];
package/dist/index.cjs CHANGED
@@ -375,7 +375,7 @@ function craftBinaryNotFoundMessage(triedPath) {
375
375
  `);
376
376
  }
377
377
  // package.json
378
- var version = "0.0.415";
378
+ var version = "0.0.417";
379
379
 
380
380
  // src/sdk-version.ts
381
381
  var SDK_VERSION = version;
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ function craftBinaryNotFoundMessage(triedPath) {
117
117
  `);
118
118
  }
119
119
  // package.json
120
- var version = "0.0.415";
120
+ var version = "0.0.417";
121
121
 
122
122
  // src/sdk-version.ts
123
123
  var SDK_VERSION = version;
@@ -317,9 +317,14 @@ function serializeSimulatorSteps(steps) {
317
317
  }
318
318
  }
319
319
  arg = JSON.stringify(step.paths);
320
- } else if ("step" in step)
321
- arg = `${token(step.id)} ${line(step.step)}`;
322
- else if ("seconds" in step && !("text" in step))
320
+ } else if ("step" in step) {
321
+ if (step.command === "iftext") {
322
+ if (!step.text.trim() || step.text.includes("|") || /[\r\n]/.test(step.text))
323
+ throw new Error("iftext needs one line of text without |");
324
+ arg = `${step.text} | ${line(step.step)}`;
325
+ } else
326
+ arg = `${token(step.id)} ${line(step.step)}`;
327
+ } else if ("seconds" in step && !("text" in step))
323
328
  arg = String(number(step.seconds));
324
329
  else if ("milliseconds" in step)
325
330
  arg = String(number(step.milliseconds));
@@ -111,6 +111,16 @@ export type SimulatorStep = {
111
111
  command: 'ifid';
112
112
  id: string;
113
113
  step: SimulatorStep;
114
+ }
115
+ /**
116
+ * Runs `step` only when something on screen shows this text, for content
117
+ * without identifiers: a web page's optional field that appears with a
118
+ * checkbox ticked, say.
119
+ */
120
+ | {
121
+ command: 'iftext';
122
+ text: string;
123
+ step: SimulatorStep;
114
124
  };
115
125
  /** Typed journeys use the same wire protocol as existing line-based scripts. */
116
126
  export declare function serializeSimulatorSteps(steps: readonly SimulatorStep[]): string;
@@ -49,6 +49,7 @@ import Darwin
49
49
  /// unlabelled logs every hittable button without a label (FAIL if any)
50
50
  /// dismiss [label] a system prompt's button (default Not Now: "Save Password?")
51
51
  /// ifid <id> <command…> runs the command only when that element is there (a screen shown the first time)
52
+ /// iftext <text> | <command…> runs the command only when something shows text (web content has no identifiers)
52
53
  /// log <text>
53
54
  ///
54
55
  /// With a bundled journey.txt, evidence is kept as native XCTest attachments
@@ -296,6 +297,12 @@ final class DriverTests: XCTestCase {
296
297
  let rest = arg.split(separator: " ", maxSplits: 1).map(String.init)
297
298
  if rest.count == 2, identified(rest[0]).waitForExistence(timeout: 3) { note("ifid \(rest[0]): shown"); run(rest[1]) }
298
299
  else { note("ifid \(rest.first ?? ""): not shown") }
300
+ case "iftext":
301
+ guard let split = arg.range(of: " | ") else { check(false, "iftext needs text | command"); return }
302
+ let text = String(arg[..<split.lowerBound])
303
+ let guarded = String(arg[split.upperBound...])
304
+ if poll(3, { element(containing: text) }) != nil { note("iftext \(text): shown"); run(guarded) }
305
+ else { note("iftext \(text): not shown") }
299
306
  case "launch": app.launch()
300
307
  case "activate": app.activate()
301
308
  case "terminate": app.terminate()
@@ -713,6 +713,10 @@ final class CraftMacBox: NSView, NSTextFieldDelegate, NSTextViewDelegate, NSDrag
713
713
  if let text = control as? NSTextField, kind == "Text" {
714
714
  let rect = (text.stringValue as NSString).boundingRect(with: CGSize(width: max(1, limit - 6 - textPadding.left - textPadding.right), height: 1_000_000), options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [.font: text.font ?? NSFont.systemFont(ofSize: 13)])
715
715
  size = CGSize(width: min(limit, ceil(rect.width) + 9 + textPadding.left + textPadding.right), height: max(18, ceil(rect.height) + 2))
716
+ // The field draws only whole lines inside its cell's insets, so a height short of what the cell
717
+ // asks for at the width it will draw at drops the last line. Ask the cell, not just the string.
718
+ let fieldWidth = max(1, size.width - textPadding.left - textPadding.right)
719
+ if let drawn = text.cell?.cellSize(forBounds: CGRect(x: 0, y: 0, width: fieldWidth, height: 1_000_000)).height { size.height = max(size.height, ceil(drawn)) }
716
720
  if text.maximumNumberOfLines > 0 { size.height = min(size.height, ceil((text.font?.ascender ?? 13) - (text.font?.descender ?? -3) + (text.font?.leading ?? 0)) * CGFloat(text.maximumNumberOfLines) + 2) }
717
721
  if text.maximumNumberOfLines == 1 { size.height = max(18, (text.font?.pointSize ?? 13) + 5) }
718
722
  size.height += textPadding.top + textPadding.bottom
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "craft-native",
3
- "version": "0.0.415",
3
+ "version": "0.0.417",
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>",