@swmansion/argent 0.31.2-next.3 → 0.31.2-next.4
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/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentExceptionGuard.h +3 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentExceptionGuard.m +11 -3
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Gestures.swift +27 -19
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Quiescence.swift +95 -0
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+TextEntry.swift +2 -2
- package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/RunnerProtocol.swift +5 -5
- package/dist/tool-args.generated.d.ts +1 -1
- package/dist/tool-server.cjs +19 -1
- package/package.json +1 -1
|
@@ -11,6 +11,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
11
11
|
/// Returns nil when the block completed, otherwise "Name: reason".
|
|
12
12
|
+ (NSString *_Nullable)runCatching:(NS_NOESCAPE dispatch_block_t)block;
|
|
13
13
|
|
|
14
|
+
/// Returns nil when the block completed, otherwise the exception it raised.
|
|
15
|
+
+ (NSException *_Nullable)exceptionFrom:(NS_NOESCAPE dispatch_block_t)block;
|
|
16
|
+
|
|
14
17
|
@end
|
|
15
18
|
|
|
16
19
|
NS_ASSUME_NONNULL_END
|
|
@@ -3,13 +3,21 @@
|
|
|
3
3
|
@implementation ArgentExceptionGuard
|
|
4
4
|
|
|
5
5
|
+ (NSString *_Nullable)runCatching:(NS_NOESCAPE dispatch_block_t)block {
|
|
6
|
+
NSException *exception = [self exceptionFrom:block];
|
|
7
|
+
if (exception == nil) {
|
|
8
|
+
return nil;
|
|
9
|
+
}
|
|
10
|
+
NSString *name = exception.name ?: @"NSException";
|
|
11
|
+
NSString *reason = exception.reason ?: @"unhandled Objective-C exception";
|
|
12
|
+
return [NSString stringWithFormat:@"%@: %@", name, reason];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
+ (NSException *_Nullable)exceptionFrom:(NS_NOESCAPE dispatch_block_t)block {
|
|
6
16
|
@try {
|
|
7
17
|
block();
|
|
8
18
|
return nil;
|
|
9
19
|
} @catch (NSException *exception) {
|
|
10
|
-
|
|
11
|
-
NSString *reason = exception.reason ?: @"unhandled Objective-C exception";
|
|
12
|
-
return [NSString stringWithFormat:@"%@: %@", name, reason];
|
|
20
|
+
return exception;
|
|
13
21
|
}
|
|
14
22
|
}
|
|
15
23
|
|
package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Gestures.swift
CHANGED
|
@@ -21,10 +21,10 @@ extension ArgentRunnerSession {
|
|
|
21
21
|
|
|
22
22
|
/// Taps at the wire coordinates: one tap, the native double-tap when
|
|
23
23
|
/// `numberOfTaps` is 2, or a loop of single taps above that. XCUICoordinate
|
|
24
|
-
/// has no N-tap API, and the loop is not one gesture
|
|
25
|
-
///
|
|
26
|
-
///
|
|
27
|
-
///
|
|
24
|
+
/// has no N-tap API, and the loop is not one gesture: each tap is its own
|
|
25
|
+
/// synthesized event and XPC round trip, about 300 ms apart on a
|
|
26
|
+
/// simulator, which a double-tap recognizer can still pair. That is
|
|
27
|
+
/// documented, not refused.
|
|
28
28
|
func performTap(_ request: CommandRequest, on app: XCUIApplication)
|
|
29
29
|
-> Envelope
|
|
30
30
|
{
|
|
@@ -39,15 +39,17 @@ extension ArgentRunnerSession {
|
|
|
39
39
|
|
|
40
40
|
let coordinate = point(app, x, y, relativeTo: app.frame.origin)
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
case 2:
|
|
46
|
-
coordinate.doubleTap()
|
|
47
|
-
default:
|
|
48
|
-
// Separate taps, not one gesture (see the doc comment above).
|
|
49
|
-
for _ in 0..<taps {
|
|
42
|
+
skippingQuiescence(of: app) {
|
|
43
|
+
switch taps {
|
|
44
|
+
case 1:
|
|
50
45
|
coordinate.tap()
|
|
46
|
+
case 2:
|
|
47
|
+
coordinate.doubleTap()
|
|
48
|
+
default:
|
|
49
|
+
// Separate taps, not one gesture (see the doc comment above).
|
|
50
|
+
for _ in 0..<taps {
|
|
51
|
+
coordinate.tap()
|
|
52
|
+
}
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -63,7 +65,11 @@ extension ArgentRunnerSession {
|
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
let seconds = max(0.05, (request.durationMs ?? 800) / 1000)
|
|
66
|
-
point(app, x, y, relativeTo: app.frame.origin)
|
|
68
|
+
let coordinate = point(app, x, y, relativeTo: app.frame.origin)
|
|
69
|
+
|
|
70
|
+
skippingQuiescence(of: app) {
|
|
71
|
+
coordinate.press(forDuration: seconds)
|
|
72
|
+
}
|
|
67
73
|
|
|
68
74
|
return .success(MessagePayload(message: "long-pressed"))
|
|
69
75
|
}
|
|
@@ -112,12 +118,14 @@ extension ArgentRunnerSession {
|
|
|
112
118
|
velocity = .default
|
|
113
119
|
}
|
|
114
120
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
skippingQuiescence(of: app) {
|
|
122
|
+
start.press(
|
|
123
|
+
forDuration: startHold,
|
|
124
|
+
thenDragTo: end,
|
|
125
|
+
withVelocity: velocity,
|
|
126
|
+
thenHoldForDuration: endHold
|
|
127
|
+
)
|
|
128
|
+
}
|
|
121
129
|
|
|
122
130
|
return .success(MessagePayload(message: "dragged"))
|
|
123
131
|
}
|
package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+Quiescence.swift
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
|
|
3
|
+
/// XCTest waits up to 60s before and after every synthesized event for the
|
|
4
|
+
/// app to report idle. A screen that never does, such as one holding a paused
|
|
5
|
+
/// UIViewPropertyAnimator (expo-blur), stalls each gesture for two minutes,
|
|
6
|
+
/// past its watchdog budget. The runner skips those waits and runs XCTest's
|
|
7
|
+
/// idle check itself under a short cap. Every API here is XCTest SPI, probed
|
|
8
|
+
/// before use: when any is missing, the event runs with XCTest's own waits.
|
|
9
|
+
extension ArgentRunnerSession {
|
|
10
|
+
/// The longest a gesture waits for the app to go idle before its event.
|
|
11
|
+
/// Covers a navigation transition, so a gesture sent right after the one
|
|
12
|
+
/// that started it lands on the new screen instead of mid-transition.
|
|
13
|
+
static let preEventSettleTimeout: TimeInterval = 2
|
|
14
|
+
|
|
15
|
+
private static let performWithInteractionOptions = NSSelectorFromString(
|
|
16
|
+
"_performWithInteractionOptions:block:"
|
|
17
|
+
)
|
|
18
|
+
/// Bit 1 skips the pre-event wait, bit 2 the post-event one.
|
|
19
|
+
private static let skipQuiescenceOptions: UInt32 = 0b11
|
|
20
|
+
|
|
21
|
+
private static let applicationImpl = NSSelectorFromString("applicationImpl")
|
|
22
|
+
private static let currentProcess = NSSelectorFromString("currentProcess")
|
|
23
|
+
private static let initiateQuiescenceChecks = NSSelectorFromString(
|
|
24
|
+
"_initiateQuiescenceChecksIncludingAnimationsIdle:"
|
|
25
|
+
)
|
|
26
|
+
private static let makeQuiescenceExpectation = NSSelectorFromString(
|
|
27
|
+
"_makeQuiescenceExpectation"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
/// Waits at most `preEventSettleTimeout` for `app` to go idle, then runs
|
|
31
|
+
/// `body`, which synthesizes events into it, without XCTest's waits.
|
|
32
|
+
func skippingQuiescence(of app: XCUIApplication, _ body: () -> Void) {
|
|
33
|
+
let selector = Self.performWithInteractionOptions
|
|
34
|
+
|
|
35
|
+
guard app.responds(to: selector),
|
|
36
|
+
awaitQuiescence(of: app, timeout: Self.preEventSettleTimeout)
|
|
37
|
+
else {
|
|
38
|
+
body()
|
|
39
|
+
return
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
typealias Perform = @convention(c) (
|
|
43
|
+
NSObject, Selector, UInt32, @convention(block) () -> Void
|
|
44
|
+
) -> Void
|
|
45
|
+
let perform = unsafeBitCast(app.method(for: selector), to: Perform.self)
|
|
46
|
+
|
|
47
|
+
// XCTest restores the prior options only when the block returns, and
|
|
48
|
+
// every XCUIApplication for this bundle id shares them, so an
|
|
49
|
+
// exception must not unwind through it.
|
|
50
|
+
var exception: NSException?
|
|
51
|
+
withoutActuallyEscaping(body) { body in
|
|
52
|
+
perform(app, selector, Self.skipQuiescenceOptions) {
|
|
53
|
+
exception = ArgentExceptionGuard.exception(from: body)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exception?.raise()
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// XCTest's own idle check (event loop and animations), under `timeout`.
|
|
60
|
+
/// False when any SPI it needs is missing.
|
|
61
|
+
private func awaitQuiescence(of app: XCUIApplication, timeout: TimeInterval)
|
|
62
|
+
-> Bool
|
|
63
|
+
{
|
|
64
|
+
guard
|
|
65
|
+
let impl = Self.object(app, Self.applicationImpl),
|
|
66
|
+
let process = Self.object(impl, Self.currentProcess),
|
|
67
|
+
process.responds(to: Self.initiateQuiescenceChecks)
|
|
68
|
+
else {
|
|
69
|
+
return false
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
typealias Initiate = @convention(c) (NSObject, Selector, Bool) -> Void
|
|
73
|
+
let initiate = unsafeBitCast(
|
|
74
|
+
process.method(for: Self.initiateQuiescenceChecks),
|
|
75
|
+
to: Initiate.self
|
|
76
|
+
)
|
|
77
|
+
initiate(process, Self.initiateQuiescenceChecks, true)
|
|
78
|
+
|
|
79
|
+
guard
|
|
80
|
+
let expectation = Self.object(process, Self.makeQuiescenceExpectation)
|
|
81
|
+
as? XCTestExpectation
|
|
82
|
+
else {
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
_ = XCTWaiter.wait(for: [expectation], timeout: timeout)
|
|
87
|
+
return true
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/// The object a zero-argument getter returns, or nil when `target` lacks it.
|
|
91
|
+
private static func object(_ target: NSObject, _ getter: Selector) -> NSObject? {
|
|
92
|
+
guard target.responds(to: getter) else { return nil }
|
|
93
|
+
return target.perform(getter)?.takeUnretainedValue() as? NSObject
|
|
94
|
+
}
|
|
95
|
+
}
|
package/dist/ios-device-runner/ArgentRunner/ArgentRunnerUITests/ArgentRunnerSession+TextEntry.swift
CHANGED
|
@@ -77,7 +77,7 @@ extension ArgentRunnerSession {
|
|
|
77
77
|
app.keyboards.keys.matching(submitKey).firstMatch,
|
|
78
78
|
] where candidate.exists && candidate.isHittable {
|
|
79
79
|
let label = candidate.label
|
|
80
|
-
candidate.tap()
|
|
80
|
+
skippingQuiescence(of: app) { candidate.tap() }
|
|
81
81
|
|
|
82
82
|
return .success(
|
|
83
83
|
MessagePayload(message: "pressed keyboard \(label)")
|
|
@@ -131,7 +131,7 @@ extension ArgentRunnerSession {
|
|
|
131
131
|
}
|
|
132
132
|
|
|
133
133
|
let exceptionDescription = ArgentExceptionGuard.runCatching {
|
|
134
|
-
app.typeText(text)
|
|
134
|
+
self.skippingQuiescence(of: app) { app.typeText(text) }
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
if let exceptionDescription {
|
|
@@ -70,10 +70,10 @@ extension CommandKind {
|
|
|
70
70
|
switch self {
|
|
71
71
|
// XCTest types long strings in real time, so typing needs extra room.
|
|
72
72
|
case .type: return 55
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
73
|
+
// tap, longPress and drag outlast XCTest's ~60s pre-event idle wait,
|
|
74
|
+
// which runs where the runner cannot skip it
|
|
75
|
+
// (ArgentRunnerSession+Quiescence.swift). touchPaths never waits for
|
|
76
|
+
// idle but shares the gesture budget.
|
|
77
77
|
case .tap, .longPress, .drag, .touchPaths: return 75
|
|
78
78
|
default: return 30
|
|
79
79
|
}
|
|
@@ -117,7 +117,7 @@ struct CommandRequest: Codable {
|
|
|
117
117
|
let y: Double?
|
|
118
118
|
/// `tap`: number of taps. Defaults to 1; 2 is the native double-tap.
|
|
119
119
|
/// Higher counts loop single taps on the device: there is no native N-tap
|
|
120
|
-
/// API, so they
|
|
120
|
+
/// API, so they are not one multi-tap gesture.
|
|
121
121
|
let numberOfTaps: Int?
|
|
122
122
|
/// `drag`: absolute start and end points.
|
|
123
123
|
let fromX: Double?
|
|
@@ -408,7 +408,7 @@ export interface ArgentToolArgs {
|
|
|
408
408
|
x: number;
|
|
409
409
|
/** Normalized vertical position 0.0–1.0 (top=0, bottom=1), not pixels */
|
|
410
410
|
y: number;
|
|
411
|
-
/** Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts
|
|
411
|
+
/** Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts loop single taps, which a double-tap recognizer may pair. On HarmonyOS only 2 is one gesture; 3 or more are separate injections a device round trip apart, which the OS reads as single taps. Default 1. */
|
|
412
412
|
clickCount?: number;
|
|
413
413
|
};
|
|
414
414
|
keyboard: {
|
package/dist/tool-server.cjs
CHANGED
|
@@ -142136,7 +142136,7 @@ var zodSchema17 = external_exports.object({
|
|
|
142136
142136
|
x: external_exports.number().min(0).max(1).describe("Normalized horizontal position 0.0\u20131.0 (left=0, right=1), not pixels"),
|
|
142137
142137
|
y: external_exports.number().min(0).max(1).describe("Normalized vertical position 0.0\u20131.0 (top=0, bottom=1), not pixels"),
|
|
142138
142138
|
clickCount: external_exports.number().int().min(1).max(10).optional().describe(
|
|
142139
|
-
"Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts
|
|
142139
|
+
"Number of taps/clicks dispatched as ONE multi-tap gesture (2 = double-tap / double-click). The taps land inside the OS double-tap window; on Chromium each click carries an escalating CDP clickCount so dblclick actually fires; on physical iOS 2 is the native double-tap and higher counts loop single taps, which a double-tap recognizer may pair. <flag:harmonyos>On HarmonyOS only 2 is one gesture; 3 or more are separate injections a device round trip apart, which the OS reads as single taps. </flag:harmonyos>Default 1."
|
|
142140
142140
|
)
|
|
142141
142141
|
});
|
|
142142
142142
|
function tapDescription(params, tense) {
|
|
@@ -142209,6 +142209,9 @@ Returns { tapped: true, timestampMs }. On physical iOS, reactivated: true = app
|
|
|
142209
142209
|
On a physical iPhone use \`describe\`; \`native-describe-screen\` is simulator-only.
|
|
142210
142210
|
Before tapping, determine the correct coordinates by using discovery tools. Pick by platform: iOS / Android use \`describe\`, \`native-describe-screen\`, or \`debugger-component-tree\`; Chromium uses \`describe\` (the DOM walker)<flag:harmonyos> and HarmonyOS uses \`describe\` (the \`uitest\` layout dump)</flag:harmonyos>, since the native and RN-specific discovery tools don't apply<flag:harmonyos> to either</flag:harmonyos>. More information in \`argent-device-interact\` skill`,
|
|
142211
142211
|
alwaysLoad: true,
|
|
142212
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
142213
|
+
// whose abort replays the call: the gesture would land once per replay.
|
|
142214
|
+
longRunning: true,
|
|
142212
142215
|
searchHint: "tap press button element device simulator emulator chromium touch down up click",
|
|
142213
142216
|
zodSchema: zodSchema17,
|
|
142214
142217
|
capability: capability9,
|
|
@@ -142336,6 +142339,9 @@ Physical iOS: an edge gesture (back-swipe) needs fromX 0 exactly; durationMs set
|
|
|
142336
142339
|
HarmonyOS: durationMs sets drag speed, clamped to uitest's 200-40000 px/s, so a short slow swipe ends early and a long fast one runs late.</flag:harmonyos>
|
|
142337
142340
|
Pass momentum:false for a momentum-free swipe that lands where the finger lifts (little to no fling at the 300 default), when you need a deterministic scroll distance; it needs durationMs >= 150 and is rejected below that, a shorter ease-out leaving the OS too little wall clock to read the deceleration as a stop. At 150 it lands short of the lift point instead, and 2 of 47 runs still flung backwards. A plain swipe takes any duration up to 10000ms and is delivered as close to the speed it was authored as a 16ms frame allows: below ~32ms the whole travel lands in one or two frames, which the OS flings as hard as it flings anything. Returns { swiped: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend<flag:harmonyos>, or \`hdc\` on HarmonyOS,</flag:harmonyos> is not reachable for the given device.`,
|
|
142338
142341
|
alwaysLoad: true,
|
|
142342
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
142343
|
+
// whose abort replays the call: the gesture would land once per replay.
|
|
142344
|
+
longRunning: true,
|
|
142339
142345
|
searchHint: "swipe scroll drag pan gesture device simulator emulator touch move",
|
|
142340
142346
|
zodSchema: zodSchema18,
|
|
142341
142347
|
capability: capability10,
|
|
@@ -142893,6 +142899,9 @@ Example pinch-to-zoom (with interpolate:10 for smoothness):
|
|
|
142893
142899
|
interpolate: 10`,
|
|
142894
142900
|
zodSchema: zodSchema21,
|
|
142895
142901
|
capability: capability13,
|
|
142902
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
142903
|
+
// whose abort replays the call: the gesture would land once per replay.
|
|
142904
|
+
longRunning: true,
|
|
142896
142905
|
// Declare the runner only for a train execute can play. A rejected train must not pay a runner cold start.
|
|
142897
142906
|
services: (params) => {
|
|
142898
142907
|
const device = resolveDevice(params.udid);
|
|
@@ -142980,6 +142989,9 @@ Auto-generates interpolated frames at ~60fps<flag:harmonyos> on iOS and Android;
|
|
|
142980
142989
|
Use when you need to zoom in or out on a map, image, or zoomable view. Physical iPhones play both fingers through the runner as one event stream. Returns { pinched: true, timestampMs }. On physical iOS, reactivated: true = app was re-fronted; re-describe. Fails if the simulator-server / emulator backend<flag:harmonyos>, or \`hdc\` on HarmonyOS,</flag:harmonyos> is not reachable for the given device, or on a physical iPhone when the app is not drawn in portrait.`,
|
|
142981
142990
|
zodSchema: zodSchema22,
|
|
142982
142991
|
capability: capability14,
|
|
142992
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
142993
|
+
// whose abort replays the call: the gesture would land once per replay.
|
|
142994
|
+
longRunning: true,
|
|
142983
142995
|
services: (params) => {
|
|
142984
142996
|
const device = resolveDevice(params.udid);
|
|
142985
142997
|
if (device.platform === "harmony") return {};
|
|
@@ -143115,6 +143127,9 @@ Use when you need to rotate a map, image picker, or any rotateable UI element. R
|
|
|
143115
143127
|
Size the orbit with radius, or with radiusX and radiusY together (the pair overrides radius); one half of the pair alone, or none of the three, is rejected.`,
|
|
143116
143128
|
zodSchema: zodSchema23,
|
|
143117
143129
|
capability: capability15,
|
|
143130
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
143131
|
+
// whose abort replays the call: the gesture would land once per replay.
|
|
143132
|
+
longRunning: true,
|
|
143118
143133
|
services: (params) => {
|
|
143119
143134
|
const device = resolveDevice(params.udid);
|
|
143120
143135
|
return isIosPhysicalDevice(device) ? { iosDeviceRunner: iosDeviceRunnerRef(device) } : { simulatorServer: simulatorServerRef(device) };
|
|
@@ -143238,6 +143253,9 @@ Returns { pressed: buttonName }.
|
|
|
143238
143253
|
Fails if the device backend is not reachable: the simulator-server for iOS, <flag:harmonyos>\`hdc\` for HarmonyOS, </flag:harmonyos>or \`adb\` for Android (Android presses are injected with \`adb shell input keyevent\`).`,
|
|
143239
143254
|
zodSchema: zodSchema24,
|
|
143240
143255
|
capability: capability16,
|
|
143256
|
+
// A physical iPhone's first call waits out the runner build, past the MCP fetch timeout,
|
|
143257
|
+
// whose abort replays the call: the press would land once per replay.
|
|
143258
|
+
longRunning: true,
|
|
143241
143259
|
// Declare only the service the resolved path actually consumes. The Android
|
|
143242
143260
|
// path uses `adb`, so a sim-server here would spawn a service the tool never
|
|
143243
143261
|
// uses (up to a 30s ready-wait) and could throw ServiceInitializationError
|
package/package.json
CHANGED