netzke-testing 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +106 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/netzke/.keep +0 -0
- data/app/assets/javascripts/netzke/testing/helpers/actions.js.coffee +74 -0
- data/app/assets/javascripts/netzke/testing/helpers/expectations.js.coffee +14 -0
- data/app/assets/javascripts/netzke/testing/helpers/form.js.coffee +7 -0
- data/app/assets/javascripts/netzke/testing/helpers/grid.js.coffee +107 -0
- data/app/assets/javascripts/netzke/testing/helpers/queries.js.coffee +88 -0
- data/app/assets/vendor/javascripts/expect/expect.js +1253 -0
- data/app/assets/vendor/javascripts/mocha/mocha.js +5340 -0
- data/app/assets/vendor/stylesheets/mocha/mocha.css +231 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/netzke/netzke/testing_controller.rb +28 -0
- data/app/helpers/.keep +0 -0
- data/app/helpers/netzke_testing_helper.rb +2 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/views/.keep +0 -0
- data/app/views/layouts/netzke/testing.html.erb +35 -0
- data/app/views/netzke/index.html.erb +2 -0
- data/config/routes.rb +8 -0
- data/lib/netzke/testing/engine.rb +6 -0
- data/lib/netzke/testing/helpers.rb +47 -0
- data/lib/netzke/testing/version.rb +5 -0
- data/lib/netzke/testing.rb +22 -0
- data/lib/netzke-testing.rb +1 -0
- data/netzke-testing.gemspec +23 -0
- data/test/controllers/netzke_testing_controller_test.rb +9 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/components/foo.rb +6 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +24 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +23 -0
- data/test/dummy/config/environments/production.rb +80 -0
- data/test/dummy/config/environments/test.rb +36 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/spec/javascripts/foo.js.coffee +3 -0
- data/test/helpers/netzke_testing_helper_test.rb +4 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/netzke_testing_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +193 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f6a8e145a80cbd76fe5872a58d199b5c0c3f6002
|
4
|
+
data.tar.gz: e7bef8a910494ec36fc1d4979f01f990bb1baac7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ecb548ed750a7cdaa03b3a8eb517524c220de8f4a0bc8f845a5a34ad8425773afdb3c8c595633d5d5d240752d2d827b8f3c825ebe06dfe972ed906b622acc3a2
|
7
|
+
data.tar.gz: 8db04d54ff7ebbd9c731297c783dc02ff7a2faea022512bdef617b49b01ef339ea22dc99cd23528c40641e2693db5b4c422a53bfdd105eefafcb1fc6e086d422
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Max Gorin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Netzke Testing
|
2
|
+
|
3
|
+
This gem helps with development and testing of Netzke components. In parcticular, it helps you with:
|
4
|
+
|
5
|
+
* isolated component development
|
6
|
+
* client-side testing of components with Mocha and Expect.js
|
7
|
+
|
8
|
+
Usage:
|
9
|
+
|
10
|
+
gem 'netzke_testing'
|
11
|
+
|
12
|
+
## Isolated component development
|
13
|
+
|
14
|
+
The gem implements a Rails engine, which (in development and test environments only) adds a route to load your
|
15
|
+
application's Netzke components individually, which can be useful for isolated development. Example (say, we have a
|
16
|
+
UserGrid component defined):
|
17
|
+
|
18
|
+
http://localhost:3000/netzke/components/UserGrid
|
19
|
+
|
20
|
+
This will load a view with UserGrid occupying the available window width, with default height of 400px. You can change
|
21
|
+
the height by providing the `height` parameter in the URL:
|
22
|
+
|
23
|
+
http://localhost:3000/netzke/components/UserGrid?height=600
|
24
|
+
|
25
|
+
## Testing components with Mocha and Expect.js
|
26
|
+
|
27
|
+
Place the Mocha specs (written in Coffeescript) for your components inside `spec/javascripts` folder. An example spec
|
28
|
+
may look like this (in `spec/javascripts/user_grid.js.coffee`):
|
29
|
+
|
30
|
+
describe 'UserGrid', ->
|
31
|
+
it 'shows proper title', ->
|
32
|
+
grid = Ext.ComponentQuery.query('panel[id="user_grid"]')[0]
|
33
|
+
expect(grid.getHeader().title).to.eql 'Test component'
|
34
|
+
|
35
|
+
This spec can be run by appending the `spec` parameter to the url:
|
36
|
+
|
37
|
+
http://localhost:3000/netzke/components/UserGrid?spec=user_grid
|
38
|
+
|
39
|
+
Specs can be structured into directories. For example, let's say we have a namescope for admin components:
|
40
|
+
|
41
|
+
class Admin::UserGrid < Netzke::Basepack::Grid
|
42
|
+
end
|
43
|
+
|
44
|
+
It makes sense to put the corresponding specs in `spec/javascripts/admin/user_grid.js.coffee`. In this case, the URL
|
45
|
+
to run the Mocha specs will be:
|
46
|
+
|
47
|
+
http://localhost:3000/netzke/components/UserGrid?spec=admin/user_grid
|
48
|
+
|
49
|
+
## Mocha spec helpers
|
50
|
+
|
51
|
+
The gem provides a number of helpers that may help you writing less code and make your specs look something like this:
|
52
|
+
|
53
|
+
describe 'UserGrid', ->
|
54
|
+
it 'allows instant removing of all users with a single button click', (done) ->
|
55
|
+
click button 'Remove all'
|
56
|
+
wait ->
|
57
|
+
expectToSee header 'Empty'
|
58
|
+
done()
|
59
|
+
|
60
|
+
Keep in mind the following:
|
61
|
+
|
62
|
+
* the current set of helpers is in flux, and may be drastically changed sooner than you may expect
|
63
|
+
* the helpers directly pollute the `window` namespace; if you decide you're better off without provided helpers,
|
64
|
+
specify 'no-helpers=true' as an extra URL parameter
|
65
|
+
|
66
|
+
See the [source code](TODO) for currently implemented helpers. Also, refer to other Netzke gems source code (like
|
67
|
+
netzke-core and netzke-basepack) to see examples using the helpers.
|
68
|
+
|
69
|
+
## Testing with selenium webdriver
|
70
|
+
|
71
|
+
Generate the `netzke_mocha_spec.rb` file that will automatically run the specs that follow a certain naming convention:
|
72
|
+
|
73
|
+
rails g netzke_testing
|
74
|
+
|
75
|
+
This spec will pick up all the `*_spec.js.coffee` files from `spec/javascripts` folder and generate an `it` clause for
|
76
|
+
each of them. Let's say we want to create the spec for UserGrid. For this we name the spec file
|
77
|
+
`spec/javascripts/user_grid_spec.js.coffee`. And the other way around: when `netzke_mocha_spec.rb` finds a file called
|
78
|
+
`spec/javascripts/order_grid_spec.js.coffee`, it'll assume existance of `OrderGrid` component that should be tested.
|
79
|
+
|
80
|
+
## Mixing client- and server-side testing code
|
81
|
+
|
82
|
+
Often we want to run some Ruby code before running the Mocha spec (e.g. to seed some test data using factories), or
|
83
|
+
after (e.g. to assert changes in the database). In this case you can create a RSpec spec that uses the `run_mocha_spec`
|
84
|
+
helper provided by the `netzke_testing` gem. Here's an example (in `spec/user_grid_spec.rb`):
|
85
|
+
|
86
|
+
require 'spec_helper'
|
87
|
+
feature GridWithDestructiveButton do
|
88
|
+
it 'allows instant removing of all records with a single button click', js: true do
|
89
|
+
10.times { FactoryGirl.create :user }
|
90
|
+
User.count.should == 10
|
91
|
+
run_mocha_spec 'grid_with_destructive_button'
|
92
|
+
User.count.should == 0
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
The `run_mocha_spec` here will run a Mocha spec from `spec/grid_with_destructive_button.js.coffee`.
|
97
|
+
|
98
|
+
You can explicitely specify a component to run the spec on (in order to override the convention):
|
99
|
+
|
100
|
+
run_mocha_spec 'grid_with_destructive_button', component: 'UserGrid'
|
101
|
+
|
102
|
+
---
|
103
|
+
Copyright (c) 2008-2013 [Max Gorin](https://twitter.com/uptomax), released under the MIT license (see LICENSE).
|
104
|
+
|
105
|
+
**Note** that Ext JS is licensed [differently](http://www.sencha.com/products/extjs/license/), and you may need to
|
106
|
+
purchase a commercial license in order to use it in your projects!
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
File without changes
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Ext.Ajax.on 'beforerequest', ->
|
2
|
+
Netzke.ajaxCount = window.ajaxCount || 0
|
3
|
+
Netzke.ajaxCount += 1
|
4
|
+
|
5
|
+
Ext.Ajax.on 'requestcomplete', ->
|
6
|
+
Netzke.ajaxCount -= 1
|
7
|
+
|
8
|
+
Ext.apply window,
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# wait ->
|
12
|
+
# afterAllAjaxActivityIsStopped()
|
13
|
+
#
|
14
|
+
# wait 2000, ->
|
15
|
+
# afterTwoSeconds()
|
16
|
+
wait: () ->
|
17
|
+
if typeof arguments[0] == 'function'
|
18
|
+
callback = arguments[0]
|
19
|
+
i = 0
|
20
|
+
id = setInterval ->
|
21
|
+
i += 1
|
22
|
+
if i >= 100
|
23
|
+
clearInterval(id)
|
24
|
+
callback.call()
|
25
|
+
|
26
|
+
# this way we ensure another 20ms cycle before we issue a callback
|
27
|
+
i = 100 if Netzke.ajaxCount == 0
|
28
|
+
, 100
|
29
|
+
else
|
30
|
+
delay = arguments[0]
|
31
|
+
callback = arguments[1]
|
32
|
+
setInterval ->
|
33
|
+
callback.call()
|
34
|
+
, delay
|
35
|
+
|
36
|
+
click: (cmp) ->
|
37
|
+
if Ext.isString(cmp)
|
38
|
+
throw "Could not locate " + cmp
|
39
|
+
else if (cmp.isXType) # is Ext component
|
40
|
+
if (cmp.isXType('tool'))
|
41
|
+
# a hack needed for tools
|
42
|
+
el = cmp.toolEl
|
43
|
+
else
|
44
|
+
el = cmp.getEl()
|
45
|
+
|
46
|
+
el.dom.click()
|
47
|
+
else if Ext.isElement(cmp)
|
48
|
+
cmp.click()
|
49
|
+
|
50
|
+
# Closes the first found window
|
51
|
+
closeWindow: ->
|
52
|
+
Ext.ComponentQuery.query("window[hidden=false]")[0].close()
|
53
|
+
|
54
|
+
select: (value, params, callback) ->
|
55
|
+
params ?= params
|
56
|
+
combo = params.in
|
57
|
+
if combo.isExpanded
|
58
|
+
combo.setValue combo.findRecordByDisplay value
|
59
|
+
combo.collapse()
|
60
|
+
else
|
61
|
+
combo.onTriggerClick()
|
62
|
+
if callback
|
63
|
+
wait ->
|
64
|
+
rec = combo.findRecordByDisplay value
|
65
|
+
combo.select rec
|
66
|
+
combo.fireEvent('select', combo, rec )
|
67
|
+
combo.collapse()
|
68
|
+
callback.call()
|
69
|
+
else
|
70
|
+
rec = combo.findRecordByDisplay value
|
71
|
+
combo.select rec
|
72
|
+
combo.fireEvent('select', combo, rec )
|
73
|
+
combo.collapse()
|
74
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
Ext.apply window,
|
2
|
+
expectToSee: (el) ->
|
3
|
+
expect(Ext.isObject(el) || Ext.isElement(el)).to.be.ok()
|
4
|
+
|
5
|
+
expectToNotSee: (el) ->
|
6
|
+
expect(Ext.isString(el)).to.be.ok()
|
7
|
+
|
8
|
+
expectDisabled: (cmp) ->
|
9
|
+
throw cmp + " not found" if Ext.isString(cmp)
|
10
|
+
expect(cmp.isDisabled()).to.be(true)
|
11
|
+
|
12
|
+
expectInvisibleBodyOf: (cmp) ->
|
13
|
+
throw cmp + " not found" if Ext.isString(cmp)
|
14
|
+
expect(cmp.body.isVisible()).to.be false
|
@@ -0,0 +1,107 @@
|
|
1
|
+
Ext.apply window,
|
2
|
+
grid: (title) ->
|
3
|
+
if title
|
4
|
+
Ext.ComponentQuery.query('grid[title="'+title+'"]')[0]
|
5
|
+
else
|
6
|
+
Ext.ComponentQuery.query('grid{isVisible(true)}')[0]
|
7
|
+
|
8
|
+
expandRowCombo: (field, params) ->
|
9
|
+
g = g || this.grid()
|
10
|
+
editor = g.getPlugin('celleditor')
|
11
|
+
column = g.headerCt.items.findIndex('name', field) - 1
|
12
|
+
window.editor = editor
|
13
|
+
editor.startEditByPosition({row: g.getSelectionModel().getCurrentPosition().row, column: column})
|
14
|
+
editor.activeEditor.field.onTriggerClick()
|
15
|
+
|
16
|
+
# Example:
|
17
|
+
# addRecords {title: 'Foo'}, {title: 'Bar'}, to: grid('Books'), submit: true
|
18
|
+
addRecords: ->
|
19
|
+
params = arguments[arguments.length - 1]
|
20
|
+
for record in arguments
|
21
|
+
if (record != params)
|
22
|
+
record = params.to.getStore().add(record)[0]
|
23
|
+
record.isNew = true
|
24
|
+
click button 'Apply' if params.submit
|
25
|
+
|
26
|
+
addRecord: (recordData, params) ->
|
27
|
+
params = params || []
|
28
|
+
grid = params.to || this.grid()
|
29
|
+
record = grid.getStore().add(recordData)
|
30
|
+
grid.getSelectionModel().select(grid.getStore().last())
|
31
|
+
|
32
|
+
updateRecord: (recordData, params) ->
|
33
|
+
params = params || []
|
34
|
+
grid = params.to || this.grid()
|
35
|
+
record = grid.getSelectionModel().getSelection()[0]
|
36
|
+
for key,value of recordData
|
37
|
+
record.set(key, value)
|
38
|
+
|
39
|
+
selectAssociation: (attr, value, callback) ->
|
40
|
+
expandRowCombo attr
|
41
|
+
wait ->
|
42
|
+
select value, in: combobox(attr)
|
43
|
+
# wait ->
|
44
|
+
callback.call()
|
45
|
+
|
46
|
+
valuesInColumn: (name, params) ->
|
47
|
+
params ?= {}
|
48
|
+
grid = params.in || this.grid()
|
49
|
+
out = []
|
50
|
+
grid.getStore().each (r) ->
|
51
|
+
assocValue = r.get('meta').associationValues[name]
|
52
|
+
out.push(if assocValue then assocValue else r.get(name))
|
53
|
+
out
|
54
|
+
|
55
|
+
selectAllRows: (params) ->
|
56
|
+
params ?= {}
|
57
|
+
grid = params.in || this.grid()
|
58
|
+
grid.getSelectionModel().selectAll()
|
59
|
+
|
60
|
+
# rowDisplayValues in: grid('Books'), of: grid('Books').getStore().last()
|
61
|
+
# Without parameters, assumes the first found grid and the selected row
|
62
|
+
rowDisplayValues: (params) ->
|
63
|
+
params ?= {}
|
64
|
+
grid = params.in || this.grid()
|
65
|
+
record = params.of || grid.getSelectionModel().getSelection()[0]
|
66
|
+
|
67
|
+
visibleColumns = []
|
68
|
+
Ext.each grid.columns, (c) ->
|
69
|
+
visibleColumns.push(c) if c.isVisible()
|
70
|
+
|
71
|
+
i = -1
|
72
|
+
return Ext.Array.map(Ext.DomQuery.select('tr[data-recordid="'+record.internalId+'"] td div'), (cell) ->
|
73
|
+
i++
|
74
|
+
if visibleColumns[i].attrType == 'boolean'
|
75
|
+
record.get(visibleColumns[i].name)
|
76
|
+
else
|
77
|
+
cell.innerHTML
|
78
|
+
)
|
79
|
+
|
80
|
+
# selectLastRow()
|
81
|
+
# selectLastRow in: grid('Book')
|
82
|
+
selectLastRow: (params) ->
|
83
|
+
params ?= {}
|
84
|
+
grid = params.in || this.grid()
|
85
|
+
grid.getSelectionModel().select(grid.getStore().last())
|
86
|
+
|
87
|
+
# selectFirstRow()
|
88
|
+
# selectFirstRow in: grid('Book')
|
89
|
+
selectFirstRow: (params) ->
|
90
|
+
params ?= {}
|
91
|
+
grid = params.in || this.grid()
|
92
|
+
grid.getSelectionModel().select(grid.getStore().first())
|
93
|
+
|
94
|
+
# Example:
|
95
|
+
# editLastRow {title: 'Foo', exemplars: 10}
|
96
|
+
editLastRow: ->
|
97
|
+
data = arguments[0]
|
98
|
+
grid = Ext.ComponentQuery.query("grid")[0]
|
99
|
+
store = grid.getStore()
|
100
|
+
record = store.last()
|
101
|
+
for key of data
|
102
|
+
record.set(key, data[key])
|
103
|
+
|
104
|
+
completeEditing: (g) ->
|
105
|
+
g = g || this.grid()
|
106
|
+
e = g.getPlugin('celleditor')
|
107
|
+
e.completeEdit()
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Query helpers will return a string denoting what was searched for, when a component/element itself could not be found. This can be used by other helpers to display a more informative error.
|
2
|
+
# KNOWN ISSUE: if the passed parameter contains symbols like "():,.", it results in an invalid query.
|
3
|
+
Ext.apply window,
|
4
|
+
header: (title) ->
|
5
|
+
Ext.ComponentQuery.query('header{isVisible(true)}[title="'+title+'"]')[0] || 'header ' + title
|
6
|
+
|
7
|
+
tab: (title) ->
|
8
|
+
Ext.ComponentQuery.query('tab[text="'+title+'"]')[0] || 'tab ' + title
|
9
|
+
|
10
|
+
panelWithContent: (text) ->
|
11
|
+
Ext.DomQuery.select("div.x-panel-body:contains(" + text + ")")[0] || 'panel with content ' + text
|
12
|
+
|
13
|
+
button: (text) ->
|
14
|
+
Ext.ComponentQuery.query("button{isVisible(true)}[text='"+text+"']")[0] || "button " + text
|
15
|
+
|
16
|
+
tool: (type) ->
|
17
|
+
Ext.ComponentQuery.query("tool{isVisible(true)}[type='"+type+"']")[0] || 'tool ' + type
|
18
|
+
|
19
|
+
component: (id) ->
|
20
|
+
Ext.ComponentQuery.query("panel{isVisible(true)}[id='"+id+"']")[0] || 'component ' + id
|
21
|
+
|
22
|
+
somewhere: (text) ->
|
23
|
+
Ext.DomQuery.select("*:contains(" + text + ")")[0] || 'anywhere ' + text
|
24
|
+
|
25
|
+
# used as work-around for the invalid query problem
|
26
|
+
currentPanelTitle: ->
|
27
|
+
panel = Ext.ComponentQuery.query('panel[hidden=false]')[0]
|
28
|
+
throw "Panel not found" if !panel
|
29
|
+
panel.getHeader().title
|
30
|
+
|
31
|
+
combobox: (name) ->
|
32
|
+
Ext.ComponentQuery.query("combo{isVisible(true)}[name='"+name+"']")[0] ||
|
33
|
+
'combobox ' + name
|
34
|
+
|
35
|
+
icon: (tooltip) ->
|
36
|
+
Ext.DomQuery.select('img[data-qtip="'+tooltip+'"]')[0] || 'icon ' + tooltip
|
37
|
+
|
38
|
+
textfield: (name) ->
|
39
|
+
Ext.ComponentQuery.query("textfield{isVisible(true)}[name='"+name+"']")[0] ||
|
40
|
+
'textfield ' + name
|
41
|
+
|
42
|
+
numberfield: (name) ->
|
43
|
+
Ext.ComponentQuery.query("numberfield{isVisible(true)}[name='"+name+"']")[0] ||
|
44
|
+
'numberfield ' + name
|
45
|
+
|
46
|
+
datefield: (name) ->
|
47
|
+
Ext.ComponentQuery.query("datefield{isVisible(true)}[name='"+name+"']")[0] ||
|
48
|
+
'datefield ' + name
|
49
|
+
|
50
|
+
xdatetime: (name) ->
|
51
|
+
Ext.ComponentQuery.query("xdatetime{isVisible(true)}[name='"+name+"']")[0] ||
|
52
|
+
'xdatetime ' + name
|
53
|
+
|
54
|
+
textFieldWith: (text) ->
|
55
|
+
_componentLike "textfield", "value", text
|
56
|
+
|
57
|
+
comboboxWith: (text) ->
|
58
|
+
_componentLike "combo", "rawValue", text
|
59
|
+
|
60
|
+
textAreaWith: (text) ->
|
61
|
+
_componentLike "textareafield", "value", text
|
62
|
+
|
63
|
+
numberFieldWith: (value) ->
|
64
|
+
_componentLike "numberfield", "value", value
|
65
|
+
|
66
|
+
activeWindow: ->
|
67
|
+
Ext.WindowMgr.getActive()
|
68
|
+
|
69
|
+
dateTimeFieldWith: (value) ->
|
70
|
+
res = 'xdatetime with value ' + value
|
71
|
+
Ext.each Ext.ComponentQuery.query('xdatetime'), (item) ->
|
72
|
+
if item.getValue().toString() == (new Date(value)).toString()
|
73
|
+
res = item
|
74
|
+
return
|
75
|
+
res
|
76
|
+
|
77
|
+
dateFieldWith: (value) ->
|
78
|
+
res = 'datefield with value ' + value
|
79
|
+
Ext.each Ext.ComponentQuery.query('datefield'), (item) ->
|
80
|
+
if item.getValue().toString() == (new Date(value)).toString()
|
81
|
+
res = item
|
82
|
+
return
|
83
|
+
res
|
84
|
+
|
85
|
+
_componentLike:(type,attr,value)->
|
86
|
+
Ext.ComponentQuery.query(type+'['+attr+'='+value+']')[0] || type + " with " + attr + " '" + value + "'"
|
87
|
+
# alias
|
88
|
+
window.anywhere = window.somewhere
|