@react-native-harness/ui 1.0.0-alpha.23 → 1.0.0-alpha.25
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 +25 -11
- package/android/src/main/java/com/harnessui/HarnessUIModule.kt +26 -16
- package/android/src/main/java/com/harnessui/UIHelperImpl.kt +136 -41
- package/android/src/main/java/com/harnessui/ViewQueryHelper.kt +36 -15
- package/android/src/main/java/com/harnessui/ViewRegistry.kt +51 -0
- package/dist/HarnessUI.d.ts +17 -0
- package/dist/HarnessUI.d.ts.map +1 -0
- package/dist/HarnessUI.js +2 -0
- package/dist/HarnessUI.web.d.ts +14 -0
- package/dist/HarnessUI.web.d.ts.map +1 -0
- package/dist/HarnessUI.web.js +46 -0
- package/dist/NativeHarness.d.ts +22 -0
- package/dist/NativeHarness.d.ts.map +1 -0
- package/dist/NativeHarness.js +2 -0
- package/dist/NativeHarnessUI.d.ts +10 -37
- package/dist/NativeHarnessUI.d.ts.map +1 -1
- package/dist/WebHarness.d.ts +14 -0
- package/dist/WebHarness.d.ts.map +1 -0
- package/dist/WebHarness.js +53 -0
- package/dist/WebHarnessUI.d.ts +15 -0
- package/dist/WebHarnessUI.d.ts.map +1 -0
- package/dist/WebHarnessUI.js +81 -0
- package/dist/harness/NativeHarness.d.ts +17 -0
- package/dist/harness/NativeHarness.d.ts.map +1 -0
- package/dist/harness/NativeHarness.js +2 -0
- package/dist/harness/WebHarness.d.ts +14 -0
- package/dist/harness/WebHarness.d.ts.map +1 -0
- package/dist/harness/WebHarness.js +53 -0
- package/dist/harness/index.d.ts +4 -0
- package/dist/harness/index.d.ts.map +1 -0
- package/dist/harness/index.js +8 -0
- package/dist/harness/native-harness.d.ts +17 -0
- package/dist/harness/native-harness.d.ts.map +1 -0
- package/dist/harness/native-harness.js +2 -0
- package/dist/harness/web-harness.d.ts +14 -0
- package/dist/harness/web-harness.d.ts.map +1 -0
- package/dist/harness/web-harness.js +53 -0
- package/dist/harness.d.ts +4 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/screen.d.ts +9 -7
- package/dist/screen.d.ts.map +1 -1
- package/dist/screen.js +50 -20
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/dist/types.d.ts +48 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/userEvent.d.ts.map +1 -1
- package/dist/userEvent.js +10 -19
- package/ios/HarnessUI.mm +58 -8
- package/ios/ViewQueryHelper.h +9 -0
- package/ios/ViewQueryHelper.mm +24 -1
- package/ios/ViewRegistry.h +8 -0
- package/ios/ViewRegistry.mm +33 -0
- package/package.json +2 -2
- package/src/NativeHarnessUI.ts +11 -45
- package/src/WebHarnessUI.ts +113 -0
- package/src/harness.ts +12 -0
- package/src/index.ts +1 -1
- package/src/screen.ts +64 -27
- package/src/types.ts +54 -0
- package/src/userEvent.ts +10 -19
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const getElementViewInfo = (element) => {
|
|
2
|
+
const rect = element.getBoundingClientRect();
|
|
3
|
+
return {
|
|
4
|
+
x: rect.left,
|
|
5
|
+
y: rect.top,
|
|
6
|
+
width: rect.width,
|
|
7
|
+
height: rect.height,
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
const WebHarnessUI = {
|
|
11
|
+
simulatePress: async (x, y) => {
|
|
12
|
+
await window.__RN_HARNESS_SIMULATE_PRESS__(x, y);
|
|
13
|
+
},
|
|
14
|
+
queryByTestId: (testId) => {
|
|
15
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
16
|
+
return element ? getElementViewInfo(element) : null;
|
|
17
|
+
},
|
|
18
|
+
queryAllByTestId: (testId) => {
|
|
19
|
+
const elements = document.querySelectorAll(`[data-testid="${testId}"]`);
|
|
20
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
21
|
+
},
|
|
22
|
+
queryByAccessibilityLabel: (label) => {
|
|
23
|
+
const element = document.querySelector(`[aria-label="${label}"]`);
|
|
24
|
+
return element ? getElementViewInfo(element) : null;
|
|
25
|
+
},
|
|
26
|
+
queryAllByAccessibilityLabel: (label) => {
|
|
27
|
+
const elements = document.querySelectorAll(`[aria-label="${label}"]`);
|
|
28
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
29
|
+
},
|
|
30
|
+
captureScreenshot: async (bounds) => {
|
|
31
|
+
return await window.__RN_HARNESS_CAPTURE_SCREENSHOT__(bounds);
|
|
32
|
+
},
|
|
33
|
+
typeChar: async (character) => {
|
|
34
|
+
await window.__RN_HARNESS_TYPE_CHAR__(character);
|
|
35
|
+
},
|
|
36
|
+
blur: async (options) => {
|
|
37
|
+
// If there is a focused element, blur it directly in the DOM first
|
|
38
|
+
// to trigger local events, then call the runner-side bridge.
|
|
39
|
+
if (document.activeElement instanceof HTMLElement ||
|
|
40
|
+
document.activeElement instanceof SVGElement) {
|
|
41
|
+
document.activeElement.blur();
|
|
42
|
+
}
|
|
43
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export default WebHarnessUI;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
export interface ViewInfo {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
}
|
|
8
|
+
interface Spec extends TurboModule {
|
|
9
|
+
simulatePress(x: number, y: number): Promise<void>;
|
|
10
|
+
queryByTestId(testId: string): ViewInfo | null;
|
|
11
|
+
queryAllByTestId(testId: string): ViewInfo[];
|
|
12
|
+
queryByAccessibilityLabel(label: string): ViewInfo | null;
|
|
13
|
+
queryAllByAccessibilityLabel(label: string): ViewInfo[];
|
|
14
|
+
captureScreenshot(bounds: ViewInfo | null): Promise<string | null>;
|
|
15
|
+
typeChar(character: string): Promise<void>;
|
|
16
|
+
blur(options: {
|
|
17
|
+
submitEditing?: boolean;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
}
|
|
20
|
+
declare const _default: Spec;
|
|
21
|
+
export default _default;
|
|
22
|
+
//# sourceMappingURL=NativeHarness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeHarness.d.ts","sourceRoot":"","sources":["../src/NativeHarness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAGrE,MAAM,WAAW,QAAQ;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,IAAK,SAAQ,WAAW;IAChC,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC7C,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC1D,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;;AAED,wBAAmE"}
|
|
@@ -1,59 +1,32 @@
|
|
|
1
1
|
import { type TurboModule } from 'react-native';
|
|
2
2
|
/**
|
|
3
|
-
* Represents
|
|
3
|
+
* Represents a bounding box in screen coordinates (points/dp).
|
|
4
4
|
*/
|
|
5
|
-
export interface
|
|
5
|
+
export interface BoundingBox {
|
|
6
6
|
x: number;
|
|
7
7
|
y: number;
|
|
8
8
|
width: number;
|
|
9
9
|
height: number;
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Internal interface used for bridge communication.
|
|
13
|
+
* This needs to be exported for TurboModule codegen.
|
|
14
|
+
*/
|
|
15
|
+
export interface ViewInfo extends BoundingBox {
|
|
16
|
+
nativeId: string;
|
|
17
|
+
}
|
|
11
18
|
interface Spec extends TurboModule {
|
|
12
|
-
|
|
13
|
-
* Simulates a native press at the specified screen coordinates.
|
|
14
|
-
* Returns a promise that resolves when the press action is complete.
|
|
15
|
-
*/
|
|
16
|
-
simulatePress(x: number, y: number): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* Finds a view by its testID (accessibilityIdentifier on iOS, tag on Android).
|
|
19
|
-
* Returns null if no view is found.
|
|
20
|
-
*/
|
|
19
|
+
simulatePress(nativeId: string, x: number, y: number): Promise<void>;
|
|
21
20
|
queryByTestId(testId: string): ViewInfo | null;
|
|
22
|
-
/**
|
|
23
|
-
* Finds all views by testID (accessibilityIdentifier on iOS, tag on Android).
|
|
24
|
-
* Returns an empty array if no views are found.
|
|
25
|
-
*/
|
|
26
21
|
queryAllByTestId(testId: string): ViewInfo[];
|
|
27
|
-
/**
|
|
28
|
-
* Finds a view by its accessibility label.
|
|
29
|
-
* Returns null if no view is found.
|
|
30
|
-
*/
|
|
31
22
|
queryByAccessibilityLabel(label: string): ViewInfo | null;
|
|
32
|
-
/**
|
|
33
|
-
* Finds all views by accessibility label.
|
|
34
|
-
* Returns an empty array if no views are found.
|
|
35
|
-
*/
|
|
36
23
|
queryAllByAccessibilityLabel(label: string): ViewInfo[];
|
|
37
|
-
/**
|
|
38
|
-
* Captures a screenshot of the app UI.
|
|
39
|
-
* @param bounds Optional bounds to capture a specific region. Pass null to capture the entire window.
|
|
40
|
-
* @returns Promise resolving to Base64 encoded string containing PNG data, or null on failure.
|
|
41
|
-
*/
|
|
42
24
|
captureScreenshot(bounds: ViewInfo | null): Promise<string | null>;
|
|
43
|
-
/**
|
|
44
|
-
* Types a single character into the currently focused text input.
|
|
45
|
-
* If no text input is focused, this is a no-op.
|
|
46
|
-
*/
|
|
47
25
|
typeChar(character: string): Promise<void>;
|
|
48
|
-
/**
|
|
49
|
-
* Blurs (resigns first responder from) the currently focused element.
|
|
50
|
-
* Optionally triggers submitEditing event before blur.
|
|
51
|
-
*/
|
|
52
26
|
blur(options: {
|
|
53
27
|
submitEditing?: boolean;
|
|
54
28
|
}): Promise<void>;
|
|
55
29
|
}
|
|
56
|
-
export type HarnessUIModule = Spec;
|
|
57
30
|
declare const _default: Spec;
|
|
58
31
|
export default _default;
|
|
59
32
|
//# sourceMappingURL=NativeHarnessUI.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NativeHarnessUI.d.ts","sourceRoot":"","sources":["../src/NativeHarnessUI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"NativeHarnessUI.d.ts","sourceRoot":"","sources":["../src/NativeHarnessUI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,QAAS,SAAQ,WAAW;IAC3C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,IAAK,SAAQ,WAAW;IAChC,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC7C,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC1D,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;;AAED,wBAAmE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type HarnessUIModule, type ViewInfo } from './types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__RN_HARNESS_CAPTURE_SCREENSHOT__: (bounds: ViewInfo | null) => Promise<string | null>;
|
|
5
|
+
__RN_HARNESS_SIMULATE_PRESS__: (x: number, y: number) => Promise<void>;
|
|
6
|
+
__RN_HARNESS_TYPE_CHAR__: (character: string) => Promise<void>;
|
|
7
|
+
__RN_HARNESS_BLUR__: (options: {
|
|
8
|
+
submitEditing?: boolean;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
declare const WebHarnessUI: HarnessUIModule;
|
|
13
|
+
export default WebHarnessUI;
|
|
14
|
+
//# sourceMappingURL=WebHarness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebHarness.d.ts","sourceRoot":"","sources":["../src/WebHarness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iCAAiC,EAAE,CACjC,MAAM,EAAE,QAAQ,GAAG,IAAI,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC5B,6BAA6B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE;YAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;SACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB;CACF;AAYD,QAAA,MAAM,YAAY,EAAE,eAkDnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const getElementViewInfo = (element) => {
|
|
2
|
+
const rect = element.getBoundingClientRect();
|
|
3
|
+
return {
|
|
4
|
+
x: rect.left,
|
|
5
|
+
y: rect.top,
|
|
6
|
+
width: rect.width,
|
|
7
|
+
height: rect.height,
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
const WebHarnessUI = {
|
|
11
|
+
simulatePress: async (x, y) => {
|
|
12
|
+
await window.__RN_HARNESS_SIMULATE_PRESS__(x, y);
|
|
13
|
+
},
|
|
14
|
+
queryByTestId: (testId) => {
|
|
15
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
16
|
+
return element ? getElementViewInfo(element) : null;
|
|
17
|
+
},
|
|
18
|
+
queryAllByTestId: (testId) => {
|
|
19
|
+
const elements = document.querySelectorAll(`[data-testid="${testId}"]`);
|
|
20
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
21
|
+
},
|
|
22
|
+
queryByAccessibilityLabel: (label) => {
|
|
23
|
+
const element = document.querySelector(`[aria-label="${label}"]`);
|
|
24
|
+
return element ? getElementViewInfo(element) : null;
|
|
25
|
+
},
|
|
26
|
+
queryAllByAccessibilityLabel: (label) => {
|
|
27
|
+
const elements = document.querySelectorAll(`[aria-label="${label}"]`);
|
|
28
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
29
|
+
},
|
|
30
|
+
captureScreenshot: async (bounds) => {
|
|
31
|
+
return await window.__RN_HARNESS_CAPTURE_SCREENSHOT__(bounds);
|
|
32
|
+
},
|
|
33
|
+
typeChar: async (character) => {
|
|
34
|
+
await window.__RN_HARNESS_TYPE_CHAR__(character);
|
|
35
|
+
},
|
|
36
|
+
blur: async (options) => {
|
|
37
|
+
if (options.submitEditing) {
|
|
38
|
+
// If we want to submit, we must NOT blur before pressing Enter.
|
|
39
|
+
// We let the runner-side bridge handle both Enter and the subsequent blur.
|
|
40
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// If there is a focused element, blur it directly in the DOM first
|
|
44
|
+
// to trigger local events, then call the runner-side bridge.
|
|
45
|
+
if (document.activeElement instanceof HTMLElement ||
|
|
46
|
+
document.activeElement instanceof SVGElement) {
|
|
47
|
+
document.activeElement.blur();
|
|
48
|
+
}
|
|
49
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export default WebHarnessUI;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type HarnessUIModule, type ViewInfo } from './types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__RN_HARNESS_CAPTURE_SCREENSHOT__: (bounds: ViewInfo | null) => Promise<string | null>;
|
|
5
|
+
__RN_HARNESS_SIMULATE_PRESS__: (x: number, y: number) => Promise<void>;
|
|
6
|
+
__RN_HARNESS_TYPE_CHAR__: (character: string) => Promise<void>;
|
|
7
|
+
__RN_HARNESS_BLUR__: (options: {
|
|
8
|
+
submitEditing?: boolean;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
__RN_HARNESS_VIEW_REGISTRY__: Map<string, Element>;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
declare const WebHarnessUI: HarnessUIModule;
|
|
14
|
+
export default WebHarnessUI;
|
|
15
|
+
//# sourceMappingURL=WebHarnessUI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebHarnessUI.d.ts","sourceRoot":"","sources":["../src/WebHarnessUI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iCAAiC,EAAE,CACjC,MAAM,EAAE,QAAQ,GAAG,IAAI,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC5B,6BAA6B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE;YAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;SACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACpB,4BAA4B,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpD;CACF;AA2BD,QAAA,MAAM,YAAY,EAAE,eAqEnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
if (!window.__RN_HARNESS_VIEW_REGISTRY__) {
|
|
2
|
+
window.__RN_HARNESS_VIEW_REGISTRY__ = new Map();
|
|
3
|
+
}
|
|
4
|
+
let nextId = 1;
|
|
5
|
+
const getElementViewInfo = (element) => {
|
|
6
|
+
const rect = element.getBoundingClientRect();
|
|
7
|
+
let nativeId = element.__harnessId;
|
|
8
|
+
if (!nativeId) {
|
|
9
|
+
nativeId = `view_${nextId++}`;
|
|
10
|
+
element.__harnessId = nativeId;
|
|
11
|
+
window.__RN_HARNESS_VIEW_REGISTRY__.set(nativeId, element);
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
x: rect.left,
|
|
15
|
+
y: rect.top,
|
|
16
|
+
width: rect.width,
|
|
17
|
+
height: rect.height,
|
|
18
|
+
nativeId,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const WebHarnessUI = {
|
|
22
|
+
simulatePress: async (nativeId, x, y) => {
|
|
23
|
+
let targetX = x;
|
|
24
|
+
let targetY = y;
|
|
25
|
+
if (nativeId) {
|
|
26
|
+
const element = window.__RN_HARNESS_VIEW_REGISTRY__.get(nativeId);
|
|
27
|
+
if (element) {
|
|
28
|
+
const rect = element.getBoundingClientRect();
|
|
29
|
+
targetX = rect.left + rect.width / 2;
|
|
30
|
+
targetY = rect.top + rect.height / 2;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
await window.__RN_HARNESS_SIMULATE_PRESS__(targetX, targetY);
|
|
34
|
+
},
|
|
35
|
+
queryByTestId: (testId) => {
|
|
36
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
37
|
+
return element ? getElementViewInfo(element) : null;
|
|
38
|
+
},
|
|
39
|
+
queryAllByTestId: (testId) => {
|
|
40
|
+
const elements = document.querySelectorAll(`[data-testid="${testId}"]`);
|
|
41
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
42
|
+
},
|
|
43
|
+
queryByAccessibilityLabel: (label) => {
|
|
44
|
+
const element = document.querySelector(`[aria-label="${label}"]`);
|
|
45
|
+
return element ? getElementViewInfo(element) : null;
|
|
46
|
+
},
|
|
47
|
+
queryAllByAccessibilityLabel: (label) => {
|
|
48
|
+
const elements = document.querySelectorAll(`[aria-label="${label}"]`);
|
|
49
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
50
|
+
},
|
|
51
|
+
captureScreenshot: async (bounds) => {
|
|
52
|
+
let captureBounds = bounds;
|
|
53
|
+
if (bounds?.nativeId && bounds.width === 0 && bounds.height === 0) {
|
|
54
|
+
const element = window.__RN_HARNESS_VIEW_REGISTRY__.get(bounds.nativeId);
|
|
55
|
+
if (element) {
|
|
56
|
+
captureBounds = getElementViewInfo(element);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return await window.__RN_HARNESS_CAPTURE_SCREENSHOT__(captureBounds);
|
|
60
|
+
},
|
|
61
|
+
typeChar: async (character) => {
|
|
62
|
+
await window.__RN_HARNESS_TYPE_CHAR__(character);
|
|
63
|
+
},
|
|
64
|
+
blur: async (options) => {
|
|
65
|
+
if (options.submitEditing) {
|
|
66
|
+
// If we want to submit, we must NOT blur before pressing Enter.
|
|
67
|
+
// We let the runner-side bridge handle both Enter and the subsequent blur.
|
|
68
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
// If there is a focused element, blur it directly in the DOM first
|
|
72
|
+
// to trigger local events, then call the runner-side bridge.
|
|
73
|
+
if (document.activeElement instanceof HTMLElement ||
|
|
74
|
+
document.activeElement instanceof SVGElement) {
|
|
75
|
+
document.activeElement.blur();
|
|
76
|
+
}
|
|
77
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
export default WebHarnessUI;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
import { type ViewInfo } from '../types.js';
|
|
3
|
+
interface Spec extends TurboModule {
|
|
4
|
+
simulatePress(x: number, y: number): Promise<void>;
|
|
5
|
+
queryByTestId(testId: string): ViewInfo | null;
|
|
6
|
+
queryAllByTestId(testId: string): ViewInfo[];
|
|
7
|
+
queryByAccessibilityLabel(label: string): ViewInfo | null;
|
|
8
|
+
queryAllByAccessibilityLabel(label: string): ViewInfo[];
|
|
9
|
+
captureScreenshot(bounds: ViewInfo | null): Promise<string | null>;
|
|
10
|
+
typeChar(character: string): Promise<void>;
|
|
11
|
+
blur(options: {
|
|
12
|
+
submitEditing?: boolean;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: Spec;
|
|
16
|
+
export default _default;
|
|
17
|
+
//# sourceMappingURL=NativeHarness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NativeHarness.d.ts","sourceRoot":"","sources":["../../src/harness/NativeHarness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,UAAU,IAAK,SAAQ,WAAW;IAChC,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC7C,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC1D,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;;AAED,wBAAmE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type HarnessUIModule, type ViewInfo } from '../types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__RN_HARNESS_CAPTURE_SCREENSHOT__: (bounds: ViewInfo | null) => Promise<string | null>;
|
|
5
|
+
__RN_HARNESS_SIMULATE_PRESS__: (x: number, y: number) => Promise<void>;
|
|
6
|
+
__RN_HARNESS_TYPE_CHAR__: (character: string) => Promise<void>;
|
|
7
|
+
__RN_HARNESS_BLUR__: (options: {
|
|
8
|
+
submitEditing?: boolean;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
declare const WebHarnessUI: HarnessUIModule;
|
|
13
|
+
export default WebHarnessUI;
|
|
14
|
+
//# sourceMappingURL=WebHarness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebHarness.d.ts","sourceRoot":"","sources":["../../src/harness/WebHarness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iCAAiC,EAAE,CACjC,MAAM,EAAE,QAAQ,GAAG,IAAI,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC5B,6BAA6B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE;YAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;SACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB;CACF;AAYD,QAAA,MAAM,YAAY,EAAE,eAkDnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const getElementViewInfo = (element) => {
|
|
2
|
+
const rect = element.getBoundingClientRect();
|
|
3
|
+
return {
|
|
4
|
+
x: rect.left,
|
|
5
|
+
y: rect.top,
|
|
6
|
+
width: rect.width,
|
|
7
|
+
height: rect.height,
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
const WebHarnessUI = {
|
|
11
|
+
simulatePress: async (x, y) => {
|
|
12
|
+
await window.__RN_HARNESS_SIMULATE_PRESS__(x, y);
|
|
13
|
+
},
|
|
14
|
+
queryByTestId: (testId) => {
|
|
15
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
16
|
+
return element ? getElementViewInfo(element) : null;
|
|
17
|
+
},
|
|
18
|
+
queryAllByTestId: (testId) => {
|
|
19
|
+
const elements = document.querySelectorAll(`[data-testid="${testId}"]`);
|
|
20
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
21
|
+
},
|
|
22
|
+
queryByAccessibilityLabel: (label) => {
|
|
23
|
+
const element = document.querySelector(`[aria-label="${label}"]`);
|
|
24
|
+
return element ? getElementViewInfo(element) : null;
|
|
25
|
+
},
|
|
26
|
+
queryAllByAccessibilityLabel: (label) => {
|
|
27
|
+
const elements = document.querySelectorAll(`[aria-label="${label}"]`);
|
|
28
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
29
|
+
},
|
|
30
|
+
captureScreenshot: async (bounds) => {
|
|
31
|
+
return await window.__RN_HARNESS_CAPTURE_SCREENSHOT__(bounds);
|
|
32
|
+
},
|
|
33
|
+
typeChar: async (character) => {
|
|
34
|
+
await window.__RN_HARNESS_TYPE_CHAR__(character);
|
|
35
|
+
},
|
|
36
|
+
blur: async (options) => {
|
|
37
|
+
if (options.submitEditing) {
|
|
38
|
+
// If we want to submit, we must NOT blur before pressing Enter.
|
|
39
|
+
// We let the runner-side bridge handle both Enter and the subsequent blur.
|
|
40
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// If there is a focused element, blur it directly in the DOM first
|
|
44
|
+
// to trigger local events, then call the runner-side bridge.
|
|
45
|
+
if (document.activeElement instanceof HTMLElement ||
|
|
46
|
+
document.activeElement instanceof SVGElement) {
|
|
47
|
+
document.activeElement.blur();
|
|
48
|
+
}
|
|
49
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export default WebHarnessUI;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;;AAU9C,wBAA8B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type TurboModule } from 'react-native';
|
|
2
|
+
import { type ViewInfo } from '../types.js';
|
|
3
|
+
interface Spec extends TurboModule {
|
|
4
|
+
simulatePress(x: number, y: number): Promise<void>;
|
|
5
|
+
queryByTestId(testId: string): ViewInfo | null;
|
|
6
|
+
queryAllByTestId(testId: string): ViewInfo[];
|
|
7
|
+
queryByAccessibilityLabel(label: string): ViewInfo | null;
|
|
8
|
+
queryAllByAccessibilityLabel(label: string): ViewInfo[];
|
|
9
|
+
captureScreenshot(bounds: ViewInfo | null): Promise<string | null>;
|
|
10
|
+
typeChar(character: string): Promise<void>;
|
|
11
|
+
blur(options: {
|
|
12
|
+
submitEditing?: boolean;
|
|
13
|
+
}): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare const _default: Spec;
|
|
16
|
+
export default _default;
|
|
17
|
+
//# sourceMappingURL=native-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-harness.d.ts","sourceRoot":"","sources":["../../src/harness/native-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AACrE,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,UAAU,IAAK,SAAQ,WAAW;IAChC,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC/C,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IAC7C,yBAAyB,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAAC;IAC1D,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;IACxD,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnE,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE;QAAE,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;;AAED,wBAAmE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type HarnessUIModule, type ViewInfo } from '../types.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface Window {
|
|
4
|
+
__RN_HARNESS_CAPTURE_SCREENSHOT__: (bounds: ViewInfo | null) => Promise<string | null>;
|
|
5
|
+
__RN_HARNESS_SIMULATE_PRESS__: (x: number, y: number) => Promise<void>;
|
|
6
|
+
__RN_HARNESS_TYPE_CHAR__: (character: string) => Promise<void>;
|
|
7
|
+
__RN_HARNESS_BLUR__: (options: {
|
|
8
|
+
submitEditing?: boolean;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
declare const WebHarnessUI: HarnessUIModule;
|
|
13
|
+
export default WebHarnessUI;
|
|
14
|
+
//# sourceMappingURL=web-harness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-harness.d.ts","sourceRoot":"","sources":["../../src/harness/web-harness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,iCAAiC,EAAE,CACjC,MAAM,EAAE,QAAQ,GAAG,IAAI,KACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;QAC5B,6BAA6B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QACvE,wBAAwB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/D,mBAAmB,EAAE,CAAC,OAAO,EAAE;YAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;SACzB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACrB;CACF;AAYD,QAAA,MAAM,YAAY,EAAE,eAkDnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
const getElementViewInfo = (element) => {
|
|
2
|
+
const rect = element.getBoundingClientRect();
|
|
3
|
+
return {
|
|
4
|
+
x: rect.left,
|
|
5
|
+
y: rect.top,
|
|
6
|
+
width: rect.width,
|
|
7
|
+
height: rect.height,
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
const WebHarnessUI = {
|
|
11
|
+
simulatePress: async (x, y) => {
|
|
12
|
+
await window.__RN_HARNESS_SIMULATE_PRESS__(x, y);
|
|
13
|
+
},
|
|
14
|
+
queryByTestId: (testId) => {
|
|
15
|
+
const element = document.querySelector(`[data-testid="${testId}"]`);
|
|
16
|
+
return element ? getElementViewInfo(element) : null;
|
|
17
|
+
},
|
|
18
|
+
queryAllByTestId: (testId) => {
|
|
19
|
+
const elements = document.querySelectorAll(`[data-testid="${testId}"]`);
|
|
20
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
21
|
+
},
|
|
22
|
+
queryByAccessibilityLabel: (label) => {
|
|
23
|
+
const element = document.querySelector(`[aria-label="${label}"]`);
|
|
24
|
+
return element ? getElementViewInfo(element) : null;
|
|
25
|
+
},
|
|
26
|
+
queryAllByAccessibilityLabel: (label) => {
|
|
27
|
+
const elements = document.querySelectorAll(`[aria-label="${label}"]`);
|
|
28
|
+
return Array.from(elements).map(getElementViewInfo);
|
|
29
|
+
},
|
|
30
|
+
captureScreenshot: async (bounds) => {
|
|
31
|
+
return await window.__RN_HARNESS_CAPTURE_SCREENSHOT__(bounds);
|
|
32
|
+
},
|
|
33
|
+
typeChar: async (character) => {
|
|
34
|
+
await window.__RN_HARNESS_TYPE_CHAR__(character);
|
|
35
|
+
},
|
|
36
|
+
blur: async (options) => {
|
|
37
|
+
if (options.submitEditing) {
|
|
38
|
+
// If we want to submit, we must NOT blur before pressing Enter.
|
|
39
|
+
// We let the runner-side bridge handle both Enter and the subsequent blur.
|
|
40
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
// If there is a focused element, blur it directly in the DOM first
|
|
44
|
+
// to trigger local events, then call the runner-side bridge.
|
|
45
|
+
if (document.activeElement instanceof HTMLElement ||
|
|
46
|
+
document.activeElement instanceof SVGElement) {
|
|
47
|
+
document.activeElement.blur();
|
|
48
|
+
}
|
|
49
|
+
await window.__RN_HARNESS_BLUR__(options);
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export default WebHarnessUI;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"harness.d.ts","sourceRoot":"","sources":["../src/harness.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;;AAU7C,wBAA8B"}
|
package/dist/harness.js
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -9,5 +9,5 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export { screen, type Screen, type ElementReference, type ScreenshotResult, } from './screen.js';
|
|
11
11
|
export { userEvent, type UserEvent } from './userEvent.js';
|
|
12
|
-
export type { ViewInfo } from './
|
|
12
|
+
export type { ViewInfo, BoundingBox } from './types.js';
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,MAAM,EACN,KAAK,MAAM,EACX,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,MAAM,EACN,KAAK,MAAM,EACX,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/screen.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BoundingBox } from './types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Represents an element found on screen
|
|
4
|
-
* This can be used with userEvent
|
|
3
|
+
* Represents an element found on screen.
|
|
4
|
+
* This is an opaque reference that can be used with userEvent or screenshot.
|
|
5
5
|
*/
|
|
6
|
-
export type ElementReference =
|
|
6
|
+
export type ElementReference = {
|
|
7
|
+
readonly nativeId: string;
|
|
8
|
+
};
|
|
7
9
|
/**
|
|
8
10
|
* Screenshot result containing PNG image data.
|
|
9
11
|
*/
|
|
@@ -57,11 +59,11 @@ export type Screen = {
|
|
|
57
59
|
*/
|
|
58
60
|
queryAllByAccessibilityLabel: (label: string) => ElementReference[];
|
|
59
61
|
/**
|
|
60
|
-
* Captures a screenshot of the entire app window
|
|
61
|
-
* @param
|
|
62
|
+
* Captures a screenshot of the entire app window, a specific element, or a region.
|
|
63
|
+
* @param target Optional element reference or bounding box to capture. If not provided, captures the entire window.
|
|
62
64
|
* @returns Promise resolving to ScreenshotResult with PNG data, or null if capture fails.
|
|
63
65
|
*/
|
|
64
|
-
screenshot: (
|
|
66
|
+
screenshot: (target?: ElementReference | BoundingBox) => Promise<ScreenshotResult | null>;
|
|
65
67
|
};
|
|
66
68
|
export declare const screen: Screen;
|
|
67
69
|
//# sourceMappingURL=screen.d.ts.map
|
package/dist/screen.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"screen.d.ts","sourceRoot":"","sources":["../src/screen.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAI7D;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,sDAAsD;IACtD,IAAI,EAAE,UAAU,CAAC;IACjB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,MAAM,GAAG;IACnB;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE5D;;;OAGG;IACH,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEjE;;;OAGG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAE3D;;;OAGG;IACH,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,gBAAgB,EAAE,CAAC;IAEzD;;;OAGG;IACH,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEvE;;;OAGG;IACH,2BAA2B,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE5E;;;OAGG;IACH,yBAAyB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,gBAAgB,GAAG,IAAI,CAAC;IAEtE;;;OAGG;IACH,4BAA4B,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,gBAAgB,EAAE,CAAC;IAEpE;;;;OAIG;IACH,UAAU,EAAE,CACV,MAAM,CAAC,EAAE,gBAAgB,GAAG,WAAW,KACpC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACvC,CAAC;AA8HF,eAAO,MAAM,MAAM,QAAiB,CAAC"}
|