kolach-melomel 0.6.4

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.
@@ -0,0 +1,155 @@
1
+ # These add-on methods provide ease of use utility methods.
2
+ module Melomel
3
+ class Bridge
4
+ # Blocks until Melomel.busy in the Flash virtual machine is false.
5
+ #
6
+ # Returns nothing.
7
+ def wait()
8
+ loop do
9
+ break unless busy!
10
+ sleep 0.1
11
+ end
12
+ end
13
+
14
+ # Checks if the Flash virtual machine is currently busy. See Melomel#busy
15
+ # in the Melomel asdocs for more information.
16
+ #
17
+ # Returns true if the Flash virtual machine is busy. Otherwise returns
18
+ # false.
19
+ def busy!
20
+ get_class!('Melomel').busy!
21
+ end
22
+
23
+ # Finds a list of display objects matching a class and hash of properties.
24
+ #
25
+ # class_name - The type of objects to search for.
26
+ # root - The object to start searching from. (Defaults to the stage).
27
+ # properties - A list of properties to match on each object.
28
+ #
29
+ # Example:
30
+ #
31
+ # bridge.find_all('mx.controls.Button', :label => 'Click me')
32
+ # # => [<Melomel::ObjectProxy>, <Melomel::ObjectProxy>]
33
+ #
34
+ # Returns a list of display objects contained by root that match the
35
+ # properties and class specified.
36
+ def find_all(class_name, root={}, properties={})
37
+ # Merge hashes if no root is specified
38
+ if root.is_a?(Hash)
39
+ properties.merge!(root)
40
+ root = nil
41
+ end
42
+
43
+ # Retrieve object
44
+ get_class('melomel.core.UI').findAll(class_name, root, properties)
45
+ end
46
+
47
+ def find_all!(class_name, root={}, properties={})
48
+ objects = find_all(class_name, root, properties)
49
+ raise MelomelError.new("No objects found") if objects.empty?
50
+ return objects
51
+ end
52
+
53
+ # Finds the first display object matching a class and hash of properties.
54
+ #
55
+ # class_name - The type of object to search for.
56
+ # root - The object to start searching from. (Defaults to the stage).
57
+ # properties - A list of properties to match on the object.
58
+ #
59
+ # Example:
60
+ #
61
+ # bridge.find('mx.controls.Button', :label => 'Click me')
62
+ # # => <Melomel::ObjectProxy>
63
+ #
64
+ # Returns the first display object contained by root that matches the
65
+ # properties and class specified.
66
+ def find(class_name, root={}, properties={})
67
+ # Merge hashes if no root is specified
68
+ if root.is_a?(Hash)
69
+ properties.merge!(root)
70
+ root = nil
71
+ end
72
+
73
+ # Retrieve object
74
+ get_class('melomel.core.UI').find(class_name, root, properties)
75
+ end
76
+
77
+ def find!(class_name, root={}, properties={})
78
+ object = find(class_name, root, properties)
79
+ raise MelomelError.new("No object found") if object.nil?
80
+ return object
81
+ end
82
+
83
+ # Finds a component based on the label of a nearby component. This works
84
+ # by first finding a Halo or Spark label component and then recursively
85
+ # searching the label's parent's children for a component of a given class.
86
+ #
87
+ # class_name - The type of object to search for.
88
+ # label_text - The label text to search for.
89
+ # root - The object to start searching from. (Defaults to the stage).
90
+ # properties - A list of properties to match on the object.
91
+ #
92
+ # Example:
93
+ #
94
+ # bridge.find_labeled('mx.controls.TextInput', 'First Name')
95
+ # # => <Melomel::ObjectProxy>
96
+ #
97
+ # Returns the first display object which is inside the parent of a given
98
+ # label.
99
+ def find_labeled(class_name, label_text, root={}, properties={})
100
+ # Merge hashes if no root is specified
101
+ if root.is_a?(Hash)
102
+ properties.merge!(root)
103
+ root = nil
104
+ end
105
+
106
+ # Retrieve object
107
+ get_class('melomel.core.UI').findLabeled(class_name, label_text, root, properties)
108
+ end
109
+
110
+ def find_labeled!(class_name, label_text, root={}, properties={})
111
+ object = find_labeled(class_name, label_text, root, properties)
112
+ raise MelomelError.new("No object found") if object.nil?
113
+ return object
114
+ end
115
+
116
+
117
+ # Imitates a click on a component
118
+ def click(component, properties={})
119
+ get_class('melomel.core.UI').click(component, properties)
120
+ end
121
+
122
+ # Imitates a double click on a component
123
+ def double_click(component, properties={})
124
+ get_class('melomel.core.UI').doubleClick(component, properties)
125
+ end
126
+
127
+
128
+ # Imitates a key down on a component
129
+ def key_down(component, char, properties={})
130
+ get_class('melomel.core.UI').keyDown(component, char, properties)
131
+ end
132
+
133
+ # Imitates a key up on a component
134
+ def key_up(component, char, properties={})
135
+ get_class('melomel.core.UI').keyUp(component, char, properties)
136
+ end
137
+
138
+ # Imitates a key press on a component
139
+ def key_press(component, char, properties={})
140
+ get_class('melomel.core.UI').keyPress(component, char, properties)
141
+ end
142
+
143
+
144
+ # Generates a list of labels created by a data control or column based on a
145
+ # data set.
146
+ #
147
+ # component - The control or column which has an itemToLabel() method.
148
+ # data - The data set to generate labels from.
149
+ #
150
+ # Returns a Ruby array of labels.
151
+ def items_to_labels!(component, data)
152
+ get_class('melomel.core.UI').itemsToLabels!(component, data)
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,150 @@
1
+ require 'cucumber'
2
+ require 'melomel'
3
+ Dir.glob(File.dirname(__FILE__) + '/cucumber/*', &method(:require))
4
+
5
+ # This class holds utility methods for running Cucumber steps.
6
+ module Melomel
7
+ class Cucumber
8
+ # A wrapper for Melomel actions that automatically waits until the Flash
9
+ # virtual machine is not busy before continuing.
10
+ #
11
+ # Returns nothing.
12
+ def self.run!
13
+ Melomel.wait()
14
+ yield
15
+ end
16
+
17
+ # Finds a component by id.
18
+ #
19
+ # class_name - The class or classes to match on.
20
+ # id - The id of the component.
21
+ # root - The root component to search from. Defaults to the stage.
22
+ # properties - Additional properties to search on.
23
+ #
24
+ # Returns a component matching the id and the additional properties.
25
+ def self.find_by_id!(class_name, id, root={}, properties={})
26
+ properties['id'] = id
27
+ Melomel.find!(class_name, root, properties)
28
+ end
29
+
30
+ # Finds a component by label. If the first character is a "#" then the
31
+ # component should be found by id. Otherwise it is found by label.
32
+ #
33
+ # class_name - The class or classes to match on.
34
+ # label - The label of the component.
35
+ # root - The root component to search from. Defaults to the stage.
36
+ # properties - Additional properties to search on.
37
+ #
38
+ # Returns a component matching the label and the additional properties.
39
+ def self.find_by_label!(class_name, label, root={}, properties={})
40
+ set_properties_key(properties, 'label', label)
41
+ Melomel.find!(class_name, root, properties)
42
+ end
43
+
44
+ # Finds a component that shares the same parent as a given label. If the
45
+ # first character is a "#" then the component should be found by id.
46
+ # Otherwise it is found by label.
47
+ #
48
+ # class_name - The class or classes to match on.
49
+ # label - The label text.
50
+ # root - The root component to search from. Defaults to the stage.
51
+ # properties - Additional properties to search on.
52
+ #
53
+ # Returns a component labeled by another component.
54
+ def self.find_labeled!(class_name, label, root={}, properties={})
55
+ if label.index('#') == 0
56
+ find_by_id!(class_name, label[1..-1], root, properties)
57
+ else
58
+ Melomel.find_labeled!(class_name, label, root, properties)
59
+ end
60
+ end
61
+
62
+ # Finds a component by title. If the first character is a "#" then the
63
+ # component should be found by id. Otherwise it is found by title.
64
+ #
65
+ # class_name - The class or classes to match on.
66
+ # title - The title of the component.
67
+ # root - The root component to search from. Defaults to the stage.
68
+ # properties - Additional properties to search on.
69
+ #
70
+ # Returns a component matching the title and the additional properties.
71
+ def self.find_by_title!(class_name, title, root={}, properties={})
72
+ set_properties_key(properties, 'title', title)
73
+ Melomel.find!(class_name, root, properties)
74
+ end
75
+
76
+ # Finds a component by text. If the first character is a "#" then the
77
+ # component should be found by id. Otherwise it is found by text.
78
+ #
79
+ # class_name - The class or classes to match on.
80
+ # text - The text property of the component.
81
+ # root - The root component to search from. Defaults to the stage.
82
+ # properties - Additional properties to search on.
83
+ #
84
+ # Returns a component matching the text and the additional properties.
85
+ def self.find_by_text!(class_name, text, root={}, properties={})
86
+ set_properties_key(properties, 'text', text)
87
+ Melomel.find!(class_name, root, properties)
88
+ end
89
+
90
+ # Sets the key in the properties hash. If the first character is "#" then
91
+ # the key is "id". Otherwise it is set to the value of "key".
92
+ #
93
+ # properties - The properties hash.
94
+ # key - The name of the key to set.
95
+ # name - The name of the component.
96
+ #
97
+ # Returns nothing.
98
+ def self.set_properties_key(properties, key, name)
99
+ if name.index('#') == 0
100
+ properties['id'] = name[1..-1]
101
+ else
102
+ properties[key] = name
103
+ end
104
+ end
105
+
106
+ # Retrieves grid data as a 2D array of rows of columns. The first row
107
+ # contains the grid's header.
108
+ #
109
+ # grid - The grid to generate the table from.
110
+ #
111
+ # Returns a 2D array of rows of columns of data.
112
+ def self.get_grid_data(grid)
113
+ # Retrieve as columns of rows
114
+ data = []
115
+ grid.columns.length.times do |i|
116
+ column_data = []
117
+ column = grid.columns[i]
118
+ labels = Melomel.items_to_labels!(column, grid.dataProvider)
119
+
120
+ # Add column header
121
+ column_data << column.headerText
122
+
123
+ # Add label data
124
+ labels.length.times do |j|
125
+ column_data << labels[j]
126
+ end
127
+
128
+ # Add column data to data set
129
+ data << column_data
130
+ end
131
+
132
+ # Transpose and return
133
+ return data.transpose()
134
+ end
135
+
136
+ # The same grid data but stripped of whitespce
137
+ def self.get_striped_grid_data(grid)
138
+ data = get_grid_data(grid)
139
+ # Trim whitespace
140
+ data.each do |row|
141
+ row.each do |cell|
142
+ if cell != nil
143
+ cell.strip!
144
+ end
145
+ end
146
+ end
147
+ end
148
+
149
+ end
150
+ end
@@ -0,0 +1,40 @@
1
+ When /^I click the "([^"]*)" button on the alert$/ do |label|
2
+ Melomel::Cucumber.run! do
3
+ classes = Melomel::Flex.get_component_classes('alert')
4
+ alert = Melomel.find!(classes)
5
+ button = Melomel::Cucumber.find_by_label!('mx.controls.Button', label, alert)
6
+ button.setFocus()
7
+ Melomel.click(button)
8
+ end
9
+ end
10
+
11
+ Then /^I should see an alert$/ do
12
+ Melomel::Cucumber.run! do
13
+ classes = Melomel::Flex.get_component_classes('alert')
14
+ Melomel.find!(classes)
15
+ end
16
+ end
17
+
18
+ Then /^I should see an alert with the title: "([^"]*)"$/ do |title|
19
+ Melomel::Cucumber.run! do
20
+ classes = Melomel::Flex.get_component_classes('alert')
21
+ alert = Melomel.find!(classes)
22
+ alert.title.should == title
23
+ end
24
+ end
25
+
26
+ Then /^I should see an alert with the message: "([^"]*)"$/ do |message|
27
+ Melomel::Cucumber.run! do
28
+ classes = Melomel::Flex.get_component_classes('alert')
29
+ alert = Melomel.find!(classes)
30
+ alert.text.should == message
31
+ end
32
+ end
33
+
34
+ Then /^I should see an alert with the following message:$/ do |message|
35
+ Melomel::Cucumber.run! do
36
+ classes = Melomel::Flex.get_component_classes('alert')
37
+ alert = Melomel.find!(classes)
38
+ alert.text.should == message
39
+ end
40
+ end
@@ -0,0 +1,17 @@
1
+ When /^I click the "([^"]*)" (button|check box|radio button|tab)$/ do |name, type|
2
+ Melomel::Cucumber.run! do
3
+ classes = Melomel::Flex.get_component_classes(type)
4
+ button = Melomel::Cucumber.find_by_label!(classes, name)
5
+ button.setFocus()
6
+ Melomel.click(button)
7
+ end
8
+ end
9
+
10
+ Then /^I should see the "([^"]*)" (button|check box|radio button) (not )?selected$/ do |name, type, neg|
11
+ Melomel::Cucumber.run! do
12
+ classes = Melomel::Flex.get_component_classes(type)
13
+ button = Melomel::Cucumber.find_by_label!(classes, name)
14
+ button.setFocus()
15
+ button.selected.should == neg.nil?
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ When /^I set the "([^"]*)" color picker to "#([0-9A-Fa-f]{6})"$/ do |name, color|
2
+ Melomel::Cucumber.run! do
3
+ classes = Melomel::Flex.get_component_classes('color picker')
4
+ picker = Melomel::Cucumber.find_labeled!(classes, name)
5
+ picker.setFocus()
6
+ picker.selectedColor = color.hex
7
+ end
8
+ end
9
+
10
+ Then /^I should see the "([^"]*)" color picker set to "#([0-9A-Fa-f]{6})"$/ do |name, color|
11
+ Melomel::Cucumber.run! do
12
+ classes = Melomel::Flex.get_component_classes('color picker')
13
+ picker = Melomel::Cucumber.find_labeled!(classes, name)
14
+ picker.setFocus()
15
+ sprintf('%06X', picker.selectedColor).should == color
16
+ end
17
+ end
18
+
@@ -0,0 +1,83 @@
1
+ When /^I select "([^"]*)" on the "([^"]*)" data grid$/ do |value, name|
2
+ Melomel::Cucumber.run! do
3
+ classes = Melomel::Flex.get_component_classes('data grid')
4
+ grid = Melomel::Cucumber.find_labeled!(classes, name)
5
+ grid.setFocus()
6
+
7
+ # Retrieve data and take off header row
8
+ data = Melomel::Cucumber.get_grid_data(grid)[1..-1]
9
+
10
+ # Loop data and check for matches
11
+ index = nil
12
+ data.each_index do |i|
13
+ row = data[i]
14
+ row.each do |cell|
15
+ if cell.strip == value
16
+ index = i
17
+ break
18
+ end
19
+ end
20
+
21
+ break unless index.nil?
22
+ end
23
+
24
+ # If we couldn't find a matching cell then throw an error
25
+ raise "Cannot find '#{value}' on data grid" if index.nil?
26
+
27
+ grid.selectedIndex = index
28
+ end
29
+ end
30
+
31
+
32
+ Then /^I should see "([^"]*)" selected on the "([^"]*)" data grid$/ do |value, name|
33
+ Melomel::Cucumber.run! do
34
+ classes = Melomel::Flex.get_component_classes('data grid')
35
+ grid = Melomel::Cucumber.find_labeled!(classes, name)
36
+ grid.setFocus()
37
+
38
+ # Retrieve data and take off header row
39
+ data = Melomel::Cucumber.get_grid_data(grid)[1..-1]
40
+
41
+ # Loop data and check for matches
42
+ index = nil
43
+ data.each_index do |i|
44
+ row = data[i]
45
+ row.each do |cell|
46
+ if cell.strip == value
47
+ index = i
48
+ break
49
+ end
50
+ end
51
+
52
+ break unless index.nil?
53
+ end
54
+
55
+ grid.selectedIndex.should == index
56
+ end
57
+ end
58
+
59
+ Then /^I should see the following data in the "([^"]*)" data grid:$/ do |name, table|
60
+ Melomel::Cucumber.run! do
61
+ classes = Melomel::Flex.get_component_classes('data grid')
62
+ grid = Melomel::Cucumber.find_labeled!(classes, name)
63
+ grid.setFocus()
64
+
65
+ data = Melomel::Cucumber.get_striped_grid_data(grid)
66
+
67
+ table.diff!(data)
68
+ end
69
+ end
70
+
71
+
72
+ Then /^I should see no data in the "([^"]*)" data grid$/ do |name|
73
+ Melomel::Cucumber.run! do
74
+ classes = Melomel::Flex.get_component_classes('data grid')
75
+ grid = Melomel::Cucumber.find_labeled!(classes, name)
76
+ grid.setFocus()
77
+
78
+ # Retrieve data and take off header row
79
+ data = Melomel::Cucumber.get_grid_data(grid)[1..-1]
80
+
81
+ data.size.should == 0
82
+ end
83
+ end