Skip to content

Commit 05bbae0

Browse files
Recover lost formatting (beware copying and pasting entire file contents in Xcode)
README.md
1 parent c1a00a7 commit 05bbae0

File tree

1 file changed

+67
-68
lines changed

1 file changed

+67
-68
lines changed

README.md

+67-68
Original file line numberDiff line numberDiff line change
@@ -29,120 +29,119 @@ Mac OS X does not allow an application to use the Accessibility API without perm
2929

3030
## New Features For Scripters (as of November 2016)
3131

32-
You can see the new features in the "calculator.py" example script.
33-
The "utilities.py" script contains a neato method to select menu items very reliably using native mouse events.
32+
You can see the new features in the calculator.py example script.
3433

3534
### Native Events
3635
AppiumForMac will generate OS X native keyboard and mouse events using Action syntax. Several examples are in /examples/calculator.py.
3736

3837
#### click
39-
ActionChains(driver).click(element).perform()
40-
41-
ActionChains(driver).click().perform()
38+
ActionChains(driver).click(element).perform()
39+
40+
ActionChains(driver).click().perform()
4241

4342
#### move to
44-
ActionChains(driver).move_to_element(element).perform()
43+
ActionChains(driver).move_to_element(element).perform()
4544

4645
#### send keys
47-
ActionChains(driver).send_keys('A string to type.').perform()
46+
ActionChains(driver).send_keys('A string to type.').perform()
4847

4948

5049
### Absolute AXPath
5150
This is a huge performance improvement, although it requires cooperation from the scripter. Instead of using a partial XPath, use a simple absolute AXPath. This is based on the OS X accessibility structure, which you can view in Accessibility Inspector. The paths are "simple" because only a limited subset of XPath syntax is supported. Locating objects by XPath is highly optimized when using absolute AXPaths.
5251

5352
A simple absolute AXPath:
5453

55-
* is a string with valid XPath syntax
56-
* uses OS X Accessibility constants, e.g. AXMenuItem or AXTitle
57-
* can specify any accessible element on the screen, in any application or window, any time
58-
* begins with /AXApplication, and contains at least one other node
59-
* does not contain "//", or use a wildcard, or specify multiple paths using |
60-
* uses predicates with a single integer for an index, or, one or more string comparisons using = and !=
61-
* may use boolean operators "and" or "or" (mutually exclusive) in between multiple comparisons
62-
* there must be a leading and trailing space, e.g. " and "
63-
* does not use predicate strings containing braces [] or parens ()
64-
* uses single quotes, not double quotes for attribute strings
65-
* does not contain spaces, except within attribute string values (optional), and, surrounding boolean operators (required)
66-
54+
* is a string with valid XPath syntax
55+
* uses OS X Accessibility constants, e.g. AXMenuItem or AXTitle
56+
* can specify any accessible element on the screen, in any application or window, any time
57+
* begins with /AXApplication, and contains at least one other node
58+
* does not contain "//", or use a wildcard, or specify multiple paths using |
59+
* uses predicates with a single integer for an index, or, one or more string comparisons using = and !=
60+
* may use boolean operators "and" or "or" (mutually exclusive) in between multiple comparisons
61+
* there must be a leading and trailing space, e.g. " and "
62+
* does not use predicate strings containing braces [] or parens ()
63+
* uses single quotes, not double quotes for attribute strings
64+
* does not contain spaces, except within attribute string values (optional), and, surrounding boolean operators (required)
65+
6766
Notes:
6867

69-
* The node "/AXApplication" without a predicate denotes the frontmost application.
70-
* Attribute values nil and '' (empty string) are defined to be equivalent.
71-
* For example, if a menu item does not have a mark character (i.e. the value is nil) then @AXMenuItemMarkChar=='' is true.
72-
* Index predicates are valid for nodes with the same AXRole. For example, AXGroup[0] refers to the first AXGroup, not simply the first child element.
68+
* The node "/AXApplication" without a predicate denotes the frontmost application.
69+
* Attribute values nil and '' (empty string) are defined to be equivalent.
70+
* For example, if a menu item does not have a mark character (i.e. the value is nil) then @AXMenuItemMarkChar=='' is true.
71+
* Index predicates are valid for nodes with the same AXRole. For example, AXGroup[0] refers to the first AXGroup, not simply the first child element.
7372

7473
Good examples:
7574

76-
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription='clear']"
77-
78-
"/AXApplication[@AXTitle='Calculator']/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Scientific']"
79-
80-
"/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and @AXMenuItemMarkChar!='']"
81-
75+
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription='clear']"
76+
77+
"/AXApplication[@AXTitle='Calculator']/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Scientific']"
78+
79+
"/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and @AXMenuItemMarkChar!='']"
80+
8281

