marty 2.3.14 → 2.3.15

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,57 @@
1
+ require 'capybara/dsl'
2
+ require 'rspec/matchers'
3
+ require Pathname.new(__FILE__).parent.parent.to_s + '/netzke'
4
+
5
+ module Marty; module RSpec; module Components
6
+ class NetzkeCombobox
7
+ include Netzke
8
+ include Capybara::DSL
9
+ #include RSpec::Matchers
10
+
11
+ attr_reader :name, :combobox
12
+
13
+ def initialize(name)
14
+ @name = name
15
+ if /^\d+$/.match(name)
16
+ @combobox = ext_find('combobox', nil, name)
17
+ else
18
+ @combobox = ext_combo(name)
19
+ end
20
+ end
21
+
22
+ def select_values(values)
23
+ run_js <<-JS
24
+ var values = #{values.split(/,\s*/)};
25
+ #{combobox}
26
+ var arr = new Array();
27
+ for(var i=0; i < values.length; i++) {
28
+ arr[i] = combo.findRecordByDisplay(values[i]);
29
+ }
30
+ combo.select(arr);
31
+ if (combo.isExpanded) {
32
+ combo.onTriggerClick();
33
+ };
34
+ return true;
35
+ JS
36
+ end
37
+
38
+ def get_values
39
+ run_js <<-JS
40
+ var values = [];
41
+ #{combobox}
42
+ combo.getStore().each(
43
+ function(r) { values.push(r.data.text || r.data.field1); });
44
+ return values;
45
+ JS
46
+ end
47
+
48
+ def click
49
+ run_js <<-JS
50
+ #{combobox}
51
+ combo.onTriggerClick();
52
+ return true;
53
+ JS
54
+ wait_for_element { !ajax_loading? }
55
+ end
56
+ end
57
+ end end end
@@ -0,0 +1,356 @@
1
+ require 'capybara/dsl'
2
+ require 'rspec/matchers'
3
+ require Pathname.new(__FILE__).parent.parent.to_s + '/netzke'
4
+
5
+ module Marty; module RSpec; module Components
6
+ class NetzkeGrid
7
+ include Netzke
8
+ include Capybara::DSL
9
+ #include RSpec::Matchers
10
+
11
+ attr_reader :name, :grid
12
+
13
+ def initialize(name, c_type)
14
+ # for now, also allows treepanel
15
+ @name = name
16
+ if /^\d+$/.match(name)
17
+ @grid = ext_find(c_type, nil, name)
18
+ else
19
+ @grid = ext_find(ext_arg(c_type, name: name))
20
+ end
21
+ end
22
+
23
+ def id
24
+ res = run_js <<-JS
25
+ var c = #{grid};
26
+ return c.view.id;
27
+ JS
28
+ res
29
+ end
30
+
31
+ def row_count
32
+ res = run_js <<-JS
33
+ return #{grid}.getStore().getTotalCount();
34
+ JS
35
+ res.to_i
36
+ end
37
+
38
+ def page_size
39
+ res = run_js <<-JS
40
+ return #{grid}.getStore().pageSize();
41
+ JS
42
+ res.to_i
43
+ end
44
+
45
+ alias :row_total :row_count
46
+
47
+ def row_modified_count
48
+ res = run_js <<-JS
49
+ return #{grid}.getStore().getUpdatedRecords().length;
50
+ JS
51
+ res.to_i
52
+ end
53
+
54
+ def data_desc row
55
+ res = run_js <<-JS
56
+ var r = #{grid}.getStore().getAt(#{row.to_i-1});
57
+ return r.data.desc
58
+ JS
59
+ res.gsub(/<.*?>/, '')
60
+ end
61
+
62
+ def click_col col
63
+ el = run_js <<-JS
64
+ #{ext_var(grid, 'grid')}
65
+ return #{ext_find(ext_arg('gridcolumn', text: col), 'grid')}.id
66
+ JS
67
+
68
+ find("#" + el).click
69
+ end
70
+
71
+ def get_col_vals(col, cnt=row_count, init=0)
72
+ # NOTE: does not validate the # of rows
73
+ run_js <<-JS
74
+ var result = [];
75
+ for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
76
+ #{ext_cell_val('i', col, grid)}
77
+ if(value instanceof Date){
78
+ result.push(value.toISOString().substring(0,value.toISOString().indexOf('T')));
79
+ } else {
80
+ result.push(value);
81
+ };
82
+ };
83
+ return result;
84
+ JS
85
+ end
86
+
87
+ def validate_col_vals(col, val, cnt, init=0)
88
+ run_js <<-JS
89
+ for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
90
+ #{ext_cell_val('i', col, grid)}
91
+ if (value != #{val}) { return false };
92
+ };
93
+ return true;
94
+ JS
95
+ end
96
+
97
+ def cell_value(row, col)
98
+ run_js <<-JS
99
+ #{ext_cell_val(row.to_i - 1, col, grid)}
100
+ return value;
101
+ JS
102
+ end
103
+
104
+ def select_row(row, click_after=true)
105
+ resid = run_js(<<-JS, 10.0)
106
+ #{ext_var(grid, 'grid')}
107
+ grid.getSelectionModel().select(#{row.to_i-1});
108
+ return grid.getView().getNode(#{row.to_i-1}).id;
109
+ JS
110
+ el = find_by_id(resid)
111
+ el.click if click_after
112
+ wait_for_ajax
113
+ return el
114
+ end
115
+
116
+ def set_row_vals row, fields
117
+ js_set_fields = fields.each_pair.map do |k,v|
118
+ "r.set('#{k}', '#{v}');"
119
+ end.join
120
+
121
+ run_js <<-JS
122
+ #{ext_var(ext_row(row.to_i - 1, grid), 'r')}
123
+ #{js_set_fields}
124
+ JS
125
+ end
126
+
127
+ def get_row_vals row, fields=nil
128
+ res = run_js <<-JS
129
+ #{ext_var(grid, 'grid')}
130
+ return Ext.encode(#{ext_row(row.to_i - 1, 'grid')}.data);
131
+ JS
132
+ temp = JSON.parse(res)
133
+ parsed = temp.merge(temp.delete('association_values') || {})
134
+ fields ? fields.each_with_object({}).each{|k,h| h[k] = parsed[k]} :
135
+ parsed
136
+ end
137
+
138
+ def sorted_by? col, direction = 'asc'
139
+ run_js <<-JS
140
+ #{ext_var(grid, 'grid')}
141
+ #{ext_var(ext_col(col, 'grid'), 'col')}
142
+ var colValues = [];
143
+
144
+ grid.getStore().each(function(r){
145
+ var val = col.assoc ? r.get('association_values')['#{col}'] :
146
+ r.get('#{col}');
147
+ if (val) colValues.#{direction == 'asc' ? 'push' : 'unshift'}(val);
148
+ });
149
+
150
+ return colValues.toString() === Ext.Array.sort(colValues).toString();
151
+ JS
152
+ end
153
+
154
+ def grid_combobox_values(row, field)
155
+ run_js <<-JS
156
+ #{start_edit_combobox(row, field)}
157
+ JS
158
+
159
+ # hacky: delay for combobox to render, assumes combobox is not empty
160
+ run_js <<-JS
161
+ #{ext_var(grid, 'grid')}
162
+ #{ext_var(ext_netzkecombo(field), 'combo')}
163
+ var r = [];
164
+ #{ext_var(ext_celleditor, 'editor')}
165
+ var store = combo.getStore();
166
+
167
+ // force a retry if the store is still loading
168
+ if (store.loading == true) {
169
+ now = new Date().getTime();
170
+ while(new Date().getTime() < now + 100) { }
171
+ return false;
172
+ }
173
+
174
+ for(var i = 0; i < store.getCount(); i++) {
175
+ r.push(store.getAt(i).get('text'));
176
+ };
177
+
178
+ editor.completeEdit();
179
+ return r;
180
+ JS
181
+ end
182
+
183
+ def get_combobox_val(index, row, field)
184
+ run_js <<-JS
185
+ #{start_edit_combobox(row, field)}
186
+ JS
187
+
188
+ run_js <<-JS
189
+ #{ext_var(grid, 'grid')}
190
+ #{ext_var(ext_netzkecombo(field), 'combo')}
191
+ #{ext_var(ext_celleditor, 'editor')}
192
+ var val = combo.getStore().getAt(#{index}).get('text');
193
+ editor.completeEdit();
194
+ return val;
195
+ JS
196
+ end
197
+
198
+ def start_edit_grid_combobox(row, field)
199
+ <<-JS
200
+ #{ext_var(grid, 'grid')}
201
+ #{ext_var(ext_netzkecombo(field), 'combo')}
202
+ #{ext_var(ext_celleditor, 'editor')}
203
+
204
+ editor.startEditByPosition({ row:#{row.to_i-1},
205
+ column:grid.headerCt.items.findIndex('name', '#{field}') });
206
+
207
+ var now = new Date().getTime();
208
+ while(new Date().getTime() < now + 500) { }
209
+
210
+ combo.onTriggerClick();
211
+ JS
212
+ end
213
+
214
+ def id_of_edit_field(row, field)
215
+ res = run_js <<-JS
216
+ #{ext_var(grid, 'grid')}
217
+ #{ext_var(ext_celleditor, 'editor')}
218
+
219
+ editor.startEditByPosition({ row:#{row.to_i-1},
220
+ column:grid.headerCt.items.findIndex('name', '#{field}') });
221
+ return editor.activeEditor.field.inputId;
222
+ JS
223
+ res
224
+ end
225
+
226
+ def end_edit(row, field)
227
+ run_js <<-JS
228
+ #{ext_var(grid, 'grid')}
229
+ #{ext_var(ext_celleditor, 'editor')}
230
+ editor.completeEdit();
231
+ return true;
232
+ JS
233
+ end
234
+
235
+ def id_of_checkbox(row, field)
236
+ res = run_js <<-JS
237
+ #{ext_var(grid, 'grid')}
238
+ #{ext_var(ext_celleditor, 'editor')}
239
+
240
+ editor.startEditByPosition({ row:#{row.to_i-1},
241
+ column:grid.headerCt.items.findIndex('name', '#{field}') });
242
+ return editor.activeEditor.field.getItemId();
243
+ JS
244
+ res
245
+ end
246
+
247
+ ############################################################################
248
+ # grid combobox helpers
249
+ ############################################################################
250
+
251
+ def select_combobox(selection, row, field)
252
+ run_js <<-JS
253
+ #{start_edit_combobox(row, field)}
254
+
255
+ rec = combo.findRecordByDisplay('#{selection}');
256
+ if (rec == false) { return false; }
257
+ combo.setValue(rec);
258
+ combo.onTriggerClick();
259
+ editor.completeEdit();
260
+ return true
261
+ JS
262
+ end
263
+
264
+ def select_combobox_enum(selection, row, field)
265
+ run_js <<-JS
266
+ #{start_edit_combobox_enum(row, field)}
267
+
268
+ rec = combo.findRecordByDisplay('#{selection}');
269
+ if (rec == false) { return false; }
270
+ combo.setValue(rec);
271
+ editor.completeEdit();
272
+ return true
273
+ JS
274
+ end
275
+
276
+ def combobox_values(row, field)
277
+ run_js <<-JS
278
+ #{start_edit_combobox(row, field)}
279
+ JS
280
+
281
+ # hacky: delay for combobox to render, assumes that the combobox is not empty
282
+ run_js <<-JS
283
+ #{ext_var(grid, 'grid')}
284
+ #{ext_var(ext_netzkecombo(field), 'combo')}
285
+ var r = [];
286
+ #{ext_var(ext_celleditor, 'editor')}
287
+ var store = combo.getStore();
288
+
289
+ // force a retry if the store is still loading
290
+ if (store.loading == true) {
291
+ now = new Date().getTime();
292
+ while(new Date().getTime() < now + 100) { }
293
+ return false;
294
+ }
295
+
296
+ for(var i = 0; i < store.getCount(); i++) {
297
+ r.push(store.getAt(i).get('text'));
298
+ };
299
+
300
+ editor.completeEdit();
301
+ return r;
302
+ JS
303
+ end
304
+
305
+ def get_combobox_val(index, row, field)
306
+ run_js <<-JS
307
+ #{start_edit_combobox(row, field)}
308
+ JS
309
+
310
+ run_js <<-JS
311
+ #{ext_var(grid, 'grid')}
312
+ #{ext_var(ext_netzkecombo(field), 'combo')}
313
+ #{ext_var(ext_celleditor, 'editor')}
314
+ var val = combo.getStore().getAt(#{index}).get('text');
315
+ editor.completeEdit();
316
+ return val;
317
+ JS
318
+ end
319
+
320
+ def start_edit_combobox(row, field)
321
+ <<-JS
322
+ #{ext_var(grid, 'grid')}
323
+ #{ext_var(ext_netzkecombo(field), 'combo')}
324
+ #{ext_var(ext_celleditor, 'editor')}
325
+
326
+ editor.startEditByPosition({ row:#{row.to_i-1},
327
+ column:grid.headerCt.items.findIndex('name', '#{field}') });
328
+
329
+ var now = new Date().getTime();
330
+ while(new Date().getTime() < now + 500) { }
331
+
332
+ combo.onTriggerClick();
333
+ JS
334
+ end
335
+
336
+ def start_edit_combobox_enum(row, field)
337
+ <<-JS
338
+ #{ext_var(grid, 'grid')}
339
+ #{ext_combo(field, 'combo')}
340
+ #{ext_var(ext_celleditor, 'editor')}
341
+
342
+ editor.startEditByPosition({ row:#{row.to_i-1},
343
+ column:grid.headerCt.items.findIndex('name', '#{field}') });
344
+ JS
345
+ end
346
+
347
+ def end_edit(row, field)
348
+ run_js <<-JS
349
+ #{ext_var(grid, 'grid')}
350
+ #{ext_var(ext_celleditor, 'editor')}
351
+ editor.completeEdit();
352
+ return true;
353
+ JS
354
+ end
355
+ end
356
+ end end end
@@ -0,0 +1,18 @@
1
+ require 'rspec'
2
+
3
+ RSpec::Matchers.define :netzke_include do |expected|
4
+ match do |actual|
5
+ parsed_values = actual.each_with_object({}) do | (k, v), h |
6
+ h[k] = v == "False" ? false : v
7
+ end
8
+ expect(parsed_values).to include(expected.stringify_keys)
9
+ end
10
+
11
+ diffable
12
+ end
13
+
14
+ RSpec::Matchers.define :match_fuzzily do |expected|
15
+ msg = nil
16
+ match { |actual| !(msg = struct_compare(actual, expected)) }
17
+ failure_message { |_| msg }
18
+ end
@@ -0,0 +1,49 @@
1
+ Capybara.add_selector(:gridpanel) do
2
+ xpath do |name|
3
+ ".//div[contains(@id, '#{name}')][not(contains(@id, 'splitter'))] | "\
4
+ ".//div[contains(@id, '#{name.camelize(:lower)}')]"\
5
+ "[not(contains(@id, 'splitter'))]"
6
+ end
7
+ end
8
+
9
+ Capybara.add_selector(:msg) do
10
+ xpath do
11
+ "//div[@id='msg-div']"
12
+ end
13
+ end
14
+
15
+ Capybara.add_selector(:body) do
16
+ xpath do
17
+ ".//div[@data-ref='body']"
18
+ end
19
+ end
20
+
21
+ Capybara.add_selector(:input) do
22
+ xpath do |name|
23
+ "//input[@name='#{name}']"
24
+ end
25
+ end
26
+
27
+ Capybara.add_selector(:status) do
28
+ xpath do |name|
29
+ "//div[contains(@id, 'statusbar')]//div[text()='#{name}']"
30
+ end
31
+ end
32
+
33
+ Capybara.add_selector(:btn) do
34
+ xpath do |name|
35
+ ".//span[text()='#{name}']"
36
+ end
37
+ end
38
+
39
+ Capybara.add_selector(:refresh) do
40
+ xpath do
41
+ ".//div[contains(@class, 'x-tool-refresh')]"
42
+ end
43
+ end
44
+
45
+ Capybara.add_selector(:gridcolumn) do
46
+ xpath do |name|
47
+ ".//span[contains(@class, 'x-column-header')][text()='#{name}']/.."
48
+ end
49
+ end