From c57e61bc3364193a03f32766b83d92abf883c99a Mon Sep 17 00:00:00 2001 From: Stewart Gleadow Date: Fri, 27 Dec 2013 18:32:54 +1100 Subject: [PATCH 01/13] Add better error messages to be_true/be_false matchers --- gem/lib/frank-cucumber/frank_helper.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gem/lib/frank-cucumber/frank_helper.rb b/gem/lib/frank-cucumber/frank_helper.rb index 050f8ce..2c91374 100644 --- a/gem/lib/frank-cucumber/frank_helper.rb +++ b/gem/lib/frank-cucumber/frank_helper.rb @@ -127,11 +127,11 @@ def element_exists( selector ) # @raise an rspec exception if the assertion fails # @see #element_exists, #check_element_does_not_exist def check_element_exists( selector ) - element_exists( selector ).should be_true + element_exists( selector ).should be_true, "Could not find element matching selector (#{selector})" end def check_element_exists_and_is_visible( selector ) - element_is_not_hidden( selector ).should be_true + element_is_not_hidden( selector ).should be_true, "Could not find visible element matching selector (#{selector})" end # Assert whether there are no views in the current view heirarchy which match the specified selector. @@ -139,11 +139,11 @@ def check_element_exists_and_is_visible( selector ) # @raise an rspec exception if the assertion fails # @see #element_exists, #check_element_exists def check_element_does_not_exist( selector ) - element_exists( selector ).should be_false + element_exists( selector ).should be_false, "Found element matching selector when it should not exist (#{selector})" end def check_element_does_not_exist_or_is_not_visible( selector ) - element_is_not_hidden( selector ).should be_false + element_is_not_hidden( selector ).should be_false, "Found visible element matching selector when it should not be visible (#{selector})" end # Indicate whether there are any views in the current view heirarchy which contain the specified accessibility label. From 9bf438716425ba3f3fafda92d6ea34f36430e6e0 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Wed, 18 Dec 2013 20:12:56 -0800 Subject: [PATCH 02/13] Added KIF as a submodule --- .gitmodules | 3 +++ lib/KIF | 1 + 2 files changed, 4 insertions(+) create mode 160000 lib/KIF diff --git a/.gitmodules b/.gitmodules index 6ac43d2..acac274 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "lib/AnyJSON"] path = lib/AnyJSON url = https://github.com/mattt/AnyJSON.git +[submodule "lib/KIF"] + path = lib/KIF + url = https://github.com/kif-framework/KIF.git diff --git a/lib/KIF b/lib/KIF new file mode 160000 index 0000000..7ba0c2a --- /dev/null +++ b/lib/KIF @@ -0,0 +1 @@ +Subproject commit 7ba0c2ae1732c7c56959e15b23b862e86775ee8a From 000532461094cb90f55b762f1f83d129f6ee2da3 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Thu, 19 Dec 2013 19:13:30 -0800 Subject: [PATCH 03/13] Update the Controls example for iOS 7 --- .../Controls.xcodeproj/project.pbxproj | 2 + .../Controls/Controls/AlertViewController.xib | 320 +------- example/Controls/Controls/Carousel.m | 1 + .../Controls/DataEntryViewController.xib | 536 ++----------- .../Controls/DoubleTapViewController.xib | 722 +++--------------- .../Controls/LongTouchViewController.xib | 721 +++-------------- example/Controls/features/doubletap.feature | 4 +- example/Controls/features/longpress.feature | 4 +- .../step_definitions/carousel_steps.rb | 4 +- .../step_definitions/data_entry_steps.rb | 2 + .../step_definitions/table_deletion_steps.rb | 20 +- .../features/step_definitions/table_steps.rb | 1 + example/Controls/features/ui_switch.feature | 10 - example/Controls/features/ui_table.feature | 11 +- 14 files changed, 324 insertions(+), 2034 deletions(-) diff --git a/example/Controls/Controls.xcodeproj/project.pbxproj b/example/Controls/Controls.xcodeproj/project.pbxproj index 27cf120..16f4a24 100644 --- a/example/Controls/Controls.xcodeproj/project.pbxproj +++ b/example/Controls/Controls.xcodeproj/project.pbxproj @@ -412,6 +412,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Controls/Controls-Prefix.pch"; INFOPLIST_FILE = "Controls/Controls-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; LIBRARY_SEARCH_PATHS = ( "$(inherited)", "$(FRANK_LIBRARY_SEARCH_PATHS)", @@ -434,6 +435,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "Controls/Controls-Prefix.pch"; INFOPLIST_FILE = "Controls/Controls-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PRODUCT_NAME = "$(TARGET_NAME)"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; diff --git a/example/Controls/Controls/AlertViewController.xib b/example/Controls/Controls/AlertViewController.xib index 27a2e24..356ea8c 100644 --- a/example/Controls/Controls/AlertViewController.xib +++ b/example/Controls/Controls/AlertViewController.xib @@ -1,281 +1,39 @@ - - - - 1536 - 12C60 - 2844 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1930 - - - IBNSLayoutConstraint - IBProxyObject - IBUIButton - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{84, 147}, {152, 44}} - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Show UIAlertView - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - {{0, 20}, {320, 548}} - - - - - 3 - MQA - - 2 - - - - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - showAlertView - - - - 7 - - - - showAlertViewPressed: - - - 7 - - 8 - - - - - - 0 - - - - - - 1 - - - - - - 3 - 0 - - 3 - 1 - - 147 - - 1000 - - 3 - 9 - 3 - - - - 9 - 0 - - 9 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - 6 - - - - - 26 - - - - - - - AlertViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 26 - - - - - AlertViewController - UIViewController - - showAlertViewPressed: - id - - - showAlertViewPressed: - - showAlertViewPressed: - id - - - - showAlertView - UIButton - - - showAlertView - - showAlertView - UIButton - - - - IBProjectSource - ./Classes/AlertViewController.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - YES - 1930 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/Controls/Controls/Carousel.m b/example/Controls/Controls/Carousel.m index 9dd22af..e58e742 100644 --- a/example/Controls/Controls/Carousel.m +++ b/example/Controls/Controls/Carousel.m @@ -42,6 +42,7 @@ - (void)setup imageView.tag = 100+i; [imageView setImage:[UIImage imageNamed:[self.images objectAtIndex:i]]]; [imageView setContentMode:UIViewContentModeScaleAspectFit]; + [imageView setAccessibilityLabel:[self.images objectAtIndex:i]]; [slide addSubview:imageView]; [imageView release]; diff --git a/example/Controls/Controls/DataEntryViewController.xib b/example/Controls/Controls/DataEntryViewController.xib index 8ea118c..1345641 100644 --- a/example/Controls/Controls/DataEntryViewController.xib +++ b/example/Controls/Controls/DataEntryViewController.xib @@ -1,454 +1,82 @@ - - - - 1552 - 11G63b - 3084 - 1138.51 - 569.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 2083 - - - IBProxyObject - IBUILabel - IBUISegmentedControl - IBUISwitch - IBUITextField - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{20, 20}, {280, 31}} - - - - _NS:9 - NO - YES - IBCocoaTouchFramework - 0 - - 3 - Edit me - - 3 - MAA - - 2 - - - YES - 17 - - 1 - IBCocoaTouchFramework - - - 1 - 14 - - - Helvetica - 14 - 16 - - - - - 292 - {{20, 323}, {280, 73}} - - - - - 3 - MC43NQA - - - NO - YES - 7 - NO - - - - - - IBCocoaTouchFramework - - - 1 - MCAwIDAAA - darkTextColor - - - 10 - 0 - 1 - - 1 - 17 - - - Helvetica - 17 - 16 - - 280 - - - - 292 - {{20, 111}, {280, 44}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 2 - 0 - - Default - Email - - - - - - - - - - - {0, 0} - {0, 0} - - - - - - - - - 292 - {{20, 82}, {110, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Keyboard type - - - 0 - - - NO - - - - 292 - {{20, 203}, {148, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Word Capitalization - - - 0 - - - NO - - - - 292 - {{208, 200}, {94, 27}} - - - - _NS:9 - NO - - - Capitalize - - IBCocoaTouchFramework - 0 - 0 - - - {{0, 64}, {320, 416}} - - - - - 3 - MQA - - - - - NO - - IBCocoaTouchFramework - - - - - - - view - - - - 3 - - - - outputLabel - - - - 9 - - - - theTextField - - - - 13 - - - - keyboardSelector - - - - 16 - - - - capitalizationSwitch - - - - 25 - - - - didEndEditing: - - - 19 - - 10 - - - - delegate - - - - 12 - - - - keyboardSelectorValueDidChange: - - - 13 - - 18 - - - - capitalizationSwitchDidChange: - - - 13 - - 26 - - - - - - 0 - - - - - - 1 - - - - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - 7 - - - - - 14 - - - - - 15 - - - - - 22 - - - - - 23 - - - - - - - DataEntryViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 28 - - - - - DataEntryViewController - UIViewController - - UISwitch - id - UISegmentedControl - - - - capitalizationSwitchDidChange: - UISwitch - - - didEndEditing: - id - - - keyboardSelectorValueDidChange: - UISegmentedControl - - - - UISwitch - UISegmentedControl - UILabel - UITextField - - - - capitalizationSwitch - UISwitch - - - keyboardSelector - UISegmentedControl - - - outputLabel - UILabel - - - theTextField - UITextField - - - - IBProjectSource - ./Classes/DataEntryViewController.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - 2083 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/Controls/Controls/DoubleTapViewController.xib b/example/Controls/Controls/DoubleTapViewController.xib index f8c6e44..e486a17 100644 --- a/example/Controls/Controls/DoubleTapViewController.xib +++ b/example/Controls/Controls/DoubleTapViewController.xib @@ -1,637 +1,85 @@ - - - - 1536 - 12C60 - 2844 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1930 - - - IBNSLayoutConstraint - IBProxyObject - IBUIButton - IBUILabel - IBUITapGestureRecognizer - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{64, 189}, {99, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Double Tap: - - 1 - MCAwIDAAA - darkTextColor - - - 0 - - 2 - 17 - - - Helvetica-Bold - 17 - 16 - - NO - - - - 292 - {{171, 189}, {86, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - <touched> - - - 0 - - - NO - - - - 292 - {{171, 218}, {86, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - <location> - - - 0 - - - NO - - - - 292 - {{64, 218}, {77, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Location: - - - 0 - - - NO - - - - 292 - {{128, 459}, {65, 44}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Reset - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - {{0, 20}, {320, 548}} - - - - - 3 - MQA - - 2 - - - - - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - 2 - - - - - - - view - - - - 3 - - - - triggeredLabel - - - - 24 - - - - locationLabel - - - - 25 - - - - gestureRecognizers - - - NSArray - YES - - 27 - - - - resetDidGetPressed: - - - 7 - - 23 - - - - doubleTapWasTriggered: - - - - 28 - - - - - - 0 - - - - - - 1 - - - - - 9 - 0 - - 9 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - - - - 4 - 0 - - 4 - 1 - - 46 - - 1000 - - 3 - 9 - 3 - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 5 - 0 - - 6 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 3 - 0 - - 4 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 3 - 0 - - 3 - 1 - - 189 - - 1000 - - 3 - 9 - 3 - - - - 5 - 0 - - 5 - 1 - - 64 - - 1000 - - 3 - 9 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - 15 - - - - - 17 - - - - - 19 - - - - - 20 - - - - - 21 - - - - - 22 - - - - - 26 - - - - - - - DoubleTapViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - - - - - - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 28 - - - - - DoubleTapViewController - UIViewController - - id - id - - - - doubleTapWasTriggered: - id - - - resetDidGetPressed: - id - - - - UILabel - UILabel - - - - locationLabel - UILabel - - - triggeredLabel - UILabel - - - - IBProjectSource - ./Classes/DoubleTapViewController.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - YES - 1930 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/Controls/Controls/LongTouchViewController.xib b/example/Controls/Controls/LongTouchViewController.xib index a282891..6676e63 100644 --- a/example/Controls/Controls/LongTouchViewController.xib +++ b/example/Controls/Controls/LongTouchViewController.xib @@ -1,636 +1,85 @@ - - - - 1536 - 12C60 - 2844 - 1187.34 - 625.00 - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - 1930 - - - IBNSLayoutConstraint - IBProxyObject - IBUIButton - IBUILabel - IBUILongPressGestureRecognizer - IBUIView - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - PluginDependencyRecalculationVersion - - - - - IBFilesOwner - IBCocoaTouchFramework - - - IBFirstResponder - IBCocoaTouchFramework - - - - 274 - - - - 292 - {{63, 158}, {99, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - LongTouch: - - 1 - MCAwIDAAA - darkTextColor - - - 0 - - 2 - 17 - - - Helvetica-Bold - 17 - 16 - - NO - - - - 292 - {{170, 158}, {86, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - <touched> - - - 0 - - - NO - - - - 292 - {{170, 187}, {86, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - <location> - - - 0 - - - NO - - - - 292 - {{63, 187}, {77, 21}} - - - - _NS:9 - NO - YES - 7 - NO - IBCocoaTouchFramework - Location: - - - 0 - - - NO - - - - 292 - {{128, 411}, {65, 44}} - - - - _NS:9 - NO - IBCocoaTouchFramework - 0 - 0 - 1 - Reset - - 3 - MQA - - - 1 - MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA - - - 3 - MC41AA - - - 2 - 15 - - - Helvetica-Bold - 15 - 16 - - - - {{0, 20}, {320, 548}} - - - - - 3 - MQA - - 2 - - - - - - IBUIScreenMetrics - - YES - - - - - - {320, 568} - {568, 320} - - - IBCocoaTouchFramework - Retina 4 Full Screen - 2 - - IBCocoaTouchFramework - - - - - - - - view - - - - 3 - - - - longTouchTriggered - - - - 50 - - - - touchLocation - - - - 51 - - - - gestureRecognizers - - - NSArray - YES - - 59 - - - - resetDidGetPressed: - - - 7 - - 53 - - - - longPressDidTrigger: - - - - 60 - - - - - - 0 - - - - - - 1 - - - - - 9 - 0 - - 9 - 1 - - 0.0 - - 1000 - - 5 - 22 - 2 - - - - 4 - 0 - - 4 - 1 - - 94 - - 1000 - - 3 - 9 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 5 - 0 - - 6 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 11 - 0 - - 11 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 3 - 0 - - 4 - 1 - - 8 - - 1000 - - 6 - 24 - 3 - - - - 5 - 0 - - 5 - 1 - - 0.0 - - 1000 - - 6 - 24 - 2 - - - - 3 - 0 - - 3 - 1 - - 158 - - 1000 - - 3 - 9 - 3 - - - - 5 - 0 - - 5 - 1 - - 63 - - 1000 - - 3 - 9 - 3 - - - - - - - - - - - -1 - - - File's Owner - - - -2 - - - - - 4 - - - - - - 10 - - - - - 20 - - - - - 23 - - - - - 25 - - - - - 28 - - - - - 29 - - - - - 30 - - - - - 39 - - - - - 42 - - - - - 46 - - - - - 47 - - - - - 48 - - - - - 49 - - - - - 57 - - - - - 58 - - - - - - - LongTouchViewController - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - UIResponder - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - - - - - - - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - com.apple.InterfaceBuilder.IBCocoaTouchPlugin - - - - - - 61 - - - - - LongTouchViewController - UIViewController - - id - id - - - - longPressDidTrigger: - id - - - resetDidGetPressed: - id - - - - UILabel - UILabel - - - - longTouchTriggered - UILabel - - - touchLocation - UILabel - - - - IBProjectSource - ./Classes/LongTouchViewController.h - - - - NSLayoutConstraint - NSObject - - IBProjectSource - ./Classes/NSLayoutConstraint.h - - - - - 0 - IBCocoaTouchFramework - YES - 3 - YES - 1930 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example/Controls/features/doubletap.feature b/example/Controls/features/doubletap.feature index 1748e80..353c7a8 100644 --- a/example/Controls/features/doubletap.feature +++ b/example/Controls/features/doubletap.feature @@ -13,6 +13,6 @@ Feature: Then I should see "YES" Scenario: Long touch the main view at a specific point - When I douple tap "Double Tap View" at x "60" y "40" + When I douple tap "Double Tap View" at x "60" y "110" Then I should see "YES" - And I should see "{60, 40}" \ No newline at end of file + And I should see "{60, 110}" diff --git a/example/Controls/features/longpress.feature b/example/Controls/features/longpress.feature index d4823ff..05483d4 100644 --- a/example/Controls/features/longpress.feature +++ b/example/Controls/features/longpress.feature @@ -12,6 +12,6 @@ Feature: Then I should see "YES" Scenario: Long touch the main view at a specific point - When I long press "Long Touch View" at x "60" y "40" + When I long press "Long Touch View" at x "60" y "110" Then I should see "YES" - And I should see "{60, 40}" \ No newline at end of file + And I should see "{60, 110}" diff --git a/example/Controls/features/step_definitions/carousel_steps.rb b/example/Controls/features/step_definitions/carousel_steps.rb index 3702a02..882d54e 100644 --- a/example/Controls/features/step_definitions/carousel_steps.rb +++ b/example/Controls/features/step_definitions/carousel_steps.rb @@ -1,6 +1,6 @@ CAROUSEL_SELECTOR_FRAGMENT = "view:'Carousel'" -PORTRAIT_IPHONE_WIDTH = 320 -PORTRAIT_IPHONE_HEIGHT = 480 +PORTRAIT_IPHONE_WIDTH = 640 +PORTRAIT_IPHONE_HEIGHT = 960 When /^I page the carousel to the right$/ do frankly_map( "#{CAROUSEL_SELECTOR_FRAGMENT}", 'swipeInDirection:', 'left' ) diff --git a/example/Controls/features/step_definitions/data_entry_steps.rb b/example/Controls/features/step_definitions/data_entry_steps.rb index 51b116f..ab29152 100644 --- a/example/Controls/features/step_definitions/data_entry_steps.rb +++ b/example/Controls/features/step_definitions/data_entry_steps.rb @@ -7,6 +7,8 @@ Then /^I should be able to enter "(.*?)" correctly using the keyboard$/ do |text_to_type| step %Q|I type "#{text_to_type}" into the "Edit me" text field using the keyboard| + wait_for_nothing_to_be_animating + sleep 1 expected_text = "text entered into text field: #{text_to_type}" check_element_exists( "view:'UILabel' text:'#{expected_text}'" ) diff --git a/example/Controls/features/step_definitions/table_deletion_steps.rb b/example/Controls/features/step_definitions/table_deletion_steps.rb index 662180d..6d40db6 100644 --- a/example/Controls/features/step_definitions/table_deletion_steps.rb +++ b/example/Controls/features/step_definitions/table_deletion_steps.rb @@ -1,6 +1,6 @@ When /^I confirm table cell deletion$/ do wait_for_nothing_to_be_animating - touch "view:'UITableViewCellDeleteConfirmationControl'" + touch "view:'UITableViewCellDeleteConfirmationButton'" wait_for_nothing_to_be_animating end @@ -10,11 +10,11 @@ end When /^I should see the confirm deletion button$/ do - check_element_exists_and_is_visible("view:'UITableViewCellDeleteConfirmationControl'") + check_element_exists_and_is_visible("view:'UITableViewCellDeleteConfirmationButton'") end When /^I should not see the confirm deletion button$/ do - check_element_does_not_exist_or_is_not_visible("view:'UITableViewCellDeleteConfirmationControl'") + check_element_does_not_exist_or_is_not_visible("view:'UITableViewCellDeleteConfirmationButton'") end Then /^I should not see an "(.*?)" button$/ do |button_mark| @@ -28,3 +28,17 @@ Then /^I should not see a "(.*?)" button$/ do |button_mark| check_element_does_not_exist_or_is_not_visible("button marked:'#{button_mark}'") end + +Then(/^"(.*?)" should be scrolled off the top of the screen$/) do |label_mark| + accessibility_frame("view:'UITableViewCell' view marked:'#{label_mark}").y.should be < 0 +end + +Then(/^"(.*?)" should be scrolled off the left of the screen$/) do |label_mark| + frame = accessibility_frame("view:'UITableViewCell' view marked:'#{label_mark}") + right = frame.x + frame.width + right.should be <= 0 +end + +Then(/^"(.*?)" should be visible on screen$/) do |label_mark| + accessibility_frame("view:'UITableViewCell' view marked:'#{label_mark}").y.should be >= 0 +end diff --git a/example/Controls/features/step_definitions/table_steps.rb b/example/Controls/features/step_definitions/table_steps.rb index 021c106..77dff0d 100644 --- a/example/Controls/features/step_definitions/table_steps.rb +++ b/example/Controls/features/step_definitions/table_steps.rb @@ -17,6 +17,7 @@ end When /^I drag the "(.*?)" row down to the "(.*?)" row$/ do |drag_row_mark, dest_row_mark| + wait_for_nothing_to_be_animating drag_target_selector = %Q|tableViewCell label marked:'#{drag_row_mark}' parent tableViewCell view:'UITableViewCellReorderControl'| drag_dest_selector = %Q|tableViewCell label marked:'#{dest_row_mark}' parent tableViewCell view:'UITableViewCellReorderControl'| diff --git a/example/Controls/features/ui_switch.feature b/example/Controls/features/ui_switch.feature index 96b99e3..b37a08d 100644 --- a/example/Controls/features/ui_switch.feature +++ b/example/Controls/features/ui_switch.feature @@ -15,13 +15,3 @@ Feature: When I swipe "the switch" rightwards Then I should see "Switch is on" - - Scenario: Swiping the switch up and down has no effect - Given I swipe "the switch" leftwards - And I should see "Switch is off" - - When I swipe "the switch" upwards - Then I should see "Switch is off" - - When I swipe "the switch" downwards - Then I should see "Switch is off" diff --git a/example/Controls/features/ui_table.feature b/example/Controls/features/ui_table.feature index 0797c03..b4a5c37 100644 --- a/example/Controls/features/ui_table.feature +++ b/example/Controls/features/ui_table.feature @@ -17,8 +17,7 @@ Scenario: delete with swipe Then I should see the confirm deletion button When I confirm table cell deletion - Then I should not see the confirm deletion button - And I should not see "Larry" + Then "Larry" should be scrolled off the left of the screen But I should see "Curly" And I should see "Moe" @@ -28,9 +27,7 @@ Scenario: delete with edit mode Then I should see the confirm deletion button When I confirm table cell deletion - Then I should not see the confirm deletion button - - And I should not see "Moe" + Then "Moe" should be scrolled off the left of the screen But I should see "Larry" And I should see "Curly" @@ -59,10 +56,10 @@ Scenario: scrolling up and down and all around When I scroll the table to the 3rd row Then I should see "Curly" - But I should not see "Larry" + But "First Row" should be scrolled off the top of the screen When I scroll the table to the top - Then I should see "First Row" + Then "First Row" should be visible on screen Scenario: rearranging rows Then the "Larry" row should be above the "Moe" row From 886f3bf608b643ab8bdf1a1a09b8b82164dee86e Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Sun, 22 Dec 2013 10:15:01 -0800 Subject: [PATCH 04/13] Limit Bonjour to IPv4 --- gem/lib/frank-cucumber/bonjour.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/gem/lib/frank-cucumber/bonjour.rb b/gem/lib/frank-cucumber/bonjour.rb index 06cd619..689abcc 100644 --- a/gem/lib/frank-cucumber/bonjour.rb +++ b/gem/lib/frank-cucumber/bonjour.rb @@ -1,3 +1,5 @@ +require 'socket' +require 'ipaddr' require 'timeout' require 'uri' @@ -27,8 +29,11 @@ def found_a_frank( reply ) address = nil addr_service.getaddrinfo r.target do |addrinfo| - address = addrinfo.address - break + ipaddr = (IPAddr.new(addrinfo.address) rescue nil) + if ipaddr != nil and ipaddr.family == Socket::AF_INET + address = addrinfo.address + break + end end debug "first address for #{r.target} is #{address}" @@ -41,7 +46,7 @@ def browse_for_franks_address DNSSD.browse! '_http._tcp.' do |reply| debug 'got a reply' - if reply.name == FRANK_SERVICE_NAME + if reply.name == FRANK_SERVICE_NAME address = found_a_frank(reply) if address debug "OK WE HAVE AN ADDRESS: #{address}" From ab07c40ff83e6fa107501a05213692e60c501693 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Sun, 22 Dec 2013 10:44:26 -0800 Subject: [PATCH 05/13] Rotation now uses private UIApplication method --- src/OrientationCommand.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/OrientationCommand.m b/src/OrientationCommand.m index 1c948db..51de2f5 100644 --- a/src/OrientationCommand.m +++ b/src/OrientationCommand.m @@ -7,11 +7,12 @@ // #import "OrientationCommand.h" - -#import #import "FranklyProtocolHelper.h" #import "JSON.h" +@interface UIApplication (Private) +- (BOOL)rotateIfNeeded:(UIDeviceOrientation)orientation; +@end @implementation OrientationCommand @@ -106,7 +107,7 @@ - (NSString *)handlePost:(NSString *)requestBody{ andDetails:[NSString stringWithFormat:@"orientation '%@' is invalid. Use 'landscape_right','landscape_left','portrait', or 'portrait_upside_down'", requestBody]]; } - [UIAutomationBridge setOrientation:requestedOrientation]; + [[UIApplication sharedApplication] rotateIfNeeded:requestedOrientation]; return [FranklyProtocolHelper generateSuccessResponseWithoutResults]; } From b9cc4b3f6d2ca0e0f7f0b93cc79a9a3f897bb930 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Wed, 15 Jan 2014 21:27:15 -0800 Subject: [PATCH 06/13] Updated touch and drag events to synthesize UIEvents, making them work on actual devices --- Frank.xcodeproj/project.pbxproj | 97 +++++++----- .../xcschemes/CocoaHTTPServer.xcscheme | 2 +- .../xcshareddata/xcschemes/Frank.xcscheme | 2 +- .../xcshareddata/xcschemes/FrankMac.xcscheme | 2 +- src/UIView+PublicAutomation.m | 140 ++++++++++++++++-- 5 files changed, 187 insertions(+), 56 deletions(-) diff --git a/Frank.xcodeproj/project.pbxproj b/Frank.xcodeproj/project.pbxproj index c8fb630..d6f1f2f 100644 --- a/Frank.xcodeproj/project.pbxproj +++ b/Frank.xcodeproj/project.pbxproj @@ -22,6 +22,16 @@ 30228E221642161200B1F9E7 /* AppCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1DD76A12BADFE100E10B8C /* AppCommand.m */; }; 30228E261642161200B1F9E7 /* EnginesCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = D6FA01B714283C4F00576AEE /* EnginesCommand.m */; }; 30228E281642161200B1F9E7 /* ExitCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = A91F3AA515F6E456003F434F /* ExitCommand.m */; }; + 3023E0F41867D60500E2EA70 /* KIFTypist.h in Headers */ = {isa = PBXBuildFile; fileRef = 3023E0F21867D60500E2EA70 /* KIFTypist.h */; }; + 3023E0F51867D60500E2EA70 /* KIFTypist.m in Sources */ = {isa = PBXBuildFile; fileRef = 3023E0F31867D60500E2EA70 /* KIFTypist.m */; }; + 3023E0FE1867D62200E2EA70 /* CGGeometry-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3023E0F61867D62200E2EA70 /* CGGeometry-KIFAdditions.h */; }; + 3023E0FF1867D62200E2EA70 /* CGGeometry-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3023E0F71867D62200E2EA70 /* CGGeometry-KIFAdditions.m */; }; + 3023E1001867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3023E0F81867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.h */; }; + 3023E1011867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3023E0F91867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.m */; }; + 3023E1021867D62200E2EA70 /* UIApplication-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3023E0FA1867D62200E2EA70 /* UIApplication-KIFAdditions.h */; }; + 3023E1031867D62200E2EA70 /* UIApplication-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3023E0FB1867D62200E2EA70 /* UIApplication-KIFAdditions.m */; }; + 3023E1041867D62200E2EA70 /* UIView-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 3023E0FC1867D62200E2EA70 /* UIView-KIFAdditions.h */; }; + 3023E1051867D62200E2EA70 /* UIView-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3023E0FD1867D62200E2EA70 /* UIView-KIFAdditions.m */; }; 302B80411646DE02000F9861 /* NSImage+Frank.h in Headers */ = {isa = PBXBuildFile; fileRef = 302B803F1646DE02000F9861 /* NSImage+Frank.h */; }; 302B80421646DE02000F9861 /* NSImage+Frank.m in Sources */ = {isa = PBXBuildFile; fileRef = 302B80401646DE02000F9861 /* NSImage+Frank.m */; }; 3034CD4B1794CCE000A3794F /* FEXTableRow.h in Headers */ = {isa = PBXBuildFile; fileRef = 3034CD491794CCE000A3794F /* FEXTableRow.h */; }; @@ -71,6 +81,8 @@ 30AC65A4165C39FF00DEB0AB /* FrankMac-Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = 30AC65A3165C39FF00DEB0AB /* FrankMac-Prefix.pch */; }; 30AC65A7165C3A4D00DEB0AB /* OSXKeyboardCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 30AC65A5165C3A4D00DEB0AB /* OSXKeyboardCommand.h */; }; 30AC65A8165C3A4D00DEB0AB /* OSXKeyboardCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 30AC65A6165C3A4D00DEB0AB /* OSXKeyboardCommand.m */; }; + 30B7346E187EF964000136CE /* UITouch-KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = 30B7346C187EF964000136CE /* UITouch-KIFAdditions.h */; }; + 30B7346F187EF964000136CE /* UITouch-KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 30B7346D187EF964000136CE /* UITouch-KIFAdditions.m */; }; 30C544B1167E4D9E0034F49C /* SuccessCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 30C544AF167E4D9E0034F49C /* SuccessCommand.h */; }; 30C544B2167E4D9E0034F49C /* SuccessCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 30C544AF167E4D9E0034F49C /* SuccessCommand.h */; }; 30C544B3167E4D9E0034F49C /* SuccessCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 30C544B0167E4D9E0034F49C /* SuccessCommand.m */; }; @@ -145,9 +157,7 @@ C18A5EF1160D4AB400DC25F6 /* ImageCaptureRoute.m in Sources */ = {isa = PBXBuildFile; fileRef = C18A5EEF160D4AB400DC25F6 /* ImageCaptureRoute.m */; }; C18A5EF5160D4AD300DC25F6 /* UIView+ImageCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = C18A5EF3160D4AD300DC25F6 /* UIView+ImageCapture.h */; }; C18A5EF6160D4AD300DC25F6 /* UIView+ImageCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = C18A5EF4160D4AD300DC25F6 /* UIView+ImageCapture.m */; }; - C18A5F17160D528C00DC25F6 /* PublicAutomation.xcodeproj in Resources */ = {isa = PBXBuildFile; fileRef = C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */; }; C18A5F1E160D547A00DC25F6 /* UIView+PublicAutomation.m in Sources */ = {isa = PBXBuildFile; fileRef = C18A5F1D160D547A00DC25F6 /* UIView+PublicAutomation.m */; }; - C18A5F21160D572300DC25F6 /* libPublicAutomation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C18A5F20160D572300DC25F6 /* libPublicAutomation.a */; }; C9605E641606BF2900170F88 /* IOSKeyboardCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = C9605E621606BF2900170F88 /* IOSKeyboardCommand.h */; }; C9605E651606BF2900170F88 /* IOSKeyboardCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = C9605E631606BF2900170F88 /* IOSKeyboardCommand.m */; }; C9605E671606BF8E00170F88 /* UIView+MapKitWorkaround.m in Sources */ = {isa = PBXBuildFile; fileRef = C9605E661606BF8E00170F88 /* UIView+MapKitWorkaround.m */; }; @@ -225,13 +235,6 @@ remoteGlobalIDString = ABA9E44015C81C2600112290; remoteInfo = CocoaHTTPServer; }; - C127EF0F1612BCD400EA121C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */; - proxyType = 2; - remoteGlobalIDString = C194253815D838BD004FC314; - remoteInfo = PublicAutomation; - }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -303,6 +306,16 @@ 30198DF917936DCD00F686A7 /* FEXTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FEXTableCell.h; sourceTree = ""; }; 30198DFA17936DCD00F686A7 /* FEXTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FEXTableCell.m; sourceTree = ""; }; 30228E2916421C4400B1F9E7 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; + 3023E0F21867D60500E2EA70 /* KIFTypist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = KIFTypist.h; path = KIF/Classes/KIFTypist.h; sourceTree = ""; }; + 3023E0F31867D60500E2EA70 /* KIFTypist.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = KIFTypist.m; path = KIF/Classes/KIFTypist.m; sourceTree = ""; }; + 3023E0F61867D62200E2EA70 /* CGGeometry-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "CGGeometry-KIFAdditions.h"; path = "KIF/Additions/CGGeometry-KIFAdditions.h"; sourceTree = ""; }; + 3023E0F71867D62200E2EA70 /* CGGeometry-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "CGGeometry-KIFAdditions.m"; path = "KIF/Additions/CGGeometry-KIFAdditions.m"; sourceTree = ""; }; + 3023E0F81867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIAccessibilityElement-KIFAdditions.h"; path = "KIF/Additions/UIAccessibilityElement-KIFAdditions.h"; sourceTree = ""; }; + 3023E0F91867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIAccessibilityElement-KIFAdditions.m"; path = "KIF/Additions/UIAccessibilityElement-KIFAdditions.m"; sourceTree = ""; }; + 3023E0FA1867D62200E2EA70 /* UIApplication-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIApplication-KIFAdditions.h"; path = "KIF/Additions/UIApplication-KIFAdditions.h"; sourceTree = ""; }; + 3023E0FB1867D62200E2EA70 /* UIApplication-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIApplication-KIFAdditions.m"; path = "KIF/Additions/UIApplication-KIFAdditions.m"; sourceTree = ""; }; + 3023E0FC1867D62200E2EA70 /* UIView-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView-KIFAdditions.h"; path = "KIF/Additions/UIView-KIFAdditions.h"; sourceTree = ""; }; + 3023E0FD1867D62200E2EA70 /* UIView-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView-KIFAdditions.m"; path = "KIF/Additions/UIView-KIFAdditions.m"; sourceTree = ""; }; 302B803F1646DE02000F9861 /* NSImage+Frank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSImage+Frank.h"; sourceTree = ""; }; 302B80401646DE02000F9861 /* NSImage+Frank.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSImage+Frank.m"; sourceTree = ""; }; 3034CD491794CCE000A3794F /* FEXTableRow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FEXTableRow.h; sourceTree = ""; }; @@ -328,6 +341,8 @@ 30AC65A3165C39FF00DEB0AB /* FrankMac-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FrankMac-Prefix.pch"; sourceTree = ""; }; 30AC65A5165C3A4D00DEB0AB /* OSXKeyboardCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSXKeyboardCommand.h; sourceTree = ""; }; 30AC65A6165C3A4D00DEB0AB /* OSXKeyboardCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSXKeyboardCommand.m; sourceTree = ""; }; + 30B7346C187EF964000136CE /* UITouch-KIFAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UITouch-KIFAdditions.h"; path = "KIF/Additions/UITouch-KIFAdditions.h"; sourceTree = ""; }; + 30B7346D187EF964000136CE /* UITouch-KIFAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UITouch-KIFAdditions.m"; path = "KIF/Additions/UITouch-KIFAdditions.m"; sourceTree = ""; }; 30C544AF167E4D9E0034F49C /* SuccessCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SuccessCommand.h; sourceTree = ""; }; 30C544B0167E4D9E0034F49C /* SuccessCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SuccessCommand.m; sourceTree = ""; }; 30E82E3017128AB500E5BC7C /* ResolutionCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResolutionCommand.h; sourceTree = ""; }; @@ -408,9 +423,7 @@ C18A5EEF160D4AB400DC25F6 /* ImageCaptureRoute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ImageCaptureRoute.m; sourceTree = ""; }; C18A5EF3160D4AD300DC25F6 /* UIView+ImageCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+ImageCapture.h"; sourceTree = ""; }; C18A5EF4160D4AD300DC25F6 /* UIView+ImageCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+ImageCapture.m"; sourceTree = ""; }; - C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = PublicAutomation.xcodeproj; path = PublicAutomation/PublicAutomation.xcodeproj; sourceTree = ""; }; C18A5F1D160D547A00DC25F6 /* UIView+PublicAutomation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+PublicAutomation.m"; sourceTree = ""; }; - C18A5F20160D572300DC25F6 /* libPublicAutomation.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPublicAutomation.a; path = "lib/PublicAutomation/build/Release-iphoneos/libPublicAutomation.a"; sourceTree = ""; }; C9605E621606BF2900170F88 /* IOSKeyboardCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = IOSKeyboardCommand.h; sourceTree = ""; }; C9605E631606BF2900170F88 /* IOSKeyboardCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IOSKeyboardCommand.m; sourceTree = ""; }; C9605E661606BF8E00170F88 /* UIView+MapKitWorkaround.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+MapKitWorkaround.m"; sourceTree = ""; }; @@ -506,7 +519,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - C18A5F21160D572300DC25F6 /* libPublicAutomation.a in Frameworks */, AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */, D629938011AB2DF300CE0FB0 /* UIKit.framework in Frameworks */, 00E864C5161D708B00E01209 /* MapKit.framework in Frameworks */, @@ -536,7 +548,6 @@ children = ( 30228E2916421C4400B1F9E7 /* Cocoa.framework */, 305CA7A31642063E00C4ACE5 /* Foundation.framework */, - C18A5F20160D572300DC25F6 /* libPublicAutomation.a */, 00E864C4161D708B00E01209 /* MapKit.framework */, 08FB77AEFE84172EC02AAC07 /* src */, D629926711AB2CF700CE0FB0 /* lib */, @@ -572,6 +583,25 @@ path = src; sourceTree = ""; }; + 3023E0F11867D5DC00E2EA70 /* KIF */ = { + isa = PBXGroup; + children = ( + 30B7346C187EF964000136CE /* UITouch-KIFAdditions.h */, + 30B7346D187EF964000136CE /* UITouch-KIFAdditions.m */, + 3023E0F61867D62200E2EA70 /* CGGeometry-KIFAdditions.h */, + 3023E0F71867D62200E2EA70 /* CGGeometry-KIFAdditions.m */, + 3023E0F81867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.h */, + 3023E0F91867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.m */, + 3023E0FA1867D62200E2EA70 /* UIApplication-KIFAdditions.h */, + 3023E0FB1867D62200E2EA70 /* UIApplication-KIFAdditions.m */, + 3023E0FC1867D62200E2EA70 /* UIView-KIFAdditions.h */, + 3023E0FD1867D62200E2EA70 /* UIView-KIFAdditions.m */, + 3023E0F21867D60500E2EA70 /* KIFTypist.h */, + 3023E0F31867D60500E2EA70 /* KIFTypist.m */, + ); + name = KIF; + sourceTree = ""; + }; 305CA7751642059400C4ACE5 /* Other Frameworks */ = { isa = PBXGroup; children = ( @@ -675,14 +705,6 @@ path = Extensions; sourceTree = ""; }; - C127EF0C1612BCD400EA121C /* Products */ = { - isa = PBXGroup; - children = ( - C127EF101612BCD400EA121C /* libPublicAutomation.a */, - ); - name = Products; - sourceTree = ""; - }; C177A4C9163231870081DF77 /* AnyJSON */ = { isa = PBXGroup; children = ( @@ -809,8 +831,8 @@ D629926711AB2CF700CE0FB0 /* lib */ = { isa = PBXGroup; children = ( + 3023E0F11867D5DC00E2EA70 /* KIF */, C177A4C9163231870081DF77 /* AnyJSON */, - C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */, D629926811AB2D0500CE0FB0 /* cocoahttpserver */, D67F2B3313F5F82700A0BFF1 /* LoadableCategory.h */, ); @@ -870,8 +892,10 @@ AA747D9F0F9514B9006C5449 /* Frank_Prefix.pch in Headers */, D6D05CB511C883AA0081C5A5 /* FrankCommandRoute.h in Headers */, D6D05CB711C883AA0081C5A5 /* FrankServer.h in Headers */, + 3023E1021867D62200E2EA70 /* UIApplication-KIFAdditions.h in Headers */, D6D05CB911C883AA0081C5A5 /* MapOperationCommand.h in Headers */, D6D05CBD11C883AA0081C5A5 /* RequestRouter.h in Headers */, + 3023E0F41867D60500E2EA70 /* KIFTypist.h in Headers */, D6D05CBF11C883AA0081C5A5 /* RoutingHTTPConnection.h in Headers */, D6D05CC111C883AA0081C5A5 /* StaticResourcesRoute.h in Headers */, D6D79B5D11D7FB8B003E0E60 /* Operation.h in Headers */, @@ -890,10 +914,14 @@ AB7947A915C4412300052B74 /* HTTPServer.h in Headers */, AB7947BB15C4412300052B74 /* WebSocket.h in Headers */, D6FA01B714283C4F00576AF1 /* EnginesCommand.h in Headers */, + 3023E1001867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.h in Headers */, A91F3AA615F6E456003F434F /* ExitCommand.h in Headers */, C9605E641606BF2900170F88 /* IOSKeyboardCommand.h in Headers */, C9605E6A1606BFAE00170F88 /* UIImage+Frank.h in Headers */, + 3023E1041867D62200E2EA70 /* UIView-KIFAdditions.h in Headers */, C18A5EF0160D4AB400DC25F6 /* ImageCaptureRoute.h in Headers */, + 3023E0FE1867D62200E2EA70 /* CGGeometry-KIFAdditions.h in Headers */, + 30B7346E187EF964000136CE /* UITouch-KIFAdditions.h in Headers */, C18A5EF5160D4AD300DC25F6 /* UIView+ImageCapture.h in Headers */, C177A4CC1632319A0081DF77 /* AnyJSON.h in Headers */, 9B3E52AF163FB98300EB24C2 /* LocationCommand.h in Headers */, @@ -1058,7 +1086,7 @@ 0867D690FE84028FC02AAC07 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0450; + LastUpgradeCheck = 0500; }; buildConfigurationList = 1DEB922208733DC00010E9CD /* Build configuration list for PBXProject "Frank" */; compatibilityVersion = "Xcode 3.2"; @@ -1074,12 +1102,6 @@ mainGroup = 0867D691FE84028FC02AAC07 /* Frank */; productRefGroup = 034768DFFF38A50411DB9C8B /* Products */; projectDirPath = ""; - projectReferences = ( - { - ProductGroup = C127EF0C1612BCD400EA121C /* Products */; - ProjectRef = C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */; - }, - ); projectRoot = ""; targets = ( D2AAC07D0554694100DB518D /* Frank */, @@ -1094,22 +1116,11 @@ }; /* End PBXProject section */ -/* Begin PBXReferenceProxy section */ - C127EF101612BCD400EA121C /* libPublicAutomation.a */ = { - isa = PBXReferenceProxy; - fileType = archive.ar; - path = libPublicAutomation.a; - remoteRef = C127EF0F1612BCD400EA121C /* PBXContainerItemProxy */; - sourceTree = BUILT_PRODUCTS_DIR; - }; -/* End PBXReferenceProxy section */ - /* Begin PBXResourcesBuildPhase section */ D6782DD711BC67FE00FD0CE1 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C18A5F17160D528C00DC25F6 /* PublicAutomation.xcodeproj in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1249,7 +1260,9 @@ buildActionMask = 2147483647; files = ( D6D05CB611C883AA0081C5A5 /* FrankCommandRoute.m in Sources */, + 3023E1031867D62200E2EA70 /* UIApplication-KIFAdditions.m in Sources */, D6D05CB811C883AA0081C5A5 /* FrankServer.m in Sources */, + 3023E1051867D62200E2EA70 /* UIView-KIFAdditions.m in Sources */, D6D05CBA11C883AA0081C5A5 /* MapOperationCommand.m in Sources */, D6D05CBE11C883AA0081C5A5 /* RequestRouter.m in Sources */, D6D05CC011C883AA0081C5A5 /* RoutingHTTPConnection.m in Sources */, @@ -1258,6 +1271,7 @@ 4C1DD76C12BADFE100E10B8C /* OrientationCommand.m in Sources */, 4C1DD76E12BADFE100E10B8C /* AppCommand.m in Sources */, D67F2AAE13F5E7FA00A0BFF1 /* AccessibilityCheckCommand.m in Sources */, + 3023E1011867D62200E2EA70 /* UIAccessibilityElement-KIFAdditions.m in Sources */, D67F2AC013F5F55A00A0BFF1 /* FrankLoader.m in Sources */, D6BD521F146C34BF001770B1 /* SelectorEngineRegistry.m in Sources */, 0071264714F8956700E738ED /* ViewJSONSerializer.m in Sources */, @@ -1268,7 +1282,10 @@ C9605E651606BF2900170F88 /* IOSKeyboardCommand.m in Sources */, 0658EF1F17E52FBB000614E6 /* UIApplication+FrankAutomation.m in Sources */, C9605E671606BF8E00170F88 /* UIView+MapKitWorkaround.m in Sources */, + 3023E0FF1867D62200E2EA70 /* CGGeometry-KIFAdditions.m in Sources */, + 30B7346F187EF964000136CE /* UITouch-KIFAdditions.m in Sources */, C9605E6B1606BFAE00170F88 /* UIImage+Frank.m in Sources */, + 3023E0F51867D60500E2EA70 /* KIFTypist.m in Sources */, C18A5EF1160D4AB400DC25F6 /* ImageCaptureRoute.m in Sources */, C18A5EF6160D4AD300DC25F6 /* UIView+ImageCapture.m in Sources */, C18A5F1E160D547A00DC25F6 /* UIView+PublicAutomation.m in Sources */, diff --git a/Frank.xcodeproj/xcshareddata/xcschemes/CocoaHTTPServer.xcscheme b/Frank.xcodeproj/xcshareddata/xcschemes/CocoaHTTPServer.xcscheme index 90d0397..312644a 100644 --- a/Frank.xcodeproj/xcshareddata/xcschemes/CocoaHTTPServer.xcscheme +++ b/Frank.xcodeproj/xcshareddata/xcschemes/CocoaHTTPServer.xcscheme @@ -1,6 +1,6 @@ - #import "LoadableCategory.h" +#import "CGGeometry-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" +#import "UITouch-KIFAdditions.h" +#import "UIView-KIFAdditions.h" MAKE_CATEGORIES_LOADABLE(UIView_PublicAutomation) +@interface UIView () + +- (UIEvent*) _eventWithTouch: (UITouch*) touch; + +@end + NSString * formatCGPointVal(NSValue *val) { CGPoint p = [val CGPointValue]; return [NSString stringWithFormat:@"[%.2f, %.2f]", p.x, p.y]; @@ -160,7 +168,7 @@ - (BOOL)FEX_touchPoint:(CGPoint)point { return NO; } - [UIAutomationBridge tapView:self atPoint:point]; + [self tapAtPoint: point]; return YES; } @@ -175,7 +183,7 @@ - (BOOL)FEX_forcedTouch { return NO; } - [UIAutomationBridge tapView:self atPoint:point]; + [self tapAtPoint: point]; return YES; } @@ -194,7 +202,7 @@ - (BOOL)FEX_forcedTouchx:(NSNumber *)x y:(NSNumber *)y { return NO; } - [UIAutomationBridge tapView:self atPoint:point]; + [self tapAtPoint: point]; return YES; } @@ -209,7 +217,8 @@ - (BOOL)doubleTapPoint:(CGPoint)point { return NO; } - [UIAutomationBridge doubleTapView:self atPoint:point]; + [self tapAtPoint: point]; + [self tapAtPoint: point]; return YES; } @@ -242,7 +251,7 @@ - (BOOL)touchAndHold:(NSTimeInterval)duration point:(CGPoint)point { return NO; } - [UIAutomationBridge longTapView:self atPoint:point forDuration:duration]; + [self longPressAtPoint: point duration: duration]; return YES; } @@ -273,15 +282,120 @@ - (BOOL)touchAndHold:(CGFloat)duration x:(NSNumber *)x y:(NSNumber *)y { //TODO //-(void)swipeInDirection:(NSString *)dir by:(int)pixels { +// THESE MAGIC NUMBERS ARE IMPORTANT. From experimentation it appears that too big or too small a ration leads to +// gestures not being recognized as such by the system. For example setting the big ratio to 0.4 leads to +// swipe-to-delete not working on UITableViewCells. +// Also note that we always include at least a small component in each axes because in the past totally 'right-angled' +//swipes weren't detected properly. But we were using a different approach to touch simulation then, +//so this might now be unnecessary. +#define BIG_RATIO (0.3) +#define BIG_RATIO_IOS7 (0.4) +#define SMALL_RATIO (0.05) +#define SWIPE_DURATION (0.1) + +//returns what portion of the view to swipe along in the x and y axes. ++ (CGSize) swipeRatiosForDirection: (NSString*) direction +{ + CGFloat bigRatio = BIG_RATIO; + + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) + { + bigRatio = BIG_RATIO_IOS7; + } + + if ([direction isEqualToString: @"left"]) + { + return CGSizeMake(-bigRatio, SMALL_RATIO); + } + else if ([direction isEqualToString: @"right"]) + { + return CGSizeMake(bigRatio, SMALL_RATIO); + } + else if ([direction isEqualToString: @"up"]) + { + return CGSizeMake(SMALL_RATIO, -bigRatio); + } + else if ([direction isEqualToString: @"down"]) + { + return CGSizeMake(SMALL_RATIO, bigRatio); + } + else + { + [NSException raise: @"invalid swipe direction" format: @"swipe direction '%@' is invalid", direction]; + return CGSizeZero; + } +} + +- (BOOL) swipeInDirection: (NSString*) strDir +{ + + CGPoint swipeStart = CGPointCenteredInRect([self accessibilityFrame]); + CGSize ratios = [[self class] swipeRatiosForDirection: strDir]; + CGSize viewSize = [self bounds].size; + CGPoint swipeEnd = CGPointMake(swipeStart.x + (ratios.width * viewSize.width), + swipeStart.y + (ratios.height * viewSize.height)); + + return [self FEX_dragToX: swipeEnd.x y: swipeEnd.y duration: SWIPE_DURATION]; +} + +#define NUM_POINTS_IN_DRAG 50 +#define DRAG_TOUCH_DELAY 0.3 -- (NSString *)swipeInDirection:(NSString *)strDir { - PADirection dir = [UIAutomationBridge parseDirection:strDir]; - NSArray *swipeExtremes = [UIAutomationBridge swipeView:self inDirection:dir]; - return [NSString stringWithFormat:@"%@ => %@", formatCGPointVal([swipeExtremes objectAtIndex:0]), formatCGPointVal([swipeExtremes objectAtIndex:1])]; +- (BOOL)FEX_dragWithInitialDelayToX:(CGFloat)x y:(CGFloat)y +{ + return [self FEX_dragToX: x y: y duration: DRAG_TOUCH_DELAY]; } -- (BOOL)FEX_dragWithInitialDelayToX:(CGFloat)x y:(CGFloat)y { - [UIAutomationBridge dragViewWithInitialDelay:self toPoint:CGPointMake(x,y)]; +- (BOOL) FEX_dragToX: (CGFloat) x y: (CGFloat) y duration: (CGFloat) duration +{ + CGPoint startPoint = CGPointCenteredInRect([self accessibilityFrame]); + CGPoint displacement = CGPointMake(x - startPoint.x, y - startPoint.y); + + CGPoint *path = alloca(NUM_POINTS_IN_DRAG * sizeof(CGPoint)); + + for (NSUInteger i = 0; i < NUM_POINTS_IN_DRAG; i++) + { + CGFloat progress = ((CGFloat)i)/(NUM_POINTS_IN_DRAG - 1); + path[i] = CGPointMake(startPoint.x + (progress * displacement.x), + startPoint.y + (progress * displacement.y)); + } + + UITouch* touch = [[UITouch alloc] initAtPoint: [self FEX_centerPoint] inView: self]; + [touch setPhase:UITouchPhaseBegan]; + + UIEvent* eventDown = [self _eventWithTouch: touch]; + [[UIApplication sharedApplication] sendEvent: eventDown]; + + CFRunLoopRunInMode(UIApplicationCurrentRunMode, duration, false); + + for (NSInteger pointIndex = 1; pointIndex < NUM_POINTS_IN_DRAG; ++pointIndex) + { + [touch setLocationInWindow: path[pointIndex]]; + [touch setPhase: UITouchPhaseMoved]; + + UIEvent *eventDrag = [self _eventWithTouch: touch]; + [[UIApplication sharedApplication] sendEvent: eventDrag]; + + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.01, false); + } + + [touch setPhase: UITouchPhaseEnded]; + + UIEvent* eventUp = [self _eventWithTouch: touch]; + [[UIApplication sharedApplication] sendEvent: eventUp]; + + if (touch.view == self && [self canBecomeFirstResponder]) + { + [self becomeFirstResponder]; + } + + while (UIApplicationCurrentRunMode != kCFRunLoopDefaultMode) + { + CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.1, false); + } + + [touch release]; + return YES; } From c2238e9b42d9adf4e4848c4498498614de8ad78a Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Thu, 16 Jan 2014 20:48:19 -0800 Subject: [PATCH 07/13] Drag UISlider thumbs using the new drag method --- src/UISlider+PublicAutomation.m | 33 +++++++++++++++++++++++---- src/UIView+PublicAutomation.m | 40 ++++++++++++++++++++------------- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/src/UISlider+PublicAutomation.m b/src/UISlider+PublicAutomation.m index a536f75..701d4d4 100644 --- a/src/UISlider+PublicAutomation.m +++ b/src/UISlider+PublicAutomation.m @@ -3,17 +3,42 @@ // // Created by Alvaro Barbeira on 27/3/13 // -#import #import "LoadableCategory.h" +#import "CGGeometry-KIFAdditions.h" +#import "UIApplication-KIFAdditions.h" + +@interface UIView () + +- (BOOL) FEX_dragFromPoint: (CGPoint) startPoint + toPoint: (CGPoint) destPoint + duration: (CGFloat) duration + delay: (BOOL) delay; + +@end + MAKE_CATEGORIES_LOADABLE(UISlider_PublicAutomation) +#define UI_SLIDER_TIME_STEP 0.1 + @implementation UISlider(PublicAutomation) -- (BOOL) FEX_dragThumbToValue:(double)value withDuration:(NSTimeInterval)interval { - return [UIAutomationBridge dragThumbInSlider:self toValue:value withDuration:interval]; +- (BOOL) FEX_dragThumbToValue: (double) value withDuration: (NSTimeInterval) duration +{ + CGRect bounds = [self bounds]; + CGRect trackRect = [self trackRectForBounds: bounds]; + CGRect startRect = [self thumbRectForBounds: bounds trackRect: trackRect value: [self value]]; + + CGPoint startPoint = CGPointCenteredInRect(startRect); + CGPoint destPoint = CGPointMake(bounds.size.width * value / [self maximumValue], 1.0); + + startPoint = [self convertPoint: startPoint toView: nil]; + destPoint = [self convertPoint: destPoint toView: nil]; + + return [self FEX_dragFromPoint: startPoint toPoint: destPoint duration: duration delay: NO]; } - (BOOL) FEX_dragThumbToValue:(double) value { - return [UIAutomationBridge dragThumbInSlider:self toValue:value]; + return [self FEX_dragThumbToValue: value withDuration: UI_SLIDER_TIME_STEP]; } + @end \ No newline at end of file diff --git a/src/UIView+PublicAutomation.m b/src/UIView+PublicAutomation.m index 491327e..261b1dd 100644 --- a/src/UIView+PublicAutomation.m +++ b/src/UIView+PublicAutomation.m @@ -19,11 +19,6 @@ - (UIEvent*) _eventWithTouch: (UITouch*) touch; @end -NSString * formatCGPointVal(NSValue *val) { - CGPoint p = [val CGPointValue]; - return [NSString stringWithFormat:@"[%.2f, %.2f]", p.x, p.y]; -} - @implementation UIView(PublicAutomation) #pragma mark - Utils @@ -338,8 +333,8 @@ - (BOOL) swipeInDirection: (NSString*) strDir return [self FEX_dragToX: swipeEnd.x y: swipeEnd.y duration: SWIPE_DURATION]; } -#define NUM_POINTS_IN_DRAG 50 #define DRAG_TOUCH_DELAY 0.3 +#define DRAG_STEP 0.1 - (BOOL)FEX_dragWithInitialDelayToX:(CGFloat)x y:(CGFloat)y { @@ -348,27 +343,42 @@ - (BOOL)FEX_dragWithInitialDelayToX:(CGFloat)x y:(CGFloat)y - (BOOL) FEX_dragToX: (CGFloat) x y: (CGFloat) y duration: (CGFloat) duration { - CGPoint startPoint = CGPointCenteredInRect([self accessibilityFrame]); - CGPoint displacement = CGPointMake(x - startPoint.x, y - startPoint.y); + CGPoint startPoint = CGPointCenteredInRect([self accessibilityFrame]); + return [self FEX_dragFromPoint: startPoint toPoint: CGPointMake(x, y) duration: duration delay: YES]; +} + +- (BOOL) FEX_dragFromPoint: (CGPoint) startPoint + toPoint: (CGPoint) destPoint + duration: (CGFloat) duration + delay: (BOOL) delay +{ + CGPoint displacement = CGPointMake(destPoint.x - startPoint.x, destPoint.y - startPoint.y); + NSUInteger numSteps = duration / DRAG_STEP; + + if (numSteps < 2) + { + numSteps = 2; + } - CGPoint *path = alloca(NUM_POINTS_IN_DRAG * sizeof(CGPoint)); + CGPoint *path = alloca(numSteps * sizeof(CGPoint)); - for (NSUInteger i = 0; i < NUM_POINTS_IN_DRAG; i++) + for (NSUInteger i = 0; i < numSteps; i++) { - CGFloat progress = ((CGFloat)i)/(NUM_POINTS_IN_DRAG - 1); + CGFloat progress = ((CGFloat)i)/(numSteps - 1); path[i] = CGPointMake(startPoint.x + (progress * displacement.x), startPoint.y + (progress * displacement.y)); } - UITouch* touch = [[UITouch alloc] initAtPoint: [self FEX_centerPoint] inView: self]; + CGPoint touchPoint = [self convertPoint: startPoint fromView: nil]; + UITouch* touch = [[UITouch alloc] initAtPoint: touchPoint inView: self]; [touch setPhase:UITouchPhaseBegan]; UIEvent* eventDown = [self _eventWithTouch: touch]; [[UIApplication sharedApplication] sendEvent: eventDown]; - CFRunLoopRunInMode(UIApplicationCurrentRunMode, duration, false); + CFRunLoopRunInMode(UIApplicationCurrentRunMode, delay ? DRAG_TOUCH_DELAY : 0.01, false); - for (NSInteger pointIndex = 1; pointIndex < NUM_POINTS_IN_DRAG; ++pointIndex) + for (NSInteger pointIndex = 1; pointIndex < numSteps; ++pointIndex) { [touch setLocationInWindow: path[pointIndex]]; [touch setPhase: UITouchPhaseMoved]; @@ -376,7 +386,7 @@ - (BOOL) FEX_dragToX: (CGFloat) x y: (CGFloat) y duration: (CGFloat) duration UIEvent *eventDrag = [self _eventWithTouch: touch]; [[UIApplication sharedApplication] sendEvent: eventDrag]; - CFRunLoopRunInMode(UIApplicationCurrentRunMode, 0.01, false); + CFRunLoopRunInMode(UIApplicationCurrentRunMode, DRAG_STEP, false); } [touch setPhase: UITouchPhaseEnded]; From 74ab637dd0e6c3798f62d33c87b456d43c2c358d Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Thu, 16 Jan 2014 21:18:23 -0800 Subject: [PATCH 08/13] Fix keyboard in portrait orientation --- src/IOSKeyboardCommand.m | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/IOSKeyboardCommand.m b/src/IOSKeyboardCommand.m index 1cf989b..37edce3 100644 --- a/src/IOSKeyboardCommand.m +++ b/src/IOSKeyboardCommand.m @@ -4,12 +4,11 @@ // To change the template use AppCode | Preferences | File Templates. // - +#import "FranklyProtocolHelper.h" #import "IOSKeyboardCommand.h" #import "JSON.h" -#import - -#import "FranklyProtocolHelper.h" +#import "KIFTypist.h" +#import "UIApplication-KIFAdditions.h" @implementation IOSKeyboardCommand { @@ -25,11 +24,14 @@ - (NSString *)handleCommandWithRequestBody:(NSString *)requestBody { NSDictionary *requestCommand = FROM_JSON(requestBody); NSString *textToType = [requestCommand objectForKey:@"text_to_type"]; - if( ![UIAutomationBridge checkForKeyboard] ){ + if( ![[UIApplication sharedApplication] keyboardWindow]){ return [self generateKeyboardNotPresentErrorResponse]; } - [UIAutomationBridge typeIntoKeyboard:textToType]; + for (NSUInteger characterIndex = 0; characterIndex < [textToType length]; characterIndex++) { + NSString *characterString = [textToType substringWithRange:NSMakeRange(characterIndex, 1)]; + [KIFTypist enterCharacter: characterString]; + } return [FranklyProtocolHelper generateSuccessResponseWithoutResults]; } From 6428f0b4d300b7ea488fc83e37898a45927ef937 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Fri, 17 Jan 2014 20:11:37 -0800 Subject: [PATCH 09/13] Updated location override to no longer use PublicAutomation --- src/LocationCommand.m | 170 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 168 insertions(+), 2 deletions(-) diff --git a/src/LocationCommand.m b/src/LocationCommand.m index ea1d8f3..6ac000c 100644 --- a/src/LocationCommand.m +++ b/src/LocationCommand.m @@ -6,15 +6,39 @@ // // +#import + #import "LocationCommand.h" -#import #import "FranklyProtocolHelper.h" #import "JSON.h" +@interface NSObject () +- (id)initWithLatitude: (double) latitude longitude: (double) longitude; + +- (id) location; + +- (void) locationManager: (id) locationManager didUpdateLocations: (NSArray*) locations; +- (void) locationManager: (id) locationManager didUpdateToLocation: (id) newLocation fromLocation: (id) oldLocation; +@end + +static LocationCommand* FEX_staticLocationCommand = nil; +static id FEX_overridenLocation = nil; +static NSMutableDictionary* FEX_locationDelegates = nil; +static NSMutableDictionary* FEX_updatingManagers = nil; @implementation LocationCommand +- (id) init +{ + if (self = [super init]) + { + FEX_staticLocationCommand = self; + } + + return self; +} + - (NSString *)handlePost:(NSString *)requestBody{ NSDictionary *requestCommand = FROM_JSON(requestBody); @@ -27,7 +51,29 @@ - (NSString *)handlePost:(NSString *)requestBody{ NSLog(@"simulating location of %f,%f",locationAsPoint.x, locationAsPoint.y); - [UIAutomationBridge setLocation:locationAsPoint]; + FEX_overridenLocation = [[NSClassFromString(@"CLLocation") alloc] initWithLatitude: locationAsPoint.x + longitude: locationAsPoint.y]; + + for (id locationManagerDescription in FEX_locationDelegates) + { + id locationManager =[FEX_updatingManagers objectForKey: locationManagerDescription]; + if (locationManager != nil) + { + id delegate = [FEX_locationDelegates objectForKey: [locationManager description]]; + if ([delegate respondsToSelector: @selector(locationManager:didUpdateLocations:)]) + { + [delegate locationManager: locationManager + didUpdateLocations: [NSArray arrayWithObject: [((NSObject*) locationManager) location]]]; + } + + if ([delegate respondsToSelector: @selector(locationManager:didUpdateToLocation:fromLocation:)]) + { + [delegate locationManager: locationManager + didUpdateToLocation: [((NSObject*) locationManager) location] + fromLocation: [((NSObject*) locationManager) location]]; + } + } + } return [FranklyProtocolHelper generateSuccessResponseWithoutResults]; } @@ -40,4 +86,124 @@ - (NSString *)handleCommandWithRequestBody:(NSString *)requestBody { return [self handlePost:requestBody]; } +- (id) FEX_location +{ + id returnValue = nil; + + if (FEX_overridenLocation != nil) + { + returnValue = FEX_overridenLocation; + } + else + { + returnValue = [self FEX_location]; + } + + return returnValue; +} + +- (void) FEX_setDelegate: (id) delegate +{ + [FEX_locationDelegates setObject: delegate forKey: [self description]]; + [self FEX_setDelegate: FEX_staticLocationCommand]; +} + +- (void) FEX_startUpdatingLocation +{ + [FEX_updatingManagers setObject: self forKey: [self description]]; + [self FEX_startUpdatingLocation]; +} + +- (void) FEX_stopUpdatingLocation +{ + [FEX_updatingManagers removeObjectForKey: [self description]]; + [self FEX_stopUpdatingLocation]; +} + +- (void) FEX_dealloc +{ + [FEX_locationDelegates removeObjectForKey: [self description]]; + [FEX_updatingManagers removeObjectForKey: [self description]]; + + [self FEX_dealloc]; +} + ++ (void) insertMethod: (SEL) newSelector andSwapWithMethod: (SEL) origSelector +{ + Class locationManagerClass = NSClassFromString(@"CLLocationManager"); + + if (locationManagerClass != nil) + { + Method origMethod = class_getInstanceMethod(locationManagerClass, origSelector); + Method newMethod = class_getInstanceMethod(self, newSelector); + IMP newIMP = method_getImplementation(newMethod); + + if (class_addMethod(locationManagerClass, newSelector, newIMP, method_getTypeEncoding(newMethod))) + { + newMethod = class_getInstanceMethod(locationManagerClass, newSelector); + + if (origMethod != NULL && newMethod != NULL) + { + method_exchangeImplementations(origMethod, newMethod); + } + } + } +} + ++ (void) load +{ + FEX_locationDelegates = [NSMutableDictionary new]; + FEX_updatingManagers = [NSMutableDictionary new]; + + [self insertMethod: @selector(FEX_setDelegate:) andSwapWithMethod: @selector(setDelegate:)]; + [self insertMethod: @selector(FEX_dealloc) andSwapWithMethod: @selector(dealloc)]; + [self insertMethod: @selector(FEX_startUpdatingLocation) andSwapWithMethod: @selector(startUpdatingLocation)]; + [self insertMethod: @selector(FEX_stopUpdatingLocation) andSwapWithMethod: @selector(stopUpdatingLocation)]; + [self insertMethod: @selector(FEX_location) andSwapWithMethod: @selector(location)]; +} + +- (void) locationManager: (id) locationManager didUpdateLocations: (NSArray*) locations +{ + if (locationManager != nil && [FEX_updatingManagers objectForKey: [locationManager description]] != nil) + { + id delegate = [FEX_locationDelegates objectForKey: [locationManager description]]; + if ([delegate respondsToSelector: @selector(locationManager:didUpdateLocations:)]) + { + if (FEX_overridenLocation == nil) + { + [delegate locationManager: locationManager + didUpdateLocations: locations]; + } + else + { + [delegate locationManager: locationManager + didUpdateLocations: [NSArray arrayWithObject: FEX_overridenLocation]]; + } + } + } +} + +- (void) locationManager: (id) locationManager didUpdateToLocation: (id) newLocation fromLocation: (id) oldLocation +{ + if (locationManager != nil && [FEX_updatingManagers objectForKey: [locationManager description]] != nil) + { + id delegate = [FEX_locationDelegates objectForKey: [locationManager description]]; + if ([delegate respondsToSelector: @selector(locationManager:didUpdateToLocation:fromLocation:)]) + { + if (FEX_overridenLocation == nil) + { + [delegate locationManager: locationManager + didUpdateToLocation: newLocation + fromLocation: oldLocation]; + } + else + { + [delegate locationManager: locationManager + didUpdateToLocation: FEX_overridenLocation + fromLocation: FEX_overridenLocation]; + } + } + } +} + @end \ No newline at end of file From de5bbe5749c32ae8e46649f7d5aef23e0ec2a427 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Fri, 17 Jan 2014 20:12:03 -0800 Subject: [PATCH 10/13] Updated Controls example to non-deprecated CLLocationManager delegate method --- example/Controls/Controls/LocationViewController.m | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/example/Controls/Controls/LocationViewController.m b/example/Controls/Controls/LocationViewController.m index 751f890..de843d7 100644 --- a/example/Controls/Controls/LocationViewController.m +++ b/example/Controls/Controls/LocationViewController.m @@ -59,7 +59,13 @@ - (void)viewDidUnload { [super viewDidUnload]; } -- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation{ - self.locationLabel.text = [NSString stringWithFormat:@"Current Location: %f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude]; +- (void) locationManager: (id) locationManager didUpdateLocations: (NSArray*) locations +{ + if ([locations count] > 0) + { + CLLocation* newLocation = [locations objectAtIndex: 0]; + self.locationLabel.text = [NSString stringWithFormat:@"Current Location: %f,%f", newLocation.coordinate.latitude, newLocation.coordinate.longitude]; + } } + @end From a1e5d408170fbb87d87049dac7bea6941a4d7910 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Fri, 17 Jan 2014 22:49:06 -0800 Subject: [PATCH 11/13] Update UISwitch swipe method to work in iOS 7 --- gem/lib/frank-cucumber/core_frank_steps.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/gem/lib/frank-cucumber/core_frank_steps.rb b/gem/lib/frank-cucumber/core_frank_steps.rb index f452ce9..4e6985b 100644 --- a/gem/lib/frank-cucumber/core_frank_steps.rb +++ b/gem/lib/frank-cucumber/core_frank_steps.rb @@ -223,7 +223,11 @@ switch_states = frankly_map( selector, "isOn" ) switch_states.each do |switch_state| - switch_state.should == expected_state + if switch_state + [true, 1].should include expected_state + else + [false, 0].should include expected_state + end end end From e6cc21c2b1f5da3a798c4fcfdd33687288410e44 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Fri, 17 Jan 2014 22:54:59 -0800 Subject: [PATCH 12/13] Remove PublicAutomation Submodule --- .gitmodules | 3 --- Frank.xcodeproj/project.pbxproj | 10 ++-------- lib/PublicAutomation | 1 - 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 160000 lib/PublicAutomation diff --git a/.gitmodules b/.gitmodules index acac274..5ba2584 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,9 +10,6 @@ [submodule "lib/cocoahttpserver"] path = lib/cocoahttpserver url = https://github.com/robbiehanson/CocoaHTTPServer.git -[submodule "lib/PublicAutomation"] - path = lib/PublicAutomation - url = https://github.com/TestingWithFrank/PublicAutomation.git [submodule "lib/AnyJSON"] path = lib/AnyJSON url = https://github.com/mattt/AnyJSON.git diff --git a/Frank.xcodeproj/project.pbxproj b/Frank.xcodeproj/project.pbxproj index d6f1f2f..e8cd93f 100644 --- a/Frank.xcodeproj/project.pbxproj +++ b/Frank.xcodeproj/project.pbxproj @@ -1351,10 +1351,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = src/Frank_Prefix.pch; INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/lib/PublicAutomation/build/Release-iphoneos\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-all_load", @@ -1378,10 +1375,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = src/Frank_Prefix.pch; INSTALL_PATH = /usr/local/lib; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "\"$(SRCROOT)/lib/PublicAutomation/build/Release-iphoneos\"", - ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; OTHER_LDFLAGS = ( "-ObjC", "-all_load", diff --git a/lib/PublicAutomation b/lib/PublicAutomation deleted file mode 160000 index 98df22a..0000000 --- a/lib/PublicAutomation +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 98df22acc920e621e0c44d13884b025e2b6c50fa From 908b675f8f91436259564c8a81ea14a3330323a2 Mon Sep 17 00:00:00 2001 From: Michael Buckley Date: Sun, 19 Jan 2014 10:25:57 -0800 Subject: [PATCH 13/13] Fix UIAlertView tests in controls example --- .../features/step_definitions/alert_view_steps.rb | 2 +- example/Controls/features/ui_alert_view.feature | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/example/Controls/features/step_definitions/alert_view_steps.rb b/example/Controls/features/step_definitions/alert_view_steps.rb index 2eea4a8..f5ebc9a 100644 --- a/example/Controls/features/step_definitions/alert_view_steps.rb +++ b/example/Controls/features/step_definitions/alert_view_steps.rb @@ -1,3 +1,3 @@ Then /^I touch the alert view's "(.*?)" button$/ do |button_mark| - touch "alertView button marked:'#{button_mark}'" + touch "view:'_UIModalItemTableViewCell' marked:'#{button_mark}'" end diff --git a/example/Controls/features/ui_alert_view.feature b/example/Controls/features/ui_alert_view.feature index ad40a95..7617524 100644 --- a/example/Controls/features/ui_alert_view.feature +++ b/example/Controls/features/ui_alert_view.feature @@ -13,12 +13,14 @@ Scenario Outline: Showing and dismissing the Alert View When I touch "Show UIAlertView" Then I should see "AlertView Title" - And I should see a button "Button1" - And I should see a button "Button 2" + And I should see "Button1" + And I should see "Button 2" When I touch the alert view's "Ok" button - And I wait for nothing to be animating + And I wait for nothing to be animating Then I should not see "AlertView Title" + And I should not see "Button1" + And I should not see "Button 2" Examples: | orientation |