funfx 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. data/History.txt +18 -0
  2. data/License.txt +20 -0
  3. data/Manifest.txt +87 -0
  4. data/README.txt +48 -0
  5. data/Rakefile +5 -0
  6. data/config/hoe.rb +67 -0
  7. data/config/requirements.rb +15 -0
  8. data/ext/FunFX.swc +0 -0
  9. data/lib/funfx.rb +34 -0
  10. data/lib/funfx/browser/firewatir.rb +47 -0
  11. data/lib/funfx/browser/flex_app_lookup.rb +22 -0
  12. data/lib/funfx/browser/safariwatir.rb +47 -0
  13. data/lib/funfx/browser/watir.rb +41 -0
  14. data/lib/funfx/decoder.rb +67 -0
  15. data/lib/funfx/flex/element.rb +161 -0
  16. data/lib/funfx/flex/elements.rb +2712 -0
  17. data/lib/funfx/flex/flex_app_id.rb +15 -0
  18. data/lib/funfx/flex/tabular_data.rb +22 -0
  19. data/lib/funfx/meta/class_dot.erb +24 -0
  20. data/lib/funfx/meta/code.erb +33 -0
  21. data/lib/funfx/meta/generator.rb +18 -0
  22. data/lib/funfx/meta/parser.rb +190 -0
  23. data/lib/funfx/version.rb +9 -0
  24. data/rake_tasks/deployment.rake +34 -0
  25. data/rake_tasks/environment.rake +7 -0
  26. data/rake_tasks/generation.rake +37 -0
  27. data/rake_tasks/hoe_ext.rake +11 -0
  28. data/rake_tasks/rspec.rake +28 -0
  29. data/script/console +10 -0
  30. data/script/console.cmd +1 -0
  31. data/script/destroy +14 -0
  32. data/script/destroy.cmd +1 -0
  33. data/script/generate +14 -0
  34. data/script/generate.cmd +1 -0
  35. data/script/txt2html +82 -0
  36. data/script/txt2html.cmd +1 -0
  37. data/setup.rb +1585 -0
  38. data/spec/funfx/demo_app/accordion_spec.rb +38 -0
  39. data/spec/funfx/demo_app/advanced_data_grid_spec.rb +74 -0
  40. data/spec/funfx/demo_app/alert_spec.rb +33 -0
  41. data/spec/funfx/demo_app/button_bar_spec.rb +21 -0
  42. data/spec/funfx/demo_app/button_spec.rb +68 -0
  43. data/spec/funfx/demo_app/check_box_spec.rb +62 -0
  44. data/spec/funfx/demo_app/control_bar_spec.rb +19 -0
  45. data/spec/funfx/demo_app/controls_with_same_id_spec.rb +37 -0
  46. data/spec/funfx/demo_app/data_grid_editable_spec.rb +78 -0
  47. data/spec/funfx/demo_app/data_grid_spec.rb +65 -0
  48. data/spec/funfx/demo_app/date_chooser_spec.rb +67 -0
  49. data/spec/funfx/demo_app/date_field_spec.rb +36 -0
  50. data/spec/funfx/demo_app/form_spec.rb +22 -0
  51. data/spec/funfx/demo_app/grid_layout_spec.rb +23 -0
  52. data/spec/funfx/demo_app/h_scrollbar_spec.rb +25 -0
  53. data/spec/funfx/demo_app/h_slider_spec.rb +21 -0
  54. data/spec/funfx/demo_app/horizontal_list_spec.rb +24 -0
  55. data/spec/funfx/demo_app/label_spec.rb +18 -0
  56. data/spec/funfx/demo_app/link_bar_spec.rb +57 -0
  57. data/spec/funfx/demo_app/link_button_spec.rb +21 -0
  58. data/spec/funfx/demo_app/list_spec.rb +23 -0
  59. data/spec/funfx/demo_app/menu_bar_spec.rb +33 -0
  60. data/spec/funfx/demo_app/menu_spec.rb +27 -0
  61. data/spec/funfx/demo_app/numeric_stepper_spec.rb +37 -0
  62. data/spec/funfx/demo_app/popup_button_spec.rb +36 -0
  63. data/spec/funfx/demo_app/popup_menu_bar_spec.rb +42 -0
  64. data/spec/funfx/demo_app/progress_bar_spec.rb +24 -0
  65. data/spec/funfx/demo_app/radio_button_group_spec.rb +50 -0
  66. data/spec/funfx/demo_app/radio_button_spec.rb +26 -0
  67. data/spec/funfx/demo_app/record_test_spec.rb +20 -0
  68. data/spec/funfx/demo_app/repeater_control_spec.rb +65 -0
  69. data/spec/funfx/demo_app/tab_bar_spec.rb +19 -0
  70. data/spec/funfx/demo_app/tab_navigator_spec.rb +19 -0
  71. data/spec/funfx/demo_app/test_spec.rb +19 -0
  72. data/spec/funfx/demo_app/text_area_spec.rb +28 -0
  73. data/spec/funfx/demo_app/text_input_spec.rb +28 -0
  74. data/spec/funfx/demo_app/text_spec.rb +18 -0
  75. data/spec/funfx/demo_app/tile_button_spec.rb +20 -0
  76. data/spec/funfx/demo_app/tile_list_spec.rb +25 -0
  77. data/spec/funfx/demo_app/title_window_spec.rb +40 -0
  78. data/spec/funfx/demo_app/toggle_button_spec.rb +19 -0
  79. data/spec/funfx/demo_app/tree_drag_and_drop_spec.rb +39 -0
  80. data/spec/funfx/demo_app/tree_spec.rb +24 -0
  81. data/spec/funfx/demo_app/view_stack_spec.rb +27 -0
  82. data/spec/funfx/flex/element_spec.rb +115 -0
  83. data/spec/funfx/flex/flex_app_id_spec.rb +40 -0
  84. data/spec/funfx/meta/generator_spec.rb +16 -0
  85. data/spec/funfx/meta/parser_spec.rb +88 -0
  86. data/spec/spec.opts +1 -0
  87. data/spec/spec_helper.rb +41 -0
  88. metadata +166 -0
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "DemoApp" do
4
+ before do
5
+ browser.goto(DEMO_APP)
6
+ @flex = browser.flex_app('DemoAppId', 'DemoAppName')
7
+ end
8
+
9
+ it "should interact with title window" do
10
+ tree = @flex.tree({:id => 'objectTree'})
11
+ tree.open('Container controls')
12
+ tree.select('Container controls>TitleWindow1')
13
+
14
+ title_window = @flex.title_window({:automationName => 'login'})
15
+
16
+ lambda do
17
+ title_window.visible?
18
+ end.should raise_error
19
+
20
+ button = @flex.button({:id => 'myButton'})
21
+ button.click
22
+
23
+ title_window = @flex.title_window({:automationName => 'login'})
24
+ title_window.should be_visible
25
+ title_window.should_not be_show_close_button
26
+ title_window.title.strip.should == "Title Window"
27
+
28
+ text_area = @flex.text_area({:id => 'userName'})
29
+ text_area.input("Tester")
30
+
31
+ button = @flex.button({:automationName => 'OK'})
32
+ button.click
33
+
34
+ title_window = @flex.title_window({:automationName => 'login'})
35
+
36
+ lambda do
37
+ title_window.visible?
38
+ end.should raise_error(FunFX::Flex::FunFXError)
39
+ end
40
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "DemoApp" do
4
+ before do
5
+ browser.goto(DEMO_APP)
6
+ @flex = browser.flex_app('DemoAppId', 'DemoAppName')
7
+ end
8
+
9
+ it "should click toggle button" do
10
+ tree = @flex.tree({:id => 'objectTree'})
11
+ tree.open('Button controls')
12
+ tree.select('Button controls>ToggleButtonBar1')
13
+
14
+ toggle_button_bar = @flex.toggle_button_bar({:id => 'toggleButtonBar'})
15
+
16
+ toggle_button_bar.change('Director')
17
+ toggle_button_bar.selected_index.should == "1"
18
+ end
19
+ end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "DemoApp" do
4
+ before do
5
+ browser.goto(DEMO_APP)
6
+ @flex = browser.flex_app('DemoAppId', 'DemoAppName')
7
+
8
+ tree = @flex.tree({:id => 'objectTree'})
9
+ tree.open('General controls')
10
+ tree.select('General controls>Tree2')
11
+ end
12
+
13
+ it "should drag and drop item by move" do
14
+ tree = @flex.tree({:id => 'tree'})
15
+ tree.open('California')
16
+ tree.open('California>San Francisco')
17
+
18
+ list = @flex.list({:id => 'list'})
19
+
20
+ list.values(0,4).should == [
21
+ ["Johnny Rocket's"],
22
+ ["Jet Pizza" ],
23
+ ["Steve's Greek" ],
24
+ ["Sonsie" ],
25
+ ["The Border Cafe"]
26
+ ]
27
+
28
+ list.drag_start('Jet Pizza')
29
+ tree.drag_drop('move', 'California>San Francisco')
30
+
31
+ list.values(0,3).should == [
32
+ ["Johnny Rocket's"],
33
+ ["Steve's Greek" ],
34
+ ["Sonsie" ],
35
+ ["The Border Cafe"]
36
+ ]
37
+ end
38
+
39
+ end
@@ -0,0 +1,24 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "DemoApp" do
4
+ before do
5
+ browser.goto(DEMO_APP)
6
+ @flex = browser.flex_app('DemoAppId', 'DemoAppName')
7
+
8
+ tree = @flex.tree({:id => 'objectTree'})
9
+ tree.open('General controls')
10
+ tree.select('General controls>Tree1')
11
+ end
12
+
13
+ it "should open tree and select item" do
14
+ tree = @flex.tree({:id => 'myTree'})
15
+ tree.open('Inbox')
16
+ tree.select('Inbox>Product Management')
17
+ end
18
+
19
+ it "should open tree and close item" do
20
+ tree = @flex.tree({:id => 'myTree'})
21
+ tree.open('Inbox')
22
+ tree.close('Inbox')
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe "DemoApp" do
4
+ before do
5
+ browser.goto(DEMO_APP)
6
+ @flex = browser.flex_app('DemoAppId', 'DemoAppName')
7
+
8
+ tree = @flex.tree({:id => 'objectTree'})
9
+ tree.open('Container controls')
10
+ tree.select('Container controls>ViewStack1')
11
+ end
12
+
13
+ it "should switch tab in a view stack" do
14
+ @flex.box({:id => 'search'}).visible?.should == true
15
+ @flex.box({:id => 'custInfo'}).visible?.should == false
16
+ @flex.box({:id => 'accountInfo'}).visible?.should == false
17
+
18
+ button = @flex.button({:id => 'aInfoButton'})
19
+ button.click
20
+
21
+ @flex.box({:id => 'search'}).visible?.should == false
22
+ @flex.box({:id => 'custInfo'}).visible?.should == false
23
+ @flex.box({:id => 'accountInfo'}).visible?.should == true
24
+
25
+
26
+ end
27
+ end
@@ -0,0 +1,115 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module FunFX
4
+ module Flex
5
+ describe Element do
6
+
7
+ describe '#get_property_value' do
8
+ it "should convert array of id hashes to flex automation id" do
9
+ flex_app = mock('FlexApp')
10
+ element = Element.new(flex_app, nil, {:id => 'box'})
11
+
12
+ flex_app.should_receive(:get_property_value).
13
+ with("{parent: null, id: {id: 'box'}}", 'WhatEver').
14
+ and_return('true')
15
+
16
+ element.get_property_value('WhatEver', TrueClass).should be_true
17
+ end
18
+
19
+ it "should convert array of id hashes with multiple definitions per object to flex automation id" do
20
+ flex_app = mock('FlexApp')
21
+ element = Element.new(flex_app, nil, {:id => 'box'})
22
+
23
+ flex_app.should_receive(:get_property_value).
24
+ with("{parent: null, id: {id: 'box'}}", 'WhatEver').
25
+ and_return('true')
26
+
27
+ element.get_property_value('WhatEver', TrueClass).should be_true
28
+ end
29
+
30
+ it "should sort a single hash and pass it through to flex as is" do
31
+ flex_app = mock('FlexApp')
32
+ element = Element.new(flex_app, nil, {:id => 'box', :automationName => 'Button Control Example', :text => 'Arbitrary Text'})
33
+
34
+ flex_app.should_receive(:get_property_value).
35
+ with("{parent: null, id: {automationName: 'Button%20Control%20Example', id: 'box', text: 'Arbitrary%20Text'}}", 'WhatEver').
36
+ and_return('true')
37
+
38
+ element.get_property_value('WhatEver', TrueClass).should be_true
39
+ end
40
+
41
+ it "should be able to use a parent object" do
42
+ flex_app = mock('FlexApp')
43
+
44
+ parent = Element.new(flex_app, nil, {:id => 'parent'})
45
+ child = parent.box({:id => 'child'})
46
+
47
+ flex_app.should_receive(:get_property_value).
48
+ with("{parent: {parent: null, id: {id: 'parent'}}, id: {id: 'child'}}", 'WhatEver').
49
+ and_return('true')
50
+
51
+ child.get_property_value('WhatEver', TrueClass).should be_true
52
+ end
53
+ end
54
+
55
+ describe "#invoke_tabular_method" do
56
+ it "should get tabular data as two-dimensional array" do
57
+ flex_app = mock('FlexApp')
58
+ element = Element.new(flex_app, nil, {:id => 'box'})
59
+ flex_app.should_receive(:invoke_tabular_method).and_return("a,b\nc,d")
60
+ element.invoke_tabular_method("getValues", Table, 3, 4).should == [["a", "b"], ["c", "d"]]
61
+ end
62
+ end
63
+
64
+ describe 'shift_case' do
65
+ it "should rename rubysyntax to automationenv notation" do
66
+ flex_app = mock('FlexApp')
67
+ element = Element.new(flex_app, nil, {:id => 'element'})
68
+ element.shift_case("box").should == "FlexBox"
69
+ end
70
+
71
+ it "should rename mutiple names with _ to automationenv notation" do
72
+ flex_app = mock('FlexApp')
73
+ element = Element.new(flex_app, nil, {:id => 'element'})
74
+ element.shift_case("menu_bar_item").should == "FlexMenuBarItem"
75
+ end
76
+
77
+ it "should rename mutiple names with _ to automationenv notation where each word is single character" do
78
+ flex_app = mock('FlexApp')
79
+ element = Element.new(flex_app, nil, {:id => 'element'})
80
+ element.shift_case("v_scroll_bar").should == "FlexVScrollBar"
81
+ end
82
+ end
83
+
84
+ it "should raise error with Flex backtrace formatted as Ruby backtrace" do
85
+ flex_error = %{____FUNFX_ERROR:
86
+ Error: Unable to resolve child for part 'undefined':'undefined' in parent 'FlexObjectTest'.
87
+ at mx.automation::AutomationManager/resolveID()[C:\\work\\flex\\dmv_automation\\projects\\automation\\src\\mx\\automation\\AutomationManager.as:1332]
88
+ at mx.automation::AutomationManager/resolveIDToSingleObject()[C:\\work\\flex\\dmv_automation\\projects\\automation\\src\\mx\\automation\\AutomationManager.as:1238]
89
+ at funfx::Proxy/findAutomationObject()[C:\\scm\\funfx\\flex\\src\\funfx\\Proxy.as:46]
90
+ at funfx::Proxy/fireEvent()[C:\\scm\\funfx\\flex\\src\\funfx\\Proxy.as:18]
91
+ at Function/http://adobe.com/AS3/2006/builtin::apply()
92
+ at <anonymous>()
93
+ at flash.external::ExternalInterface$/_callIn()
94
+ at <anonymous>()}
95
+
96
+ element = Element.new(nil, nil, {})
97
+ begin
98
+ element.raise_if_funfx_error(flex_error)
99
+ violated
100
+ rescue => e
101
+ e.message.should == "Error: Unable to resolve child for part 'undefined':'undefined' in parent 'FlexObjectTest'."
102
+ e.backtrace[0..7].join("\n").should == %{C:/work/flex/dmv_automation/projects/automation/src/mx/automation/AutomationManager.as:1332:in `mx.automation::AutomationManager/resolveID()'
103
+ C:/work/flex/dmv_automation/projects/automation/src/mx/automation/AutomationManager.as:1238:in `mx.automation::AutomationManager/resolveIDToSingleObject()'
104
+ C:/scm/funfx/flex/src/funfx/Proxy.as:46:in `funfx::Proxy/findAutomationObject()'
105
+ C:/scm/funfx/flex/src/funfx/Proxy.as:18:in `funfx::Proxy/fireEvent()'
106
+ UNKNOWN:in `Function/http://adobe.com/AS3/2006/builtin::apply()'
107
+ UNKNOWN:in `<anonymous>()'
108
+ UNKNOWN:in `flash.external::ExternalInterface$/_callIn()'
109
+ UNKNOWN:in `<anonymous>()'}
110
+ e.backtrace[8].should =~ /lib\/funfx\/flex\/element.rb:\d+:in `raise_if_funfx_error'/
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,40 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module FunFX
4
+ module Flex
5
+ module FlexAppId
6
+
7
+ describe 'full_id' do
8
+ it "should return prefixed full id" do
9
+ FlexAppIdWrapperWithIdPrefix.new.full_id('test_id').should == 'prefix|test_id'
10
+ end
11
+
12
+ it "should return full id if prefix is not set" do
13
+ FlexAppIdWrapper.new.full_id('test_id').should == 'test_id'
14
+ end
15
+ end
16
+
17
+ describe 'automation_id' do
18
+ it "should description" do
19
+ test_id = 'test_id'
20
+ automation_id = 'automation_id'
21
+ wrapper = FlexAppIdWrapper.new
22
+ wrapper.should_receive('full_id').with(test_id).and_return(automation_id)
23
+
24
+ wrapper.automation_id(test_id).should == "{automationID: '#{automation_id}'}"
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+ class FlexAppIdWrapper
33
+ include FunFX::Flex::FlexAppId
34
+ end
35
+
36
+ class FlexAppIdWrapperWithIdPrefix < FlexAppIdWrapper
37
+ def initialize
38
+ @id_prefix = 'prefix'
39
+ end
40
+ end
@@ -0,0 +1,16 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'funfx/meta/generator'
3
+
4
+ module FunFX
5
+ module Meta
6
+ describe Generator do
7
+ it "should produce a dot graph" do
8
+ classes = ClassLib.new.classes
9
+ generator = Generator.new(classes, :class_dot)
10
+ dot = generator.generate
11
+ dot.should =~ /FlexDisplayObject/
12
+ dot.should =~ /TrueClass\\ltab_enabled?/
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,88 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require 'funfx/meta/parser'
3
+
4
+ module FunFX
5
+ module Meta
6
+ describe ClassLib do
7
+ before do
8
+ @lib = ClassLib.new
9
+ end
10
+
11
+ it "should parse classes" do
12
+ @lib.classes.length.should == 89
13
+ end
14
+
15
+ it "should extract some classes" do
16
+ classes = @lib.classes(%w{FlexMenuBar FlexLabel FlexObject})
17
+ classes.map{|c| c.name}.should == %w{FlexObject FlexLabel FlexMenuBar}
18
+ @lib.classes.length.should == 89
19
+ end
20
+
21
+ it "should know about children" do
22
+ flex_area_series = @lib['FlexListBase']
23
+ flex_area_series.children.map{|c| c.name}.sort.should == %w{FlexDataGrid FlexList FlexTree}
24
+ end
25
+
26
+ it "should have a toplevel class that knows about children" do
27
+ ob = @lib.object
28
+ ob.children.map{|c| c.name}.sort.should == %w{FlexDisplayObject FlexRepeater}
29
+ end
30
+
31
+ it "should have string properties" do
32
+ prop = @lib['FlexObject'].properties[0]
33
+ prop.name.should == 'automationName'
34
+ prop.ruby_name.should == 'automation_name'
35
+ prop.ruby_type.should == String
36
+ end
37
+
38
+ it "should have boolean properties" do
39
+ prop = @lib['FlexDisplayObject'].properties[0]
40
+ prop.name.should == 'tabChildren'
41
+ prop.ruby_name.should == 'tab_children?'
42
+ prop.ruby_type.should == TrueClass
43
+ end
44
+
45
+ it "should have event methods" do
46
+ meth = @lib['FlexDisplayObject'].events[0]
47
+ meth.name.should == 'MouseMove'
48
+ meth.ruby_name.should == 'mouse_move'
49
+ end
50
+
51
+ it "should have event method args" do
52
+ meth = @lib['FlexDisplayObject'].events[0]
53
+ arg1 = meth.args[0]
54
+
55
+ arg1.name.should == 'localX'
56
+ arg1.ruby_name.should == 'local_x'
57
+ arg1.ruby_type.should == Integer
58
+ arg1.default_value.should == 0
59
+ end
60
+
61
+ it "should generate dot property list" do
62
+ @lib['FlexObject'].dot_property_list.gsub(/\\l/, "\n").strip.should == %{automation_name : String
63
+ automation_class_name : String
64
+ id : String
65
+ class_name : String
66
+ automation_index : String
67
+ current_state : String
68
+ focus_enabled? : TrueClass
69
+ tool_tip : String
70
+ error_string : String
71
+ percent_height : Integer
72
+ percent_width : Integer
73
+ scale_x : Integer
74
+ scale_y : Integer
75
+ error_color : String
76
+ theme_color : String
77
+ enabled? : TrueClass
78
+ use_hand_cursor? : TrueClass
79
+ num_automation_children : Integer}
80
+ end
81
+
82
+ it "should generate dot event method list" do
83
+ @lib['FlexDisplayObject'].dot_event_list.gsub(/\\l/, "\n").strip.should == %{mouse_move(local_x=0, local_y=0, key_modifier=[\\\"0\\\"])
84
+ click(key_modifier=[\\\"0\\\"])}
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+
4
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
5
+ require 'funfx'
6
+ DEMO_APP = "http://localhost:9851/index.html" unless defined?(DEMO_APP)
7
+
8
+ def browser
9
+ if $browser.nil?
10
+ require_watir
11
+ $browser = $browser_class.new
12
+ $browser.visible = true if $browser.respond_to?(:visible=)
13
+ at_exit do
14
+ $browser.close
15
+ end
16
+ end
17
+ $browser
18
+ end
19
+
20
+ def require_watir
21
+ if ENV['FIREWATIR'] # Set this in your shell if you want FireFox
22
+ require 'funfx/browser/firewatir'
23
+ $browser_class = FireWatir::Firefox
24
+ else
25
+ case RUBY_PLATFORM
26
+ when /darwin/
27
+ require 'funfx/browser/safariwatir'
28
+ $browser_class = Watir::Safari
29
+ when /win32|mingw/
30
+ require 'funfx/browser/firewatir'
31
+ $browser_class = FireWatir::Firefox
32
+ #require 'funfx/browser/watir'
33
+ #$browser_class = Watir::IE
34
+ when /linux/
35
+ require 'funfx/browser/firewatir'
36
+ $browser_class = FireWatir::Firefox
37
+ else
38
+ raise "This platform is not supported (#{RUBY_PLATFORM})"
39
+ end
40
+ end
41
+ end