marty_rspec 0.0.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.
- checksums.yaml +15 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +37 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +6 -0
- data/lib/marty_rspec/netzke_grid.rb +230 -0
- data/lib/marty_rspec/util.rb +316 -0
- data/lib/marty_rspec/version.rb +3 -0
- data/lib/marty_rspec.rb +4 -0
- data/spec/marty_rspec_spec.rb +18 -0
- data/spec/spec_helper.rb +7 -0
- metadata +70 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NjMyNGU3ZTA2N2MyZmI2ZWNmMjFjY2VjMGJhNmZlNDhlMzIwMGU5Yg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDE3YzJmNjNhY2U0OTI0NGNjMGRmMjU5ZmNhZmI0YjcxNWJhYWQ3OA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGMxOWQxZTMwYWM5YTkzY2NlMThlMGQ5NTI5ZGRkN2Q4OTQwNDQxNDg3Mjll
|
10
|
+
NGU5ZWE4Njc0MGQ2NTQzZGI5OGVkYWUyN2E3NzZjNGJhOTQwYTk0ZjRiZWUx
|
11
|
+
YzU2ZTRmOGUxZDliYjA2MGVkNjQ5NGU4MTM2NzM0ZDg1OTY1OGY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MjZlN2I0MTU0YWQ3NWM2Yzk5ZGQzNTA3OWNmMWU5OGM1NGVlZDA1MjEwMGZj
|
14
|
+
NzBhZWMyZDE1MDlhYTA4ZTgxYzA3ZDc2NWFjOWEwZjFjMGYxNWMzYTRmZjJi
|
15
|
+
NjFkYzQzODI3Y2UzNjVlOGJlODE3NzRkYmJmNWY1YjIwNjk4ODM=
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
marty_rspec (0.0.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
addressable (2.4.0)
|
10
|
+
capybara (2.7.1)
|
11
|
+
addressable
|
12
|
+
mime-types (>= 1.16)
|
13
|
+
nokogiri (>= 1.3.3)
|
14
|
+
rack (>= 1.0.0)
|
15
|
+
rack-test (>= 0.5.4)
|
16
|
+
xpath (~> 2.0)
|
17
|
+
mime-types (3.1)
|
18
|
+
mime-types-data (~> 3.2015)
|
19
|
+
mime-types-data (3.2016.0521)
|
20
|
+
mini_portile2 (2.0.0)
|
21
|
+
nokogiri (1.6.7.2)
|
22
|
+
mini_portile2 (~> 2.0.0.rc2)
|
23
|
+
rack (1.6.4)
|
24
|
+
rack-test (0.6.3)
|
25
|
+
rack (>= 1.0)
|
26
|
+
xpath (2.0.0)
|
27
|
+
nokogiri (~> 1.3)
|
28
|
+
|
29
|
+
PLATFORMS
|
30
|
+
ruby
|
31
|
+
|
32
|
+
DEPENDENCIES
|
33
|
+
capybara
|
34
|
+
marty_rspec!
|
35
|
+
|
36
|
+
BUNDLED WITH
|
37
|
+
1.11.2
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 sleepn247
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# MartyRspec
|
2
|
+
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/marty_rspec`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
+
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'marty_rspec'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install marty_rspec
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
TODO: Write usage instructions here
|
26
|
+
|
27
|
+
## Development
|
28
|
+
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
+
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
+
|
33
|
+
## Contributing
|
34
|
+
|
35
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/marty_rspec.
|
36
|
+
|
37
|
+
|
38
|
+
## License
|
39
|
+
|
40
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
41
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,230 @@
|
|
1
|
+
require 'capybara/dsl'
|
2
|
+
|
3
|
+
module MartyRSpec
|
4
|
+
module NetzkeGrid
|
5
|
+
def netzke_find(name, grid_type = 'gridpanel')
|
6
|
+
NetzkeGridNode.new(name, grid_type)
|
7
|
+
end
|
8
|
+
|
9
|
+
class NetzkeGridNode
|
10
|
+
include Util
|
11
|
+
include Capybara::DSL
|
12
|
+
|
13
|
+
attr_reader :name, :grid
|
14
|
+
|
15
|
+
def initialize(name, grid_type)
|
16
|
+
@name = name
|
17
|
+
if /^\d+$/.match(name)
|
18
|
+
@grid = ext_find(grid_type, nil, name)
|
19
|
+
else
|
20
|
+
@grid = ext_find(ext_arg(grid_type, name: name))
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def id
|
25
|
+
res = run_js <<-JS
|
26
|
+
var c = #{grid};
|
27
|
+
return c.view.id;
|
28
|
+
JS
|
29
|
+
res
|
30
|
+
end
|
31
|
+
|
32
|
+
def row_count
|
33
|
+
res = run_js <<-JS
|
34
|
+
return #{grid}.getStore().getTotalCount();
|
35
|
+
JS
|
36
|
+
res.to_i
|
37
|
+
end
|
38
|
+
|
39
|
+
def row_total
|
40
|
+
res = run_js <<-JS
|
41
|
+
return #{grid}.getStore().getTotalCount();
|
42
|
+
JS
|
43
|
+
res.to_i
|
44
|
+
end
|
45
|
+
|
46
|
+
def row_modified_count
|
47
|
+
res = run_js <<-JS
|
48
|
+
return #{grid}.getStore().getUpdatedRecords().length;
|
49
|
+
JS
|
50
|
+
res.to_i
|
51
|
+
end
|
52
|
+
|
53
|
+
def data_desc row
|
54
|
+
res = run_js <<-JS
|
55
|
+
var r = #{grid}.getStore().getAt(#{row.to_i-1});
|
56
|
+
return r.data.desc
|
57
|
+
JS
|
58
|
+
res.gsub(/<.*?>/, '')
|
59
|
+
end
|
60
|
+
|
61
|
+
def click_col col
|
62
|
+
run_js <<-JS
|
63
|
+
#{ext_find(ext_arg('gridcolumn', text: col), grid)}.click();
|
64
|
+
JS
|
65
|
+
end
|
66
|
+
|
67
|
+
def col_values(col, cnt, init=0)
|
68
|
+
#does not validate the # of rows
|
69
|
+
run_js <<-JS
|
70
|
+
var result = [];
|
71
|
+
for (var i = #{init}; i < #{init.to_i + cnt.to_i}; i++) {
|
72
|
+
#{ext_cell_val('i', col, grid)}
|
73
|
+
if(value instanceof Date){
|
74
|
+
result.push(value.toISOString().substring(0,value.toISOString().indexOf('T')));
|
75
|
+
} else {
|
76
|
+
result.push(value);
|
77
|
+
};
|
78
|
+
};
|
79
|
+
return result;
|
80
|
+
JS
|
81
|
+
end
|
82
|
+
|
83
|
+
def cell_value(row, col)
|
84
|
+
run_js <<-JS
|
85
|
+
#{ext_cell_val(row.to_i - 1, col, grid)}
|
86
|
+
return value;
|
87
|
+
JS
|
88
|
+
end
|
89
|
+
|
90
|
+
def select_row(row)
|
91
|
+
resid = run_js(<<-JS, 10.0)
|
92
|
+
#{ext_var(grid, 'grid')}
|
93
|
+
grid.getSelectionModel().select(#{row.to_i-1});
|
94
|
+
return grid.getView().getNode(#{row.to_i-1}).id;
|
95
|
+
JS
|
96
|
+
el = find_by_id(resid)
|
97
|
+
return el
|
98
|
+
end
|
99
|
+
|
100
|
+
def set_row_vals row, fields
|
101
|
+
js_set_fields = fields.each_pair.map do |k,v|
|
102
|
+
"r.set('#{k}', '#{v}');"
|
103
|
+
end.join
|
104
|
+
|
105
|
+
run_js <<-JS
|
106
|
+
#{ext_var(ext_row(row.to_i - 1, grid), 'r')}
|
107
|
+
#{js_set_fields}
|
108
|
+
JS
|
109
|
+
end
|
110
|
+
|
111
|
+
def validate_row_values row, fields
|
112
|
+
js_get_fields = fields.each_key.map do |k|
|
113
|
+
<<-JS
|
114
|
+
var col = Ext.ComponentQuery.query('gridcolumn[name=\"#{k}\"]', grid)[0];
|
115
|
+
var value = col.assoc ? r.get('meta').associationValues['#{k}'] :
|
116
|
+
r.get('#{k}');
|
117
|
+
if (value instanceof Date) {
|
118
|
+
obj['#{k}'] = value.toISOString().substring(0,
|
119
|
+
value.toISOString().indexOf('T'));
|
120
|
+
} else {
|
121
|
+
obj['#{k}'] = value;
|
122
|
+
};
|
123
|
+
JS
|
124
|
+
end.join
|
125
|
+
|
126
|
+
res = run_js <<-JS
|
127
|
+
#{ext_var(grid, 'grid')}
|
128
|
+
#{ext_var(ext_row(row.to_i - 1, 'grid'), 'r')}
|
129
|
+
var obj = {};
|
130
|
+
#{js_get_fields}
|
131
|
+
return obj;
|
132
|
+
JS
|
133
|
+
wait_for_element { expect(res).to eq fields.stringify_keys }
|
134
|
+
end
|
135
|
+
|
136
|
+
def sorted_by? col, direction = 'asc'
|
137
|
+
run_js <<-JS
|
138
|
+
#{ext_var(grid, 'grid')}
|
139
|
+
#{ext_var(ext_col(col, 'grid'), 'col')}
|
140
|
+
var colValues = [];
|
141
|
+
|
142
|
+
grid.getStore().each(function(r){
|
143
|
+
var val = col.assoc ? r.get('meta').associationValues['#{col}'] :
|
144
|
+
r.get('#{col}');
|
145
|
+
if (val) colValues.#{direction == 'asc' ? 'push' : 'unshift'}(val);
|
146
|
+
});
|
147
|
+
|
148
|
+
return colValues.toString() === Ext.Array.sort(colValues).toString();
|
149
|
+
JS
|
150
|
+
end
|
151
|
+
|
152
|
+
def grid_combobox_values(row, field)
|
153
|
+
run_js <<-JS
|
154
|
+
#{start_edit_grid_combobox(row, field, grid)}
|
155
|
+
JS
|
156
|
+
|
157
|
+
# hacky: delay for combobox to render, assumes combobox is not empty
|
158
|
+
run_js <<-JS
|
159
|
+
#{ext_var(grid, 'grid')}
|
160
|
+
#{ext_var(ext_netzkecombo(field), 'combo')}
|
161
|
+
var r = [];
|
162
|
+
#{ext_var(ext_celleditor, 'editor')}
|
163
|
+
var store = combo.getStore();
|
164
|
+
|
165
|
+
// force a retry if the store is still loading
|
166
|
+
if (store.loading == true) { throw "store not loaded yet"; }
|
167
|
+
|
168
|
+
for(var i = 0; i < store.getCount(); i++) {
|
169
|
+
r.push(store.getAt(i).get('text'));
|
170
|
+
};
|
171
|
+
|
172
|
+
editor.completeEdit();
|
173
|
+
return r;
|
174
|
+
JS
|
175
|
+
end
|
176
|
+
|
177
|
+
def get_grid_combobox_val(index, row, field)
|
178
|
+
run_js <<-JS
|
179
|
+
#{start_edit_grid_combobox(row, field, grid)}
|
180
|
+
JS
|
181
|
+
|
182
|
+
run_js <<-JS
|
183
|
+
#{ext_var(grid, 'grid')}
|
184
|
+
#{ext_var(ext_netzkecombo(field), 'combo')}
|
185
|
+
#{ext_var(ext_celleditor, 'editor')}
|
186
|
+
var val = combo.getStore().getAt(#{index}).get('text');
|
187
|
+
editor.completeEdit();
|
188
|
+
return val;
|
189
|
+
JS
|
190
|
+
end
|
191
|
+
|
192
|
+
def start_edit_grid_combobox(row, field)
|
193
|
+
<<-JS
|
194
|
+
#{ext_var(grid, 'grid')}
|
195
|
+
#{ext_var(ext_netzkecombo(field), 'combo')}
|
196
|
+
#{ext_var(ext_celleditor, 'editor')}
|
197
|
+
|
198
|
+
editor.startEditByPosition({ row:#{row.to_i-1},
|
199
|
+
column:grid.headerCt.items.findIndex('name', '#{field}') });
|
200
|
+
|
201
|
+
var now = new Date().getTime();
|
202
|
+
while(new Date().getTime() < now + 500) { }
|
203
|
+
|
204
|
+
combo.onTriggerClick();
|
205
|
+
JS
|
206
|
+
end
|
207
|
+
|
208
|
+
def id_of_edit_field(row, field)
|
209
|
+
res = run_js <<-JS
|
210
|
+
#{ext_var(grid, 'grid')}
|
211
|
+
#{ext_var(ext_celleditor, 'editor')}
|
212
|
+
|
213
|
+
editor.startEditByPosition({ row:#{row.to_i-1},
|
214
|
+
column:grid.headerCt.items.findIndex('name', '#{field}') });
|
215
|
+
return editor.activeEditor.field.inputId;
|
216
|
+
JS
|
217
|
+
res
|
218
|
+
end
|
219
|
+
|
220
|
+
def end_edit(row, field)
|
221
|
+
run_js <<-JS
|
222
|
+
#{ext_var(grid, 'grid')}
|
223
|
+
#{ext_var(ext_celleditor, 'editor')}
|
224
|
+
editor.completeEdit();
|
225
|
+
return true;
|
226
|
+
JS
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
@@ -0,0 +1,316 @@
|
|
1
|
+
module MartyRSpec::Util
|
2
|
+
|
3
|
+
# essentially works as documentation & wait
|
4
|
+
def by message, level=0
|
5
|
+
wait_for_ready(10)
|
6
|
+
pending(message) unless block_given?
|
7
|
+
yield
|
8
|
+
end
|
9
|
+
|
10
|
+
alias and_by by
|
11
|
+
|
12
|
+
# navigation helpers
|
13
|
+
def ensure_on(path)
|
14
|
+
visit(path) unless current_path == path
|
15
|
+
end
|
16
|
+
|
17
|
+
def log_in(username, password)
|
18
|
+
wait_for_ready(10)
|
19
|
+
|
20
|
+
if first("a[data-qtip='Current user']")
|
21
|
+
log_out
|
22
|
+
wait_for_ajax
|
23
|
+
end
|
24
|
+
|
25
|
+
find(:xpath, "//span", text: 'Sign in', match: :first, wait: 5).click
|
26
|
+
fill_in("login", :with => username)
|
27
|
+
fill_in("password", :with => password)
|
28
|
+
press("OK")
|
29
|
+
wait_for_ajax
|
30
|
+
end
|
31
|
+
|
32
|
+
def log_out
|
33
|
+
press("Current user")
|
34
|
+
press("Sign out")
|
35
|
+
end
|
36
|
+
|
37
|
+
def press button_name, index_of = 0
|
38
|
+
wait_for_element do
|
39
|
+
begin
|
40
|
+
cmp = first("a[data-qtip='#{button_name}']")
|
41
|
+
cmp ||= first(:xpath, ".//a", text: "#{button_name}")
|
42
|
+
cmp ||= find(:btn, button_name, match: :first)
|
43
|
+
cmp.click
|
44
|
+
true
|
45
|
+
rescue
|
46
|
+
find_by_id(ext_button_id(button_name, index_of), visible: :all).click
|
47
|
+
true
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def popup message = ''
|
53
|
+
wait_for_ready
|
54
|
+
yield if block_given?
|
55
|
+
close_window
|
56
|
+
end
|
57
|
+
|
58
|
+
def close_window
|
59
|
+
find(:xpath, '//img[contains(@class, "x-tool-close")]', wait: 5).click
|
60
|
+
end
|
61
|
+
|
62
|
+
def wait_for_ready wait_time = nil
|
63
|
+
if wait_time
|
64
|
+
find(:status, 'Ready', wait: wait_time)
|
65
|
+
else
|
66
|
+
find(:status, 'Ready')
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def wait_for_ajax
|
71
|
+
wait_for_ready(10)
|
72
|
+
wait_for_element { !ajax_loading? }
|
73
|
+
wait_for_ready
|
74
|
+
end
|
75
|
+
|
76
|
+
def ajax_loading?
|
77
|
+
page.execute_script <<-JS
|
78
|
+
return Netzke.ajaxIsLoading() || Ext.Ajax.isLoading();
|
79
|
+
JS
|
80
|
+
end
|
81
|
+
|
82
|
+
def zoom_out
|
83
|
+
el = find('body')
|
84
|
+
el.native.send_keys([:control, '0'])
|
85
|
+
el.native.send_keys([:control, '-'])
|
86
|
+
el.native.send_keys([:control, '-'])
|
87
|
+
el.native.send_keys([:control, '-'])
|
88
|
+
end
|
89
|
+
|
90
|
+
def wait_for_element(seconds_to_wait = 2.0, sleeptime = 0.1)
|
91
|
+
res = nil
|
92
|
+
start_time = current_time = Time.now
|
93
|
+
while !res && current_time - start_time < seconds_to_wait
|
94
|
+
begin
|
95
|
+
res = yield
|
96
|
+
rescue
|
97
|
+
ensure
|
98
|
+
sleep sleeptime
|
99
|
+
current_time = Time.now
|
100
|
+
end
|
101
|
+
end
|
102
|
+
res
|
103
|
+
end
|
104
|
+
|
105
|
+
def run_js js_str, seconds_to_wait = 5.0, sleeptime = 0.1
|
106
|
+
result = wait_for_element(seconds_to_wait, sleeptime) do
|
107
|
+
res = nil
|
108
|
+
page.document.synchronize { res = page.execute_script(js_str) }
|
109
|
+
res.nil? ? true : res
|
110
|
+
end
|
111
|
+
result
|
112
|
+
end
|
113
|
+
|
114
|
+
# Component helpers
|
115
|
+
def show_submenu text
|
116
|
+
run_js <<-JS
|
117
|
+
Ext.ComponentQuery.query('menuitem[text="#{text}"] menu')[0].show()
|
118
|
+
JS
|
119
|
+
end
|
120
|
+
|
121
|
+
def ext_button_id title, scope = nil, index_of = 0
|
122
|
+
c_str = ext_arg('button{isVisible(true)}', text: "\"#{title}\"")
|
123
|
+
run_js <<-JS
|
124
|
+
return #{ext_find(c_str, scope, index_of)}.id;
|
125
|
+
JS
|
126
|
+
end
|
127
|
+
|
128
|
+
def set_field_value value, field_type='textfield', name=''
|
129
|
+
args1 = name.empty? ? "" : "[fieldLabel='#{name}']"
|
130
|
+
args2 = name.empty? ? "" : "[name='#{name}']"
|
131
|
+
run_js <<-JS
|
132
|
+
var field = Ext.ComponentQuery.query("#{field_type}#{args1}")[0];
|
133
|
+
field = field || Ext.ComponentQuery.query("#{field_type}#{args2}")[0];
|
134
|
+
field.setValue("#{value}");
|
135
|
+
return true;
|
136
|
+
JS
|
137
|
+
end
|
138
|
+
|
139
|
+
def get_total_pages
|
140
|
+
# will get deprecated by Netzke 1.0
|
141
|
+
result = find(:xpath, ".//div[contains(@id, 'tbtext-')]",
|
142
|
+
text: /^of (\d+)$/, match: :first).text
|
143
|
+
result.split(' ')[1].to_i
|
144
|
+
end
|
145
|
+
|
146
|
+
def simple_escape! text
|
147
|
+
text.gsub!(/(\r\n|\n)/, "\\n")
|
148
|
+
text.gsub!(/\t/, "\\t")
|
149
|
+
end
|
150
|
+
|
151
|
+
def paste text, textarea
|
152
|
+
# bit hacky: textarea doesn't like receiving tabs and newlines via fill_in
|
153
|
+
simple_escape!(text)
|
154
|
+
|
155
|
+
find(:xpath, ".//textarea[@name='#{textarea}']")
|
156
|
+
run_js <<-JS
|
157
|
+
#{ext_var(ext_find(ext_arg('textarea', name: textarea)), 'area')}
|
158
|
+
area.setValue("#{text}");
|
159
|
+
JS
|
160
|
+
end
|
161
|
+
|
162
|
+
def btn_disabled? text
|
163
|
+
res = wait_for_element do
|
164
|
+
find_by_id(ext_button_id(text))
|
165
|
+
end
|
166
|
+
!res[:class].match(/disabled/).nil?
|
167
|
+
end
|
168
|
+
|
169
|
+
# Netzke component lookups, arguments for helper methods below
|
170
|
+
# (i.e. component) require JS scripts instead of objects
|
171
|
+
def ext_arg(component, c_args = {})
|
172
|
+
res = component
|
173
|
+
c_args.each do |k, v|
|
174
|
+
res += "[#{k.to_s}=#{v.to_s}]"
|
175
|
+
end
|
176
|
+
res
|
177
|
+
end
|
178
|
+
|
179
|
+
def ext_find(ext_arg_str, scope = nil, index = 0)
|
180
|
+
scope_str = scope.nil? ? '' : ", #{scope}"
|
181
|
+
<<-JS
|
182
|
+
Ext.ComponentQuery.query('#{ext_arg_str}'#{scope_str})[#{index}]
|
183
|
+
JS
|
184
|
+
end
|
185
|
+
|
186
|
+
def ext_var(ext_find_str, var_name='ext_c')
|
187
|
+
<<-JS
|
188
|
+
var #{var_name} = #{ext_find_str};
|
189
|
+
JS
|
190
|
+
end
|
191
|
+
|
192
|
+
def ext_netzkecombo field
|
193
|
+
<<-JS
|
194
|
+
#{ext_find(ext_arg('netzkeremotecombo', name: field))}
|
195
|
+
JS
|
196
|
+
end
|
197
|
+
|
198
|
+
def ext_combo combo_label, c_name='combo'
|
199
|
+
<<-JS
|
200
|
+
#{ext_var(ext_find(ext_arg('combobox', fieldLabel: combo_label)), c_name)}
|
201
|
+
#{c_name} = #{c_name} ||
|
202
|
+
#{ext_find(ext_arg('combobox', name: combo_label))};
|
203
|
+
JS
|
204
|
+
end
|
205
|
+
|
206
|
+
def ext_celleditor(grid_name='grid')
|
207
|
+
<<-JS
|
208
|
+
#{grid_name}.getPlugin('celleditor')
|
209
|
+
JS
|
210
|
+
end
|
211
|
+
|
212
|
+
def ext_row(row, grid_name='grid')
|
213
|
+
<<-JS
|
214
|
+
#{grid_name}.getStore().getAt(#{row})
|
215
|
+
JS
|
216
|
+
end
|
217
|
+
|
218
|
+
def ext_col(col, grid_name='grid')
|
219
|
+
<<-JS
|
220
|
+
#{ext_find(ext_arg('gridcolumn', name: "\"#{col}\""), grid_name)}
|
221
|
+
JS
|
222
|
+
end
|
223
|
+
|
224
|
+
def ext_cell_val(row, col, grid, var_str = 'value')
|
225
|
+
# FOR NETZKE 1.0, use this line for columns
|
226
|
+
# r.get('association_values')['#{col}'] :
|
227
|
+
<<-JS
|
228
|
+
#{ext_var(grid, 'grid')}
|
229
|
+
#{ext_var(ext_col(col, 'grid'), 'col')}
|
230
|
+
#{ext_var(ext_row(row, 'grid'), 'row')}
|
231
|
+
var #{var_str} = col.assoc ?
|
232
|
+
row.get('meta').associationValues['#{col}'] :
|
233
|
+
row.get('#{col}');
|
234
|
+
JS
|
235
|
+
end
|
236
|
+
|
237
|
+
# Field edit/Key in Helpers
|
238
|
+
def type_in(type_s, el_id)
|
239
|
+
el = find_by_id("#{el_id}")
|
240
|
+
el.native.clear()
|
241
|
+
type_s.each_char do |key|
|
242
|
+
el.native.send_keys(key)
|
243
|
+
end
|
244
|
+
el.send_keys(:enter)
|
245
|
+
end
|
246
|
+
|
247
|
+
def press_key_in(key, el_id)
|
248
|
+
kd = key.downcase
|
249
|
+
use_key = ['enter', 'return'].include?(kd) ? kd.to_sym : key
|
250
|
+
el = find_by_id("#{el_id}")
|
251
|
+
el.native.send_keys(use_key)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Combobox Helpers
|
255
|
+
def select_combobox(values, combo_label)
|
256
|
+
run_js <<-JS
|
257
|
+
var values = #{values.split(/,\s*/)};
|
258
|
+
#{ext_combo(combo_label)}
|
259
|
+
|
260
|
+
var arr = new Array();
|
261
|
+
for(var i=0; i < values.length; i++) {
|
262
|
+
arr[i] = combo.findRecordByDisplay(values[i]);
|
263
|
+
}
|
264
|
+
combo.select(arr);
|
265
|
+
if (combo.isExpanded) { combo.onTriggerClick(); }
|
266
|
+
JS
|
267
|
+
end
|
268
|
+
|
269
|
+
def combobox_values(combo_label)
|
270
|
+
run_js <<-JS
|
271
|
+
#{ext_combo(combo_label)}
|
272
|
+
var values = [];
|
273
|
+
combo.getStore().each(
|
274
|
+
function(r) { values.push(r.data.text || r.data.field1); });
|
275
|
+
return values;
|
276
|
+
JS
|
277
|
+
end
|
278
|
+
|
279
|
+
def click_combobox combo_label
|
280
|
+
run_js <<-JS
|
281
|
+
#{ext_combo(combo_label)}
|
282
|
+
combo.onTriggerClick();
|
283
|
+
JS
|
284
|
+
wait_for_element { !ajax_loading? }
|
285
|
+
end
|
286
|
+
|
287
|
+
# Capybara finders
|
288
|
+
def custom_selectors
|
289
|
+
Capybara.add_selector(:gridpanel) do
|
290
|
+
xpath { |name| ".//div[contains(@id, '#{name}')] | " +
|
291
|
+
".//div[contains(@id, '#{name.camelize(:lower)}')]" }
|
292
|
+
end
|
293
|
+
Capybara.add_selector(:msg) do
|
294
|
+
xpath { "//div[@id='msg-div']" }
|
295
|
+
end
|
296
|
+
Capybara.add_selector(:body) do
|
297
|
+
xpath { ".//div[@data-ref='body']" }
|
298
|
+
end
|
299
|
+
Capybara.add_selector(:input) do
|
300
|
+
xpath { |name| "//input[@name='#{name}']" }
|
301
|
+
end
|
302
|
+
Capybara.add_selector(:status) do
|
303
|
+
xpath { |name| "//div[contains(@id, 'statusbar')]//div[text()='#{name}']" }
|
304
|
+
end
|
305
|
+
Capybara.add_selector(:btn) do
|
306
|
+
xpath { |name| ".//span[text()='#{name}']" }
|
307
|
+
end
|
308
|
+
Capybara.add_selector(:refresh) do
|
309
|
+
xpath { "//img[contains(@class, 'x-tool-refresh')]" }
|
310
|
+
end
|
311
|
+
Capybara.add_selector(:gridcolumn) do
|
312
|
+
xpath { |name| ".//span[contains(@class, 'x-column-header')]" +
|
313
|
+
"//span[text()='#{name}']" }
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
data/lib/marty_rspec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MartyRSpec do
|
4
|
+
it 'has a version number' do
|
5
|
+
expect(MartyRSpec::VERSION).not_to be nil
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'get the grid name' do
|
9
|
+
foo_grid = netzke_find('foo')
|
10
|
+
expect(foo_grid.name).to eq 'foo'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'escape util function works' do
|
14
|
+
some_string = "blah\tblah\n"
|
15
|
+
simple_escape!(some_string)
|
16
|
+
expect(some_string).to eq "blah\\tblah\\n"
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: marty_rspec
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Masaki Matsuo
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-06-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capybara
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
description:
|
28
|
+
email: masaki.matsuo@pnmac.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- Gemfile
|
34
|
+
- Gemfile.lock
|
35
|
+
- LICENSE.txt
|
36
|
+
- README.md
|
37
|
+
- Rakefile
|
38
|
+
- lib/marty_rspec.rb
|
39
|
+
- lib/marty_rspec/netzke_grid.rb
|
40
|
+
- lib/marty_rspec/util.rb
|
41
|
+
- lib/marty_rspec/version.rb
|
42
|
+
- spec/marty_rspec_spec.rb
|
43
|
+
- spec/spec_helper.rb
|
44
|
+
homepage: https://github.com/pennymac/marty_rspec
|
45
|
+
licenses:
|
46
|
+
- MIT
|
47
|
+
metadata: {}
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
requirements: []
|
63
|
+
rubyforge_project:
|
64
|
+
rubygems_version: 2.6.3
|
65
|
+
signing_key:
|
66
|
+
specification_version: 4
|
67
|
+
summary: RSpec helper methods for Marty
|
68
|
+
test_files:
|
69
|
+
- spec/marty_rspec_spec.rb
|
70
|
+
- spec/spec_helper.rb
|