marty 0.5.39 → 0.5.40
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/app/controllers/marty/diagnostic_controller.rb +2 -2
- data/lib/marty/version.rb +1 -1
- data/spec/features/auth_app_spec.rb +4 -4
- data/spec/features/data_import_spec.rb +13 -9
- data/spec/features/reporting_spec.rb +28 -20
- data/spec/features/scripting_spec.rb +66 -47
- data/spec/features/scripting_test_spec.rb +18 -12
- data/spec/features/user_view_spec.rb +34 -32
- data/spec/spec_helper.rb +3 -0
- data/spec/support/integration_helpers.rb +0 -590
- metadata +1 -1
@@ -92,18 +92,18 @@ DELOREAN
|
|
92
92
|
end
|
93
93
|
end
|
94
94
|
|
95
|
-
let(:tg) { gridpanel('tag_grid') }
|
96
|
-
let(:sg) { gridpanel('script_grid') }
|
97
|
-
|
98
95
|
it 'switches between tags & scripts, computes values and checks for errors' do
|
99
96
|
log_in_as('dev1')
|
100
97
|
go_to_scripting
|
101
98
|
|
99
|
+
tag_grid = netzke_find('tag_grid')
|
100
|
+
script_grid = netzke_find('script_grid')
|
101
|
+
|
102
102
|
by 'select M1 sample script' do
|
103
103
|
wait_for_ajax
|
104
|
-
zoom_out
|
105
|
-
select_row(2
|
106
|
-
select_row(1
|
104
|
+
zoom_out
|
105
|
+
tag_grid.select_row(2)
|
106
|
+
script_grid.select_row(1)
|
107
107
|
tab_press('Testing')
|
108
108
|
end
|
109
109
|
|
@@ -155,8 +155,8 @@ DELOREAN
|
|
155
155
|
tab_press('Selection')
|
156
156
|
wait_for_ajax
|
157
157
|
find(:gridpanel, 'script_grid', match: :first, wait: 10)
|
158
|
-
select_row(1
|
159
|
-
select_row(1
|
158
|
+
tag_grid.select_row(1)
|
159
|
+
script_grid.select_row(1)
|
160
160
|
tab_press('Testing')
|
161
161
|
end
|
162
162
|
|
@@ -187,7 +187,7 @@ DELOREAN
|
|
187
187
|
and_by 'select M2 sample grid' do
|
188
188
|
tab_press('Selection')
|
189
189
|
wait_for_ajax
|
190
|
-
select_row(2
|
190
|
+
script_grid.select_row(2)
|
191
191
|
tab_press('Testing')
|
192
192
|
end
|
193
193
|
|
@@ -209,9 +209,12 @@ DELOREAN
|
|
209
209
|
log_in_as('dev1')
|
210
210
|
go_to_scripting
|
211
211
|
|
212
|
+
tag_grid = netzke_find('tag_grid')
|
213
|
+
script_grid = netzke_find('script_grid')
|
214
|
+
|
212
215
|
by 'select M1 sample script' do
|
213
216
|
wait_for_ajax
|
214
|
-
select_row(1
|
217
|
+
script_grid.select_row(1)
|
215
218
|
tab_press('Testing')
|
216
219
|
end
|
217
220
|
|
@@ -271,10 +274,13 @@ DELOREAN
|
|
271
274
|
log_in_as('dev1')
|
272
275
|
go_to_scripting
|
273
276
|
|
277
|
+
tag_grid = netzke_find('tag_grid')
|
278
|
+
script_grid = netzke_find('script_grid')
|
279
|
+
|
274
280
|
by 'select M3 sample script' do
|
275
281
|
wait_for_ajax
|
276
|
-
zoom_out
|
277
|
-
select_row(3
|
282
|
+
zoom_out
|
283
|
+
script_grid.select_row(3)
|
278
284
|
tab_press('Testing')
|
279
285
|
end
|
280
286
|
|
@@ -35,15 +35,15 @@ feature 'under Sytem menu, User Management worflows', js: true do
|
|
35
35
|
check(name, false)
|
36
36
|
end
|
37
37
|
|
38
|
-
let(:uv) { gridpanel('user_view') }
|
39
|
-
|
40
38
|
it 'marty user can add/edit but not delete users' do
|
41
39
|
log_in_as('marty')
|
42
40
|
go_to_user_view
|
43
41
|
|
42
|
+
user_view = netzke_find('user_view')
|
43
|
+
|
44
44
|
by 'add new user' do
|
45
45
|
wait_for_ajax
|
46
|
-
zoom_out
|
46
|
+
zoom_out
|
47
47
|
press('New User')
|
48
48
|
within(:gridpanel, 'add_window', match: :first) do
|
49
49
|
press 'OK'
|
@@ -64,8 +64,8 @@ feature 'under Sytem menu, User Management worflows', js: true do
|
|
64
64
|
|
65
65
|
and_by 'edit the added user' do
|
66
66
|
wait_for_ajax
|
67
|
-
expect(row_count
|
68
|
-
select_row(2
|
67
|
+
expect(user_view.row_count).to eq 2
|
68
|
+
user_view.select_row(2)
|
69
69
|
press('Edit in form')
|
70
70
|
|
71
71
|
within(:gridpanel, 'edit_window', match: :first) do
|
@@ -80,27 +80,27 @@ feature 'under Sytem menu, User Management worflows', js: true do
|
|
80
80
|
|
81
81
|
and_by 'check row got edited' do
|
82
82
|
wait_for_ajax
|
83
|
-
validate_row_values(2,
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
83
|
+
user_view.validate_row_values(2,
|
84
|
+
:login => 'new_login',
|
85
|
+
:firstname => 'new_fname',
|
86
|
+
:lastname => 'new_lname',
|
87
|
+
:active => true,
|
88
|
+
:roles => 'User Manager,Viewer')
|
89
89
|
end
|
90
90
|
|
91
91
|
and_by 'delete user fails' do
|
92
|
-
select_row(2
|
92
|
+
user_view.select_row(2)
|
93
93
|
press("Delete")
|
94
94
|
press("Yes")
|
95
95
|
expect(find(:msg)).to have_content("Users cannot be deleted - set " +
|
96
96
|
"'Active' to false to disable the " +
|
97
97
|
"account")
|
98
|
-
select_row(1
|
98
|
+
user_view.select_row(1)
|
99
99
|
press("Delete")
|
100
100
|
press("Yes")
|
101
101
|
expect(find(:msg)).to have_content("You cannot delete your own account")
|
102
102
|
|
103
|
-
expect(row_count
|
103
|
+
expect(user_view.row_count).to eq 2
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
@@ -115,49 +115,51 @@ feature 'under Sytem menu, User Management worflows', js: true do
|
|
115
115
|
go_to_user_view
|
116
116
|
by 'check buttons' do
|
117
117
|
find(:btn, 'New User', match: :first)
|
118
|
-
zoom_out
|
119
|
-
expect(btn_disabled?('New User'
|
120
|
-
expect(btn_disabled?('Edit in form'
|
121
|
-
expect(btn_disabled?('Delete'
|
118
|
+
zoom_out
|
119
|
+
expect(btn_disabled?('New User')).to be_falsy
|
120
|
+
expect(btn_disabled?('Edit in form')).to be_falsy
|
121
|
+
expect(btn_disabled?('Delete')).to be_falsy
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'admin has access' do
|
126
126
|
log_in_as('admin1')
|
127
127
|
go_to_user_view
|
128
|
-
|
128
|
+
by 'check buttons' do
|
129
129
|
find(:btn, 'New User', match: :first)
|
130
|
-
expect(btn_disabled?('New User'
|
131
|
-
expect(btn_disabled?('Edit in form'
|
132
|
-
expect(btn_disabled?('Delete'
|
130
|
+
expect(btn_disabled?('New User')).to be_falsy
|
131
|
+
expect(btn_disabled?('Edit in form')).to be_falsy
|
132
|
+
expect(btn_disabled?('Delete')).to be_falsy
|
133
133
|
end
|
134
134
|
end
|
135
135
|
|
136
136
|
it 'viewer denied access' do
|
137
137
|
log_in_as('viewer1')
|
138
138
|
go_to_user_view_backdoor
|
139
|
-
|
139
|
+
user_view = netzke_find('user_view')
|
140
|
+
by 'check buttons' do
|
140
141
|
find(:btn, 'New User', match: :first)
|
141
142
|
#selection needed to make delete button disappear
|
142
143
|
wait_for_ajax
|
143
|
-
select_row(1
|
144
|
-
expect(btn_disabled?('New User'
|
145
|
-
expect(btn_disabled?('Edit in form'
|
146
|
-
expect(btn_disabled?('Delete'
|
144
|
+
user_view.select_row(1)
|
145
|
+
expect(btn_disabled?('New User')).to be_truthy
|
146
|
+
expect(btn_disabled?('Edit in form')).to be_truthy
|
147
|
+
expect(btn_disabled?('Delete')).to be_truthy
|
147
148
|
end
|
148
149
|
end
|
149
150
|
|
150
151
|
it 'developer denied access' do
|
151
152
|
log_in_as('dev1')
|
152
153
|
go_to_user_view_backdoor
|
153
|
-
|
154
|
+
user_view = netzke_find('user_view')
|
155
|
+
by 'check buttons' do
|
154
156
|
find(:btn, 'New User', match: :first)
|
155
157
|
#selection needed to make delete button disappear
|
156
158
|
wait_for_ajax
|
157
|
-
select_row(1
|
158
|
-
expect(btn_disabled?('New User'
|
159
|
-
expect(btn_disabled?('Edit in form'
|
160
|
-
expect(btn_disabled?('Delete'
|
159
|
+
user_view.select_row(1)
|
160
|
+
expect(btn_disabled?('New User')).to be_truthy
|
161
|
+
expect(btn_disabled?('Edit in form')).to be_truthy
|
162
|
+
expect(btn_disabled?('Delete')).to be_truthy
|
161
163
|
end
|
162
164
|
end
|
163
165
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,7 @@ ENV["RAILS_ENV"] ||= "test"
|
|
3
3
|
require 'dummy/config/application'
|
4
4
|
require 'rspec/rails'
|
5
5
|
require 'database_cleaner'
|
6
|
+
require 'marty_rspec'
|
6
7
|
|
7
8
|
Dummy::Application.initialize!
|
8
9
|
|
@@ -35,6 +36,8 @@ RSpec.configure do |config|
|
|
35
36
|
config.include CleanDbHelpers
|
36
37
|
config.include SpecSetup
|
37
38
|
config.include Marty::IntegrationHelpers
|
39
|
+
config.include MartyRSpec::Util
|
40
|
+
config.include MartyRSpec::NetzkeGrid
|
38
41
|
|
39
42
|
Capybara.default_max_wait_time = 3
|
40
43
|
|
@@ -1,33 +1,4 @@
|
|
1
1
|
module Marty::IntegrationHelpers
|
2
|
-
|
3
|
-
MAX_WAIT_TIME = 5.0
|
4
|
-
|
5
|
-
# without rspec-by gem, essentially works as documentation & wait
|
6
|
-
def by message, level=0
|
7
|
-
wait_for_ready(10)
|
8
|
-
pending(message) unless block_given?
|
9
|
-
begin
|
10
|
-
by_start(message)
|
11
|
-
yield
|
12
|
-
ensure
|
13
|
-
by_end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
alias and_by by
|
18
|
-
|
19
|
-
def by_start message
|
20
|
-
if RSpec.configuration.reporter.respond_to? :by_started
|
21
|
-
RSpec.configuration.reporter.by_started(message)
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def by_end
|
26
|
-
if RSpec.configuration.reporter.respond_to? :by_ended
|
27
|
-
RSpec.configuration.reporter.by_ended()
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
2
|
# test setup helpers
|
32
3
|
def populate_test_users
|
33
4
|
(1..2).each { |i|
|
@@ -59,27 +30,6 @@ module Marty::IntegrationHelpers
|
|
59
30
|
user.save
|
60
31
|
end
|
61
32
|
|
62
|
-
# navigation helpers
|
63
|
-
def ensure_on(path)
|
64
|
-
visit(path) unless current_path == path
|
65
|
-
end
|
66
|
-
|
67
|
-
def log_in(username, password)
|
68
|
-
wait_for_ready(10)
|
69
|
-
|
70
|
-
if first("a[data-qtip='Current user']")
|
71
|
-
log_out
|
72
|
-
wait_for_ajax
|
73
|
-
end
|
74
|
-
|
75
|
-
find(:xpath, "//span", text: 'Sign in', match: :first, wait: 5).click
|
76
|
-
find(:xpath, "//span", text: 'Password', match: :first, wait: 5)
|
77
|
-
fill_in("login", :with => username)
|
78
|
-
fill_in("password", :with => password)
|
79
|
-
press("OK")
|
80
|
-
wait_for_ajax
|
81
|
-
end
|
82
|
-
|
83
33
|
def log_in_as(username)
|
84
34
|
Rails.configuration.marty.auth_source = 'local'
|
85
35
|
|
@@ -87,544 +37,4 @@ module Marty::IntegrationHelpers
|
|
87
37
|
log_in(username, Rails.configuration.marty.local_password)
|
88
38
|
ensure_on("/")
|
89
39
|
end
|
90
|
-
|
91
|
-
def log_out
|
92
|
-
press("Current user")
|
93
|
-
press("Sign out")
|
94
|
-
end
|
95
|
-
|
96
|
-
def press button_name, index_of = 0
|
97
|
-
wait_for_element do
|
98
|
-
begin
|
99
|
-
cmp = first("a[data-qtip='#{button_name}']")
|
100
|
-
cmp ||= first(:xpath, ".//a", text: "#{button_name}")
|
101
|
-
cmp ||= find(:btn, button_name, match: :first)
|
102
|
-
cmp.click
|
103
|
-
true
|
104
|
-
rescue
|
105
|
-
find_by_id(ext_button_id(button_name, index_of), visible: :all).click
|
106
|
-
true
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
def popup message = ''
|
112
|
-
by_start('popup: ' + message)
|
113
|
-
wait_for_ready
|
114
|
-
yield if block_given?
|
115
|
-
close_window
|
116
|
-
by_end
|
117
|
-
end
|
118
|
-
|
119
|
-
def close_window
|
120
|
-
find(:xpath, '//img[contains(@class, "x-tool-close")]', wait: 5).click
|
121
|
-
end
|
122
|
-
|
123
|
-
def wait_for_ready wait_time = nil
|
124
|
-
if wait_time
|
125
|
-
find(:status, 'Ready', wait: wait_time)
|
126
|
-
else
|
127
|
-
find(:status, 'Ready')
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def wait_for_ajax
|
132
|
-
wait_for_ready(10)
|
133
|
-
wait_for_element { !ajax_loading? }
|
134
|
-
wait_for_ready
|
135
|
-
end
|
136
|
-
|
137
|
-
def ajax_loading?
|
138
|
-
page.execute_script <<-JS
|
139
|
-
return Netzke.ajaxIsLoading() || Ext.Ajax.isLoading();
|
140
|
-
JS
|
141
|
-
end
|
142
|
-
|
143
|
-
def zoom_out component
|
144
|
-
wait_for_element do
|
145
|
-
el_id = id_of(component)
|
146
|
-
el = find_by_id(el_id)
|
147
|
-
el.native.send_keys([:control, '0'])
|
148
|
-
el.native.send_keys([:control, '-'])
|
149
|
-
el.native.send_keys([:control, '-'])
|
150
|
-
el.native.send_keys([:control, '-'])
|
151
|
-
end
|
152
|
-
end
|
153
|
-
|
154
|
-
def wait_for_element(seconds_to_wait = 2.0, sleeptime = 0.1)
|
155
|
-
res = nil
|
156
|
-
start_time = current_time = Time.now
|
157
|
-
while !res && current_time - start_time < seconds_to_wait
|
158
|
-
begin
|
159
|
-
res = yield
|
160
|
-
rescue
|
161
|
-
ensure
|
162
|
-
sleep sleeptime
|
163
|
-
current_time = Time.now
|
164
|
-
end
|
165
|
-
end
|
166
|
-
res
|
167
|
-
end
|
168
|
-
|
169
|
-
def run_js js_str, seconds_to_wait = MAX_WAIT_TIME, sleeptime = 0.1
|
170
|
-
result = wait_for_element(seconds_to_wait, sleeptime) do
|
171
|
-
res = nil
|
172
|
-
page.document.synchronize { res = page.execute_script(js_str) }
|
173
|
-
res.nil? ? true : res
|
174
|
-
end
|
175
|
-
result
|
176
|
-
end
|
177
|
-
|
178
|
-
# Component helpers
|
179
|
-
def show_submenu text
|
180
|
-
run_js <<-JS
|
181
|
-
Ext.ComponentQuery.query('menuitem[text="#{text}"] menu')[0].show()
|
182
|
-
JS
|
183
|
-
end
|
184
|
-
|
185
|
-
def ext_button_id title, scope = nil, index_of = 0
|
186
|
-
c_str = ext_arg('button{isVisible(true)}', text: "\"#{title}\"")
|
187
|
-
run_js <<-JS
|
188
|
-
return #{ext_find(c_str, scope, index_of)}.id;
|
189
|
-
JS
|
190
|
-
end
|
191
|
-
|
192
|
-
def set_field_value value, field_type='textfield', name=''
|
193
|
-
args1 = name.empty? ? "" : "[fieldLabel='#{name}']"
|
194
|
-
args2 = name.empty? ? "" : "[name='#{name}']"
|
195
|
-
run_js <<-JS
|
196
|
-
var field = Ext.ComponentQuery.query("#{field_type}#{args1}")[0];
|
197
|
-
field = field || Ext.ComponentQuery.query("#{field_type}#{args2}")[0];
|
198
|
-
field.setValue("#{value}");
|
199
|
-
return true;
|
200
|
-
JS
|
201
|
-
end
|
202
|
-
|
203
|
-
def get_total_pages
|
204
|
-
# will get deprecated by Netzke 1.0
|
205
|
-
result = find(:xpath, ".//div[contains(@id, 'tbtext-')]",
|
206
|
-
text: /^of (\d+)$/, match: :first).text
|
207
|
-
result.split(' ')[1].to_i
|
208
|
-
end
|
209
|
-
|
210
|
-
def simple_escape! text
|
211
|
-
text.gsub!(/(\r\n|\n)/, "\\n")
|
212
|
-
text.gsub!(/\t/, "\\t")
|
213
|
-
end
|
214
|
-
|
215
|
-
def paste text, textarea
|
216
|
-
# bit hacky: textarea doesn't like receiving tabs and newlines via fill_in
|
217
|
-
simple_escape!(text)
|
218
|
-
|
219
|
-
find(:xpath, ".//textarea[@name='#{textarea}']")
|
220
|
-
run_js <<-JS
|
221
|
-
#{ext_var(ext_find(ext_arg('textarea', name: textarea)), 'area')}
|
222
|
-
area.setValue("#{text}");
|
223
|
-
JS
|
224
|
-
end
|
225
|
-
|
226
|
-
def btn_disabled? text, grid
|
227
|
-
res = wait_for_element do
|
228
|
-
find_by_id(ext_button_id(text))
|
229
|
-
end
|
230
|
-
!res[:class].match(/disabled/).nil?
|
231
|
-
end
|
232
|
-
|
233
|
-
# Netzke component lookups, arguments for helper methods below
|
234
|
-
# (i.e. component) require JS scripts instead of objects
|
235
|
-
def ext_arg(component, c_args = {})
|
236
|
-
res = component
|
237
|
-
c_args.each do |k, v|
|
238
|
-
res += "[#{k.to_s}=#{v.to_s}]"
|
239
|
-
end
|
240
|
-
res
|
241
|
-
end
|
242
|
-
|
243
|
-
def ext_find(ext_arg_str, scope = nil, index = 0)
|
244
|
-
scope_str = scope.nil? ? '' : ", #{scope}"
|
245
|
-
<<-JS
|
246
|
-
Ext.ComponentQuery.query('#{ext_arg_str}'#{scope_str})[#{index}]
|
247
|
-
JS
|
248
|
-
end
|
249
|
-
|
250
|
-
def ext_var(ext_find_str, var_name='ext_c')
|
251
|
-
<<-JS
|
252
|
-
var #{var_name} = #{ext_find_str};
|
253
|
-
JS
|
254
|
-
end
|
255
|
-
|
256
|
-
def ext_netzkecombo field
|
257
|
-
<<-JS
|
258
|
-
#{ext_find(ext_arg('netzkeremotecombo', name: field))}
|
259
|
-
JS
|
260
|
-
end
|
261
|
-
|
262
|
-
def ext_combo combo_label, c_name='combo'
|
263
|
-
<<-JS
|
264
|
-
#{ext_var(ext_find(ext_arg('combobox', fieldLabel: combo_label)), c_name)}
|
265
|
-
#{c_name} = #{c_name} ||
|
266
|
-
#{ext_find(ext_arg('combobox', name: combo_label))};
|
267
|
-
JS
|
268
|
-
end
|
269
|
-
|
270
|
-
def ext_celleditor(grid_name='grid')
|
271
|
-
<<-JS
|
272
|
-
#{grid_name}.getPlugin('celleditor')
|
273
|
-
JS
|
274
|
-
end
|
275
|
-
|
276
|
-
def ext_row(row, grid_name='grid')
|
277
|
-
<<-JS
|
278
|
-
#{grid_name}.getStore().getAt(#{row})
|
279
|
-
JS
|
280
|
-
end
|
281
|
-
|
282
|
-
def ext_col(col, grid_name='grid')
|
283
|
-
<<-JS
|
284
|
-
#{ext_find(ext_arg('gridcolumn', name: "\"#{col}\""), grid_name)}
|
285
|
-
JS
|
286
|
-
end
|
287
|
-
|
288
|
-
def ext_cell_val(row, col, grid, var_str = 'value')
|
289
|
-
# FOR NETZKE 1.0, use this line for columns
|
290
|
-
# r.get('association_values')['#{col}'] :
|
291
|
-
<<-JS
|
292
|
-
#{ext_var(grid, 'grid')}
|
293
|
-
#{ext_var(ext_col(col, 'grid'), 'col')}
|
294
|
-
#{ext_var(ext_row(row, 'grid'), 'row')}
|
295
|
-
var #{var_str} = col.assoc ?
|
296
|
-
row.get('meta').associationValues['#{col}'] :
|
297
|
-
row.get('#{col}');
|
298
|
-
JS
|
299
|
-
end
|
300
|
-
|
301
|
-
####
|
302
|
-
def gridpanel arg
|
303
|
-
# use these to generate component args for below
|
304
|
-
if /^\d+$/.match(arg)
|
305
|
-
ext_find('gridpanel', nil, arg)
|
306
|
-
else
|
307
|
-
ext_find(ext_arg('gridpanel', name: arg))
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
def treepanel arg
|
312
|
-
if /^\d+$/.match(arg)
|
313
|
-
ext_find('treepanel', nil, arg)
|
314
|
-
else
|
315
|
-
ext_find(ext_arg('treepanel', name: arg))
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
# Netzke helper methods
|
320
|
-
# Grid helpers
|
321
|
-
def id_of component
|
322
|
-
res = run_js <<-JS
|
323
|
-
var c = #{component};
|
324
|
-
return c.view.id;
|
325
|
-
JS
|
326
|
-
res
|
327
|
-
end
|
328
|
-
|
329
|
-
def row_count grid
|
330
|
-
res = run_js <<-JS
|
331
|
-
return #{grid}.getStore().getCount();
|
332
|
-
JS
|
333
|
-
res.to_i
|
334
|
-
end
|
335
|
-
|
336
|
-
def row_total grid
|
337
|
-
res = run_js <<-JS
|
338
|
-
return #{grid}.getStore().getTotalCount();
|
339
|
-
JS
|
340
|
-
res.to_i
|
341
|
-
end
|
342
|
-
|
343
|
-
def row_modified_count grid
|
344
|
-
res = run_js <<-JS
|
345
|
-
return #{grid}.getStore().getUpdatedRecords().length;
|
346
|
-
JS
|
347
|
-
res.to_i
|
348
|
-
end
|
349
|
-
|
350
|
-
def data_desc row, grid
|
351
|
-
res = run_js <<-JS
|
352
|
-
var r = #{grid}.getStore().getAt(#{row.to_i-1});
|
353
|
-
return r.data.desc
|
354
|
-
JS
|
355
|
-
res.gsub(/<.*?>/, '')
|
356
|
-
end
|
357
|
-
|
358
|
-
def click_col col, grid
|
359
|
-
run_js <<-JS
|
360
|
-
#{ext_find(ext_arg('gridcolumn', text: col), grid)}.click();
|
361
|
-
JS
|
362
|
-
end
|
363
|
-
|
364
|
-
def col_values(col, grid, cnt, init=0)
|
365
|
-
#does not validate the # of rows
|
366
|
-
run_js <<-JS
|
367
|
-
var result = [];
|
368
|
-
for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
|
369
|
-
#{ext_cell_val('i', col, grid)}
|
370
|
-
if(value instanceof Date){
|
371
|
-
result.push(value.toISOString().substring(0,value.toISOString().indexOf('T')));
|
372
|
-
} else {
|
373
|
-
result.push(value);
|
374
|
-
};
|
375
|
-
};
|
376
|
-
return result;
|
377
|
-
JS
|
378
|
-
end
|
379
|
-
|
380
|
-
def validate_col_values(col, val, grid, cnt, init=0)
|
381
|
-
run_js <<-JS
|
382
|
-
for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
|
383
|
-
#{ext_cell_val('i', col, grid)}
|
384
|
-
if (value != #{val}) { return false };
|
385
|
-
};
|
386
|
-
return true;
|
387
|
-
JS
|
388
|
-
end
|
389
|
-
|
390
|
-
def cell_value(row, col, grid)
|
391
|
-
run_js <<-JS
|
392
|
-
#{ext_cell_val(row.to_i - 1, col, grid)}
|
393
|
-
return value;
|
394
|
-
JS
|
395
|
-
end
|
396
|
-
|
397
|
-
def select_row(row, grid, click_after=true)
|
398
|
-
resid = run_js(<<-JS, 10.0)
|
399
|
-
#{ext_var(grid, 'grid')}
|
400
|
-
grid.getSelectionModel().select(#{row.to_i-1});
|
401
|
-
return grid.getView().getNode(#{row.to_i-1}).id;
|
402
|
-
JS
|
403
|
-
find_by_id(resid).click if click_after
|
404
|
-
wait_for_ajax
|
405
|
-
return resid
|
406
|
-
end
|
407
|
-
|
408
|
-
def set_row_vals row, grid, fields
|
409
|
-
js_set_fields = fields.each_pair.map do |k,v|
|
410
|
-
"r.set('#{k}', '#{v}');"
|
411
|
-
end.join
|
412
|
-
|
413
|
-
run_js <<-JS
|
414
|
-
#{ext_var(ext_row(row.to_i - 1, grid), 'r')}
|
415
|
-
#{js_set_fields}
|
416
|
-
JS
|
417
|
-
end
|
418
|
-
|
419
|
-
def validate_row_values row, grid, fields
|
420
|
-
js_get_fields = fields.each_key.map do |k|
|
421
|
-
<<-JS
|
422
|
-
var col = Ext.ComponentQuery.query('gridcolumn[name=\"#{k}\"]', grid)[0];
|
423
|
-
var value = col.assoc ? r.get('meta').associationValues['#{k}'] :
|
424
|
-
r.get('#{k}');
|
425
|
-
if (value instanceof Date) {
|
426
|
-
obj['#{k}'] = value.toISOString().substring(0,
|
427
|
-
value.toISOString().indexOf('T'));
|
428
|
-
} else {
|
429
|
-
obj['#{k}'] = value;
|
430
|
-
};
|
431
|
-
JS
|
432
|
-
end.join
|
433
|
-
|
434
|
-
res = run_js <<-JS
|
435
|
-
#{ext_var(grid, 'grid')}
|
436
|
-
#{ext_var(ext_row(row.to_i - 1, 'grid'), 'r')}
|
437
|
-
var obj = {};
|
438
|
-
#{js_get_fields}
|
439
|
-
return obj;
|
440
|
-
JS
|
441
|
-
wait_for_element { expect(res).to eq fields.stringify_keys }
|
442
|
-
end
|
443
|
-
|
444
|
-
def sorted_by? col, grid, direction = 'asc'
|
445
|
-
run_js <<-JS
|
446
|
-
#{ext_var(grid, 'grid')}
|
447
|
-
#{ext_var(ext_col(col, 'grid'), 'col')}
|
448
|
-
var colValues = [];
|
449
|
-
|
450
|
-
grid.getStore().each(function(r){
|
451
|
-
var val = col.assoc ? r.get('meta').associationValues['#{col}'] :
|
452
|
-
r.get('#{col}');
|
453
|
-
if (val) colValues.#{direction == 'asc' ? 'push' : 'unshift'}(val);
|
454
|
-
});
|
455
|
-
|
456
|
-
return colValues.toString() === Ext.Array.sort(colValues).toString();
|
457
|
-
JS
|
458
|
-
end
|
459
|
-
|
460
|
-
# Grid Combobox Helpers
|
461
|
-
def select_grid_combobox(selection, row, field, grid)
|
462
|
-
run_js <<-JS
|
463
|
-
#{start_edit_grid_combobox(row, field, grid)}
|
464
|
-
|
465
|
-
rec = combo.findRecordByDisplay('#{selection}');
|
466
|
-
if (rec == false) { return false; }
|
467
|
-
combo.setValue(rec);
|
468
|
-
combo.onTriggerClick();
|
469
|
-
editor.completeEdit();
|
470
|
-
return true
|
471
|
-
JS
|
472
|
-
end
|
473
|
-
|
474
|
-
def grid_combobox_values(row, field, grid)
|
475
|
-
run_js <<-JS
|
476
|
-
#{start_edit_grid_combobox(row, field, grid)}
|
477
|
-
JS
|
478
|
-
|
479
|
-
# hacky: delay for combobox to render, assumes that the combobox is not empty
|
480
|
-
run_js <<-JS
|
481
|
-
#{ext_var(grid, 'grid')}
|
482
|
-
#{ext_var(ext_netzkecombo(field), 'combo')}
|
483
|
-
var r = [];
|
484
|
-
#{ext_var(ext_celleditor, 'editor')}
|
485
|
-
var store = combo.getStore();
|
486
|
-
|
487
|
-
// force a retry if the store is still loading
|
488
|
-
if (store.loading == true) { throw "store not loaded yet"; }
|
489
|
-
|
490
|
-
for(var i = 0; i < store.getCount(); i++) {
|
491
|
-
r.push(store.getAt(i).get('text'));
|
492
|
-
};
|
493
|
-
|
494
|
-
editor.completeEdit();
|
495
|
-
return r;
|
496
|
-
JS
|
497
|
-
end
|
498
|
-
|
499
|
-
def get_grid_combobox_val(index, row, field, grid)
|
500
|
-
run_js <<-JS
|
501
|
-
#{start_edit_grid_combobox(row, field, grid)}
|
502
|
-
JS
|
503
|
-
|
504
|
-
run_js <<-JS
|
505
|
-
#{ext_var(grid, 'grid')}
|
506
|
-
#{ext_var(ext_netzkecombo(field), 'combo')}
|
507
|
-
#{ext_var(ext_celleditor, 'editor')}
|
508
|
-
var val = combo.getStore().getAt(#{index}).get('text');
|
509
|
-
editor.completeEdit();
|
510
|
-
return val;
|
511
|
-
JS
|
512
|
-
end
|
513
|
-
|
514
|
-
def start_edit_grid_combobox(row, field, grid)
|
515
|
-
<<-JS
|
516
|
-
#{ext_var(grid, 'grid')}
|
517
|
-
#{ext_var(ext_netzkecombo(field), 'combo')}
|
518
|
-
#{ext_var(ext_celleditor, 'editor')}
|
519
|
-
|
520
|
-
editor.startEditByPosition({ row:#{row.to_i-1},
|
521
|
-
column:grid.headerCt.items.findIndex('name', '#{field}') });
|
522
|
-
|
523
|
-
var now = new Date().getTime();
|
524
|
-
while(new Date().getTime() < now + 500) { }
|
525
|
-
|
526
|
-
combo.onTriggerClick();
|
527
|
-
JS
|
528
|
-
end
|
529
|
-
|
530
|
-
# Field edit/Key in Helpers
|
531
|
-
def type_in(type_s, el_id)
|
532
|
-
el = find_by_id("#{el_id}")
|
533
|
-
el.native.clear()
|
534
|
-
type_s.each_char do |key|
|
535
|
-
el.native.send_keys(key)
|
536
|
-
end
|
537
|
-
el.send_keys(:enter)
|
538
|
-
end
|
539
|
-
|
540
|
-
def press_key_in(key, el_id)
|
541
|
-
kd = key.downcase
|
542
|
-
use_key = ['enter', 'return'].include?(kd) ? kd.to_sym : key
|
543
|
-
el = find_by_id("#{el_id}")
|
544
|
-
el.native.send_keys(use_key)
|
545
|
-
end
|
546
|
-
|
547
|
-
def id_of_edit_field(row, field, grid)
|
548
|
-
res = run_js <<-JS
|
549
|
-
#{ext_var(grid, 'grid')}
|
550
|
-
#{ext_var(ext_celleditor, 'editor')}
|
551
|
-
|
552
|
-
editor.startEditByPosition({ row:#{row.to_i-1},
|
553
|
-
column:grid.headerCt.items.findIndex('name', '#{field}') });
|
554
|
-
return editor.activeEditor.field.inputId;
|
555
|
-
JS
|
556
|
-
res
|
557
|
-
end
|
558
|
-
|
559
|
-
def end_edit(row, field, grid)
|
560
|
-
run_js <<-JS
|
561
|
-
#{ext_var(grid, 'grid')}
|
562
|
-
#{ext_var(ext_celleditor, 'editor')}
|
563
|
-
editor.completeEdit();
|
564
|
-
return true;
|
565
|
-
JS
|
566
|
-
end
|
567
|
-
|
568
|
-
# Combobox Helpers
|
569
|
-
def select_combobox(values, combo_label)
|
570
|
-
run_js <<-JS
|
571
|
-
var values = #{values.split(/,\s*/)};
|
572
|
-
#{ext_combo(combo_label)}
|
573
|
-
|
574
|
-
var arr = new Array();
|
575
|
-
for(var i=0; i < values.length; i++) {
|
576
|
-
arr[i] = combo.findRecordByDisplay(values[i]);
|
577
|
-
}
|
578
|
-
combo.select(arr);
|
579
|
-
if (combo.isExpanded) { combo.onTriggerClick(); }
|
580
|
-
JS
|
581
|
-
end
|
582
|
-
|
583
|
-
def combobox_values(combo_label)
|
584
|
-
run_js <<-JS
|
585
|
-
#{ext_combo(combo_label)}
|
586
|
-
var values = [];
|
587
|
-
combo.getStore().each(
|
588
|
-
function(r) { values.push(r.data.text || r.data.field1); });
|
589
|
-
return values;
|
590
|
-
JS
|
591
|
-
end
|
592
|
-
|
593
|
-
def click_combobox combo_label
|
594
|
-
run_js <<-JS
|
595
|
-
#{ext_combo(combo_label)}
|
596
|
-
combo.onTriggerClick();
|
597
|
-
JS
|
598
|
-
wait_for_element { !ajax_loading? }
|
599
|
-
end
|
600
|
-
|
601
|
-
# Capybara finders
|
602
|
-
def custom_selectors
|
603
|
-
Capybara.add_selector(:gridpanel) do
|
604
|
-
xpath { |name| ".//div[contains(@id, '#{name}')] | " +
|
605
|
-
".//div[contains(@id, '#{name.camelize(:lower)}')]" }
|
606
|
-
end
|
607
|
-
Capybara.add_selector(:msg) do
|
608
|
-
xpath { "//div[@id='msg-div']" }
|
609
|
-
end
|
610
|
-
Capybara.add_selector(:body) do
|
611
|
-
xpath { ".//div[@data-ref='body']" }
|
612
|
-
end
|
613
|
-
Capybara.add_selector(:input) do
|
614
|
-
xpath { |name| "//input[@name='#{name}']" }
|
615
|
-
end
|
616
|
-
Capybara.add_selector(:status) do
|
617
|
-
xpath { |name| "//div[contains(@id, 'statusbar')]//div[text()='#{name}']" }
|
618
|
-
end
|
619
|
-
Capybara.add_selector(:btn) do
|
620
|
-
xpath { |name| ".//span[text()='#{name}']" }
|
621
|
-
end
|
622
|
-
Capybara.add_selector(:refresh) do
|
623
|
-
xpath { "//img[contains(@class, 'x-tool-refresh')]" }
|
624
|
-
end
|
625
|
-
Capybara.add_selector(:gridcolumn) do
|
626
|
-
xpath { |name| ".//span[contains(@class, 'x-column-header')]" +
|
627
|
-
"//span[text()='#{name}']" }
|
628
|
-
end
|
629
|
-
end
|
630
40
|
end
|