8382
Bad examples:
8483

85-
"//AXButton[@AXDescription='clear']"
86-
(does not begin with /AXApplication, and contains //)
84+
"//AXButton[@AXDescription='clear']"
85+
(does not begin with /AXApplication, and contains //)
86+
87+
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXButton[@AXDescription='clear']"
88+
(not an absolute path: missing AXGroup)
89+
90+
"/AXApplication[@AXTitle="Calculator"]/AXWindow[0]"
91+
(a predicate string uses double quotes)
8792

88-
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXButton[@AXDescription='clear']"
89-
(not an absolute path: missing AXGroup)
93+
"/AXApplication[@AXTitle='Calculator']"
94+
(path does not contain at least two nodes)
9095

91-
"/AXApplication[@AXTitle="Calculator"]/AXWindow[0]"
92-
(a predicate string uses double quotes)
96+
"/AXApplication[@AXTitle='Calculator']/AXMenuBar/AXMenuBarItems/AXMenuBarItem[@AXTitle='(Window)']"
97+
(a predicate string contains forbidden characters)
9398

94-
"/AXApplication[@AXTitle='Calculator']"
95-
(path does not contain at least two nodes)
99+
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription ='clear']"
100+
(a predicate contain a space before the =)
96101

97-
"/AXApplication[@AXTitle='Calculator']/AXMenuBar/AXMenuBarItems/AXMenuBarItem[@AXTitle='(Window)']"
98-
(a predicate string contains forbidden characters)
102+
"/AXApplication[@AXTitle='Calculator']/AXWindow[position()>3]/AXGroup[1]/AXButton[@AXDescription='clear']"
103+
(a predicate is not a simple string or integer, and specifies more than one node)
99104

100-
"/AXApplication[@AXTitle='Calculator']/AXWindow[0]/AXGroup[1]/AXButton[@AXDescription ='clear']"
101-
(a predicate contain a space before the =)
105+
"/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and@AXMenuItemMarkChar!='']"
106+
(leading and trailing spaces required for the boolean operator)
102107

103-
"/AXApplication[@AXTitle='Calculator']/AXWindow[position()>3]/AXGroup[1]/AXButton[@AXDescription='clear']"
104-
(a predicate is not a simple string or integer, and specifies more than one node)
105-
106-
"/AXApplication/AXMenuBarItems/AXMenuBarItem[@AXTitle='View']/AXMenu/AXMenuItem[@AXTitle='Basic' and@AXMenuItemMarkChar!='']"
107-
(leading and trailing spaces required for the boolean operator)
108-
109-
"/AXApplication[@AXTitle="Calculator"]/AXWindow[0]/AXButton[@AXDescription='clear' and @AXEnabled='YES' or @AXDescription='clear all']"
110-
(predicate uses multiple kinds of boolean operators; use one or more 'and', or, use one or more 'or', but not both)
108+
"/AXApplication[@AXTitle="Calculator"]/AXWindow[0]/AXButton[@AXDescription='clear' and @AXEnabled='YES' or @AXDescription='clear all']"
109+
(predicate uses multiple kinds of boolean operators; use one or more 'and', or, use one or more 'or', but not both)
111110

112111

113112
### Implicit Timeouts
114113
AppumForMac supports standard implicit timeouts when finding an element. Pass a milliseconds value as a desired capability. The default is 0.0 seconds, that is, there will be only one attempt.
115114

116-
For example, 'implicitTimeout':20000 will retry for 20 seconds before returning an error.
115+
For example, 'implicitTimeout':20000 will retry for 20 seconds before returning an error.
117116

118117
### Loop Delay
119118
During an implicit timeout to find an element, you can specify how long to wait between attempts. Pass a milliseconds value as a desired capability. The default is 1.0 seconds. The loop delay occurs _after_ each attempt, so if the element is found on the first attempt, there will be no delay. The total waiting time will not exceed implicitTimeout, regardless of the loopDelay value.
120119

121-
For example, 'loopDelay':1000 will wait 1 second between each attempt.
120+
For example, 'loopDelay':1000 will wait 1 second between each attempt.
122121

123122
### Command Delay
124123
This provides a simple way to slow down a script if needed, e.g. for debugging. It specifies an arbitrary delay _before_ each command. Pass a milliseconds value as a desired capability. The default is 0.0 seconds so your script runs at full speed!
125124

126-
For example, 'commandDelay':2500 will wait 2.5 seconds before executing each command.
125+
For example, 'commandDelay':2500 will wait 2.5 seconds before executing each command.
127126

128127
### Mouse Move Speed
129128
For native mouse events, this determines how fast the mouse moves across the screen, in pixels per second. Several examples are in /examples/calculator.py.
130129

131-
For example, 'mouseMoveSpeed':100 will move about 2x faster than 'mouseMoveSpeed':50.
132-
133-
Be careful setting mouse speed too high, or your application may not detect the mouse-over for some elements.
130+
For example, 'mouseMoveSpeed':100 will move about 2x faster than 'mouseMoveSpeed':50.
131+
132+
Be careful setting mouse speed too high, or your application may not detect the mouse-over for some elements.
134133

135134
### Session Diagnostics Directories
136135
AppiumForMac can create a directory for all diagnostics, named "AppiumDiagnostics". This will contain other items such as per-session diagnostic directories. The per-session directory stores items like screen shots. Pass a string file path in as a desiredCapability. If you do not pass any path, then there will be no diagnostic records, such as screen shots.
137136

138-
For example, "diagnosticsDirectoryLocation":"~/Documents/" will add a directory named AppiumDiagnostics to your Documents folder.
137+
For example, "diagnosticsDirectoryLocation":"~/Documents/" will add a directory named AppiumDiagnostics to your Documents folder.
139138

140139
### Screen Shots
141140
AppiumForMac can take a screen shot automatically whenever an element is not found before the implicit timeout. These can be used to analyze errors. The screen shots are stored in the per-session diagnostic directory. Pass in a non-zero number as a desiredCapability to enable the feature. If you pass in zero, or do not provide this desiredCapability, then there will be no screen shots.
142141

143-
For example, "screenShotOnError":1 will enable automatic screen shots when find element fails.
144-
145-
For example, "screenShotOnError":0 will disable screen shots.
142+
For example, "screenShotOnError":1 will enable automatic screen shots when find element fails.
143+
144+
For example, "screenShotOnError":0 will disable screen shots.
146145

147146

148147

@@ -170,19 +169,19 @@ There is no more need to update the giant httpResponseForMethod:URI: method. The
170169
1. Your handler is automatically called whenever AppiumForMac receives its matching wire protocol request.
171170
1. Your handler code block receives three arguments: session, commandParams, and status.
172171

173-
* session: The AfMSessionController instance created when your script created a new web driver. This provides access to the machine and other applications.
174-
* commandParams: A dictionary containing http request parameters. It includes elements referenced from the URL path, and all POST json objects. The "elementObject" dictionary key retrieves a validated element.
175-
* status: A pointer to an int to write back a status code to your caller. This is not a substitute for your handler return value.
176-
172+
* session: The AfMSessionController instance created when your script created a new web driver. This provides access to the machine and other applications.
173+
* commandParams: A dictionary containing http request parameters. It includes elements referenced from the URL path, and all POST json objects. The "elementObject" dictionary key retrieves a validated element.
174+
* status: A pointer to an int to write back a status code to your caller. This is not a substitute for your handler return value.
175+
177176
1. Your code block should return an object created with [AppiumMacHTTPJSONResponse responseWithJson:status:session:] or [AppiumMacHTTPJSONResponse responseWithJsonError:session:].
178177
1. If your code block returns responseWithJsonError:kAfMStatusCodeNoSuchElement, then the block (not the entire handler method) will be automatically called again, within the constraints of implicitTimeout, and loopDelay.
179178
1. However, if your block returns nil, then a kAfMStatusCodeNoSuchElement error is _immediately_ returned to the scripter, even if implicitTimeout has not yet been reached.
180179
1. If you expect thrown exceptions, add them to your own code block. Execution exceptions which you do not catch are logged but not re-thrown.
181180
1. AppiumForMac automatically returns common errors to the scripter so you don't need to worry about them:
182181

183-
* There is no session with the sessionId specified in the request path.
184-
* The specified element is invalid.
185-
* Your handler returned kAfMStatusCodeNoSuchElement, but the implicitTimeout period was exceeded.
186-
* Your handler doesn't exist (or you named it incorrectly).
187-
* Your handler returned a nil value.
182+
* There is no session with the sessionId specified in the request path.
183+
* The specified element is invalid.
184+
* Your handler returned kAfMStatusCodeNoSuchElement, but the implicitTimeout period was exceeded.
185+
* Your handler doesn't exist (or you named it incorrectly).
186+
* Your handler returned a nil value.
188187

0 commit comments

Comments
 (0)