rufus 0.4 → 0.5
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 +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
|