frank-cucumber 1.1.9.pre1 → 1.1.10

Sign up to get free protection for your applications and to get access to all the features.
@@ -28,7 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_dependency( "json" ) # TODO: figure out how to be more permissive as to which JSON gems we allow
29
29
  s.add_dependency( "dnssd" )
30
30
  s.add_dependency( "thor" )
31
- s.add_dependency( "xcodeproj" )
31
+ s.add_dependency( "xcodeproj", [">=0.5.3"] )
32
32
 
33
33
  s.add_development_dependency( "rr" )
34
34
  s.add_development_dependency( "yard" )
@@ -1,22 +1,9 @@
1
1
  (function() {
2
- var RELOAD_INTERVAL, guessAtDeviceFamilyBasedOnViewDump,
2
+ var RELOAD_INTERVAL,
3
3
  __slice = [].slice;
4
4
 
5
5
  RELOAD_INTERVAL = 500;
6
6
 
7
- guessAtDeviceFamilyBasedOnViewDump = function(viewHier) {
8
- switch (viewHier.accessibilityFrame.size.height) {
9
- case 1024:
10
- return 'ipad';
11
- case 480:
12
- case 568:
13
- return 'iphone';
14
- default:
15
- console.warn("couldn't recognize device family based on screen height of " + viewHeir.accessibilityFrame.size.height + "px");
16
- return 'unknown';
17
- }
18
- };
19
-
20
7
  define(['frank'], function(frank) {
21
8
  var createController;
22
9
  createController = function(_arg) {
@@ -117,12 +104,14 @@
117
104
  reload = function() {
118
105
  var deferable;
119
106
  deferable = $.Deferred();
120
- $.when(frank.fetchViewHierarchy(), frank.fetchOrientation()).done(function(_arg1, orientation) {
121
- var accessibleViews, deviceFamily, rawHier;
107
+ $.when(frank.fetchViewHierarchy(), frank.fetchResolution(), frank.fetchOrientation(), frank.fetchDevice()).done(function(_arg1, resolution, orientation, deviceFamily) {
108
+ var accessibleViews, rawHier;
122
109
  rawHier = _arg1[0];
123
- deviceFamily = guessAtDeviceFamilyBasedOnViewDump(rawHier);
110
+ if (deviceFamily == 'mac') {
111
+ $liveButton.hide();
112
+ }
124
113
  treeView.model.resetViewHier(rawHier);
125
- ersatzView.model.resetViews(treeView.model.get('allViews'), deviceFamily, orientation);
114
+ ersatzView.model.resetViews(treeView.model.get('allViews'), resolution, deviceFamily, orientation);
126
115
  accessibleViews = treeView.model.getAccessibleViews();
127
116
  accessibleViewsView.collection.reset(accessibleViews);
128
117
  ersatzView.render();
@@ -15,8 +15,9 @@
15
15
  return _this.temporaryHighlightTimeout = void 0;
16
16
  }, 1500);
17
17
  },
18
- resetViews: function(views, deviceFamily, orientation) {
18
+ resetViews: function(views, resolution, deviceFamily, orientation) {
19
19
  this.set('allViews', views);
20
+ this.set('resolution', resolution);
20
21
  this.set('deviceFamily', deviceFamily);
21
22
  this.set('orientation', orientation);
22
23
  this.set('highlightFrames', []);
@@ -1,5 +1,5 @@
1
1
  (function() {
2
- var ISO_MAJOR_OFFSET, ISO_MINOR_OFFSET, ISO_SKEW, SCREEN_BOUNDS,
2
+ var ISO_MAJOR_OFFSET, ISO_MINOR_OFFSET, ISO_SKEW,
3
3
  __slice = [].slice;
4
4
 
5
5
  ISO_SKEW = 15;
@@ -8,35 +8,29 @@
8
8
 
9
9
  ISO_MINOR_OFFSET = 5;
10
10
 
11
- SCREEN_BOUNDS = {
12
- iphone: {
13
- x: 0,
14
- y: 0,
15
- width: 320,
16
- height: 480
17
- },
18
- ipad: {
19
- x: 0,
20
- y: 0,
21
- width: 768,
22
- height: 1024
23
- }
24
- };
25
-
26
11
  define(['transform_stack', 'ersatz_model'], function(transformStack, ErsatzModel) {
27
12
  var ErsatzView, ErsatzViewSnapshotView, drawStaticBackdropAndReturnTransformer, transformFromBaseForViewModel;
28
- drawStaticBackdropAndReturnTransformer = function(paper, deviceFamily, orientation, isoSkew) {
29
- var isiPhone, rotation, rotationPoint, transformer;
13
+ drawStaticBackdropAndReturnTransformer = function(paper, resolution, deviceFamily, orientation, isoSkew) {
14
+ var isiPhone, isiPad, rotation, rotationPoint, transformer;
30
15
  paper.clear();
31
16
  paper.canvas.setAttribute("width", "100%");
32
17
  paper.canvas.setAttribute("height", "100%");
33
18
  isiPhone = 'iphone' === deviceFamily;
19
+ isiPad = 'ipad' == deviceFamily;
34
20
  if (isiPhone) {
35
- paper.canvas.setAttribute("viewBox", "0 0 380 720");
36
- rotationPoint = [190, 360];
37
- } else {
38
- paper.canvas.setAttribute("viewBox", "0 0 875 1200");
39
- rotationPoint = [437, 600];
21
+ width = resolution.width + 60;
22
+ height = resolution.height + 240;
23
+ paper.canvas.setAttribute("viewBox", "0 0 " + width + " " + height);
24
+ rotationPoint = [width / 2, height / 2];
25
+ } else if (isiPad) {
26
+ width = resolution.width + 108;
27
+ height = resolution.height + 176;
28
+ paper.canvas.setAttribute("viewBox", "0 0 " + width + " " + height);
29
+ rotationPoint = [width / 2, height / 2];
30
+ }
31
+ else
32
+ {
33
+ paper.canvas.setAttribute("viewBox", "0 0 " + resolution.width + " " + resolution.height);
40
34
  }
41
35
  transformer = transformStack();
42
36
  transformer.skew(0, isoSkew).translate(6, 6);
@@ -56,29 +50,36 @@
56
50
  transformer.rotateAroundPoint.apply(transformer, [rotation].concat(__slice.call(rotationPoint)));
57
51
  }
58
52
  if (isiPhone) {
59
- paper.rect(0, 0, 360, 708, 40).attr({
53
+ width = resolution.width + 40;
54
+ height = resolution.height + 228;
55
+ paper.rect(0, 0, width, height, 40).attr({
60
56
  fill: "black",
61
57
  stroke: "gray",
62
58
  "stroke-width": 4
63
59
  }).transform(transformer.desc());
64
- } else {
65
- paper.rect(10, 10, 855, 1110, 20).attr({
60
+ } else if (isiPad) {
61
+ width = resolution.width + 108;
62
+ height = resolution.height + 86;
63
+ paper.rect(10, 10, width, height, 20).attr({
66
64
  'fill': 'black',
67
65
  'stroke': 'gray',
68
66
  'stroke-width': 6
69
67
  }).transform(transformer.desc());
70
68
  }
71
69
  if (isiPhone) {
72
- transformer.push().translate(180, 655);
70
+ x = resolution.width / 2 + 20;
71
+ y = resolution.height + 175;
72
+ transformer.push().translate(x, y);
73
73
  paper.circle(0, 0, 34).transform(transformer.desc()).attr("fill", "90-#303030-#101010");
74
74
  paper.rect(0, 0, 22, 22, 5).attr({
75
75
  stroke: "gray",
76
76
  "stroke-width": 2
77
77
  }).transform(transformer.push().translate(-11, -11).descAndPop());
78
78
  transformer.translate(20, 120);
79
- } else {
79
+ } else if (isiPad) {
80
80
  transformer.translate(50, 50);
81
81
  }
82
+
82
83
  if (isoSkew > 0) {
83
84
  transformer.translate(-ISO_MAJOR_OFFSET, 0);
84
85
  }
@@ -137,7 +138,7 @@
137
138
  var isoSkew;
138
139
  this.highlights = [];
139
140
  isoSkew = (this.model.get('isAsploded') ? ISO_SKEW : 0);
140
- this.backdropTransformer = drawStaticBackdropAndReturnTransformer(this.paper, this.model.get('deviceFamily'), this.model.get('orientation'), isoSkew);
141
+ this.backdropTransformer = drawStaticBackdropAndReturnTransformer(this.paper, this.model.get('resolution'), this.model.get('deviceFamily'), this.model.get('orientation'), isoSkew);
141
142
  this.backdrop = this.paper.image();
142
143
  this.refreshBaseScreenshot();
143
144
  if (this.model.get('isAsploded')) {
@@ -147,7 +148,13 @@
147
148
  return this.el;
148
149
  },
149
150
  screenBounds: function() {
150
- return SCREEN_BOUNDS[this.model.get('deviceFamily')];
151
+ resolution = this.model.get('resolution');
152
+ return {
153
+ x: 0,
154
+ y: 0,
155
+ width: resolution.width,
156
+ height: resolution.height
157
+ };
151
158
  },
152
159
  refreshBaseScreenshot: function() {
153
160
  var newScreenshotUrl;
@@ -1,5 +1,5 @@
1
1
  (function() {
2
- var baseUrlFor, cacheBust, displayErrorResponse, fetchOrientation, fetchViewHierarchy, isErrorResponse, requestSnapshotRefresh, sendMapRequest;
2
+ var baseUrlFor, cacheBust, displayErrorResponse, fetchResolution, fetchOrientation, fetchViewHierarchy, fetchDevice, isErrorResponse, requestSnapshotRefresh, sendMapRequest;
3
3
 
4
4
  cacheBust = function(url) {
5
5
  return "" + url + "?" + ((new Date()).getTime());
@@ -26,6 +26,19 @@
26
26
  });
27
27
  };
28
28
 
29
+ fetchResolution = function() {
30
+ var deferable, request;
31
+ deferable = new $.Deferred();
32
+ request = $.ajax({
33
+ type: "GET",
34
+ dataType: "json",
35
+ url: baseUrlFor("/resolution")
36
+ }).done(function(response) {
37
+ return deferable.resolve(response || 'unknown');
38
+ }).fail(deferable.reject);
39
+ return deferable.promise();
40
+ };
41
+
29
42
  fetchOrientation = function() {
30
43
  var deferable, request;
31
44
  deferable = new $.Deferred();
@@ -39,6 +52,19 @@
39
52
  return deferable.promise();
40
53
  };
41
54
 
55
+ fetchDevice = function() {
56
+ var deferable, request;
57
+ deferable = new $.Deferred();
58
+ request = $.ajax({
59
+ type: "GET",
60
+ dataType: "json",
61
+ url: baseUrlFor("/device")
62
+ }).done(function(response) {
63
+ return deferable.resolve(response && response.device || 'unknown');
64
+ }).fail(deferable.reject);
65
+ return deferable.promise();
66
+ };
67
+
42
68
  requestSnapshotRefresh = function() {
43
69
  return $.ajax({
44
70
  type: 'GET',
@@ -83,7 +109,9 @@
83
109
  define(function() {
84
110
  return {
85
111
  fetchViewHierarchy: fetchViewHierarchy,
112
+ fetchResolution: fetchResolution,
86
113
  fetchOrientation: fetchOrientation,
114
+ fetchDevice: fetchDevice,
87
115
  requestSnapshotRefresh: requestSnapshotRefresh,
88
116
  baseScreenshotUrl: function() {
89
117
  return cacheBust(baseUrlFor('/screenshot'));
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -8,6 +8,7 @@ require 'frank-cucumber/launcher'
8
8
  require 'frank-cucumber/console'
9
9
  require 'frank-cucumber/frankifier'
10
10
  require 'frank-cucumber/mac_launcher'
11
+ require 'xcodeproj'
11
12
 
12
13
  module Frank
13
14
  class CLI < Thor
@@ -32,6 +33,7 @@ module Frank
32
33
  method_option WITHOUT_LUMBERJACK, :type => :boolean
33
34
  method_option :build_configuration, :aliases=>'--conf', :type=>:string, :default => 'Debug'
34
35
  method_option :target, :type=>:string
36
+ method_option :project, :type=>:string
35
37
  def setup
36
38
  @libs = %w(Shelley CocoaAsyncSocket CocoaLumberjack CocoaHTTPServer Frank)
37
39
  @libsMac = %w(CocoaAsyncSocketMac CocoaLumberjackMac CocoaHTTPServerMac FrankMac)
@@ -43,7 +45,7 @@ module Frank
43
45
  @libsMac -= %w(CocoaLumberjackMac) if options[WITHOUT_LUMBERJACK]
44
46
  directory ".", "Frank"
45
47
 
46
- Frankifier.frankify!( File.expand_path('.'), :build_config => options[:build_configuration], :target => options[:target] )
48
+ Frankifier.frankify!( File.expand_path('.'), :build_config => options[:build_configuration], :target => options[:target], :project => options[:project] )
47
49
  end
48
50
 
49
51
  desc "update", "updates the frank server components inside your Frank directory"
@@ -55,13 +57,12 @@ module Frank
55
57
  directory( 'frank_static_resources.bundle', 'Frank/frank_static_resources.bundle', :force => true )
56
58
  end
57
59
 
58
- XCODEBUILD_OPTIONS = %w{workspace scheme target configuration}
60
+ XCODEBUILD_OPTIONS = %w{workspace project scheme target configuration}
59
61
  desc "build", "builds a Frankified version of your native app"
60
62
  XCODEBUILD_OPTIONS.each do |option|
61
63
  method_option option
62
64
  end
63
65
  method_option 'arch', :type => :string, :default => 'i386'
64
- method_option 'mac', :type => :boolean, :default => false
65
66
  method_option :noclean, :type => :boolean, :default => false, :aliases => '--nc', :desc => "Don't clean the build directory before building"
66
67
  def build
67
68
  clean = !options['noclean']
@@ -99,7 +100,9 @@ module Frank
99
100
  separate_configuration_option = "-configuration Debug"
100
101
  end
101
102
 
102
- if options['mac']
103
+ build_mac = determine_build_patform(options) == :osx
104
+
105
+ if build_mac
103
106
  run %Q|xcodebuild -xcconfig Frank/frankify.xcconfig #{build_steps} #{extra_opts} #{separate_configuration_option} DEPLOYMENT_LOCATION=YES DSTROOT="#{build_output_dir}" FRANK_LIBRARY_SEARCH_PATHS="\\"#{frank_lib_directory}\\""|
104
107
  else
105
108
  extra_opts += " -arch #{options['arch']}"
@@ -111,7 +114,7 @@ module Frank
111
114
  app = app.first
112
115
  FileUtils.cp_r("#{app}/.", frankified_app_dir)
113
116
 
114
- if options['mac']
117
+ if build_mac
115
118
  in_root do
116
119
  FileUtils.cp_r(
117
120
  File.join( 'Frank',static_bundle),
@@ -236,6 +239,88 @@ module Frank
236
239
  end
237
240
  end
238
241
 
242
+ # The xcodeproj gem doesn't currently support schemes, and schemes have been difficult
243
+ # to figure out. I plan to either implement schemes in xcodeproj at a later date, or
244
+ # wait for them to be implemented, and then fix this function
245
+ def determine_build_patform ( options )
246
+ project_path = nil
247
+
248
+ if options["workspace"] != nil
249
+ if options["scheme"] != nil
250
+ workspace = Xcodeproj::Workspace.new_from_xcworkspace(options["workspace"])
251
+ projects = workspace.projpaths
252
+
253
+ projects.each { | current_project |
254
+ lines = `xcodebuild -project #{current_project} -list`
255
+
256
+ found_schemes = false
257
+
258
+ lines.split("\n").each { | line |
259
+ if found_schemes
260
+ line = line[8..-1]
261
+
262
+ if line == ""
263
+ found_schemes = false
264
+ else
265
+ if line == options["scheme"]
266
+ project_path = current_project
267
+ end
268
+ end
269
+
270
+ else
271
+ line = line [4..-1]
272
+
273
+ if line == "Schemes:"
274
+ found_schemes = true
275
+ end
276
+
277
+ end
278
+ }
279
+ }
280
+ else
281
+ say "You must specify a scheme if you specify a workplace"
282
+ exit 10
283
+ end
284
+ else
285
+ project_path = options["project"]
286
+ end
287
+
288
+ if project_path == nil
289
+ Dir.foreach(Dir.pwd) { | file |
290
+ if file.end_with? ".xcodeproj"
291
+ if project_path != nil
292
+ say "You must specify a project if there are more than one .xcodeproj bundles in a directory"
293
+ exit 10
294
+ else
295
+ project_path = file
296
+ end
297
+ end
298
+ }
299
+ end
300
+
301
+ project = Xcodeproj::Project.new(project_path)
302
+
303
+ target = nil
304
+
305
+ if options["target"] != nil
306
+ project.targets.each { | proj_target |
307
+ if target.name == options["target"]
308
+ target = proj_target
309
+ end
310
+ }
311
+ else
312
+ target = project.targets[0]
313
+ end
314
+
315
+ if target == nil
316
+ say "Unable to determine a target from the options provided"
317
+ exit 10
318
+ end
319
+
320
+ return target.platform_name
321
+
322
+ end
323
+
239
324
  end
240
325
  end
241
326
 
@@ -14,10 +14,11 @@ class Frankifier
14
14
  @root = Pathname.new( root_dir )
15
15
  @target_build_configuration = options[:build_config]
16
16
  @target_selection = options[:target]
17
+ load_xcode_proj_option(options[:project])
17
18
  end
18
19
 
19
20
  def frankify!
20
- decide_on_project
21
+ decide_on_project if @project.nil?
21
22
  decide_on_target
22
23
  report_project_and_target
23
24
 
@@ -33,6 +34,17 @@ class Frankifier
33
34
  end
34
35
 
35
36
  private
37
+ def load_xcode_proj_option(xcodeproj)
38
+ if xcodeproj
39
+ unless File.exists?(xcodeproj)
40
+ raise "Project file '#{xcodeproj}' does not exist. Please specify the relative path."
41
+ end
42
+
43
+ @xcodeproj_path = Pathname.new(xcodeproj)
44
+ @project = Xcodeproj::Project.new(@xcodeproj_path)
45
+ end
46
+ end
47
+
36
48
  def decide_on_project
37
49
  projects = Pathname.glob( @root+'*.xcodeproj' )
38
50
  xcodeproj = case projects.size
@@ -63,6 +63,37 @@ module Frank
63
63
  raise "Could not find anything matching [#{selector}] to double tap" if touch_successes.empty?
64
64
  raise "Some views could not be double tap (probably because they are not within the current viewport)" if touch_successes.include?(false)
65
65
  end
66
+
67
+ # Drag the slider thumb to required value, taking the specified time
68
+ #
69
+ # @param [String] selector A view selector
70
+ # @param [Number] value The value up to which the slider should be dragged
71
+ # @param [Number] duration The time interval that the drag should take
72
+ #
73
+ # @return [Array<Boolean>] an array indicating for each view which matched the selector if the value was acceptable or not
74
+ #
75
+ # @raise an expection if no views matched the selector
76
+ # @raise an expection if no views which matched the selector could have their thumbs dragged
77
+ def drag_thumb_in_slider( selector, value, duration )
78
+ touch_successes = frankly_map( selector, "FEX_dragThumbToValue:withDuration:", value, duration)
79
+ raise "Could not find anything matching [#{selector}] to have its thumb dragged" if touch_successes.empty?
80
+ raise "Some views could not had their thumbs dragged (are they even UISLiders?)" if touch_successes.include?(false)
81
+ end
82
+
83
+ # Drag the slider thumb to required value
84
+ #
85
+ # @param [String] selector A view selector
86
+ # @param [Number] value The value up to which the slider should be dragged
87
+ #
88
+ # @return [Array<Boolean>] an array indicating for each view which matched the selector if the value was acceptable or not
89
+ #
90
+ # @raise an expection if no views matched the selector
91
+ # @raise an expection if no views which matched the selector could have their thumbs dragged
92
+ def drag_thumb_in_slider_with_default_duration( selector, value )
93
+ touch_successes = frankly_map( selector, "FEX_dragThumbToValue:", value )
94
+ raise "Could not find anything matching [#{selector}] to have its thumb dragged" if touch_successes.empty?
95
+ raise "Some views could not had their thumbs dragged (are they even UISLiders?)" if touch_successes.include?(false)
96
+ end
66
97
  end
67
98
  end
68
99
  end
@@ -1,5 +1,5 @@
1
1
  module Frank
2
2
  module Cucumber
3
- VERSION = "1.1.9.pre1"
3
+ VERSION = "1.1.10"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: frank-cucumber
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.9.pre1
5
- prerelease: 6
4
+ version: 1.1.10
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Pete Hodgson
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-03-21 00:00:00.000000000 Z
13
+ date: 2013-04-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: cucumber
@@ -147,7 +147,7 @@ dependencies:
147
147
  requirements:
148
148
  - - ! '>='
149
149
  - !ruby/object:Gem::Version
150
- version: '0'
150
+ version: 0.5.3
151
151
  type: :runtime
152
152
  prerelease: false
153
153
  version_requirements: !ruby/object:Gem::Requirement
@@ -155,7 +155,7 @@ dependencies:
155
155
  requirements:
156
156
  - - ! '>='
157
157
  - !ruby/object:Gem::Version
158
- version: '0'
158
+ version: 0.5.3
159
159
  - !ruby/object:Gem::Dependency
160
160
  name: rr
161
161
  requirement: !ruby/object:Gem::Requirement
@@ -376,9 +376,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
376
376
  required_rubygems_version: !ruby/object:Gem::Requirement
377
377
  none: false
378
378
  requirements:
379
- - - ! '>'
379
+ - - ! '>='
380
380
  - !ruby/object:Gem::Version
381
- version: 1.3.1
381
+ version: '0'
382
382
  requirements: []
383
383
  rubyforge_project:
384
384
  rubygems_version: 1.8.24