@goliapkg/smix 1.0.0 → 1.0.1
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 +33 -47
- package/package.json +1 -1
- package/src/SimRuntime.ts +6 -6
- package/src/index.ts +4 -4
package/README.md
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
1
|
# @goliapkg/smix
|
|
2
2
|
|
|
3
|
-
> **Status (2026-06-30)**: v0.1.0 ✅ **PUBLISHED to npm** as `@goliapkg/smix`。
|
|
4
|
-
> TS SDK API surface complete, 61 vitest unit tests + 4 demo flows running
|
|
5
|
-
> end-to-end PASS + 24-fixture cross-binary harness × 3 backend byte-identical
|
|
6
|
-
> (Rust + Swift + TS).
|
|
7
|
-
>
|
|
8
|
-
> Earlier unscoped `smix-rn` package(briefly published during ship transition)
|
|
9
|
-
> is deprecated pointing here。
|
|
10
|
-
>
|
|
11
|
-
> See also [v7 full initiative wrap](../../docs/plan-history/v7-full-initiative-wrap.md)
|
|
12
|
-
> for the 10-cycle outcome summary。
|
|
13
|
-
|
|
14
3
|
Playwright-style iOS Simulator + Android emulator UI automation SDK for
|
|
15
|
-
TypeScript / React Native / Expo / Detox-compatible test runners.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
20+ module。
|
|
4
|
+
TypeScript / React Native / Expo / Detox-compatible test runners. Brings
|
|
5
|
+
smix's Rust-core selector resolver to TS via HTTP client (production) or
|
|
6
|
+
in-process mock (unit tests), packaged as an ESM Node 20+ module.
|
|
19
7
|
|
|
20
8
|
## Installation
|
|
21
9
|
|
|
@@ -25,11 +13,11 @@ bun add -D @goliapkg/smix
|
|
|
25
13
|
npm install -D @goliapkg/smix
|
|
26
14
|
```
|
|
27
15
|
|
|
28
|
-
For test target / Detox-
|
|
29
|
-
|
|
30
|
-
|
|
16
|
+
For test target / Detox-equivalent consumer. This package should only be
|
|
17
|
+
listed in `devDependencies` — never bundled into a production RN/Expo app
|
|
18
|
+
via metro/expo tree-shaking.
|
|
31
19
|
|
|
32
|
-
## Quick start(MockSimRuntime — unit tests)
|
|
20
|
+
## Quick start (MockSimRuntime — unit tests)
|
|
33
21
|
|
|
34
22
|
```typescript
|
|
35
23
|
import { Smix, Selector, literal, MockSimRuntime, MockSelectorResolver, bundleId } from '@goliapkg/smix'
|
|
@@ -51,7 +39,7 @@ await welcome.toBeVisible({ timeoutMs: 5_000 })
|
|
|
51
39
|
```typescript
|
|
52
40
|
import { Smix, Selector, bundleId, HttpSimRuntime } from '@goliapkg/smix'
|
|
53
41
|
|
|
54
|
-
// Connects to smix-runner-server running on host(see swift-bridge/SmixRunnerCore)
|
|
42
|
+
// Connects to smix-runner-server running on host (see swift-bridge/SmixRunnerCore)
|
|
55
43
|
const runtime = new HttpSimRuntime('http://localhost:14101')
|
|
56
44
|
|
|
57
45
|
const app = await Smix.launchApp(bundleId('com.example.MyApp'), runtime, runtime.resolver, runtime.labelsResolver)
|
|
@@ -62,12 +50,12 @@ await app.find(Selector.role('button')).toHaveCount(3, { timeoutMs: 5_000 })
|
|
|
62
50
|
HTTP endpoints documented in [`src/HttpRunner.ts`](src/HttpRunner.ts) +
|
|
63
51
|
[Swift server route handler](../../swift-bridge/Sources/SmixRunnerCore/SmixRunnerServer.swift).
|
|
64
52
|
|
|
65
|
-
## API surface
|
|
53
|
+
## API surface
|
|
66
54
|
|
|
67
55
|
### Selector
|
|
68
56
|
|
|
69
57
|
```typescript
|
|
70
|
-
// Base discriminators(untagged JSON wire shape — matches Rust smix-selector)
|
|
58
|
+
// Base discriminators (untagged JSON wire shape — matches Rust smix-selector)
|
|
71
59
|
Selector.id('btn-login')
|
|
72
60
|
Selector.text(literal('Sign In'))
|
|
73
61
|
Selector.text(regex('^Sub', 'i'))
|
|
@@ -78,20 +66,20 @@ Selector.focused()
|
|
|
78
66
|
Selector.anchor({ below: Selector.text(literal('Total')) }, { nth: 0 })
|
|
79
67
|
Selector.localizedText({ en: 'Submit', ja: '送信' })
|
|
80
68
|
|
|
81
|
-
// Fluent modifier chaining(returns new Selector with Modifiers updated)
|
|
69
|
+
// Fluent modifier chaining (returns new Selector with Modifiers updated)
|
|
82
70
|
Selector.id('btn').below(Selector.text(literal('Address')))
|
|
83
71
|
Selector.label('Edit').nth(0)
|
|
84
72
|
Selector.text(literal('Item')).above(Selector.text(literal('Footer'))).first()
|
|
85
73
|
Selector.role('button').near(Selector.text(literal('Confirm'))).ancestor(Selector.role('dialog'))
|
|
86
74
|
```
|
|
87
75
|
|
|
88
|
-
Wire JSON(untagged + flatten — byte-identical to Rust smix-selector):
|
|
76
|
+
Wire JSON (untagged + flatten — byte-identical to Rust smix-selector):
|
|
89
77
|
|
|
90
78
|
```json
|
|
91
79
|
{"id": "btn-login", "below": {"text": "Address"}, "nth": 0}
|
|
92
80
|
```
|
|
93
81
|
|
|
94
|
-
### App(act)
|
|
82
|
+
### App (act)
|
|
95
83
|
|
|
96
84
|
```typescript
|
|
97
85
|
await app.tap(selector: Selector, opts?: { timeoutMs?: number })
|
|
@@ -104,7 +92,7 @@ await app.relaunch()
|
|
|
104
92
|
await app.launchFresh({ clearState?: boolean, clearKeychain?: boolean, appPath?: string })
|
|
105
93
|
```
|
|
106
94
|
|
|
107
|
-
### App(sense)
|
|
95
|
+
### App (sense)
|
|
108
96
|
|
|
109
97
|
```typescript
|
|
110
98
|
const png: Uint8Array = await app.screenshot()
|
|
@@ -113,7 +101,7 @@ const popups: A11yNode[] = await app.systemPopups()
|
|
|
113
101
|
await app.openUrl('myapp://deep/link')
|
|
114
102
|
```
|
|
115
103
|
|
|
116
|
-
### Locator(assertions)
|
|
104
|
+
### Locator (assertions)
|
|
117
105
|
|
|
118
106
|
```typescript
|
|
119
107
|
const loc = app.find(Selector.text(literal('Welcome')))
|
|
@@ -123,7 +111,7 @@ await loc.toHaveLabel('Sign In', { timeoutMs: 5_000 }) // strict equal
|
|
|
123
111
|
await loc.toHaveCount(3, { timeoutMs: 5_000 }) // exact match count
|
|
124
112
|
```
|
|
125
113
|
|
|
126
|
-
### ExpectationFailure(AI-readable JSON)
|
|
114
|
+
### ExpectationFailure (AI-readable JSON)
|
|
127
115
|
|
|
128
116
|
```typescript
|
|
129
117
|
try {
|
|
@@ -142,7 +130,7 @@ try {
|
|
|
142
130
|
|
|
143
131
|
## Demos
|
|
144
132
|
|
|
145
|
-
Run any of the
|
|
133
|
+
Run any of the realistic e2e flows in [`examples/demo-app/`](examples/demo-app):
|
|
146
134
|
|
|
147
135
|
```bash
|
|
148
136
|
cd examples/demo-app
|
|
@@ -164,28 +152,26 @@ bash ../../scripts/sdk/run-cross-binary-harness.sh
|
|
|
164
152
|
# Summary: 24 / 24 fixtures byte-identical (Rust + Swift + TS)
|
|
165
153
|
```
|
|
166
154
|
|
|
167
|
-
##
|
|
155
|
+
## Test-target-only
|
|
168
156
|
|
|
169
|
-
`@goliapkg/smix` is
|
|
170
|
-
|
|
171
|
-
production bundle excludes it. The `HttpSimRuntime` connects to a
|
|
172
|
-
smix-runner-server running on the host(via 127.0.0.1:port loopback),
|
|
173
|
-
not in-process
|
|
157
|
+
`@goliapkg/smix` is intended for `devDependencies` only — never bundled
|
|
158
|
+
into a production RN/Expo app. `metro`/`expo`'s tree-shaking guarantees
|
|
159
|
+
the production bundle excludes it. The `HttpSimRuntime` connects to a
|
|
160
|
+
smix-runner-server running on the host (via `127.0.0.1:port` loopback),
|
|
161
|
+
not in-process.
|
|
174
162
|
|
|
175
163
|
## Architecture
|
|
176
164
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
- **
|
|
183
|
-
|
|
184
|
-
- **
|
|
185
|
-
|
|
186
|
-
- **SDK facade**(`src/{Smix,App,Selector,Modifiers,Locator,ExpectationFailure}.ts`):
|
|
187
|
-
Playwright-style ergonomic surface,class-based fluent chaining。
|
|
165
|
+
- **Rust stone core** (`crates/smix-{selector,selector-resolver,screen,error}`):
|
|
166
|
+
selector resolution + AI-readable failure types, shared across all
|
|
167
|
+
language SDKs.
|
|
168
|
+
- **HTTP runtime** (`src/HttpRunner.ts`): wraps fetch to smix-runner-server
|
|
169
|
+
on the host. Production-default.
|
|
170
|
+
- **Mock runtime** (`src/SimRuntime.ts MockSimRuntime`): in-memory tree +
|
|
171
|
+
event log. Used by vitest unit tests + demo flows.
|
|
172
|
+
- **SDK facade** (`src/{Smix,App,Selector,Modifiers,Locator,ExpectationFailure}.ts`):
|
|
173
|
+
Playwright-style ergonomic surface, class-based fluent chaining.
|
|
188
174
|
|
|
189
175
|
## License
|
|
190
176
|
|
|
191
|
-
Apache-2.0 OR MIT(dual,at your option)
|
|
177
|
+
Apache-2.0 OR MIT (dual, at your option).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goliapkg/smix",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Playwright-shape iOS Simulator / Android emulator UI automation SDK for React Native + Expo + Detox-compatible TypeScript test runners.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0 OR MIT",
|
package/src/SimRuntime.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
//
|
|
1
|
+
// SmixSimRuntime interface + MockSimRuntime impl.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// - HttpSimRuntime (real, lives in src/HttpRunner.ts
|
|
6
|
-
//
|
|
3
|
+
// Mirrors the Swift and Kotlin SimRuntime architecture. The TS SDK is
|
|
4
|
+
// HTTP-runner-friendly:
|
|
5
|
+
// - HttpSimRuntime (real, lives in src/HttpRunner.ts): wraps the
|
|
6
|
+
// smix-runner HTTP server via fetch (cross-platform iOS+Android).
|
|
7
7
|
// - MockSimRuntime (here): in-memory tree + event log for unit tests.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// This module is intended for test targets only.
|
|
10
10
|
|
|
11
11
|
import type { A11yNode } from './A11yNode.js'
|
|
12
12
|
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
//
|
|
1
|
+
// @goliapkg/smix public API exports.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
3
|
+
// Mirrors Kotlin SDK + Swift SDK surface. This package is intended for
|
|
4
|
+
// test harnesses (vitest / jest / Detox-like runners) — it should not be
|
|
5
|
+
// bundled into a production RN app.
|
|
6
6
|
|
|
7
7
|
export {
|
|
8
8
|
App,
|