rufus 0.1 → 0.3
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.
- checksums.yaml +15 -0
- data/Gemfile.lock +1 -1
- data/LICENSE.txt +21 -0
- data/README.md +63 -78
- data/RufusApp/RufusApp/RUViewController.h +4 -1
- data/RufusApp/RufusApp/RUViewController.m +21 -0
- data/RufusApp/RufusApp/RufusPageViewController.xib +52 -372
- data/RufusApp/RufusApp/en.lproj/RUViewController.xib +75 -525
- data/features/alert.feature +16 -0
- data/features/step_definitions/alert_steps.rb.rb +4 -0
- data/features/step_definitions/view_steps.rb +6 -0
- data/features/support/hooks.rb +3 -0
- data/features/support/screens/home_page.rb +3 -0
- data/features/view.feature +2 -6
- data/lib/rufus/accessors/accessors.rb +4 -0
- data/lib/rufus/accessors/view.rb +4 -0
- data/lib/rufus/driver.rb +74 -18
- data/lib/rufus/drivers/iOS_device.rb +23 -0
- data/lib/rufus/drivers/iOS_simulator.rb +25 -0
- data/rufus.gemspec +3 -2
- data/spec/{driver_spec.rb → drivers_specs/driver_spec.rb} +138 -11
- data/spec/drivers_specs/iOS_device_spec.rb +18 -0
- data/spec/drivers_specs/iOS_simulator_spec.rb +17 -0
- data/spec/view_spec.rb +8 -0
- metadata +16 -13
@@ -0,0 +1,16 @@
|
|
1
|
+
Feature: Interacting with alerts
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on the "HomePage"
|
5
|
+
When I click the view defined "show_alert"
|
6
|
+
|
7
|
+
Scenario: Getting the title of an alert view
|
8
|
+
Then I see the title of the alert defined "alert" is "Rufus Alert"
|
9
|
+
|
10
|
+
Scenario: Selecting action button in alert view
|
11
|
+
And I select the "Ok" button on the alert defined "alert"
|
12
|
+
Then I am on the "RufusPage"
|
13
|
+
|
14
|
+
Scenario: Selecting cancel button in alert view
|
15
|
+
And I select the "Cancel" button on the alert defined "alert"
|
16
|
+
Then I am on the "HomePage"
|
@@ -9,4 +9,10 @@ Then(/^I can find the "([^"]*)" view defined by "([^"]*)"$/) do |which, how|
|
|
9
9
|
end
|
10
10
|
Given(/^I start the driver$/) do
|
11
11
|
puts selenium
|
12
|
+
end
|
13
|
+
Then(/^I am presented with an alert with the title "([^"]*)"$/) do |title|
|
14
|
+
|
15
|
+
end
|
16
|
+
Then(/^I see the title of the alert defined "([^"]*)" is "([^"]*)"$/) do |alert, title|
|
17
|
+
on(HomePage).send("#{alert}_view").title.should == title
|
12
18
|
end
|
data/features/view.feature
CHANGED
@@ -1,10 +1,6 @@
|
|
1
1
|
Feature: Interacting with views
|
2
|
-
There are some things here that we can use
|
3
2
|
|
4
|
-
|
5
|
-
Given I start the driver
|
6
|
-
|
7
|
-
Scenario: Clicking a view
|
3
|
+
Scenario: Clicking a view
|
8
4
|
Given I am on the "HomePage"
|
9
5
|
When I click the view defined "rufus"
|
10
|
-
Then I am on the "RufusPage"
|
6
|
+
Then I am on the "RufusPage"
|
data/lib/rufus/accessors/view.rb
CHANGED
data/lib/rufus/driver.rb
CHANGED
@@ -1,18 +1,15 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'rufus/drivers/iOS_device'
|
3
|
+
require 'rufus/drivers/iOS_simulator'
|
2
4
|
require 'selenium-webdriver'
|
3
5
|
|
4
6
|
module Rufus
|
5
7
|
class Driver
|
6
8
|
|
7
9
|
def initialize
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@url = 'http://127.0.0.1:4723/wd/hub'
|
12
|
-
else
|
13
|
-
@url = @config["appium_url"]
|
14
|
-
end
|
15
|
-
|
10
|
+
raise 'No config.yml found' if !File.exists?('config.yml')
|
11
|
+
@config = YAML.load_file('config.yml')
|
12
|
+
@url = url(@config)
|
16
13
|
end
|
17
14
|
|
18
15
|
def start
|
@@ -98,23 +95,82 @@ module Rufus
|
|
98
95
|
end
|
99
96
|
end
|
100
97
|
|
98
|
+
def find_alert(locator)
|
99
|
+
alert = nil
|
100
|
+
all_elements.each do |element|
|
101
|
+
if is_alert?(element)
|
102
|
+
alert = element if match?(element, locator[:name])
|
103
|
+
end
|
104
|
+
end
|
105
|
+
alert
|
106
|
+
end
|
107
|
+
|
108
|
+
def click_alert(button)
|
109
|
+
if alert_shown?
|
110
|
+
click_alert_button(button)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
def alert_shown?
|
115
|
+
all_elements.each do |element|
|
116
|
+
if is_alert?(element)
|
117
|
+
return true
|
118
|
+
end
|
119
|
+
end
|
120
|
+
false
|
121
|
+
end
|
122
|
+
|
123
|
+
def class_for(element)
|
124
|
+
element.tag_name
|
125
|
+
end
|
126
|
+
|
127
|
+
def match?(element, name)
|
128
|
+
element.attribute(:name).eql? name
|
129
|
+
end
|
130
|
+
|
101
131
|
private
|
132
|
+
|
133
|
+
def url(config)
|
134
|
+
if config["appium_url"].nil? || config["appium_url"].eql?("")
|
135
|
+
'http://127.0.0.1:4723/wd/hub'
|
136
|
+
else
|
137
|
+
config["appium_url"]
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def click_alert_button(button)
|
142
|
+
all_elements.each do |element|
|
143
|
+
element.click if is_table_view_cell?(element) && match?(element, button)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def is_alert?(element)
|
148
|
+
class_for(element).eql?('UIAAlert')
|
149
|
+
end
|
150
|
+
|
151
|
+
def is_table_view_cell?(element)
|
152
|
+
class_for(element).eql?('UIATableCell')
|
153
|
+
end
|
154
|
+
|
155
|
+
def all_elements
|
156
|
+
elements_by_tag('UIAElement')
|
157
|
+
end
|
158
|
+
|
102
159
|
def elements_by_tag(name)
|
103
160
|
driver.find_elements(:tag_name, name)
|
104
161
|
end
|
105
162
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
'app' => @config["app"]
|
113
|
-
}
|
163
|
+
def driver
|
164
|
+
if use_device
|
165
|
+
@selenium ||= Rufus::Drivers::IOS_Device.for(@config,@url)
|
166
|
+
else
|
167
|
+
@selenium ||= Rufus::Drivers::IOS_Simulator.for(@config,@url)
|
168
|
+
end
|
114
169
|
end
|
115
170
|
|
116
|
-
def
|
117
|
-
@
|
171
|
+
def use_device
|
172
|
+
@config["use_physical"] == true
|
118
173
|
end
|
174
|
+
|
119
175
|
end
|
120
176
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'selenium-webdriver'
|
2
|
+
|
3
|
+
module Rufus
|
4
|
+
module Drivers
|
5
|
+
class IOS_Device
|
6
|
+
|
7
|
+
def self.for(config,url)
|
8
|
+
@config = config
|
9
|
+
Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => url)
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.capabilities
|
14
|
+
{
|
15
|
+
'browserName' => @config["browser"],
|
16
|
+
'platform' => @config["platform"],
|
17
|
+
'version' => @config["version"].to_s,
|
18
|
+
'app' => @config["app"]
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'selenium-webdriver'
|
2
|
+
|
3
|
+
module Rufus
|
4
|
+
module Drivers
|
5
|
+
class IOS_Simulator
|
6
|
+
|
7
|
+
def self.for(config,url)
|
8
|
+
@config = config
|
9
|
+
Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => url)
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
private
|
14
|
+
def self.capabilities
|
15
|
+
{
|
16
|
+
'browserName' => @config["browser"],
|
17
|
+
'platform' => @config["platform"],
|
18
|
+
'version' => @config["version"].to_s,
|
19
|
+
'app' => @config["sim_app_path"],
|
20
|
+
'device' => "iPhoneSimulator"
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/rufus.gemspec
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
Gem::Specification.new do |gem|
|
2
2
|
gem.name = "rufus"
|
3
|
-
gem.version = "0.
|
3
|
+
gem.version = "0.3"
|
4
4
|
gem.authors = ["Jeremy Stewart"]
|
5
5
|
gem.email = ["jlstewart379@gmail.com"]
|
6
6
|
gem.description = "Page object wrapper for Appium"
|
7
7
|
gem.summary = "Page object wrapper for Appium"
|
8
8
|
gem.homepage = "https://github.com/jlstewart379/rufus"
|
9
9
|
gem.require_paths = ["lib"]
|
10
|
+
gem.license = 'MIT'
|
10
11
|
gem.files = `git ls-files`.split($/)
|
11
12
|
gem.add_dependency 'page_navigation', '>= 0.7'
|
12
13
|
gem.add_development_dependency 'rspec'
|
13
|
-
end
|
14
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rufus/driver'
|
3
|
+
require 'rufus/drivers/iOS_device'
|
4
|
+
require 'rufus/drivers/iOS_simulator'
|
3
5
|
require 'yaml'
|
4
6
|
|
5
7
|
describe Rufus::Driver do
|
@@ -10,22 +12,33 @@ describe Rufus::Driver do
|
|
10
12
|
|
11
13
|
let(:yaml){double('YAML loader')}
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
context 'config file exists' do
|
16
|
+
before(:each) do
|
17
|
+
File.stub(:exists?).and_return(true)
|
18
|
+
YAML.should_receive(:load_file).with("config.yml").and_return("browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app")
|
19
|
+
@driver = Rufus::Driver.new
|
20
|
+
end
|
21
|
+
it 'loads the config file' do
|
22
|
+
config = @driver.config
|
23
|
+
config["browser_name"].should eq("iOS")
|
24
|
+
config["platform"].should eq("Mac")
|
25
|
+
config["version"].should eq("6.1")
|
26
|
+
config["app"].should eq("/Users/app/path/rufus.app")
|
27
|
+
end
|
18
28
|
end
|
29
|
+
context 'config file does not exists' do
|
19
30
|
|
20
|
-
|
31
|
+
before(:each) do
|
32
|
+
File.stub(:exists?).and_return(false)
|
33
|
+
end
|
21
34
|
|
22
|
-
config
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
config["app"].should eq("/Users/app/path/rufus.app")
|
35
|
+
it 'raises an exception if no config found' do
|
36
|
+
|
37
|
+
expect{Rufus::Driver.new}.to raise_error(RuntimeError, 'No config.yml found')
|
38
|
+
end
|
27
39
|
end
|
28
40
|
|
41
|
+
|
29
42
|
end
|
30
43
|
|
31
44
|
context 'dealing with elements' do
|
@@ -149,4 +162,118 @@ describe Rufus::Driver do
|
|
149
162
|
|
150
163
|
end
|
151
164
|
end
|
165
|
+
|
166
|
+
context 'finding alerts' do
|
167
|
+
|
168
|
+
let(:mock_driver){double('mock selenium driver')}
|
169
|
+
let(:mock_alert){double('mock alert view')}
|
170
|
+
let(:mock_elements){double('mock elements')}
|
171
|
+
let(:mock_element){double('mock element')}
|
172
|
+
|
173
|
+
before(:each) do
|
174
|
+
File.stub(:exists?).and_return(true)
|
175
|
+
YAML.should_receive(:load_file).with("config.yml").and_return("browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app")
|
176
|
+
@driver = Rufus::Driver.new
|
177
|
+
Selenium::WebDriver.should_receive(:for).and_return(mock_driver)
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context 'searching elements' do
|
182
|
+
let(:mock_element){double('mock element')}
|
183
|
+
let(:mock_driver){double('mock selenium driver')}
|
184
|
+
|
185
|
+
before(:each) do
|
186
|
+
File.stub(:exists?).and_return(true)
|
187
|
+
YAML.should_receive(:load_file).with("config.yml").and_return("browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app")
|
188
|
+
@driver = Rufus::Driver.new
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'can find the class for an element' do
|
192
|
+
mock_element.should_receive(:tag_name).and_return('UIAAlert')
|
193
|
+
@driver.class_for(mock_element).should eq('UIAAlert')
|
194
|
+
end
|
195
|
+
|
196
|
+
context 'matching elements by name' do
|
197
|
+
it 'returns true if element matches' do
|
198
|
+
mock_element.should_receive(:attribute).with(:name).and_return('Rufus Alert')
|
199
|
+
@driver.match?(mock_element, 'Rufus Alert').should be_true
|
200
|
+
end
|
201
|
+
it 'returns false if element does not match' do
|
202
|
+
mock_element.should_receive(:attribute).with(:name).and_return('Some other alert title')
|
203
|
+
@driver.match?(mock_element, 'Rufus Alert').should be_false
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'clicking alert view buttons' do
|
208
|
+
|
209
|
+
let(:mock_element){double{'mock element'}}
|
210
|
+
let(:mock_driver){double('mock selenium driver')}
|
211
|
+
|
212
|
+
before(:each) do
|
213
|
+
File.stub(:exists?).and_return(true)
|
214
|
+
YAML.should_receive(:load_file).with("config.yml").and_return("browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app")
|
215
|
+
@driver = Rufus::Driver.new
|
216
|
+
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'can tell if an alert is in the view hierarchy' do
|
220
|
+
mock_element.should_receive(:tag_name).and_return('UIAAlert')
|
221
|
+
@driver.send(:is_alert?, mock_element).should be_true
|
222
|
+
end
|
223
|
+
it 'can tell if an alert is not in the view hierarchy' do
|
224
|
+
mock_element.should_receive(:tag_name).and_return('SomeOtherClass')
|
225
|
+
@driver.send(:is_alert?, mock_element).should be_false
|
226
|
+
end
|
227
|
+
|
228
|
+
it 'can tell if a table cell is in the view hierarchy' do
|
229
|
+
mock_element.should_receive(:tag_name).and_return('UIATableCell')
|
230
|
+
@driver.send(:is_table_view_cell?, mock_element).should be_true
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'can click an alert button' do
|
234
|
+
mock_driver.should_receive(:find_elements).at_least(2).times.with(:tag_name, 'UIAElement').and_return([mock_element])
|
235
|
+
Selenium::WebDriver.should_receive(:for).and_return(mock_driver)
|
236
|
+
mock_element.should_receive(:tag_name).at_least(2).times.and_return('UIAAlert')
|
237
|
+
@driver.click_alert('Ok')
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
context 'starting drivers' do
|
243
|
+
|
244
|
+
let(:yaml){double('YAML loader')}
|
245
|
+
let(:mock_driver){'a mock app driver'}
|
246
|
+
let(:url){'http://127.0.0.1:4723/wd/hub'}
|
247
|
+
|
248
|
+
context 'starting iOS device driver' do
|
249
|
+
before(:each) do
|
250
|
+
File.stub(:exists?).and_return(true)
|
251
|
+
@config = {"browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app", "use_physical" => true}
|
252
|
+
YAML.should_receive(:load_file).with("config.yml").and_return(@config)
|
253
|
+
@driver = Rufus::Driver.new
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'can start the driver for an iOS device' do
|
257
|
+
Rufus::Drivers::IOS_Device.should_receive(:for).with(@config, url).and_return(mock_driver)
|
258
|
+
mock_driver.should_receive(:get)
|
259
|
+
@driver.start
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context 'starting iOS simulator driver' do
|
264
|
+
before(:each) do
|
265
|
+
File.stub(:exists?).and_return(true)
|
266
|
+
@config = {"browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app", "use_physical" => false}
|
267
|
+
YAML.should_receive(:load_file).with("config.yml").and_return(@config)
|
268
|
+
@driver = Rufus::Driver.new
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'can start the driver for an iOS simulator' do
|
272
|
+
Rufus::Drivers::IOS_Simulator.should_receive(:for).with(@config, url).and_return(mock_driver)
|
273
|
+
mock_driver.should_receive(:get)
|
274
|
+
@driver.start
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
152
279
|
end
|