furter 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +21 -0
- data/.rspec +2 -0
- data/.travis.yml +2 -0
- data/Changelog +3 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +25 -0
- data/Rakefile +30 -0
- data/app/FurterApp/Frank/features/my_first.feature +12 -0
- data/app/FurterApp/Frank/features/step_definitions/launch_steps.rb +20 -0
- data/app/FurterApp/Frank/features/support/env.rb +8 -0
- data/app/FurterApp/Frank/frankify.xcconfig +6 -0
- data/app/FurterApp/Frank/libCocoaAsyncSocket.a +0 -0
- data/app/FurterApp/Frank/libCocoaAsyncSocketMac.a +0 -0
- data/app/FurterApp/Frank/libCocoaHTTPServer.a +0 -0
- data/app/FurterApp/Frank/libCocoaHTTPServerMac.a +0 -0
- data/app/FurterApp/Frank/libCocoaLumberjack.a +0 -0
- data/app/FurterApp/Frank/libCocoaLumberjackMac.a +0 -0
- data/app/FurterApp/Frank/libFrank.a +0 -0
- data/app/FurterApp/Frank/libFrankMac.a +0 -0
- data/app/FurterApp/Frank/libShelley.a +0 -0
- data/app/FurterApp/Frank/libShelleyMac.a +0 -0
- data/app/FurterApp/FurterApp.xcodeproj/project.pbxproj +807 -0
- data/app/FurterApp/FurterApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- data/app/FurterApp/FurterApp.xcodeproj/project.xcworkspace/xcuserdata/lwilson.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/app/FurterApp/FurterApp.xcodeproj/xcuserdata/lwilson.xcuserdatad/xcschemes/FurterApp.xcscheme +86 -0
- data/app/FurterApp/FurterApp.xcodeproj/xcuserdata/lwilson.xcuserdatad/xcschemes/xcschememanagement.plist +22 -0
- data/app/FurterApp/FurterApp/AppDelegate.h +22 -0
- data/app/FurterApp/FurterApp/AppDelegate.m +161 -0
- data/app/FurterApp/FurterApp/Default-568h@2x.png +0 -0
- data/app/FurterApp/FurterApp/Default.png +0 -0
- data/app/FurterApp/FurterApp/Default@2x.png +0 -0
- data/app/FurterApp/FurterApp/DetailViewController.h +23 -0
- data/app/FurterApp/FurterApp/DetailViewController.m +80 -0
- data/app/FurterApp/FurterApp/FurterApp-Info.plist +59 -0
- data/app/FurterApp/FurterApp/FurterApp-Prefix.pch +15 -0
- data/app/FurterApp/FurterApp/FurterApp.xcdatamodeld/.xccurrentversion +8 -0
- data/app/FurterApp/FurterApp/FurterApp.xcdatamodeld/FurterApp.xcdatamodel/contents +9 -0
- data/app/FurterApp/FurterApp/MasterViewController.h +22 -0
- data/app/FurterApp/FurterApp/MasterViewController.m +235 -0
- data/app/FurterApp/FurterApp/en.lproj/InfoPlist.strings +2 -0
- data/app/FurterApp/FurterApp/en.lproj/MainStoryboard_iPad.storyboard +260 -0
- data/app/FurterApp/FurterApp/en.lproj/MainStoryboard_iPhone.storyboard +129 -0
- data/app/FurterApp/FurterApp/main.m +18 -0
- data/cucumber.yml +2 -0
- data/features/button.feature +12 -0
- data/features/label.feature +10 -0
- data/features/navigation.feature +5 -0
- data/features/step_definitions/button_steps.rb +7 -0
- data/features/step_definitions/label_steps.rb +8 -0
- data/features/step_definitions/navigation_steps.rb +7 -0
- data/features/step_definitions/switches_steps.rb +12 -0
- data/features/step_definitions/text_steps.rb +25 -0
- data/features/support/core_ext/string.rb +9 -0
- data/features/support/env.rb +25 -0
- data/features/support/hooks.rb +3 -0
- data/features/support/screens/detail.rb +15 -0
- data/features/support/screens/elsewhere_page.rb +7 -0
- data/features/switches.feature +7 -0
- data/features/text.feature +15 -0
- data/furter.gemspec +26 -0
- data/lib/furter.rb +53 -0
- data/lib/furter/accessors.rb +87 -0
- data/lib/furter/accessors/alert_button.rb +18 -0
- data/lib/furter/accessors/button.rb +17 -0
- data/lib/furter/accessors/label.rb +13 -0
- data/lib/furter/accessors/map_pin.rb +18 -0
- data/lib/furter/accessors/switch.rb +20 -0
- data/lib/furter/accessors/table.rb +15 -0
- data/lib/furter/accessors/table_item.rb +10 -0
- data/lib/furter/accessors/text.rb +27 -0
- data/lib/furter/accessors/view.rb +46 -0
- data/lib/furter/navigation.rb +25 -0
- data/lib/furter/version.rb +3 -0
- data/spec/lib/furter/accessors/button_spec.rb +23 -0
- data/spec/lib/furter/accessors/label_spec.rb +24 -0
- data/spec/lib/furter/accessors/switch_spec.rb +28 -0
- data/spec/lib/furter/accessors/text_spec.rb +39 -0
- data/spec/lib/furter/accessors/view_spec.rb +43 -0
- data/spec/lib/furter/accessors_spec.rb +116 -0
- data/spec/spec_helper.rb +18 -0
- metadata +234 -0
@@ -0,0 +1,129 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="2.0" toolsVersion="3084" systemVersion="12D78" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" initialViewController="3">
|
3
|
+
<dependencies>
|
4
|
+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="2083"/>
|
5
|
+
</dependencies>
|
6
|
+
<scenes>
|
7
|
+
<!--Navigation Controller-->
|
8
|
+
<scene sceneID="11">
|
9
|
+
<objects>
|
10
|
+
<navigationController id="3" sceneMemberID="viewController">
|
11
|
+
<navigationBar key="navigationBar" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" id="4">
|
12
|
+
<autoresizingMask key="autoresizingMask"/>
|
13
|
+
</navigationBar>
|
14
|
+
<connections>
|
15
|
+
<segue destination="12" kind="relationship" relationship="rootViewController" id="19"/>
|
16
|
+
</connections>
|
17
|
+
</navigationController>
|
18
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="10" sceneMemberID="firstResponder"/>
|
19
|
+
</objects>
|
20
|
+
<point key="canvasLocation" x="-1" y="64"/>
|
21
|
+
</scene>
|
22
|
+
<!--Master View Controller - Master-->
|
23
|
+
<scene sceneID="18">
|
24
|
+
<objects>
|
25
|
+
<tableViewController storyboardIdentifier="" title="Master" id="12" customClass="MasterViewController" sceneMemberID="viewController">
|
26
|
+
<tableView key="view" opaque="NO" clipsSubviews="YES" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="13">
|
27
|
+
<rect key="frame" x="0.0" y="64" width="320" height="504"/>
|
28
|
+
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
29
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
30
|
+
<prototypes>
|
31
|
+
<tableViewCell contentMode="scaleToFill" selectionStyle="blue" accessoryType="disclosureIndicator" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="Cell" textLabel="phq-AM-6qj" style="IBUITableViewCellStyleDefault" id="lJ0-d7-vTF">
|
32
|
+
<rect key="frame" x="0.0" y="22" width="320" height="44"/>
|
33
|
+
<autoresizingMask key="autoresizingMask"/>
|
34
|
+
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
35
|
+
<rect key="frame" x="0.0" y="0.0" width="300" height="43"/>
|
36
|
+
<autoresizingMask key="autoresizingMask"/>
|
37
|
+
<subviews>
|
38
|
+
<label opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" text="Title" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="phq-AM-6qj">
|
39
|
+
<rect key="frame" x="10" y="0.0" width="280" height="43"/>
|
40
|
+
<autoresizingMask key="autoresizingMask"/>
|
41
|
+
<fontDescription key="fontDescription" type="boldSystem" pointSize="20"/>
|
42
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
43
|
+
<color key="highlightedColor" red="1" green="1" blue="1" alpha="1" colorSpace="calibratedRGB"/>
|
44
|
+
</label>
|
45
|
+
</subviews>
|
46
|
+
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
47
|
+
</view>
|
48
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
49
|
+
<connections>
|
50
|
+
<segue destination="21" kind="push" identifier="showDetail" id="jZb-fq-zAk"/>
|
51
|
+
</connections>
|
52
|
+
</tableViewCell>
|
53
|
+
</prototypes>
|
54
|
+
<sections/>
|
55
|
+
<connections>
|
56
|
+
<outlet property="dataSource" destination="12" id="16"/>
|
57
|
+
<outlet property="delegate" destination="12" id="15"/>
|
58
|
+
</connections>
|
59
|
+
</tableView>
|
60
|
+
<navigationItem key="navigationItem" title="Master" id="36"/>
|
61
|
+
</tableViewController>
|
62
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="17" sceneMemberID="firstResponder"/>
|
63
|
+
</objects>
|
64
|
+
<point key="canvasLocation" x="459" y="64"/>
|
65
|
+
</scene>
|
66
|
+
<!--Detail View Controller - Detail-->
|
67
|
+
<scene sceneID="24">
|
68
|
+
<objects>
|
69
|
+
<viewController storyboardIdentifier="" title="Detail" id="21" customClass="DetailViewController" sceneMemberID="viewController">
|
70
|
+
<view key="view" contentMode="scaleToFill" id="22">
|
71
|
+
<rect key="frame" x="0.0" y="64" width="320" height="504"/>
|
72
|
+
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
73
|
+
<subviews>
|
74
|
+
<label clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" text="Detail view content goes here" textAlignment="center" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="27">
|
75
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
76
|
+
<fontDescription key="fontDescription" type="system" size="system"/>
|
77
|
+
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
78
|
+
<nil key="highlightedColor"/>
|
79
|
+
</label>
|
80
|
+
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BGA-y0-odx">
|
81
|
+
<fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
|
82
|
+
<state key="normal" title="Button">
|
83
|
+
<color key="titleColor" red="0.19607843459999999" green="0.30980393290000002" blue="0.52156865600000002" alpha="1" colorSpace="calibratedRGB"/>
|
84
|
+
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
85
|
+
</state>
|
86
|
+
<state key="highlighted">
|
87
|
+
<color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
88
|
+
</state>
|
89
|
+
</button>
|
90
|
+
</subviews>
|
91
|
+
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
92
|
+
<constraints>
|
93
|
+
<constraint firstAttribute="bottom" secondItem="BGA-y0-odx" secondAttribute="bottom" constant="107" id="Oz5-UI-e4N"/>
|
94
|
+
<constraint firstItem="27" firstAttribute="leading" secondItem="22" secondAttribute="leading" constant="20" symbolic="YES" type="default" id="R0m-z7-TWk"/>
|
95
|
+
<constraint firstItem="BGA-y0-odx" firstAttribute="leading" secondItem="22" secondAttribute="leading" constant="20" symbolic="YES" type="default" id="a4V-WS-rvQ"/>
|
96
|
+
<constraint firstItem="27" firstAttribute="top" secondItem="22" secondAttribute="top" constant="9" id="fqs-Iu-ZEi"/>
|
97
|
+
<constraint firstAttribute="trailing" secondItem="27" secondAttribute="trailing" constant="20" symbolic="YES" type="default" id="pRe-qY-58T"/>
|
98
|
+
</constraints>
|
99
|
+
</view>
|
100
|
+
<navigationItem key="navigationItem" title="Detail" id="26"/>
|
101
|
+
<connections>
|
102
|
+
<outlet property="detailDescriptionLabel" destination="27" id="28"/>
|
103
|
+
</connections>
|
104
|
+
</viewController>
|
105
|
+
<placeholder placeholderIdentifier="IBFirstResponder" id="23" sceneMemberID="firstResponder"/>
|
106
|
+
</objects>
|
107
|
+
<point key="canvasLocation" x="902" y="64"/>
|
108
|
+
</scene>
|
109
|
+
</scenes>
|
110
|
+
<classes>
|
111
|
+
<class className="DetailViewController" superclassName="UIViewController">
|
112
|
+
<source key="sourceIdentifier" type="project" relativePath="./Classes/DetailViewController.h"/>
|
113
|
+
<relationships>
|
114
|
+
<relationship kind="outlet" name="detailDescriptionLabel" candidateClass="UILabel"/>
|
115
|
+
</relationships>
|
116
|
+
</class>
|
117
|
+
<class className="MasterViewController" superclassName="UITableViewController">
|
118
|
+
<source key="sourceIdentifier" type="project" relativePath="./Classes/MasterViewController.h"/>
|
119
|
+
</class>
|
120
|
+
<class className="NSLayoutConstraint" superclassName="NSObject">
|
121
|
+
<source key="sourceIdentifier" type="project" relativePath="./Classes/NSLayoutConstraint.h"/>
|
122
|
+
</class>
|
123
|
+
</classes>
|
124
|
+
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
125
|
+
<simulatedStatusBarMetrics key="statusBar"/>
|
126
|
+
<simulatedOrientationMetrics key="orientation"/>
|
127
|
+
<simulatedScreenMetrics key="destination" type="retina4"/>
|
128
|
+
</simulatedMetricsContainer>
|
129
|
+
</document>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
//
|
2
|
+
// main.m
|
3
|
+
// FurterApp
|
4
|
+
//
|
5
|
+
// Created by Levi Wilson on 3/20/13.
|
6
|
+
// Copyright (c) 2013 Levi Wilson. All rights reserved.
|
7
|
+
//
|
8
|
+
|
9
|
+
#import <UIKit/UIKit.h>
|
10
|
+
|
11
|
+
#import "AppDelegate.h"
|
12
|
+
|
13
|
+
int main(int argc, char *argv[])
|
14
|
+
{
|
15
|
+
@autoreleasepool {
|
16
|
+
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
17
|
+
}
|
18
|
+
}
|
data/cucumber.yml
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Feature: Working with buttons
|
2
|
+
|
3
|
+
Scenario: Clicking buttons by text
|
4
|
+
When I click the button identified by "text"
|
5
|
+
Then the text identified by "label" should be "The button was clicked!"
|
6
|
+
|
7
|
+
Scenario: Clicking buttons by label
|
8
|
+
When I click the button identified by "label"
|
9
|
+
Then the text identified by "label" should be "The labeled button was clicked!"
|
10
|
+
|
11
|
+
Scenario: Working with the raw button view
|
12
|
+
Then we can interact with the raw view of the button identified by "label"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Feature: Working with label controls
|
2
|
+
|
3
|
+
Scenario: Getting the value of a label by accessibility label
|
4
|
+
Then I know that the label identified by "id" is "Detail view content goes here"
|
5
|
+
|
6
|
+
Scenario: Accessing the raw view properties of a label
|
7
|
+
Then the label identified by "id" should be "visible"
|
8
|
+
|
9
|
+
Scenario: Finding labels by their text
|
10
|
+
Then the label identified by "text" should be "visible"
|
@@ -0,0 +1,7 @@
|
|
1
|
+
When /^I click the button identified by "([^"]*)"$/ do |how|
|
2
|
+
on(DetailPage).send("button_#{how}")
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^we can interact with the raw view of the button identified by "([^"]*)"$/ do |how|
|
6
|
+
on(DetailPage).send("button_#{how}_view").should be_kind_of(Furter::Accessors::View)
|
7
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
Then /^I know that the label identified by "([^"]*)" is "([^"]*)"$/ do |how, what|
|
2
|
+
on(DetailPage).send("label_#{how}").should eq(what)
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^the label identified by "([^"]*)" should be "([^"]*)"$/ do |how, property|
|
6
|
+
which_method = "#{property}?".to_sym
|
7
|
+
on(DetailPage).send("label_#{how}_view").send(which_method).should be_true
|
8
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
Then(/^switches can be toggled both on or off$/) do
|
2
|
+
on(DetailPage) do |screen|
|
3
|
+
[true, false].each do |what_now|
|
4
|
+
screen.switch_toggle = what_now
|
5
|
+
screen.switch_toggle.should eq(what_now)
|
6
|
+
end
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^we have access to the switch view$/ do
|
11
|
+
on(DetailPage).switch_toggle_view.should be_kind_of(Furter::Accessors::View)
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
When(/^I set the text identified by "(.*?)" to "(.*?)"$/) do |how, text|
|
2
|
+
on(DetailPage).send("text_#{how}=", text)
|
3
|
+
end
|
4
|
+
|
5
|
+
Then(/^the text identified by "(.*?)" should be "(.*?)"$/) do |how, text|
|
6
|
+
on(DetailPage).send("text_#{how}").should eq(text)
|
7
|
+
end
|
8
|
+
|
9
|
+
Then(/^we know if a text field is both editable and not editable$/) do
|
10
|
+
first_field = "textField placeholder:'First Field'"
|
11
|
+
|
12
|
+
on(DetailPage) do |screen|
|
13
|
+
frankly_map(first_field, 'setEnabled:', false)
|
14
|
+
screen.should_not be_text_placeholder_editable
|
15
|
+
|
16
|
+
frankly_map(first_field, 'setEnabled:', true)
|
17
|
+
screen.should be_text_placeholder_editable
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
Then(/^we can interact with the raw text view identified by "(.*?)"$/) do |how|
|
22
|
+
text_view = on(DetailPage).send("text_#{how}_view")
|
23
|
+
text_view.should be_kind_of(Furter::Accessors::View)
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
|
2
|
+
|
3
|
+
require 'furter'
|
4
|
+
require 'require_all'
|
5
|
+
|
6
|
+
require 'rspec-expectations'
|
7
|
+
|
8
|
+
World(Furter::Navigation)
|
9
|
+
|
10
|
+
require_rel '/screens'
|
11
|
+
|
12
|
+
APP_BUNDLE_PATH = File.expand_path( '../../../app/FurterApp/Frank/frankified_build/FurterApp.app', __FILE__ )
|
13
|
+
|
14
|
+
Frank::Cucumber::FrankHelper.use_shelley_from_now_on
|
15
|
+
|
16
|
+
Furter::Navigation.routes = {
|
17
|
+
:default => [],
|
18
|
+
:crazy_route => [
|
19
|
+
[DetailPage, :button_text],
|
20
|
+
[DetailPage, :button_label],
|
21
|
+
[DetailPage, :switch_toggle],
|
22
|
+
[DetailPage, :go_elsewhere],
|
23
|
+
[ElsewherePage, :active?]
|
24
|
+
]
|
25
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class DetailPage
|
2
|
+
include Furter
|
3
|
+
|
4
|
+
text(:text_placeholder, :placeholder => 'First Field')
|
5
|
+
text(:text_label, :label => 'textByLabel')
|
6
|
+
|
7
|
+
label(:label_id, :label => 'labelByAccessibilityLabel')
|
8
|
+
label(:label_text, :text => 'Placeholder')
|
9
|
+
|
10
|
+
button(:button_text, :text => 'Some Button')
|
11
|
+
button(:button_label, :label => 'labeledButtonId')
|
12
|
+
button(:go_elsewhere, :text => 'Go Elsewhere')
|
13
|
+
|
14
|
+
switch(:switch_toggle, :label => 'switchToggle')
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: Working with text controls
|
2
|
+
|
3
|
+
Scenario: Getting and setting text by placeholder
|
4
|
+
When I set the text identified by "placeholder" to "The first field's text"
|
5
|
+
Then the text identified by "placeholder" should be "The first field's text"
|
6
|
+
|
7
|
+
Scenario: Getting and setting text by label
|
8
|
+
When I set the text identified by "label" to "the label text"
|
9
|
+
Then the text identified by "label" should be "the label text"
|
10
|
+
|
11
|
+
Scenario: Determining if a text field is editable
|
12
|
+
Then we know if a text field is both editable and not editable
|
13
|
+
|
14
|
+
Scenario: Working with the raw view
|
15
|
+
Then we can interact with the raw text view identified by "placeholder"
|
data/furter.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'furter/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "furter"
|
8
|
+
gem.version = Furter::VERSION
|
9
|
+
gem.authors = ["Levi Wilson"]
|
10
|
+
gem.email = ["levi@leviwilson.com"]
|
11
|
+
gem.description = %q{Higher-level abstraction around iOS drivers}
|
12
|
+
gem.summary = %q{Higher-level abstraction around iOS drivers}
|
13
|
+
gem.homepage = ""
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency 'frank-cucumber', '~> 1.1.8'
|
21
|
+
gem.add_dependency 'page_navigation', '>= 0.7'
|
22
|
+
|
23
|
+
gem.add_development_dependency 'rspec'
|
24
|
+
gem.add_development_dependency 'rake'
|
25
|
+
gem.add_development_dependency 'require_all'
|
26
|
+
end
|
data/lib/furter.rb
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'frank-cucumber'
|
2
|
+
require 'furter/navigation'
|
3
|
+
require 'furter/accessors'
|
4
|
+
require 'furter/accessors/view'
|
5
|
+
require 'furter/accessors/alert_button'
|
6
|
+
require 'furter/accessors/button'
|
7
|
+
require 'furter/accessors/map_pin'
|
8
|
+
require 'furter/accessors/switch'
|
9
|
+
require 'furter/accessors/table'
|
10
|
+
require 'furter/accessors/table_item'
|
11
|
+
require 'furter/accessors/text'
|
12
|
+
require 'furter/accessors/label'
|
13
|
+
|
14
|
+
module Furter
|
15
|
+
include Frank::Cucumber::FrankHelper
|
16
|
+
|
17
|
+
TIMEOUT = 30
|
18
|
+
|
19
|
+
def self.included(cls)
|
20
|
+
cls.extend Furter::Accessors
|
21
|
+
end
|
22
|
+
|
23
|
+
def has_text?(text)
|
24
|
+
Furter::Accessors::Text.new.has_text? text
|
25
|
+
end
|
26
|
+
|
27
|
+
def wait_for_text(text)
|
28
|
+
wait_until(:message => "Timed out waiting for text \"#{text}\"", :timeout => Furter::TIMEOUT) do
|
29
|
+
has_text? text
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def exists?(locator)
|
34
|
+
element_exists locator
|
35
|
+
end
|
36
|
+
|
37
|
+
def wait_for(locator, &block)
|
38
|
+
wait_until(:message => "Timed out waiting for \"#{locator}\"", :timeout => Furter::TIMEOUT) do
|
39
|
+
exists? locator
|
40
|
+
end
|
41
|
+
block.call locator if block
|
42
|
+
end
|
43
|
+
|
44
|
+
def wait_for_and_touch(locator)
|
45
|
+
wait_for(locator) do |locator|
|
46
|
+
touch locator
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def active?
|
51
|
+
true
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Furter
|
2
|
+
module Accessors
|
3
|
+
def text(name, locator)
|
4
|
+
define_method("#{name}") do
|
5
|
+
Furter::Accessors::Text.new(locator).get_text
|
6
|
+
end
|
7
|
+
define_method("#{name}_editable?") do
|
8
|
+
Furter::Accessors::Text.new(locator).editable?
|
9
|
+
end
|
10
|
+
define_method("#{name}=") do |text|
|
11
|
+
Furter::Accessors::Text.new(locator).set_text text
|
12
|
+
end
|
13
|
+
define_method("#{name}_view") do
|
14
|
+
Furter::Accessors::Text.new(locator)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def label(name, locator)
|
19
|
+
define_method("#{name}") do
|
20
|
+
Furter::Accessors::Label.new(locator).text
|
21
|
+
end
|
22
|
+
define_method("#{name}_view") do
|
23
|
+
Furter::Accessors::Label.new(locator)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def view(name, locator)
|
28
|
+
define_method("#{name}") do
|
29
|
+
Furter::Accessors::View.new(locator).click
|
30
|
+
end
|
31
|
+
define_method("#{name}_view") do
|
32
|
+
Furter::Accessors::View.new(locator)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def button(name, locator)
|
37
|
+
define_method("#{name}") do
|
38
|
+
Furter::Accessors::Button.new(locator).click
|
39
|
+
end
|
40
|
+
define_method("#{name}_view") do
|
41
|
+
Furter::Accessors::Button.new(locator)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def alert_button(name, locator)
|
46
|
+
define_method("#{name}") do
|
47
|
+
Furter::Accessors::AlertButton.new(locator).click
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def table(name, locator)
|
52
|
+
define_method("#{name}=") do |which|
|
53
|
+
Furter::Accessors::TableItem.new(:text => which).click
|
54
|
+
end
|
55
|
+
define_method("#{name}_options") do
|
56
|
+
Furter::Accessors::Table.new(locator).options
|
57
|
+
end
|
58
|
+
define_method("#{name}_view") do
|
59
|
+
Furter::Accessors::Table.new(locator)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def table_item(name, locator)
|
64
|
+
define_method("#{name}") do
|
65
|
+
Furter::Accessors::TableItem.new(locator).click
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def map_pin(name, locator)
|
70
|
+
define_method("#{name}") do
|
71
|
+
Furter::Accessors::MapPin.new(locator).click
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def switch(name, locator)
|
76
|
+
define_method("#{name}") do
|
77
|
+
Furter::Accessors::Switch.new(locator).on?
|
78
|
+
end
|
79
|
+
define_method("#{name}=") do |on_or_off|
|
80
|
+
Furter::Accessors::Switch.new(locator).set on_or_off
|
81
|
+
end
|
82
|
+
define_method("#{name}_view") do
|
83
|
+
Furter::Accessors::Switch.new(locator)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|