-
Notifications
You must be signed in to change notification settings - Fork 1
/
README.html
261 lines (171 loc) · 10.1 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
<h1>This guide explains how to setup and use LessPainful for iOS.</h1>
<p>After completing this guide you will be able to run
tests locally against the iOS Simulator. You can also
interactively explore your applications using the Ruby
irb console.</p>
<p>Finally you will be able to build your application using special "test
target" and run that on real iOS devices via
<a href="http://www.lesspainful.com/">the LessPainful service</a>.</p>
<p>This guide takes approximately 10-15 minutes to complete.</p>
<h2>Preparing your application.</h2>
<p>To use LessPainful for iOS in your app, you must create a new target
for your app. This target links with a couple of frameworks, as
described here.</p>
<p><em>Note</em>: it is important that you create a separate target as a copy the target you usually use when distributing you app to your users. Don't link with our framework in your production app - this may cause app rejection by Apple since we are using private APIs.</p>
<ul>
<li><p>Duplicate target.</p>
<ul>
<li>Select your project in XCode and select your target for your app.</li>
<li>Right click (two-finger tap) your target and select "Duplicate target"</li>
<li>Select "Duplicate only" (no transition to iPad)</li>
<li>Rename your new target from ".. copy" to "..-LP"</li>
<li>From the menu select Edit Scheme and select manage schemes.</li>
<li>Rename the Scheme from ".. copy" to "..-LP"</li>
</ul></li>
<li><p>Target Build Settings</p>
<ul>
<li>Click on your project and select your new "-LP" target.</li>
<li>Select "Build Settings".</li>
<li>Ensure that "All" and not "Basic" settings are selected in "build settings".</li>
<li>Find "Other Linker Flags" (you can type other link in the search field).</li>
<li>Ensure that "Other linker flags" contains: -all_load -lstdc++</li>
</ul></li>
</ul>
<p>This screenshot is a reference for you build settings.</p>
<p><img src="https://github.com/LessPainful/LessPainful_ios/raw/master/documentation/example-2.png" alt="Build settings" title="Build settings" /></p>
<h3>Linking the test target with Frameworks:</h3>
<p>Open your application project. Expand the Frameworks folder.</p>
<p>You must link with the frameworks listed below. The easiest way is to simply drag the framework located in the <code>lib</code> folder of this project from finder to your Frameworks folder.</p>
<p>Make sure that (i) <code>Copy items into destination group's folder (if needed)</code> is <em>not</em> checked and (ii) only your "-LP " target is checked in <code>Add to targets</code>.</p>
<p>Then make sure the other frameworks mentioned in the screenshot below are added (MapKit is optional).</p>
<p><img src="https://github.com/LessPainful/LessPainful_ios/raw/master/documentation/Frameworks.png" alt="Build settings" title="Linking with frameworks" /></p>
<p><img src="https://github.com/LessPainful/LessPainful_ios/raw/master/documentation/example-4.png" alt="Build settings" title="Options" /></p>
<h3>Try it out!</h3>
<p>Make sure you select your "..-LP" scheme and then run you app on 4.x/5
iPhone simulator.</p>
<p>Verify that you see console output like</p>
<pre><code>2011-11-14 21:20:00.699 Example copy[12296:18203] Creating the server: <HTTPServer: 0x8995850>
2011-11-14 21:20:00:703 Example copy[12296:18203] HTTPServer: Started HTTP server on port 37265
2011-11-14 21:20:01:354 Example copy[12296:1a703] Bonjour Service Published: domain(local.) type(_http._tcp.) name(iLessPainful Server)
</code></pre>
<p>You should now be able to explore your application by installing the client as described below.</p>
<p>If you are having problems don't waste time! Contact <code>[email protected]</code> ASAP :)</p>
<h2>Installing the client.</h2>
<h3>Prerequisites</h3>
<p>You need to have Ruby 1.9.2+ installed, and a recent RubyGems
installation. I use RVM to manage my Ruby installations.</p>
<p>For RVM, see:</p>
<p><a href="http://beginrescueend.com/">http://beginrescueend.com/</a></p>
<p>You also need XCode 4.x. This guide aims at XCode 4.2, but should
also work for XCode versions >= 4.0.</p>
<h3>Installation</h3>
<ul>
<li><p>Make sure ruby and ruby gems is on your path.</p>
<pre><code>krukow:~/examples$ ruby -v
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]
krukow:~/examples$ gem -v
1.8.10
</code></pre></li>
<li><p>Install <code>ilesspainfulclient-cucumber</code> gem version 0.1.3:</p>
<pre><code>krukow:~/examples$ gem install ilesspainfulclient-cucumber
Fetching: ilesspainfulclient-cucumber-0.1.3.gem (100%)
Successfully installed ilesspainfulclient-cucumber-0.1.3
1 gem installed...
</code></pre></li>
</ul>
<h2>Exploring the sample application.</h2>
<p>Download the sample app:</p>
<p>(https://github.com/LessPainful/LessPainful<em>ios</em>sample_app)</p>
<p>You can now explore the sample application:</p>
<p>Let's say you've extracted the sample app file into a working
directory, <code>examples</code>.</p>
<p>Open the XCode project: LPSimpleExample.xcodeproj using XCode.</p>
<p>Select the LPSimpleExample-LP and iPhone Simulator 4.3/5.0 scheme
under schemes.</p>
<p><img src="https://github.com/LessPainful/LessPainful_ios/raw/master/documentation/example-1.png" alt="Selecting the right scheme" title="Selecting Scheme" /></p>
<h3>Run it</h3>
<p>CMD-R to run. Look at the log output and verify that you see:</p>
<pre><code>LPSimpleExample[11298:13703] HTTPServer: Started HTTP server on port 37265
</code></pre>
<p>If that message is there, you're good to go.</p>
<h3>Play with it</h3>
<p>The easy way is to just run one of the irb scripts: <code>irb_ios4.sh</code> or
<code>irb_ios5.sh</code>.</p>
<p>From this console you can explore your application interactively.</p>
<p>You can query, touch, scroll, etc from the irb session.
For example, notice that the sample app has a button: "Login".</p>
<h3>Query</h3>
<p>If you're running the iOS5 iPhone simulator run <code>irb_ios5.sh</code> otherwise: <code>irb_ios4.sh</code>.</p>
<p>Now try this from the irb:</p>
<pre><code>ruby-1.9.2-p290 :003 > query("button")
</code></pre>
<p>You should see something like this:</p>
<pre><code>=> ["<UIRoundedRectButton: 0x6567e00; frame = (109 215; 73 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6567ef0>>"]
</code></pre>
<p>The <code>query</code> function takes a string query as an argument. They query argument is similar to a css selector, for example we can do:</p>
<pre><code>ruby-1.9.2-p290 :009 > query("button label")
=> ["<UIButtonLabel: 0x6624f40; frame = (16 9; 40 19); text = 'Login'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x6645ec0>>"]
</code></pre>
<p>It may also take parameters that are mapped to Objective-C selectors on the found object.</p>
<pre><code>ruby-1.9.2-p290 :010 > query("button label", :text)
=> ["Login"]
</code></pre>
<h3>Touch</h3>
<p>Anything that can be found using query can also be touched.
Try this while you watch the iOS Simulator:</p>
<pre><code>ruby-1.9.2-p290 :011 > touch("button")
</code></pre>
<p>Notice that the button is touched (turns blue), although this button doesn't do anything.</p>
<p>You can also touch the tab bars:</p>
<pre><code>ruby-1.9.2-p290 :016 > touch("tabBarButton index:1")
</code></pre>
<p>The filter: <code>index:1</code> means that it is the second tab-bar button that should be touched.</p>
<h3>Accessibility</h3>
<p>In general UI views are found using accesibility labels. To use those in the simulator they must be enabled.</p>
<ul>
<li>Press the "home-screen" button in the iOS Simulator</li>
<li>Scroll left and open the Settings app insied iOS Simulator</li>
<li>Select <code>General</code> > <code>Accessibility</code> > <code>Accessibility Inspector</code> : On.</li>
<li>Re-run the sample app from XCode.</li>
</ul>
<p>In your irb session try this:</p>
<pre><code>ruby-1.9.2-p290 :025 > query("view marked:'switch'")
</code></pre>
<p>This command finds a view with accessibility label 'switch' (not that we use single quotes to delimit the accessibility label.</p>
<p>In general, many views have accessibility labels that "make sense". For example the tab bar buttons have accessibility labels:</p>
<pre><code>ruby-1.9.2-p290 :029 > touch("tabBarButton marked:'second'")
</code></pre>
<p>To control accessibility labels on your views use:
<code>isAccessibilityElement = YES, and accessibilityLabel = @"somelbl";</code> This can be done in interface builder or programmatically:</p>
<pre><code> (void) viewDidLoad {
[super viewDidLoad];
self.uiswitch.isAccessibilityElement = YES;
self.uiswitch.accessibilityLabel = @"switch";
}
</code></pre>
<h3>Advanced commands</h3>
<p>Surprisingly, these commands are enough to navigate fairly many iOS apps. However, there are many more commands available. Consult the file GherkinAPI.txt for examples of how to use these.</p>
<h3>Writing tests.</h3>
<p>Test are run using Cucumber and written in a special particularly readable language: Gherkin.</p>
<p>In your project directory you can run the following command to setup a test directory.</p>
<pre><code>krukow:~/examples/Example/Example$ ilesspainful-skeleton
...
</code></pre>
<p>This generates a features directory containing a single test that
simply takes a screenshot. Alternatively, you can create the directory
by copying that of the LPSimpleExample.</p>
<p>Try running it with cucumber (<code>OS=ios5</code> if running iOS 5).</p>
<pre><code>krukow:~/examples/Example/Example$ STEP_PAUSE=2 OS=ios4 DEVICE=iphone DEVICE_ENDPOINT=http://localhost:37265 cucumber
Feature:
As an iOS developer
I want to have a sample feature file
So I can begin testing quickly
Scenario: Example steps # features/my_first.feature:6
Given the app is running # ilesspainfulclient-cucumber-0.1.3/lib/ilesspainfulclient-cucumber/lesspainful_steps.rb:6
Then take picture # ilesspainfulclient-cucumber-0.1.3/lib/ilesspainfulclient-cucumber/lesspainful_steps.rb:155
1 scenario (1 passed)
2 steps (2 passed)
0m2.366s
</code></pre>
<p>To see what steps are available and how they are implemented using the Ruby API see the file GherkinAPI.txt</p>
<p>Again, please contact <code>[email protected]</code> with any questions or problems.</p>