@react-native-windows/automation-commands 0.1.320 → 0.1.321
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.
|
@@ -50,13 +50,13 @@ export type VisualNode = {
|
|
|
50
50
|
Comment?: string;
|
|
51
51
|
Offset?: `${number} ${number} ${number}`;
|
|
52
52
|
Size?: `${number} ${number}`;
|
|
53
|
-
|
|
53
|
+
'Visual Type'?: string;
|
|
54
54
|
__Children?: [VisualNode];
|
|
55
55
|
};
|
|
56
56
|
export type VisualTree = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
'Automation Tree': AutomationNode;
|
|
58
|
+
'Component Tree': ComponentNode;
|
|
59
|
+
'Visual Tree': VisualNode;
|
|
60
60
|
};
|
|
61
61
|
declare global {
|
|
62
62
|
const automationClient: AutomationClient | undefined;
|
|
@@ -21,16 +21,16 @@ async function dumpVisualTree(accessibilityId, opts) {
|
|
|
21
21
|
throw new Error(dumpResponse.message);
|
|
22
22
|
}
|
|
23
23
|
const element = dumpResponse.result;
|
|
24
|
-
if (
|
|
24
|
+
if ('XamlType' in element && (opts === null || opts === void 0 ? void 0 : opts.pruneCollapsed) !== false) {
|
|
25
25
|
pruneCollapsedElements(element);
|
|
26
26
|
}
|
|
27
|
-
if (
|
|
27
|
+
if ('XamlType' in element && (opts === null || opts === void 0 ? void 0 : opts.deterministicOnly) !== false) {
|
|
28
28
|
removeNonDeterministicProps(element);
|
|
29
29
|
}
|
|
30
|
-
if (
|
|
30
|
+
if ('XamlType' in element && (opts === null || opts === void 0 ? void 0 : opts.removeDefaultProps) !== false) {
|
|
31
31
|
removeDefaultProps(element);
|
|
32
32
|
}
|
|
33
|
-
if (!(
|
|
33
|
+
if (!('XamlType' in element) && (opts === null || opts === void 0 ? void 0 : opts.removeGuidsFromImageSources) !== false) {
|
|
34
34
|
removeGuidsFromImageSources(element);
|
|
35
35
|
}
|
|
36
36
|
return element;
|
|
@@ -45,13 +45,16 @@ function removeGuidsFromImageSourcesHelper(node) {
|
|
|
45
45
|
source.Uri = source.Uri.replace(/size=\d{5}/, 'size=<size>');
|
|
46
46
|
}
|
|
47
47
|
else if (source.Uri.startsWith('https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=')) {
|
|
48
|
-
source.Uri =
|
|
48
|
+
source.Uri =
|
|
49
|
+
'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=<some_hash_here>';
|
|
49
50
|
}
|
|
50
51
|
else if (source.Uri.startsWith('https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=')) {
|
|
51
|
-
source.Uri =
|
|
52
|
+
source.Uri =
|
|
53
|
+
'https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=<some_hash_here>';
|
|
52
54
|
}
|
|
53
55
|
else if (source.Uri.startsWith('https://www.facebook.com/ads/pics/successstories.png?hash=')) {
|
|
54
|
-
source.Uri =
|
|
56
|
+
source.Uri =
|
|
57
|
+
'https://www.facebook.com/ads/pics/successstories.png?hash=<some_hash_here>';
|
|
55
58
|
}
|
|
56
59
|
else {
|
|
57
60
|
// When getting files from a prebuilt bundle the uri is going to include a local path, which would make snapshots inconsistent,
|
|
@@ -59,7 +62,9 @@ function removeGuidsFromImageSourcesHelper(node) {
|
|
|
59
62
|
// file://E:\\repos\\react-native-windows\\packages\\e2e-test-app-fabric\\windows\\RNTesterApp-Fabric.Package\\bin\\x64\\Release\\AppX\\RNTesterApp-Fabric\\Bundle\\@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png
|
|
60
63
|
// becomes
|
|
61
64
|
// <localOrBundlerUri>@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png
|
|
62
|
-
const packagesPath = require('path')
|
|
65
|
+
const packagesPath = require('path')
|
|
66
|
+
.resolve(__dirname, '../../..')
|
|
67
|
+
.replace(/\\/g, '\\\\');
|
|
63
68
|
source.Uri = source.Uri.replace(new RegExp(`file://${packagesPath}.*\\\\Bundle\\\\assets/_+`), '<localOrBundlerUri>');
|
|
64
69
|
// When loading the bundle from metro local paths will be replaced with paths to localhost, which will not align with snapshots made with prebuilt bundles.
|
|
65
70
|
// This logic replaces the localhost uri, with the same uri that we would have gotten from a prebuild bundle. This makes it easier to debug without breaking snapshots
|
|
@@ -77,7 +82,7 @@ function removeGuidsFromImageSourcesHelper(node) {
|
|
|
77
82
|
}
|
|
78
83
|
}
|
|
79
84
|
function removeGuidsFromImageSources(visualTree) {
|
|
80
|
-
removeGuidsFromImageSourcesHelper(visualTree[
|
|
85
|
+
removeGuidsFromImageSourcesHelper(visualTree['Component Tree']);
|
|
81
86
|
}
|
|
82
87
|
/**
|
|
83
88
|
* Removes trees of XAML that are not visible.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dumpVisualTree.js","sourceRoot":"","sources":["../src/dumpVisualTree.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\nimport {AutomationClient} from '@react-native-windows/automation-channel';\n\n/**\n * Schema of tree dumped node\n */\nexport type UIElement = {\n XamlType: string;\n Foreground?: string | null;\n Background?: string | null;\n Padding?: string | null;\n Margin?: string | null;\n RenderSize?: number[] | null;\n Visibility?: 'Collapsed' | 'Visible' | null;\n CornerRadius?: string | null;\n BorderThickness?: string | null;\n Width?: number | null;\n Height?: number | null;\n BorderBrush?: string | null;\n VerticalAlignment?: string | null;\n HorizontalAlignment?: string | null;\n Clip?: string | null;\n FlowDirection?: string | null;\n Name?: string | null;\n Text?: string | null;\n children?: UIElement[];\n [index: string]: unknown;\n};\n\nexport type AutomationNode = {\n AutomationId?: string,\n ControlType?: number,\n LocalizedControlType?: string,\n __Children?: [AutomationNode],\n}\n\nexport type ComponentNode = {\n Type: string,\n _Props?: {\n TestId?: string,\n Sources?: [{Uri?: string}],\n },\n __Children?: [ComponentNode],\n}\n\nexport type VisualNode = {\n Comment?: string,\n Offset?: `${number} ${number} ${number}`,\n Size?: `${number} ${number}`,\n \"Visual Type\"?: string,\n __Children?: [VisualNode]\n}\n\nexport type VisualTree = {\n \"Automation Tree\": AutomationNode,\n \"Component Tree\": ComponentNode,\n \"Visual Tree\": VisualNode,\n}\n\ndeclare global {\n const automationClient: AutomationClient | undefined;\n}\n\n/**\n * Dump a section of the native visual tree.\n */\nexport default async function dumpVisualTree(\n accessibilityId: string,\n opts?: {\n pruneCollapsed?: boolean;\n deterministicOnly?: boolean;\n removeDefaultProps?: boolean;\n removeGuidsFromImageSources?: boolean;\n additionalProperties?: string[];\n },\n): Promise<UIElement | VisualTree> {\n if (!automationClient) {\n throw new Error('RPC client is not enabled');\n }\n\n const dumpResponse = await automationClient.invoke('DumpVisualTree', {\n accessibilityId,\n ...opts,\n });\n\n if (dumpResponse.type === 'error') {\n throw new Error(dumpResponse.message);\n }\n\n const element: UIElement | VisualTree = dumpResponse.result;\n\n if (\"XamlType\" in element && opts?.pruneCollapsed !== false) {\n pruneCollapsedElements(element);\n }\n\n if (\"XamlType\" in element && opts?.deterministicOnly !== false) {\n removeNonDeterministicProps(element);\n }\n\n if (\"XamlType\" in element && opts?.removeDefaultProps !== false) {\n removeDefaultProps(element);\n }\n\n if (!(\"XamlType\" in element) && opts?.removeGuidsFromImageSources !== false) {\n removeGuidsFromImageSources(element);\n }\n \n return element;\n}\n\nfunction removeGuidsFromImageSourcesHelper(node: ComponentNode) {\n if (node._Props && node._Props.Sources) {\n node._Props.Sources.forEach((source : any) => {\n if (source.Uri) {\n if (source.Uri.startsWith('blob:')) {\n source.Uri = source.Uri.replace(/blob:[a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+/, 'blob:<some_guid_here>');\n source.Uri = source.Uri.replace(/size=\\d{5}/, 'size=<size>');\n } else if (source.Uri.startsWith('https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=')) {\n source.Uri = 'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=<some_hash_here>';\n } else if (source.Uri.startsWith('https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=')) {\n source.Uri = 'https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=<some_hash_here>';\n } else if (source.Uri.startsWith('https://www.facebook.com/ads/pics/successstories.png?hash=')) {\n source.Uri = 'https://www.facebook.com/ads/pics/successstories.png?hash=<some_hash_here>';\n } else {\n\n // When getting files from a prebuilt bundle the uri is going to include a local path, which would make snapshots inconsistent,\n // This logic replaces the local path so that we get consistent results.\n // file://E:\\\\repos\\\\react-native-windows\\\\packages\\\\e2e-test-app-fabric\\\\windows\\\\RNTesterApp-Fabric.Package\\\\bin\\\\x64\\\\Release\\\\AppX\\\\RNTesterApp-Fabric\\\\Bundle\\\\@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\n // becomes\n // <localOrBundlerUri>@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\n const packagesPath = require('path').resolve(__dirname, '../../..').replace(/\\\\/g, '\\\\\\\\');\n source.Uri = source.Uri.replace(new RegExp(`file://${packagesPath}.*\\\\\\\\Bundle\\\\\\\\assets/_+`), '<localOrBundlerUri>');\n\n // When loading the bundle from metro local paths will be replaced with paths to localhost, which will not align with snapshots made with prebuilt bundles.\n // This logic replaces the localhost uri, with the same uri that we would have gotten from a prebuild bundle. This makes it easier to debug without breaking snapshots\n // http://localhost:8081/assets/@@/@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png?platform=windows&hash=c6f5aec4d9e0aa47c0887e4266796224\n // becomes\n // \"<localOrBundlerUri>@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\"\n source.Uri = source.Uri.replace(/http:\\/\\/localhost:8081\\/assets\\/(@@\\/)+/, '<localOrBundlerUri>');\n source.Uri = source.Uri.replace(/\\?platform=windows&hash=[^=]$/, '');\n }\n }\n });\n }\n if (node.__Children) {\n node.__Children.forEach((child : any) => removeGuidsFromImageSourcesHelper(child));\n }\n}\n\nfunction removeGuidsFromImageSources(visualTree: VisualTree) {\n removeGuidsFromImageSourcesHelper(visualTree[\"Component Tree\"]);\n}\n\n/**\n * Removes trees of XAML that are not visible.\n */\nfunction pruneCollapsedElements(element: UIElement) {\n if (!element.children) {\n return;\n }\n\n element.children = element.children.filter(\n child => child.Visibility !== 'Collapsed',\n );\n\n element.children.forEach(pruneCollapsedElements);\n}\n\n/**\n * Removes trees of properties that are not deterministic\n */\nfunction removeNonDeterministicProps(element: UIElement) {\n if (element.RenderSize) {\n // RenderSize is subject to rounding, etc and should mostly be derived from\n // other deterministic properties in the tree.\n delete element.RenderSize;\n }\n\n if (element.children) {\n element.children.forEach(removeNonDeterministicProps);\n }\n}\n\n/**\n * Removes noise from snapshot by removing properties with the default value\n */\nfunction removeDefaultProps(element: UIElement) {\n const defaultValues: [string, unknown][] = [['Tooltip', null]];\n\n defaultValues.forEach(([propname, defaultValue]) => {\n if (element[propname] === defaultValue) {\n delete element[propname];\n }\n });\n\n if (element.children) {\n element.children.forEach(removeDefaultProps);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"dumpVisualTree.js","sourceRoot":"","sources":["../src/dumpVisualTree.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Copyright (c) Microsoft Corporation.\n * Licensed under the MIT License.\n *\n * @format\n */\n\nimport {AutomationClient} from '@react-native-windows/automation-channel';\n\n/**\n * Schema of tree dumped node\n */\nexport type UIElement = {\n XamlType: string;\n Foreground?: string | null;\n Background?: string | null;\n Padding?: string | null;\n Margin?: string | null;\n RenderSize?: number[] | null;\n Visibility?: 'Collapsed' | 'Visible' | null;\n CornerRadius?: string | null;\n BorderThickness?: string | null;\n Width?: number | null;\n Height?: number | null;\n BorderBrush?: string | null;\n VerticalAlignment?: string | null;\n HorizontalAlignment?: string | null;\n Clip?: string | null;\n FlowDirection?: string | null;\n Name?: string | null;\n Text?: string | null;\n children?: UIElement[];\n [index: string]: unknown;\n};\n\nexport type AutomationNode = {\n AutomationId?: string;\n ControlType?: number;\n LocalizedControlType?: string;\n __Children?: [AutomationNode];\n};\n\nexport type ComponentNode = {\n Type: string;\n _Props?: {\n TestId?: string;\n Sources?: [{Uri?: string}];\n };\n __Children?: [ComponentNode];\n};\n\nexport type VisualNode = {\n Comment?: string;\n Offset?: `${number} ${number} ${number}`;\n Size?: `${number} ${number}`;\n 'Visual Type'?: string;\n __Children?: [VisualNode];\n};\n\nexport type VisualTree = {\n 'Automation Tree': AutomationNode;\n 'Component Tree': ComponentNode;\n 'Visual Tree': VisualNode;\n};\n\ndeclare global {\n const automationClient: AutomationClient | undefined;\n}\n\n/**\n * Dump a section of the native visual tree.\n */\nexport default async function dumpVisualTree(\n accessibilityId: string,\n opts?: {\n pruneCollapsed?: boolean;\n deterministicOnly?: boolean;\n removeDefaultProps?: boolean;\n removeGuidsFromImageSources?: boolean;\n additionalProperties?: string[];\n },\n): Promise<UIElement | VisualTree> {\n if (!automationClient) {\n throw new Error('RPC client is not enabled');\n }\n\n const dumpResponse = await automationClient.invoke('DumpVisualTree', {\n accessibilityId,\n ...opts,\n });\n\n if (dumpResponse.type === 'error') {\n throw new Error(dumpResponse.message);\n }\n\n const element: UIElement | VisualTree = dumpResponse.result;\n\n if ('XamlType' in element && opts?.pruneCollapsed !== false) {\n pruneCollapsedElements(element);\n }\n\n if ('XamlType' in element && opts?.deterministicOnly !== false) {\n removeNonDeterministicProps(element);\n }\n\n if ('XamlType' in element && opts?.removeDefaultProps !== false) {\n removeDefaultProps(element);\n }\n\n if (!('XamlType' in element) && opts?.removeGuidsFromImageSources !== false) {\n removeGuidsFromImageSources(element);\n }\n\n return element;\n}\n\nfunction removeGuidsFromImageSourcesHelper(node: ComponentNode) {\n if (node._Props && node._Props.Sources) {\n node._Props.Sources.forEach((source: any) => {\n if (source.Uri) {\n if (source.Uri.startsWith('blob:')) {\n source.Uri = source.Uri.replace(\n /blob:[a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+-[a-f0-9]+/,\n 'blob:<some_guid_here>',\n );\n source.Uri = source.Uri.replace(/size=\\d{5}/, 'size=<size>');\n } else if (\n source.Uri.startsWith(\n 'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=',\n )\n ) {\n source.Uri =\n 'https://www.facebook.com/assets/fb_lite_messaging/E2EE-settings@3x.png?r=1&t=<some_hash_here>';\n } else if (\n source.Uri.startsWith(\n 'https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=',\n )\n ) {\n source.Uri =\n 'https://www.facebook.com/ar_effect/external_textures/648609739826677.png?hash=<some_hash_here>';\n } else if (\n source.Uri.startsWith(\n 'https://www.facebook.com/ads/pics/successstories.png?hash=',\n )\n ) {\n source.Uri =\n 'https://www.facebook.com/ads/pics/successstories.png?hash=<some_hash_here>';\n } else {\n // When getting files from a prebuilt bundle the uri is going to include a local path, which would make snapshots inconsistent,\n // This logic replaces the local path so that we get consistent results.\n // file://E:\\\\repos\\\\react-native-windows\\\\packages\\\\e2e-test-app-fabric\\\\windows\\\\RNTesterApp-Fabric.Package\\\\bin\\\\x64\\\\Release\\\\AppX\\\\RNTesterApp-Fabric\\\\Bundle\\\\@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\n // becomes\n // <localOrBundlerUri>@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\n const packagesPath = require('path')\n .resolve(__dirname, '../../..')\n .replace(/\\\\/g, '\\\\\\\\');\n source.Uri = source.Uri.replace(\n new RegExp(`file://${packagesPath}.*\\\\\\\\Bundle\\\\\\\\assets/_+`),\n '<localOrBundlerUri>',\n );\n\n // When loading the bundle from metro local paths will be replaced with paths to localhost, which will not align with snapshots made with prebuilt bundles.\n // This logic replaces the localhost uri, with the same uri that we would have gotten from a prebuild bundle. This makes it easier to debug without breaking snapshots\n // http://localhost:8081/assets/@@/@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png?platform=windows&hash=c6f5aec4d9e0aa47c0887e4266796224\n // becomes\n // \"<localOrBundlerUri>@react-native-windows/tester/js/assets/uie_thumb_normal@2x.png\"\n source.Uri = source.Uri.replace(\n /http:\\/\\/localhost:8081\\/assets\\/(@@\\/)+/,\n '<localOrBundlerUri>',\n );\n source.Uri = source.Uri.replace(/\\?platform=windows&hash=[^=]$/, '');\n }\n }\n });\n }\n if (node.__Children) {\n node.__Children.forEach((child: any) =>\n removeGuidsFromImageSourcesHelper(child),\n );\n }\n}\n\nfunction removeGuidsFromImageSources(visualTree: VisualTree) {\n removeGuidsFromImageSourcesHelper(visualTree['Component Tree']);\n}\n\n/**\n * Removes trees of XAML that are not visible.\n */\nfunction pruneCollapsedElements(element: UIElement) {\n if (!element.children) {\n return;\n }\n\n element.children = element.children.filter(\n child => child.Visibility !== 'Collapsed',\n );\n\n element.children.forEach(pruneCollapsedElements);\n}\n\n/**\n * Removes trees of properties that are not deterministic\n */\nfunction removeNonDeterministicProps(element: UIElement) {\n if (element.RenderSize) {\n // RenderSize is subject to rounding, etc and should mostly be derived from\n // other deterministic properties in the tree.\n delete element.RenderSize;\n }\n\n if (element.children) {\n element.children.forEach(removeNonDeterministicProps);\n }\n}\n\n/**\n * Removes noise from snapshot by removing properties with the default value\n */\nfunction removeDefaultProps(element: UIElement) {\n const defaultValues: [string, unknown][] = [['Tooltip', null]];\n\n defaultValues.forEach(([propname, defaultValue]) => {\n if (element[propname] === defaultValue) {\n delete element[propname];\n }\n });\n\n if (element.children) {\n element.children.forEach(removeDefaultProps);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-native-windows/automation-commands",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.321",
|
|
4
4
|
"description": "Allows controlling your react-native-windows application",
|
|
5
5
|
"main": "lib-commonjs/index.js",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
"watch": "rnw-scripts watch"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@react-native-windows/automation-channel": "^0.12.
|
|
22
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
23
|
-
"@typescript-eslint/parser": "^
|
|
21
|
+
"@react-native-windows/automation-channel": "^0.12.218",
|
|
22
|
+
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
|
23
|
+
"@typescript-eslint/parser": "^7.1.1"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@jest/types": "^29.2.1",
|
|
27
|
-
"@rnw-scripts/eslint-config": "1.2.
|
|
28
|
-
"@rnw-scripts/just-task": "2.3.
|
|
27
|
+
"@rnw-scripts/eslint-config": "1.2.30",
|
|
28
|
+
"@rnw-scripts/just-task": "2.3.47",
|
|
29
29
|
"@rnw-scripts/ts-config": "2.0.5",
|
|
30
30
|
"@types/jest": "^29.2.2",
|
|
31
31
|
"@types/node": "^18.0.0",
|