@specific.dev/spectest 0.23.0 → 0.24.0
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/package.json +1 -1
- package/src/components/expo.ts +8 -1
- package/src/daemon.ts +2 -0
- package/src/mobile.ts +13 -3
- package/src/recorder.ts +1 -1
package/package.json
CHANGED
package/src/components/expo.ts
CHANGED
|
@@ -35,6 +35,13 @@ export interface ExpoOptions {
|
|
|
35
35
|
* too late. Everything else applies to the static-server container only.
|
|
36
36
|
*/
|
|
37
37
|
env?: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Script installed before each `ctx.mobile(ctx.svc.app)` session's first
|
|
40
|
+
* navigation, so it runs ahead of the app bundle on the very first document
|
|
41
|
+
* — no relaunch. Declare shims here once (reduced-motion, `Notification`, …)
|
|
42
|
+
* instead of calling them at the top of every test.
|
|
43
|
+
*/
|
|
44
|
+
initScript?: string;
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
/** The handle `expo()` exposes on `ctx.svc.<name>` — a {@link MobileApp}. */
|
|
@@ -154,7 +161,7 @@ ${publicEnvLines ? `${publicEnvLines}\n` : ""}RUN npx expo export --platform web
|
|
|
154
161
|
// TLS → net::ERR_SSL_PROTOCOL_ERROR), while a dotted host navigates as
|
|
155
162
|
// plain HTTP. Node-side `fetch` is unaffected, but the mobile session
|
|
156
163
|
// drives a real browser, so the URL must be browser-navigable.
|
|
157
|
-
return mobileApp(`http://${name}.internal:${port}
|
|
164
|
+
return mobileApp(`http://${name}.internal:${port}`, opts.initScript);
|
|
158
165
|
},
|
|
159
166
|
} satisfies ServiceDefinition<ExpoHelpers>;
|
|
160
167
|
}
|
package/src/daemon.ts
CHANGED
|
@@ -3973,6 +3973,7 @@ async function runOne(testCase: TestCase<unknown>): Promise<RunResult> {
|
|
|
3973
3973
|
const { mobile, attached, detach, safeAreaInsets } = await openPersistentMobile({
|
|
3974
3974
|
url: app.url,
|
|
3975
3975
|
recorder: session.recorder,
|
|
3976
|
+
initScript: app.initScript,
|
|
3976
3977
|
});
|
|
3977
3978
|
if (safeAreaInsets) session.record.safeAreaInsets = safeAreaInsets;
|
|
3978
3979
|
if (attached && session.record.initialUrl === undefined) {
|
|
@@ -4295,6 +4296,7 @@ async function evalCode(
|
|
|
4295
4296
|
const { mobile, attached, detach, safeAreaInsets } = await openPersistentMobile({
|
|
4296
4297
|
url: app.url,
|
|
4297
4298
|
recorder: session.recorder,
|
|
4299
|
+
initScript: app.initScript,
|
|
4298
4300
|
});
|
|
4299
4301
|
if (safeAreaInsets) session.record.safeAreaInsets = safeAreaInsets;
|
|
4300
4302
|
if (attached && session.record.initialUrl === undefined) {
|
package/src/mobile.ts
CHANGED
|
@@ -36,6 +36,11 @@ export interface MobileApp {
|
|
|
36
36
|
readonly [MOBILE_APP]: true;
|
|
37
37
|
/** Resolved in-VM URL of the app's web build (e.g. `http://app.internal:8081`). */
|
|
38
38
|
readonly url: string;
|
|
39
|
+
/** Optional script installed before the session's first navigation, so it
|
|
40
|
+
* runs ahead of the app bundle on the very first document (no relaunch) —
|
|
41
|
+
* the place to plant reduced-motion / `Notification` shims once for every
|
|
42
|
+
* `ctx.mobile(app)` call. Set via `expo({ initScript })`. */
|
|
43
|
+
readonly initScript?: string;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
/** True if `x` is a {@link MobileApp} handle. */
|
|
@@ -48,9 +53,10 @@ export function isMobileApp(x: unknown): x is MobileApp {
|
|
|
48
53
|
);
|
|
49
54
|
}
|
|
50
55
|
|
|
51
|
-
/** Build a {@link MobileApp} handle from a resolved URL
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
/** Build a {@link MobileApp} handle from a resolved URL (and an optional
|
|
57
|
+
* init script installed before the session's first navigation). */
|
|
58
|
+
export function mobileApp(url: string, initScript?: string): MobileApp {
|
|
59
|
+
return { [MOBILE_APP]: true, url, initScript };
|
|
54
60
|
}
|
|
55
61
|
|
|
56
62
|
// ────────────────────────────────────────────────────────────────────────
|
|
@@ -102,6 +108,9 @@ export async function openMobile(opts: {
|
|
|
102
108
|
export async function openPersistentMobile(opts: {
|
|
103
109
|
url: string;
|
|
104
110
|
recorder: BrowserSessionRecorder | null;
|
|
111
|
+
/** Installed before the fresh session's first navigation (ignored on an
|
|
112
|
+
* attached session, which already carries it on the forked holder). */
|
|
113
|
+
initScript?: string;
|
|
105
114
|
}): Promise<{
|
|
106
115
|
mobile: Mobile;
|
|
107
116
|
attached: boolean;
|
|
@@ -113,6 +122,7 @@ export async function openPersistentMobile(opts: {
|
|
|
113
122
|
const { browser, attached, detach } = await acquirePersistentMobileBackend(
|
|
114
123
|
opts.url,
|
|
115
124
|
opts.recorder,
|
|
125
|
+
opts.initScript,
|
|
116
126
|
);
|
|
117
127
|
return {
|
|
118
128
|
mobile: browser,
|
package/src/recorder.ts
CHANGED
|
@@ -375,7 +375,7 @@ export interface EnvEvent extends BaseEvent {
|
|
|
375
375
|
// method name verbatim. Both renderers (control-plane web + CLI) treat it as
|
|
376
376
|
// an opaque string with a generic `{action} <target>` fallback, so new method
|
|
377
377
|
// names need no Rust change. Representative values: "goto", "goBack",
|
|
378
|
-
// "goForward", "reload", "evaluate", "
|
|
378
|
+
// "goForward", "reload", "evaluate", "waitForFunction",
|
|
379
379
|
// "click", "dblclick", "tap", "fill", "clear", "press", "type", "scroll",
|
|
380
380
|
// "check", "hover", "textContent", "inputValue", "count", "screenshot".
|
|
381
381
|
export type BrowserAction = string;
|