rufus 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +3 -0
- data/RufusApp/RufusApp/EnabledPageViewController.h +2 -0
- data/RufusApp/RufusApp/EnabledPageViewController.m +10 -14
- data/RufusApp/RufusApp/EnabledPageViewController.xib +26 -4
- data/RufusApp/RufusApp/RUViewController.h +2 -0
- data/RufusApp/RufusApp/RUViewController.m +7 -2
- data/RufusApp/RufusApp/en.lproj/RUViewController.xib +7 -3
- data/config.yml +8 -0
- data/features/driver.feature +12 -7
- data/features/rufus.feature +20 -0
- data/features/step_definitions/driver_steps.rb +7 -1
- data/features/step_definitions/rufus_steps.rb +15 -0
- data/features/step_definitions/view_steps.rb +13 -1
- data/features/support/routes.rb +4 -0
- data/features/support/screens/enabled_page.rb +13 -0
- data/features/support/screens/home_page.rb +2 -1
- data/features/view.feature +11 -2
- data/lib/rufus.rb +17 -1
- data/lib/rufus/driver.rb +16 -11
- data/lib/rufus/navigation.rb +4 -5
- data/rakefile +90 -0
- data/rufus.gemspec +1 -1
- data/spec/drivers_specs/driver_spec.rb +28 -5
- data/spec/navigation_spec.rb +46 -0
- data/spec/rufus_spec.rb +29 -2
- data/spec/spec_helper.rb +2 -0
- metadata +9 -3
- data/RufusApp/Rakefile +0 -28
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZGE1MmQwYzQ3YzA1YTFjZDQzYmJkMzI5OTdlYWJiZTA0MjMxNmEwMw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDk3OGRlZDVkYjdlOTQ0MTEzNzcyZTYyZjcxOWViOTdkYmNhOTEzNQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZWZiZTJkZTBjMzJhMDA0OTAxNWE0NjQyYzlhM2Y3ZDYzMTQ0MmQ1NmE3ZTFl
|
10
|
+
ZmFhNDQwZDE1YWM5N2I3Mjc2ODBmYjdjMTNjMDY3MDIwNmE0YWYwMjc0ZTA5
|
11
|
+
MWJlZmIwYzIyZTIwMzk1YjUzYjVmMzZmMjE1YjdjOTE3NWUzNzU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NDNjNGRlYjY1ODAwYThkNTQ0ZTQyMmM1ZmVhNDAxMWM4Yjg1MDgzZGMzYjk0
|
14
|
+
MDllYzJkMzY5Y2FiYzViZWUzNjdhYjIyN2FiZDkzYmMyMTA5ZGQ5MWI0YjBi
|
15
|
+
MDljYzViMTcyYTA0ZjE2NTQ0YTExNWEwNzQzYWIwZTNhNmJlNTc=
|
data/.travis.yml
ADDED
@@ -13,26 +13,22 @@
|
|
13
13
|
@end
|
14
14
|
|
15
15
|
@implementation EnabledPageViewController
|
16
|
+
@synthesize enabledTextField, notEnabledTextField;
|
17
|
+
|
16
18
|
|
17
|
-
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
18
|
-
{
|
19
|
-
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
20
|
-
if (self) {
|
21
|
-
// Custom initialization
|
22
|
-
}
|
23
|
-
return self;
|
24
|
-
}
|
25
19
|
|
26
|
-
-
|
20
|
+
-(void)viewDidLoad
|
27
21
|
{
|
28
|
-
[
|
29
|
-
|
22
|
+
[enabledTextField setEnabled:NO];
|
23
|
+
[notEnabledTextField setEnabled:NO];
|
24
|
+
[self performSelector:@selector(enableTheTextField) withObject:nil afterDelay:5];
|
30
25
|
}
|
31
26
|
|
32
|
-
-
|
27
|
+
-(void)enableTheTextField
|
33
28
|
{
|
34
|
-
[
|
35
|
-
// Dispose of any resources that can be recreated.
|
29
|
+
[enabledTextField setEnabled:YES];
|
36
30
|
}
|
37
31
|
|
32
|
+
|
33
|
+
|
38
34
|
@end
|
@@ -1,20 +1,42 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F45" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
|
3
3
|
<dependencies>
|
4
|
-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="
|
4
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
|
5
5
|
</dependencies>
|
6
6
|
<objects>
|
7
7
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="EnabledPageViewController">
|
8
8
|
<connections>
|
9
|
+
<outlet property="enabledTextField" destination="CNH-j4-jZp" id="igO-L4-d1r"/>
|
10
|
+
<outlet property="notEnabledTextField" destination="C8U-NZ-tS3" id="pGf-qt-wJY"/>
|
9
11
|
<outlet property="view" destination="2" id="3"/>
|
10
12
|
</connections>
|
11
13
|
</placeholder>
|
12
14
|
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
13
15
|
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="2">
|
14
|
-
<rect key="frame" x="0.0" y="
|
16
|
+
<rect key="frame" x="0.0" y="0.0" width="768" height="1004"/>
|
15
17
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
18
|
+
<subviews>
|
19
|
+
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="This text field is enabled after 5 seconds" borderStyle="roundedRect" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="CNH-j4-jZp">
|
20
|
+
<rect key="frame" x="214" y="285" width="349" height="30"/>
|
21
|
+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
22
|
+
<accessibility key="accessibilityConfiguration" label="enabledTextField">
|
23
|
+
<bool key="isElement" value="NO"/>
|
24
|
+
</accessibility>
|
25
|
+
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
26
|
+
<textInputTraits key="textInputTraits"/>
|
27
|
+
</textField>
|
28
|
+
<textField opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="left" contentVerticalAlignment="center" text="This textbox will never be enabled" borderStyle="roundedRect" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="C8U-NZ-tS3">
|
29
|
+
<rect key="frame" x="264" y="382" width="241" height="30"/>
|
30
|
+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
31
|
+
<accessibility key="accessibilityConfiguration" label="notEnabledTextField">
|
32
|
+
<bool key="isElement" value="NO"/>
|
33
|
+
</accessibility>
|
34
|
+
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
35
|
+
<textInputTraits key="textInputTraits"/>
|
36
|
+
</textField>
|
37
|
+
</subviews>
|
16
38
|
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
17
|
-
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="
|
39
|
+
<simulatedStatusBarMetrics key="simulatedStatusBarMetrics" statusBarStyle="lightContent"/>
|
18
40
|
</view>
|
19
41
|
</objects>
|
20
42
|
</document>
|
@@ -14,7 +14,9 @@
|
|
14
14
|
@property (weak, nonatomic) IBOutlet UIButton *existsPageButton;
|
15
15
|
@property (weak, nonatomic) IBOutlet UIButton *showAlertButton;
|
16
16
|
@property (weak, nonatomic) IBOutlet UIButton *rufusButton;
|
17
|
+
@property (weak, nonatomic) IBOutlet UIButton *enabledPageButton;
|
17
18
|
|
19
|
+
- (IBAction)toEnabledPage:(id)sender;
|
18
20
|
- (IBAction)toRufusPage:(id)sender;
|
19
21
|
- (IBAction)showAlert:(id)sender;
|
20
22
|
- (IBAction)toExistsPage:(id)sender;
|
@@ -10,6 +10,7 @@
|
|
10
10
|
#import "RufusPageViewController.h"
|
11
11
|
#import "ExistsPageViewController.h"
|
12
12
|
#import "DisplayedPageViewController.h"
|
13
|
+
#import "EnabledPageViewController.h"
|
13
14
|
|
14
15
|
@interface RUViewController ()
|
15
16
|
|
@@ -45,8 +46,12 @@
|
|
45
46
|
|
46
47
|
ExistsPageViewController *existsPageViewController = [[ExistsPageViewController alloc] init];
|
47
48
|
[[self navigationController] pushViewController:existsPageViewController animated:YES];
|
48
|
-
|
49
|
-
|
49
|
+
}
|
50
|
+
|
51
|
+
-(void)toEnabledPage:(id)sender
|
52
|
+
{
|
53
|
+
EnabledPageViewController *enabledPageViewController = [[EnabledPageViewController alloc] init];
|
54
|
+
[[self navigationController] pushViewController:enabledPageViewController animated:YES];
|
50
55
|
}
|
51
56
|
|
52
57
|
- (IBAction)toDisplayedPage:(id)sender {
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.iPad.XIB" version="3.0" toolsVersion="4510" systemVersion="12F45" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" useAutolayout="YES">
|
3
3
|
<dependencies>
|
4
4
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="3742"/>
|
5
5
|
</dependencies>
|
@@ -7,6 +7,7 @@
|
|
7
7
|
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RUViewController">
|
8
8
|
<connections>
|
9
9
|
<outlet property="displayedPageButton" destination="cx3-SH-qUq" id="ntd-NP-UTK"/>
|
10
|
+
<outlet property="enabledPageButton" destination="8Xe-wy-gw2" id="mNp-pl-GZO"/>
|
10
11
|
<outlet property="existsPageButton" destination="ptK-30-J0y" id="eem-Ie-lJP"/>
|
11
12
|
<outlet property="rufusButton" destination="4" id="11"/>
|
12
13
|
<outlet property="showAlertButton" destination="VTc-fX-2Iw" id="ndi-Zu-qSy"/>
|
@@ -37,7 +38,7 @@
|
|
37
38
|
<textInputTraits key="textInputTraits"/>
|
38
39
|
</textField>
|
39
40
|
<label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" misplaced="YES" text="Rufus Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="24">
|
40
|
-
<rect key="frame" x="
|
41
|
+
<rect key="frame" x="324" y="180" width="107" height="21"/>
|
41
42
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
42
43
|
<accessibility key="accessibilityConfiguration" label="rufusLabel"/>
|
43
44
|
<constraints>
|
@@ -73,10 +74,13 @@
|
|
73
74
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8Xe-wy-gw2">
|
74
75
|
<rect key="frame" x="306" y="388" width="146" height="30"/>
|
75
76
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
76
|
-
<accessibility key="accessibilityConfiguration" label="
|
77
|
+
<accessibility key="accessibilityConfiguration" label="enabledPageButton"/>
|
77
78
|
<state key="normal" title="Enabled Page Button">
|
78
79
|
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
79
80
|
</state>
|
81
|
+
<connections>
|
82
|
+
<action selector="toEnabledPage:" destination="-1" eventType="touchUpInside" id="4YW-DD-SpI"/>
|
83
|
+
</connections>
|
80
84
|
</button>
|
81
85
|
<button opaque="NO" contentMode="scaleToFill" fixedFrame="YES" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cx3-SH-qUq">
|
82
86
|
<rect key="frame" x="300" y="434" width="158" height="30"/>
|
data/config.yml
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
browser: iOS
|
2
|
+
platform: Mac
|
3
|
+
version: 7.0
|
4
|
+
app: ./build/Debug-iphoneos/RufusApp.app
|
5
|
+
udid: 4550a561efc2c047637f342bd6320623ba98c385
|
6
|
+
use_physical: false
|
7
|
+
sim_app_path: <%=ENV['HOME']%>/Library/Application Support/iPhone Simulator/7.0/Applications/4550a561efc2c047637f342bd6320623ba98c385/RufusApp.app
|
8
|
+
device: iPhoneSimulator
|
data/features/driver.feature
CHANGED
@@ -5,13 +5,18 @@ Feature: Interacting with a view
|
|
5
5
|
Given I have created a valid appium driver for iOS
|
6
6
|
|
7
7
|
Scenario: Rotating the orientation of device to landscape
|
8
|
-
Given the app is in the "
|
9
|
-
When I rotate the app to "
|
10
|
-
Then the app is in the "
|
8
|
+
Given the app is in the "portrait" orientation
|
9
|
+
When I rotate the app to "landscape"
|
10
|
+
Then the app is in the "landscape" orientation
|
11
11
|
|
12
12
|
Scenario: Rotating the orientation twice
|
13
|
-
Given the app is in the "
|
14
|
-
When I rotate the app to "
|
15
|
-
And I rotate the app to "
|
16
|
-
Then the app is in the "
|
13
|
+
Given the app is in the "portrait" orientation
|
14
|
+
When I rotate the app to "landscape"
|
15
|
+
And I rotate the app to "portrait"
|
16
|
+
Then the app is in the "portrait" orientation
|
17
|
+
@sending
|
18
|
+
Scenario: Typing into a text field
|
19
|
+
Given I am on the "HomePage"
|
20
|
+
When I type "BooYah" into the text field defined "text_box"
|
21
|
+
Then the view marked "text_box" has the text "BooYah"
|
17
22
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
@rufus
|
2
|
+
Feature: Using Rufus
|
3
|
+
|
4
|
+
Background:
|
5
|
+
Given I am on the "HomePage"
|
6
|
+
|
7
|
+
Scenario: Getting an element by name without accessor
|
8
|
+
Then I do not need an accessor to find the view defined "rufusButton"
|
9
|
+
|
10
|
+
Scenario: Clicking on an element by name without accessor
|
11
|
+
Given I have clicked on view defined "rufusButton" with an accessor
|
12
|
+
Then I am on the "RufusPage"
|
13
|
+
|
14
|
+
Scenario: Getting the page source
|
15
|
+
Then I can print out the page data
|
16
|
+
|
17
|
+
Scenario: Getting page elements by class
|
18
|
+
Then I can get a list of the buttons
|
19
|
+
|
20
|
+
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rufus/driver'
|
2
2
|
|
3
3
|
Given(/^I have created a valid appium driver for iOS$/) do
|
4
|
-
app_path = '/
|
4
|
+
app_path = './build/Debug-iphoneos/RufusApp.app'
|
5
5
|
config = $driver.config
|
6
6
|
config["browser"].should eq "iOS"
|
7
7
|
config["platform"].should eq "Mac"
|
@@ -16,4 +16,10 @@ When(/^I rotate the app to "([^"]*)"$/) do |orient|
|
|
16
16
|
orientation = :portrait
|
17
17
|
orientation = :landscape if orient.eql?('landscape')
|
18
18
|
$driver.rotate orientation
|
19
|
+
end
|
20
|
+
When(/^I type "([^"]*)" into the text field defined "([^"]*)"$/) do |keys, which|
|
21
|
+
on(HomePage).send("view_#{which}_view").send_keys keys
|
22
|
+
end
|
23
|
+
Then(/^the view marked "([^"]*)" has the text "([^"]*)"$/) do |which, keys|
|
24
|
+
on(HomePage).send("view_#{which}_view").text.should eq keys
|
19
25
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Then(/^I do not need an accessor to find the view defined "([^"]*)"$/) do |which|
|
2
|
+
element = find(:name => which)
|
3
|
+
element.attribute('name').should eq which
|
4
|
+
end
|
5
|
+
Given(/^I have clicked on view defined "([^"]*)" with an accessor$/) do |which|
|
6
|
+
click(:name => which)
|
7
|
+
end
|
8
|
+
Then(/^I can print out the page data$/) do
|
9
|
+
page_source.include?('rufusButton').should be_true
|
10
|
+
end
|
11
|
+
Then(/^I can get a list of the buttons$/) do
|
12
|
+
elements_of_type('UIAButton').each do |element|
|
13
|
+
element.class.name.should eq('Selenium::WebDriver::Element')
|
14
|
+
end
|
15
|
+
end
|
@@ -22,8 +22,20 @@ Then(/^I will not find the view marked "([^"]*)" after waiting$/) do |arg|
|
|
22
22
|
view = on(HomePage).view_zilch_view
|
23
23
|
exists_after_wait?(view).should be_false
|
24
24
|
end
|
25
|
-
When(/^the view marked "([^"]*)" exists is( not)? displayed$/) do |which, not_displayed|
|
25
|
+
When(/^the view marked "([^"]*)" exists but is( not)? displayed$/) do |which, not_displayed|
|
26
26
|
on(DisplayedPage).active?.should be_true
|
27
27
|
view = on(DisplayedPage).send("view_#{which}_view")
|
28
28
|
displayed_after_wait?(view).should == not_displayed.nil?
|
29
|
+
end
|
30
|
+
When(/^the view marked "([^"]*)" is( not)? enabled$/) do |which, not_enabled|
|
31
|
+
on(EnabledPage).active?.should be_true
|
32
|
+
view = on(EnabledPage).send("view_#{which}_view")
|
33
|
+
enabled_after_wait?(view).should == not_enabled.nil?
|
34
|
+
end
|
35
|
+
Then(/^in a block can see the existence of views "([^"]*)", "([^"]*)" and "([^"]*)"$/) do |view_1, view_2, view_3|
|
36
|
+
on(HomePage) do |screen|
|
37
|
+
screen.send("view_#{view_1}_view").exists?.should be_true
|
38
|
+
screen.send("view_#{view_2}_view").exists?.should be_true
|
39
|
+
screen.send("view_#{view_3}_view").exists?.should be_true
|
40
|
+
end
|
29
41
|
end
|
data/features/support/routes.rb
CHANGED
@@ -5,15 +5,16 @@ class HomePage
|
|
5
5
|
|
6
6
|
view(:view_rufus, :name =>'rufusButton')
|
7
7
|
view(:view_zilch, :name => 'zilch')
|
8
|
+
text(:view_text_box, :name => 'rufusTextBox')
|
8
9
|
button(:view_show_alert, :name => 'showAlertButton')
|
9
10
|
alert(:alert_rufus, :name => 'Rufus Alert')
|
10
11
|
button(:view_exists, :name => 'existsButton')
|
11
12
|
button(:view_displayed, :name => 'displayedPageButton')
|
13
|
+
button(:view_enabled, :name => 'enabledPageButton')
|
12
14
|
button(:alert_Ok, :name => 'Ok')
|
13
15
|
button(:alert_Cancel, :name => 'Cancel')
|
14
16
|
|
15
17
|
|
16
|
-
|
17
18
|
def active?
|
18
19
|
view_rufus_view.exists?
|
19
20
|
true
|
data/features/view.feature
CHANGED
@@ -21,9 +21,18 @@ Feature: Interacting with views
|
|
21
21
|
Scenario: Waiting for a view that is not there
|
22
22
|
Given I am on the "HomePage"
|
23
23
|
Then I will not find the view marked "zilch" after waiting
|
24
|
-
|
24
|
+
|
25
25
|
Scenario: Waiting for a view to be displayed
|
26
26
|
Given I have navigated to the "DisplayedPage" using the "to_displayed" route
|
27
27
|
Then I am on the "DisplayedPage"
|
28
|
-
And the view marked "invisible" exists is not displayed
|
28
|
+
And the view marked "invisible" exists but is not displayed
|
29
|
+
|
30
|
+
Scenario: Waiting for a view to be enabled
|
31
|
+
Given I have navigated to the "EnabledPage" using the "to_enabled" route
|
32
|
+
Then I am on the "EnabledPage"
|
33
|
+
And the view marked "not_enabled" is not enabled
|
34
|
+
@block
|
35
|
+
Scenario: Calling views in a block
|
36
|
+
Given I am on the "HomePage"
|
37
|
+
Then in a block can see the existence of views "rufus", "exists" and "displayed"
|
29
38
|
|
data/lib/rufus.rb
CHANGED
@@ -31,13 +31,29 @@ module Rufus
|
|
31
31
|
def enabled_after_wait?(view, timeout = 5)
|
32
32
|
wait = Selenium::WebDriver::Wait.new :timeout => timeout
|
33
33
|
begin
|
34
|
-
wait.until{view.
|
34
|
+
wait.until{view.enabled?}
|
35
35
|
rescue Selenium::WebDriver::Error::TimeOutError
|
36
36
|
return false
|
37
37
|
end
|
38
38
|
true
|
39
39
|
end
|
40
40
|
|
41
|
+
def find(locator)
|
42
|
+
selenium.find(locator)
|
43
|
+
end
|
44
|
+
|
45
|
+
def click(locator)
|
46
|
+
selenium.find(locator).click
|
47
|
+
end
|
48
|
+
|
49
|
+
def page_source
|
50
|
+
selenium.page_source
|
51
|
+
end
|
52
|
+
|
53
|
+
def elements_of_type(type)
|
54
|
+
selenium.elements_by_tag(type)
|
55
|
+
end
|
56
|
+
|
41
57
|
end
|
42
58
|
|
43
59
|
|
data/lib/rufus/driver.rb
CHANGED
@@ -66,8 +66,10 @@ module Rufus
|
|
66
66
|
end
|
67
67
|
|
68
68
|
def type(keys, name)
|
69
|
-
|
70
|
-
|
69
|
+
element = find(:name => name)
|
70
|
+
element.click
|
71
|
+
sleep 1
|
72
|
+
element.send_keys keys
|
71
73
|
end
|
72
74
|
|
73
75
|
def sequence(*names, times)
|
@@ -147,6 +149,18 @@ module Rufus
|
|
147
149
|
element.attribute(:name).eql? name
|
148
150
|
end
|
149
151
|
|
152
|
+
def page_source
|
153
|
+
driver.page_source
|
154
|
+
end
|
155
|
+
|
156
|
+
def all_elements
|
157
|
+
elements_by_tag('UIAElement')
|
158
|
+
end
|
159
|
+
|
160
|
+
def elements_by_tag(name)
|
161
|
+
driver.find_elements(:tag_name, name)
|
162
|
+
end
|
163
|
+
|
150
164
|
private
|
151
165
|
|
152
166
|
def url(config)
|
@@ -171,14 +185,6 @@ module Rufus
|
|
171
185
|
class_for(element).eql?('UIATableCell')
|
172
186
|
end
|
173
187
|
|
174
|
-
def all_elements
|
175
|
-
elements_by_tag('UIAElement')
|
176
|
-
end
|
177
|
-
|
178
|
-
def elements_by_tag(name)
|
179
|
-
driver.find_elements(:tag_name, name)
|
180
|
-
end
|
181
|
-
|
182
188
|
def driver
|
183
189
|
if use_device
|
184
190
|
@selenium ||= Rufus::Drivers::IOS_Device.for(@config,@url)
|
@@ -190,6 +196,5 @@ module Rufus
|
|
190
196
|
def use_device
|
191
197
|
@config["use_physical"] == true
|
192
198
|
end
|
193
|
-
|
194
199
|
end
|
195
200
|
end
|
data/lib/rufus/navigation.rb
CHANGED
@@ -4,19 +4,18 @@ module Rufus
|
|
4
4
|
module Navigation
|
5
5
|
include PageNavigation
|
6
6
|
|
7
|
-
def on(cls)
|
7
|
+
def on(cls, timeout = 10, &block)
|
8
8
|
screen = cls.new
|
9
|
-
|
10
9
|
wait = 0
|
11
|
-
until wait ==
|
12
|
-
|
10
|
+
until wait == timeout do
|
13
11
|
if screen.active?
|
12
|
+
block.call screen if block
|
14
13
|
return screen
|
15
14
|
else
|
15
|
+
sleep 1
|
16
16
|
wait += 1
|
17
17
|
end
|
18
18
|
end
|
19
|
-
|
20
19
|
raise "Expected #{cls} to be active"
|
21
20
|
end
|
22
21
|
end
|
data/rakefile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'cucumber/rake/task'
|
4
|
+
require 'erb'
|
5
|
+
require 'childprocess'
|
6
|
+
|
7
|
+
desc "Start appium and run features"
|
8
|
+
task :test => [:build_sim, :install_sim, :appium_sim, :specs, :features, :stop_sim_server]
|
9
|
+
|
10
|
+
desc "Running specs appium server"
|
11
|
+
RSpec::Core::RakeTask.new(:specs)
|
12
|
+
|
13
|
+
desc "build RufusApp for simulator"
|
14
|
+
task :build_sim do
|
15
|
+
Dir.chdir("./RufusApp") do
|
16
|
+
`xcodebuild -project RufusApp.xcodeproj -target RufusApp -sdk iphonesimulator -configuration Debug clean build 1>&2`
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "build RufusApp for device"
|
21
|
+
task :build_device do
|
22
|
+
Dir.chdir("./RufusApp") do
|
23
|
+
`xcodebuild -project RufusApp.xcodeproj -target RufusApp -sdk iphoneos -configuration Debug clean build 1>&2`
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Run the features"
|
28
|
+
task :features do
|
29
|
+
`bundle exec cucumber --tags @rufus 1>&2`
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Starting the appium server"
|
33
|
+
task :appium_sim do
|
34
|
+
process = ChildProcess.build('rake', 'appium_server')
|
35
|
+
process.duplex = true
|
36
|
+
process.start
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Stops the appium server for simulator"
|
40
|
+
task :stop_sim_server do
|
41
|
+
system('pkill -9 -f node /usr/local/bin/appium --app #{ENV["HOME"]}/Library/Application Support/iPhone Simulator/#{config["version"]}/Applications')
|
42
|
+
end
|
43
|
+
|
44
|
+
desc "Starting appium server for simulator"
|
45
|
+
task :appium_server do
|
46
|
+
config = YAML.load(ERB.new(File.read('config.yml')).result)
|
47
|
+
app_path = config["sim_app_path"]
|
48
|
+
system('appium --app "' + app_path + '" --force-ipad --native-instruments-lib 1>&2')
|
49
|
+
end
|
50
|
+
|
51
|
+
desc "Install CoPilot to simulator"
|
52
|
+
task :install_sim do
|
53
|
+
config = YAML.load(ERB.new(File.read('config.yml')).result)
|
54
|
+
folder_dir="#{ENV['HOME']}/Library/Application Support/iPhone Simulator/#{config["version"]}/Applications"
|
55
|
+
|
56
|
+
top_dir="#{folder_dir}/#{config["udid"]}"
|
57
|
+
FileUtils.mkdir_p(top_dir)
|
58
|
+
FileUtils.mkdir_p("#{top_dir}/Documents")
|
59
|
+
FileUtils.mkdir_p("#{top_dir}/Library")
|
60
|
+
FileUtils.mkdir_p("#{top_dir}/tmp")
|
61
|
+
|
62
|
+
FileUtils.cp_r("./RufusApp/build/Debug-iphonesimulator/RufusApp.app", "#{top_dir}/RufusApp.app")
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
desc "Start the simulator"
|
67
|
+
task :start_sim do
|
68
|
+
system('open /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Applications/iPhone\ Simulator.app')
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Starting appium server for device"
|
72
|
+
task :appium do
|
73
|
+
config = YAML.load_file('config.yml')
|
74
|
+
app_path = config["app"]
|
75
|
+
udid = config["udid"]
|
76
|
+
`appium -U udid --app app_path 1>&2`
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Reset the simulator"
|
80
|
+
task :reset_sim do
|
81
|
+
%x{osascript<<APPLESCRIPT
|
82
|
+
tell application "System Events"
|
83
|
+
click menu item 5 of menu "iOS Simulator" of menu bar of process "iPhone Simulator"
|
84
|
+
tell window 1 of process "iPhone Simulator"
|
85
|
+
click button "Reset"
|
86
|
+
end tell
|
87
|
+
end tell
|
88
|
+
APPLESCRIPT}
|
89
|
+
end
|
90
|
+
|
data/rufus.gemspec
CHANGED
@@ -37,8 +37,6 @@ describe Rufus::Driver do
|
|
37
37
|
expect{Rufus::Driver.new}.to raise_error(RuntimeError, 'No config.yml found')
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
41
|
-
|
42
40
|
end
|
43
41
|
|
44
42
|
context 'dealing with elements' do
|
@@ -94,6 +92,7 @@ describe Rufus::Driver do
|
|
94
92
|
|
95
93
|
it 'can enter text into an element' do
|
96
94
|
mock_driver.should_receive(:find_element).with(:name, 'rufusButton').and_return(mock_element)
|
95
|
+
mock_element.should_receive(:click)
|
97
96
|
mock_element.should_receive(:send_keys).with('text')
|
98
97
|
@driver.type('text', 'rufusButton')
|
99
98
|
end
|
@@ -314,18 +313,42 @@ describe Rufus::Driver do
|
|
314
313
|
mock_driver.should_receive(:rotate).with('portrait')
|
315
314
|
@driver.rotate('portrait')
|
316
315
|
end
|
316
|
+
end
|
317
|
+
end
|
317
318
|
|
319
|
+
context 'getting the page data' do
|
318
320
|
|
321
|
+
let(:yaml){double('YAML loader')}
|
322
|
+
let(:mock_driver){'a mock app driver'}
|
323
|
+
let(:url){'http://127.0.0.1:4723/wd/hub'}
|
319
324
|
|
325
|
+
before(:each) do
|
326
|
+
File.stub(:exists?).and_return(true)
|
327
|
+
@config = {"browser_name" =>"iOS", "platform"=>"Mac", "version"=>"6.1", "app"=>"/Users/app/path/rufus.app", "use_physical" => false}
|
328
|
+
YAML.should_receive(:load).and_return(@config)
|
329
|
+
@driver = Rufus::Driver.new
|
330
|
+
end
|
320
331
|
|
332
|
+
it 'can get all the page data' do
|
321
333
|
|
322
|
-
|
323
|
-
|
324
|
-
|
334
|
+
Rufus::Drivers::IOS_Simulator.should_receive(:for).with(@config, url).and_return(mock_driver)
|
335
|
+
mock_driver.should_receive(:page_source).and_return("some page data")
|
336
|
+
@driver.page_source.should eq("some page data")
|
325
337
|
end
|
326
338
|
|
339
|
+
context 'getting element lists by class' do
|
340
|
+
|
341
|
+
let(:mock_list){'a mock list of elements'}
|
327
342
|
|
343
|
+
before(:each) do
|
344
|
+
Rufus::Drivers::IOS_Simulator.should_receive(:for).with(@config, url).and_return(mock_driver)
|
345
|
+
end
|
328
346
|
|
347
|
+
it 'can get all the buttons' do
|
348
|
+
mock_driver.should_receive(:find_elements).with(:tag_name, 'UIAButton').and_return(mock_list)
|
349
|
+
@driver.elements_by_tag('UIAButton').should eq(mock_list)
|
350
|
+
end
|
351
|
+
end
|
329
352
|
end
|
330
353
|
end
|
331
354
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rufus/navigation'
|
3
|
+
include Rufus::Navigation
|
4
|
+
|
5
|
+
class RufusNavPage
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Rufus::Navigation do
|
10
|
+
|
11
|
+
let(:mock_page){'mock page object'}
|
12
|
+
let(:mock_block){lambda{}}
|
13
|
+
|
14
|
+
context 'getting the active screen' do
|
15
|
+
|
16
|
+
before (:each) do
|
17
|
+
mock_page.should_receive(:new).and_return(mock_page)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'raises exception if screen does not become active' do
|
21
|
+
mock_page.should_receive(:active?).at_least(1).times.and_return false
|
22
|
+
expect{on(mock_page, 1)}.to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns the active screen' do
|
26
|
+
mock_page.should_receive(:active?).and_return true
|
27
|
+
on(mock_page).should eq mock_page
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'can execute a block' do
|
31
|
+
mock_page.should_receive(:active?).and_return true
|
32
|
+
mock_block.should_receive(:call).with mock_page
|
33
|
+
on(mock_page, &mock_block)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
end
|
data/spec/rufus_spec.rb
CHANGED
@@ -7,8 +7,6 @@ require 'yaml'
|
|
7
7
|
describe Rufus do
|
8
8
|
include Rufus
|
9
9
|
|
10
|
-
|
11
|
-
|
12
10
|
context 'waiting for an element to exist' do
|
13
11
|
|
14
12
|
let(:mock_wait){'mock Selenium::WebDriver::Wait'}
|
@@ -85,4 +83,33 @@ describe Rufus do
|
|
85
83
|
end
|
86
84
|
end
|
87
85
|
end
|
86
|
+
|
87
|
+
context 'elements without accessors' do
|
88
|
+
|
89
|
+
let(:selenium){'mock selenium driver'}
|
90
|
+
let(:mock_element){'mock selenium element'}
|
91
|
+
|
92
|
+
it 'can find an element by name' do
|
93
|
+
selenium.should_receive(:find).with({:name => 'rufusButton'}).and_return(mock_element)
|
94
|
+
mock_element.should_receive(:click)
|
95
|
+
click(:name => 'rufusButton')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'getting the raw page data' do
|
100
|
+
|
101
|
+
let(:selenium){'mock selenium driver'}
|
102
|
+
let(:elements){'mock list of elements'}
|
103
|
+
|
104
|
+
it 'can get the raw page data' do
|
105
|
+
selenium.should_receive(:page_source).and_return("source data")
|
106
|
+
page_source.should eq("source data")
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'can get a list of buttons' do
|
110
|
+
selenium.should_receive(:elements_by_tag).with('UIAButton').and_return(elements)
|
111
|
+
elements_of_type 'UIAButton'
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
88
115
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rufus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.5'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Stewart
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: page_navigation
|
@@ -47,6 +47,7 @@ extra_rdoc_files: []
|
|
47
47
|
files:
|
48
48
|
- .gitignore
|
49
49
|
- .gitmodules
|
50
|
+
- .travis.yml
|
50
51
|
- Gemfile
|
51
52
|
- Gemfile.lock
|
52
53
|
- LICENSE.txt
|
@@ -268,7 +269,6 @@ files:
|
|
268
269
|
- RufusApp/Frank/libFrankMac.a
|
269
270
|
- RufusApp/Frank/libShelley.a
|
270
271
|
- RufusApp/Frank/libShelleyMac.a
|
271
|
-
- RufusApp/Rakefile
|
272
272
|
- RufusApp/RufusApp.xcodeproj/project.pbxproj
|
273
273
|
- RufusApp/RufusApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
|
274
274
|
- RufusApp/RufusApp/Default-568h@2x.png
|
@@ -311,16 +311,20 @@ files:
|
|
311
311
|
- RufusApp/RufusAppTests/RufusAppTests.h
|
312
312
|
- RufusApp/RufusAppTests/RufusAppTests.m
|
313
313
|
- RufusApp/RufusAppTests/en.lproj/InfoPlist.strings
|
314
|
+
- config.yml
|
314
315
|
- features/alert.feature
|
315
316
|
- features/driver.feature
|
317
|
+
- features/rufus.feature
|
316
318
|
- features/step_definitions/alert_steps.rb.rb
|
317
319
|
- features/step_definitions/driver_steps.rb
|
320
|
+
- features/step_definitions/rufus_steps.rb
|
318
321
|
- features/step_definitions/view_steps.rb
|
319
322
|
- features/support/core_ext/string.rb
|
320
323
|
- features/support/env.rb
|
321
324
|
- features/support/hooks.rb
|
322
325
|
- features/support/routes.rb
|
323
326
|
- features/support/screens/displayed_page.rb
|
327
|
+
- features/support/screens/enabled_page.rb
|
324
328
|
- features/support/screens/exists_page.rb
|
325
329
|
- features/support/screens/home_page.rb
|
326
330
|
- features/support/screens/rufus_page.rb
|
@@ -332,11 +336,13 @@ files:
|
|
332
336
|
- lib/rufus/drivers/iOS_device.rb
|
333
337
|
- lib/rufus/drivers/iOS_simulator.rb
|
334
338
|
- lib/rufus/navigation.rb
|
339
|
+
- rakefile
|
335
340
|
- rufus.gemspec
|
336
341
|
- spec/accessors_spec.rb
|
337
342
|
- spec/drivers_specs/driver_spec.rb
|
338
343
|
- spec/drivers_specs/iOS_device_spec.rb
|
339
344
|
- spec/drivers_specs/iOS_simulator_spec.rb
|
345
|
+
- spec/navigation_spec.rb
|
340
346
|
- spec/rufus_spec.rb
|
341
347
|
- spec/spec_helper.rb
|
342
348
|
- spec/view_spec.rb
|
data/RufusApp/Rakefile
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require 'cucumber'
|
2
|
-
require 'cucumber/rake/task'
|
3
|
-
require 'rspec/core/rake_task'
|
4
|
-
|
5
|
-
desc "Build CoPilot for physical deployment"
|
6
|
-
task :frankify do
|
7
|
-
|
8
|
-
`xcodebuild -target RufusApp -xcconfig /Users/jstewart/rubymineprojects/rufus/rufusapp/frank/frankify.xcconfig -arch armv7 -configuration Debug -sdk iphoneos DEPLOYMENT_LOCATION=YES DSTROOT=\`pwd\`/Frank/Frankified_build FRANK_LIBRARY_SEARCH_PATHS=\`pwd\`/Frank clean build`
|
9
|
-
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Install CoPilot on iPad"
|
13
|
-
task :fruitstrap do
|
14
|
-
|
15
|
-
Dir.chdir("/Users/jstewart/documents/projects/copilot/frameworks/fruitstrap") do
|
16
|
-
|
17
|
-
`./fruitstrap -b /Users/jstewart/Library/Developer/Xcode/DerivedData/RufusApp-bseyccodcsszzhcwbshowgsppecs/Build/Products/Debug-iphoneos/RufusApp.app 2>&1`
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
desc "Start Appium server"
|
23
|
-
task :appium do
|
24
|
-
|
25
|
-
Dir.chdir("/Users/jstewart/rubymineprojects/rufus/appium") do
|
26
|
-
`appium -U 4550a561efc2c047637f342bd6320623ba98c385 --app /Users/jstewart/Library/Developer/Xcode/DerivedData/RufusApp-bseyccodcsszzhcwbshowgsppecs/Build/Products/Debug-iphoneos/RufusApp.app`
|
27
|
-
end
|
28
|
-
end
|