Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'KingOfBrian/master'

Conflicts:
	Frank.xcodeproj/project.pbxproj
  • Loading branch information...
commit 9a2366b6e65940fb3f9432443c1e68064300761a 2 parents 3082ae3 + bca825f
@moredip moredip authored
View
8 Frank.xcodeproj/project.pbxproj
@@ -13,6 +13,8 @@
4C1DD76D12BADFE100E10B8C /* OrientationCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1DD76912BADFE100E10B8C /* OrientationCommand.h */; };
4C1DD76E12BADFE100E10B8C /* AppCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C1DD76A12BADFE100E10B8C /* AppCommand.m */; };
4C1DD76F12BADFE100E10B8C /* AppCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1DD76B12BADFE100E10B8C /* AppCommand.h */; };
+ 86123C8814F8221000266AFC /* UIImage+Frank.h in Headers */ = {isa = PBXBuildFile; fileRef = 86123C8614F8221000266AFC /* UIImage+Frank.h */; };
+ 86123C8914F8221000266AFC /* UIImage+Frank.m in Sources */ = {isa = PBXBuildFile; fileRef = 86123C8714F8221000266AFC /* UIImage+Frank.m */; };
AA747D9F0F9514B9006C5449 /* Frank_Prefix.pch in Headers */ = {isa = PBXBuildFile; fileRef = AA747D9E0F9514B9006C5449 /* Frank_Prefix.pch */; };
AACBBE4A0F95108600F1A2B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AACBBE490F95108600F1A2B1 /* Foundation.framework */; };
D629926B11AB2D1F00CE0FB0 /* AsyncSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = D629926911AB2D1F00CE0FB0 /* AsyncSocket.h */; };
@@ -160,6 +162,8 @@
4C1DD76912BADFE100E10B8C /* OrientationCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OrientationCommand.h; path = src/OrientationCommand.h; sourceTree = "<group>"; };
4C1DD76A12BADFE100E10B8C /* AppCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppCommand.m; path = src/AppCommand.m; sourceTree = "<group>"; };
4C1DD76B12BADFE100E10B8C /* AppCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppCommand.h; path = src/AppCommand.h; sourceTree = "<group>"; };
+ 86123C8614F8221000266AFC /* UIImage+Frank.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Frank.h"; path = "src/UIImage+Frank.h"; sourceTree = "<group>"; };
+ 86123C8714F8221000266AFC /* UIImage+Frank.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Frank.m"; path = "src/UIImage+Frank.m"; sourceTree = "<group>"; };
AA747D9E0F9514B9006C5449 /* Frank_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Frank_Prefix.pch; sourceTree = SOURCE_ROOT; };
AACBBE490F95108600F1A2B1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
D2AAC07E0554694100DB518D /* libFrank.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFrank.a; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -351,6 +355,8 @@
08FB77AEFE84172EC02AAC07 /* src */ = {
isa = PBXGroup;
children = (
+ 86123C8614F8221000266AFC /* UIImage+Frank.h */,
+ 86123C8714F8221000266AFC /* UIImage+Frank.m */,
D67F2ABD13F5F55A00A0BFF1 /* FrankLoader.h */,
D67F2ABE13F5F55A00A0BFF1 /* FrankLoader.m */,
D67F2AAB13F5E7FA00A0BFF1 /* AccessibilityCheckCommand.h */,
@@ -656,6 +662,7 @@
D6325EE41437F7180057330D /* WaitUntilIdle.h in Headers */,
D6BD5222146C36A3001770B1 /* UIQuerySelectorEngine.h in Headers */,
0071264614F8956700E738ED /* ViewJSONSerializer.h in Headers */,
+ 86123C8814F8221000266AFC /* UIImage+Frank.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -794,6 +801,7 @@
D6BD521F146C34BF001770B1 /* SelectorEngineRegistry.m in Sources */,
D6BD5223146C36A3001770B1 /* UIQuerySelectorEngine.m in Sources */,
0071264714F8956700E738ED /* ViewJSONSerializer.m in Sources */,
+ 86123C8914F8221000266AFC /* UIImage+Frank.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
2  frank_static_resources.bundle/index.haml
@@ -29,7 +29,7 @@
%label(for="query") Selector
%input#query(placeholder="label marked:'Search'")
%button#flash_button Flash
- %button#shelley_flash_button Flash using Shelley
+ %input#selector_engine(placeholder="uiquery")
%td
#refresh
%img#loading(src="images/ajax-loader.gif")
View
2  frank_static_resources.bundle/index.html
@@ -29,7 +29,7 @@
<label for='query'>Selector</label>
<input id='query' placeholder="label marked:'Search'" />
<button id='flash_button'>Flash</button>
- <button id='shelley_flash_button'>Flash using Shelley</button>
+ <input id='selector_engine' placeholder='uiquery' />
</div>
</td>
<td>
View
13 frank_static_resources.bundle/symbiote.js
@@ -380,10 +380,10 @@ $(document).ready(function() {
- function sendFlashCommand( selector, use_shelley ) {
+ function sendFlashCommand( selector, engine ) {
var command = {
- query: selector,
- selector_engine: use_shelley ? 'shelley_compat' : 'uiquery',
+ query: selector,
+ selector_engine: engine ? engine : 'uiquery' ,
operation: {
method_name: 'flash',
arguments: []
@@ -482,13 +482,8 @@ $(document).ready(function() {
});
$('#flash_button').click( function(){
- sendFlashCommand( $("input#query").val(), false );
+ sendFlashCommand( $("input#query").val(), $("input#selector_engine").val() );
});
-
- $('#shelley_flash_button').click( function(){
- sendFlashCommand( $("input#query").val(), true );
- });
-
liveView = symbiote.LiveView( uiLocator.updateBackdrop, refreshViewHeirarchy );
View
31 gem/lib/frank-cucumber/frank_helper.rb
@@ -5,6 +5,8 @@
module Frank module Cucumber
module FrankHelper
+ HOST = "localhost"
+ FRANK_PORT = 37265
class << self
# TODO: adding an ivar to the module itself is a big ugyl hack. We need a FrankDriver class, or similar
@@ -69,14 +71,12 @@ def app_exec(method_name, *method_args)
res['results']
end
-
-
- def frankly_map( query, method_name, *method_args )
+
+ def frankly_engine_map( selector_engine, query, method_name, *method_args )
operation_map = {
:method_name => method_name,
:arguments => method_args,
}
- selector_engine = Frank::Cucumber::FrankHelper.selector_engine || 'uiquery' # default to UIQuery for backwards compatibility
res = post_to_uispec_server( 'map', :query => query, :operation => operation_map, :selector_engine => selector_engine )
res = JSON.parse( res )
if res['outcome'] != 'SUCCESS'
@@ -85,12 +85,29 @@ def frankly_map( query, method_name, *method_args )
res['results']
end
+
+ def frankly_map( query, method_name, *method_args )
+ selector_engine = Frank::Cucumber::FrankHelper.selector_engine || 'uiquery' # default to UIQuery for backwards compatibility
+ frankly_engine_map( selector_engine, query, method_name, *method_args )
+ end
def frankly_dump
res = get_to_uispec_server( 'dump' )
puts JSON.pretty_generate(JSON.parse(res)) rescue puts res #dumping a super-deep DOM causes errors
end
+ def frankly_screenshot(filename, subframe=nil, allwindows=true)
+ path = 'screenshot'
+ path += '/allwindows' if allwindows
+ path += "/frame/" + URI.escape(subframe) if (subframe != nil)
+
+ data = get_to_uispec_server( path )
+
+ open(filename, "wb") do |file|
+ file.write(data)
+ end
+ end
+
def frankly_oriented_portrait?
'portrait' == frankly_current_orientation
end
@@ -173,8 +190,10 @@ def get_to_uispec_server( verb )
make_http_request( url, req )
end
- def frank_url_for( verb )
- url = URI.parse "http://localhost:37265/"
+ def frank_url_for( verb , port=nil )
+ port ||= FRANK_PORT
+
+ url = URI.parse "http://#{HOST}:#{port}/"
url.path = '/'+verb
url
end
View
43 src/FrankCommandRoute.m
@@ -9,7 +9,7 @@
#import "FrankCommandRoute.h"
#import "RoutingHTTPConnection.h"
-#import <QuartzCore/QuartzCore.h>
+#import "UIImage+Frank.h"
extern BOOL frankLogEnabled;
@@ -34,17 +34,6 @@ -(void) registerCommand: (id<FrankCommand>)command withName:(NSString *)commandN
[_commandDict setObject:command forKey:commandName];
}
-- (NSData *) grabScreenshot {
- UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
-
- UIGraphicsBeginImageContext(keyWindow.bounds.size);
- [keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
- UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- return UIImagePNGRepresentation(image);
-}
-
#pragma mark Route implementation
- (id<FrankCommand>) commandForPath: (NSArray *)path{
@@ -54,6 +43,7 @@ - (NSData *) grabScreenshot {
return [_commandDict objectForKey:[path objectAtIndex:0]];
}
+
- (NSObject<HTTPResponse> *) handleRequestForPath: (NSArray *)path withConnection:(RoutingHTTPConnection *)connection{
if(frankLogEnabled) {
@@ -62,7 +52,34 @@ - (NSData *) grabScreenshot {
if( [@"screenshot" isEqualToString:[path objectAtIndex:0]] )
{
- return [[[HTTPDataResponse alloc] initWithData:[self grabScreenshot]] autorelease];
+ BOOL allWindows = [path count] > 1 && [[path objectAtIndex:0] isEqualToString:@"allwindows"];
+ UIImage *screenshot = [UIImage imageFromApplication:allWindows];
+
+ if ([path count] == 4)
+ {
+ NSString *stringRepresentation = [path objectAtIndex:3];
+ NSArray *parts = [stringRepresentation componentsSeparatedByString:@"."];
+ CGRect rect = CGRectZero;
+
+ rect.origin.x = [[parts objectAtIndex:0] integerValue];
+ rect.origin.y = [[parts objectAtIndex:1] integerValue];
+ rect.size.width = [[parts objectAtIndex:2] integerValue];
+ rect.size.height = [[parts objectAtIndex:3] integerValue];
+
+ //
+ // Crop image or mask out an area (IE: Timestamp)
+ //
+ if ([[path objectAtIndex:2] isEqualToString:@"frame"])
+ screenshot = [screenshot imageCropedToFrame:rect];
+ else if ([[path objectAtIndex:2] isEqualToString:@"mask"])
+ screenshot = [screenshot imageMaskedAtFrame:rect];
+ else
+ NSLog(@"Unknown Operation");
+ }
+
+ NSData *response = UIImagePNGRepresentation(screenshot);
+
+ return [[[HTTPDataResponse alloc] initWithData:response] autorelease];
}
id<FrankCommand> command = [self commandForPath:path];
View
2  src/FrankServer.h
@@ -13,6 +13,8 @@
@interface FrankServer : NSObject {
HTTPServer *_httpServer;
}
++ (void)setDefaultHttpPort:(NSUInteger)port;
+
- (id) initWithDefaultBundle;
- (id) initWithStaticFrankBundleNamed:(NSString *)bundleName;
View
7 src/FrankServer.m
@@ -18,8 +18,13 @@
#import "AppCommand.h"
#import "AccessibilityCheckCommand.h"
+static NSUInteger __defaultPort = FRANK_SERVER_PORT;
@implementation FrankServer
++ (void)setDefaultHttpPort:(NSUInteger)port
+{
+ __defaultPort = port;
+}
- (id) initWithDefaultBundle {
return [self initWithStaticFrankBundleNamed: @"frank_static_resources"];
}
@@ -48,7 +53,7 @@ - (id) initWithStaticFrankBundleNamed:(NSString *)bundleName
[_httpServer setName:@"Frank UISpec server"];
[_httpServer setType:@"_http._tcp."];
[_httpServer setConnectionClass:[RoutingHTTPConnection class]];
- [_httpServer setPort:FRANK_SERVER_PORT];
+ [_httpServer setPort:__defaultPort];
NSLog( @"Creating the server: %@", _httpServer );
}
return self;
View
2  src/Operation.m
@@ -40,6 +40,8 @@ - (void)castNumber:(NSNumber *)number toType:(const char*)objCType intoBuffer:(v
*((int *)buffer) = [number intValue];
}else if( !strcmp(objCType, @encode(uint)) ){
*((uint *)buffer) = [number unsignedIntValue];
+ }else if( !strcmp(objCType, @encode(double)) ){
+ *((double *)buffer) = [number doubleValue];
}else {
NSLog(@"Didn't know how to convert NSNumber to type %s", objCType);
}
View
19 src/UIImage+Frank.h
@@ -0,0 +1,19 @@
+//
+// UIImage+Frank.h
+// Frank
+//
+// Created by Brian King on 2/24/12.
+// Copyright 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import <UIKit/UIKit.h>
+
+
+@interface UIImage(Frank)
+
++ (UIImage *)imageFromApplication:(BOOL)allWindows;
+- (UIImage *)imageCropedToFrame:(CGRect)cropFrame;
+- (UIImage *)imageMaskedAtFrame:(CGRect)maskFrame;
+
+
+@end
View
59 src/UIImage+Frank.m
@@ -0,0 +1,59 @@
+//
+// UIImage+Frank.m
+// Frank
+//
+// Created by Brian King on 2/24/12.
+// Copyright 2012 __MyCompanyName__. All rights reserved.
+//
+
+#import "UIImage+Frank.h"
+#import <QuartzCore/QuartzCore.h>
+
+
+@implementation UIImage(Frank)
+
++ (UIImage *) imageFromApplication:(BOOL)allWindows
+{
+ UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow];
+
+ UIGraphicsBeginImageContext(keyWindow.bounds.size);
+ if (allWindows)
+ {
+ for (UIWindow *w in [[UIApplication sharedApplication] windows])
+ {
+ [w.layer renderInContext:UIGraphicsGetCurrentContext()];
+ }
+ }
+ else
+ {
+ [keyWindow.layer renderInContext:UIGraphicsGetCurrentContext()];
+ }
+ UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+ return image;
+}
+
+- (UIImage *)imageCropedToFrame:(CGRect)cropFrame
+{
+ CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], cropFrame);
+ UIImage *result = [UIImage imageWithCGImage:imageRef];
+ CGImageRelease(imageRef);
+ return result;
+}
+
+- (UIImage *)imageMaskedAtFrame:(CGRect)maskFrame
+{
+ CGRect imageFrame = CGRectMake(0, 0, self.size.width, self.size.height);
+ UIGraphicsBeginImageContext(self.size);
+ [self drawInRect:imageFrame];
+
+ [[UIColor blackColor] set];
+ UIRectFill(maskFrame);
+
+ UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+
+ return result;
+}
+
+@end
Please sign in to comment.
Something went wrong with that request. Please try again.