diff --git a/Frank.xcodeproj/project.pbxproj b/Frank.xcodeproj/project.pbxproj
index e8cd93f..30a336e 100644
--- a/Frank.xcodeproj/project.pbxproj
+++ b/Frank.xcodeproj/project.pbxproj
@@ -200,6 +200,13 @@
remoteGlobalIDString = 305CA782164205F800C4ACE5;
remoteInfo = CocoaHTTPServerMac;
};
+ 3092C0F3189EF7EB00371BF9 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C18A5F16160D528C00DC25F6 /* PublicAutomation.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = C194253715D838BD004FC314;
+ remoteInfo = PublicAutomation;
+ };
65DBDDB616A89D97007D3D43 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
@@ -1073,6 +1080,7 @@
buildRules = (
);
dependencies = (
+ 3092C0F4189EF7EB00371BF9 /* PBXTargetDependency */,
ABA9E46815C81C8D00112290 /* PBXTargetDependency */,
);
name = Frank;
@@ -1310,6 +1318,11 @@
target = 305CA782164205F800C4ACE5 /* CocoaHTTPServerMac */;
targetProxy = 30228E1D1642146F00B1F9E7 /* PBXContainerItemProxy */;
};
+ 3092C0F4189EF7EB00371BF9 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = PublicAutomation;
+ targetProxy = 3092C0F3189EF7EB00371BF9 /* PBXContainerItemProxy */;
+ };
65DBDDB716A89D97007D3D43 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 65DBDD7216A89CCA007D3D43 /* CocoaAsyncSocket */;
@@ -1342,7 +1355,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ ARCHS = "$(ARCHS_STANDARD)";
COPY_PHASE_STRIP = NO;
DSTROOT = /tmp/Frank.dst;
GCC_DYNAMIC_NO_PIC = NO;
@@ -1351,6 +1364,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = src/Frank_Prefix.pch;
INSTALL_PATH = /usr/local/lib;
+ IPHONEOS_DEPLOYMENT_TARGET = 5.1.1;
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = (
"-ObjC",
@@ -1358,7 +1372,7 @@
);
PRODUCT_NAME = Frank;
SDKROOT = iphoneos;
- USER_HEADER_SEARCH_PATHS = lib/Shelley/Shelley;
+ USER_HEADER_SEARCH_PATHS = "lib/Shelley/Shelley lib/PublicAutomation\"";
};
name = Debug;
};
@@ -1366,10 +1380,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = YES;
- ARCHS = (
- "$(ARCHS_STANDARD_32_BIT)",
- armv6,
- );
+ ARCHS = "$(ARCHS_STANDARD)";
DSTROOT = /tmp/Frank.dst;
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
@@ -1382,14 +1393,14 @@
);
PRODUCT_NAME = Frank;
SDKROOT = iphoneos;
- USER_HEADER_SEARCH_PATHS = lib/Shelley/Shelley;
+ USER_HEADER_SEARCH_PATHS = "lib/Shelley/Shelley lib/PublicAutomation\"";
};
name = Release;
};
1DEB922308733DC00010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ ARCHS = "$(ARCHS_STANDARD)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
@@ -1403,7 +1414,7 @@
1DEB922408733DC00010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+ ARCHS = "$(ARCHS_STANDARD)";
GCC_C_LANGUAGE_STANDARD = c99;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
diff --git a/Frank.xcodeproj/xcshareddata/xcschemes/Frank.xcscheme b/Frank.xcodeproj/xcshareddata/xcschemes/Frank.xcscheme
index 0628871..6242d25 100644
--- a/Frank.xcodeproj/xcshareddata/xcschemes/Frank.xcscheme
+++ b/Frank.xcodeproj/xcshareddata/xcschemes/Frank.xcscheme
@@ -67,6 +67,15 @@
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
+
+
+
+
diff --git a/gem/frank-cucumber.gemspec b/gem/frank-cucumber.gemspec
index 3a03925..ec0214d 100644
--- a/gem/frank-cucumber.gemspec
+++ b/gem/frank-cucumber.gemspec
@@ -20,15 +20,15 @@ Gem::Specification.new do |s|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
s.require_paths = ["lib"]
- s.add_dependency( "cucumber" )
- s.add_dependency( "rspec", [">=2.0"] )
- s.add_dependency( "sim_launcher", [">=0.4.6"] )
- s.add_dependency( "i18n" )
- s.add_dependency( "plist" )
- s.add_dependency( "json" ) # TODO: figure out how to be more permissive as to which JSON gems we allow
- s.add_dependency( "dnssd" )
- s.add_dependency( "thor" )
- s.add_dependency( "xcodeproj", [">=0.5.3"] )
+ s.add_dependency( "cucumber", ["~>1.3.10"] )
+ s.add_dependency( "rspec", ["~>2.14.1"] )
+ s.add_dependency( "sim_launcher", ["~>0.4.6"] )
+ s.add_dependency( "i18n", ["~>0.6.9"] )
+ s.add_dependency( "plist", ["~>3.1.0"] )
+ s.add_dependency( "json", ["1.8.1"] ) # TODO: figure out how to be more permissive as to which JSON gems we allow
+ s.add_dependency( "dnssd", ["~>2.0"] )
+ s.add_dependency( "thor", ["~>0.18.1"] )
+ s.add_dependency( "xcodeproj", ["~>0.14.1"] )
s.add_development_dependency( "rr" )
s.add_development_dependency( "yard" )
diff --git a/gem/frank-skeleton/libCocoaAsyncSocket.a b/gem/frank-skeleton/libCocoaAsyncSocket.a
index 43a2ec2..2e40d02 100644
Binary files a/gem/frank-skeleton/libCocoaAsyncSocket.a and b/gem/frank-skeleton/libCocoaAsyncSocket.a differ
diff --git a/gem/frank-skeleton/libCocoaAsyncSocketMac.a b/gem/frank-skeleton/libCocoaAsyncSocketMac.a
index c5787b1..620c1b2 100644
Binary files a/gem/frank-skeleton/libCocoaAsyncSocketMac.a and b/gem/frank-skeleton/libCocoaAsyncSocketMac.a differ
diff --git a/gem/frank-skeleton/libCocoaHTTPServer.a b/gem/frank-skeleton/libCocoaHTTPServer.a
index 94e1d1e..ebd91a0 100644
Binary files a/gem/frank-skeleton/libCocoaHTTPServer.a and b/gem/frank-skeleton/libCocoaHTTPServer.a differ
diff --git a/gem/frank-skeleton/libCocoaHTTPServerMac.a b/gem/frank-skeleton/libCocoaHTTPServerMac.a
index e5ae2f3..43971fd 100644
Binary files a/gem/frank-skeleton/libCocoaHTTPServerMac.a and b/gem/frank-skeleton/libCocoaHTTPServerMac.a differ
diff --git a/gem/frank-skeleton/libCocoaLumberjack.a b/gem/frank-skeleton/libCocoaLumberjack.a
index 3cd2432..46ddcc3 100644
Binary files a/gem/frank-skeleton/libCocoaLumberjack.a and b/gem/frank-skeleton/libCocoaLumberjack.a differ
diff --git a/gem/frank-skeleton/libCocoaLumberjackMac.a b/gem/frank-skeleton/libCocoaLumberjackMac.a
index a74d7c4..efc9657 100644
Binary files a/gem/frank-skeleton/libCocoaLumberjackMac.a and b/gem/frank-skeleton/libCocoaLumberjackMac.a differ
diff --git a/gem/frank-skeleton/libFrank.a b/gem/frank-skeleton/libFrank.a
index b94040f..a3fa853 100644
Binary files a/gem/frank-skeleton/libFrank.a and b/gem/frank-skeleton/libFrank.a differ
diff --git a/gem/frank-skeleton/libFrankMac.a b/gem/frank-skeleton/libFrankMac.a
index d6f12dc..3642294 100644
Binary files a/gem/frank-skeleton/libFrankMac.a and b/gem/frank-skeleton/libFrankMac.a differ
diff --git a/gem/frank-skeleton/libShelley.a b/gem/frank-skeleton/libShelley.a
index 7f7ab37..715dc2a 100644
Binary files a/gem/frank-skeleton/libShelley.a and b/gem/frank-skeleton/libShelley.a differ
diff --git a/gem/frank-skeleton/libShelleyMac.a b/gem/frank-skeleton/libShelleyMac.a
index 2aec0dc..407da29 100644
Binary files a/gem/frank-skeleton/libShelleyMac.a and b/gem/frank-skeleton/libShelleyMac.a differ
diff --git a/gem/lib/frank-cucumber/cli.rb b/gem/lib/frank-cucumber/cli.rb
index 2d67dfb..cbe7b8e 100644
--- a/gem/lib/frank-cucumber/cli.rb
+++ b/gem/lib/frank-cucumber/cli.rb
@@ -167,6 +167,7 @@ def build_and_launch
desc "launch", "open the Frankified app in the simulator"
method_option :debug, :type => :boolean, :default => false
method_option :idiom, :banner => 'iphone|ipad', :type => :string, :default => (ENV['FRANK_SIM_IDIOM'] || 'iphone')
+ method_option :sdk, :type => :string, :default => nil
def launch
$DEBUG = options[:debug]
version = case options[:idiom].downcase
@@ -188,7 +189,7 @@ def launch
say "LAUNCHING APP..."
- launch_app(frankified_app_dir, nil, version, false)
+ launch_app(frankified_app_dir, options[:sdk], version, false)
end
end
diff --git a/gem/lib/frank-cucumber/core_frank_steps.rb b/gem/lib/frank-cucumber/core_frank_steps.rb
index 4e6985b..3907ae4 100644
--- a/gem/lib/frank-cucumber/core_frank_steps.rb
+++ b/gem/lib/frank-cucumber/core_frank_steps.rb
@@ -20,19 +20,19 @@
Then /^I should see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
quote = get_selector_quote(expected_mark)
- check_element_exists( "navigationItemView marked:#{quote}#{expected_mark}#{quote}" )
+ quoted_text = "#{quote}#{expected_mark}#{quote}"
+ navigation_title_exists_with_text("#{quoted_text}").should be_true, "expected to see a navigation bar titled #{quoted_text}"
end
-Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
- quote = get_selector_quote(expected_mark)
- wait_until( :timeout => 30, :message => "waited to see a navigation bar titled #{quote}#{expected_mark}#{quote}" ) {
- element_exists( "navigationItemView marked:#{quote}#{expected_mark}#{quote}" )
- }
+Then /^I wait to see a navigation bar titled "([^\"]*)"$/ do |expected_title|
+ wait_until(message: "waited to see a navigation bar titled #{quoted_text}") do
+ navigation_title_with_text_exists(expected_title)
+ end
end
Then /^I wait to not see a navigation bar titled "([^\"]*)"$/ do |expected_mark|
quote = get_selector_quote(expected_mark)
- wait_until( :timeout => 30, :message => "waited to not see a navigation bar titled #{quote}#{expected_mark}#{quote}" ) {
+ wait_until( :message => "waited to not see a navigation bar titled #{quote}#{expected_mark}#{quote}" ) {
!element_exists( "navigationItemView marked:#{quote}#{expected_mark}#{quote}" )
}
end
@@ -66,7 +66,11 @@
end
Then /^I should see an alert view titled "([^\"]*)"$/ do |expected_mark|
- values = frankly_map( 'alertView', 'title')
+ if frankly_os_version.to_f >= 7.0
+ values = frankly_map( "view:'_UIModalItemRepresentationView' label", 'text')
+ else
+ values = frankly_map( 'alertView', 'title')
+ end
values.should include(expected_mark)
end
@@ -76,7 +80,11 @@
end
Then /^I should not see an alert view$/ do
- check_element_does_not_exist( 'alertView' )
+ if frankly_os_version.to_f >= 7.0
+ check_element_does_not_exist( '_UIModalItemRepresentationView' )
+ else
+ check_element_does_not_exist( 'alertView' )
+ end
end
Then /^I should see an element of class "([^\"]*)" with name "([^\"]*)" with the following labels: "([^\"]*)"$/ do |className, classLabel, listOfLabels|
diff --git a/gem/lib/frank-cucumber/frank_helper.rb b/gem/lib/frank-cucumber/frank_helper.rb
index 2c91374..433c503 100644
--- a/gem/lib/frank-cucumber/frank_helper.rb
+++ b/gem/lib/frank-cucumber/frank_helper.rb
@@ -155,6 +155,25 @@ def view_with_mark_exists(expected_mark)
element_exists( "view marked:#{quote}#{expected_mark}#{quote}" )
end
+ # Indicate whether the title of the navigation bar matches the expected title.
+ # @param [String] expected_title the expected title of the navigation bar
+ # @return [Boolean]
+ def navigation_title_with_text_exists(expected_title)
+ quoted_text = "#{quote}#{expected_title}#{quote}"
+
+ navFrame = frankly_map('view:"UINavigationBar"', 'frame').first
+ navCenter = navFrame["size"]["width"] / 2.0
+
+ frame = frankly_map("view:'UINavigationBar' view:'UINavigationItemView' marked:#{quoted_text}", 'frame').first
+ return false unless frame && frame["origin"] && frame["size"]
+
+ left = frame["origin"]["x"]
+ right = frame["origin"]["x"] + frame["size"]["width"]
+ return false unless left && right && left < right
+
+ (left < navCenter) && (navCenter < right)
+ end
+
# Assert whether there are any views in the current view heirarchy which contain the specified accessibility label.
# @param [String] expected_mark the expected accessibility label
# @raise an rspec exception if the assertion fails
@@ -173,6 +192,26 @@ def check_view_with_mark_does_not_exist(expected_mark)
check_element_does_not_exist( "view marked:#{quote}#{expected_mark}#{quote}" )
end
+ # Assert the title of the navigation bar.
+ # @param [String] expected_title the expected title of the navigation bar
+ # @raise an rspec exception if the assertion fails
+ # @raise an rspec exception if the navigation bar and its subview `UINavigationItemView` cannot be found
+ # @raise an rspec exception if the `UINavigationItemView` does not cover the center x of the navigation bar
+ def check_navigation_title_with_text_exists(expected_title)
+ quoted_text = "#{quote}#{expected_title}#{quote}"
+
+ navFrame = frankly_map('view:"UINavigationBar"', 'frame').first
+ navCenter = navFrame["size"]["width"] / 2.0
+
+ frame = frankly_map("view:'UINavigationBar' view:'UINavigationItemView' marked:#{quoted_text}", 'frame').first
+ raise "Could not find navigation bar with title (#{expected_title})" unless frame && frame["origin"] && frame["size"]
+
+ left = frame["origin"]["x"]
+ right = frame["origin"]["x"] + frame["size"]["width"]
+ raise "Expected title (#{expected_title}) not in center of navigation bar" unless left && right && left < right
+
+ ((left < navCenter) && (navCenter < right)).should be_true, "Could not find navigation title in center of navigation bar matching text (#{expected_title})"
+ end
# Waits for any of the specified selectors to match a view.
#
diff --git a/gem/lib/frank-cucumber/version.rb b/gem/lib/frank-cucumber/version.rb
index 87d6660..4bbf4d7 100644
--- a/gem/lib/frank-cucumber/version.rb
+++ b/gem/lib/frank-cucumber/version.rb
@@ -1,5 +1,5 @@
module Frank
module Cucumber
- VERSION = "1.2.2"
+ VERSION = "1.2.5"
end
end
diff --git a/src/AccessibilityCheckCommand.m b/src/AccessibilityCheckCommand.m
index cb6d2ff..8d35d8e 100644
--- a/src/AccessibilityCheckCommand.m
+++ b/src/AccessibilityCheckCommand.m
@@ -29,15 +29,15 @@ + (BOOL) accessibilitySeemsToBeTurnedOn {
#if __MAC_OS_X_VERSION_MAX_ALLOWED < 1090
-extern Boolean AXIsProcessTrustedWithOptions(CFDictionaryRef options);
-extern CFStringRef kAXTrustedCheckOptionPrompt;
+extern Boolean AXIsProcessTrustedWithOptions(CFDictionaryRef options) __attribute__((weak_import));
+extern CFStringRef kAXTrustedCheckOptionPrompt __attribute__((weak_import));
#endif // __MAC_OS_X_VERSION_MAX_ALLOWED < 1090
+ (BOOL) accessibilitySeemsToBeTurnedOn {
BOOL returnValue = NO;
- if (AXIsProcessTrusted != NULL)
+ if (AXIsProcessTrustedWithOptions != NULL)
{
NSDictionary* options = @{ (id) kAXTrustedCheckOptionPrompt : @YES };
return AXIsProcessTrustedWithOptions((CFDictionaryRef) options);
diff --git a/src/FrankLoader.m b/src/FrankLoader.m
index b95727e..617ce57 100644
--- a/src/FrankLoader.m
+++ b/src/FrankLoader.m
@@ -25,13 +25,13 @@
@implementation FrankLoader
+ (void)applicationDidBecomeActive:(NSNotification *)notification{
+ static dispatch_once_t frankDidBecomeActiveToken;
#if TARGET_OS_IPHONE
- FrankServer *server = [[FrankServer alloc] initWithDefaultBundle];
- [server startServer];
-
+ dispatch_once(&frankDidBecomeActiveToken, ^{
+ FrankServer *server = [[FrankServer alloc] initWithDefaultBundle];
+ [server startServer];
+ });
#else
- static dispatch_once_t frankDidBecomeActiveToken;
-
dispatch_once(&frankDidBecomeActiveToken, ^{
FrankServer *server = [[FrankServer alloc] initWithDefaultBundle];
[server startServer];
@@ -86,6 +86,26 @@ + (void)load{
selector:@selector(applicationDidBecomeActive:)
name:notificationName
object:nil];
+
+#if TARGET_OS_IPHONE
+ NSArray *iOSVersionComponents = [[UIDevice currentDevice].systemVersion componentsSeparatedByString:@"."];
+ int majorVersion = [[iOSVersionComponents objectAtIndex:0] intValue];
+
+ if (majorVersion >= 9)
+ {
+ // iOS9 is installed. The UIApplicationDidBecomeActiveNotification may have been fired *before*
+ // this code is called.
+ // See also:
+ // http://stackoverflow.com/questions/31785878/ios-9-uiapplicationdidbecomeactivenotification-callback-not-called
+
+ // Call applicationDidBecomeActive: after 0.5 second.
+ // Delay execution of my block for 10 seconds.
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 500 * USEC_PER_SEC), dispatch_get_main_queue(), ^{
+ NSLog(@"Forcefully invoking applicationDidBecomeActive");
+ [FrankLoader applicationDidBecomeActive:nil];
+ });
+ }
+#endif
}
@end
diff --git a/src/MapOperationCommand.m b/src/MapOperationCommand.m
index eadd139..27b5de9 100644
--- a/src/MapOperationCommand.m
+++ b/src/MapOperationCommand.m
@@ -58,7 +58,15 @@ - (NSString *)handleCommandWithRequestBody:(NSString *)requestBody {
for (FrankMapViewType *view in viewsToMap) {
@try {
id result = [self performOperation:operation onView:view];
- [results addObject:[ViewJSONSerializer jsonify:result]];
+ NSString *resultValue = [ViewJSONSerializer jsonify:result];
+
+ // Can't add nil objects to an array.
+ if(resultValue == nil)
+ {
+ resultValue = @"";
+ }
+
+ [results addObject:resultValue];
}
@catch (NSException * e) {
NSLog( @"Exception while performing operation %@\n%@", operation, e );
diff --git a/src/OrientationCommand.m b/src/OrientationCommand.m
index 51de2f5..df5128b 100644
--- a/src/OrientationCommand.m
+++ b/src/OrientationCommand.m
@@ -83,7 +83,7 @@ - (NSString *)getOrientationDescriptionViaDevice{
- (NSString *)handleGet{
NSDictionary *orientationDescription = [self getOrientationRepresentationViaDevice];
if( !orientationDescription )
- orientationDescription = [self getOrientationRepresentationViaDevice];
+ orientationDescription = [self getOrientationRepresentationViaStatusBar];
return TO_JSON(orientationDescription);
}