├── .bithoundrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── dist
├── mocha-extjs.css
└── mocha-extjs.js
├── gulpfile.js
├── mocha-extjs.js
├── package.json
├── scripts
└── copy-demo.sh
├── scss
└── mocha-extjs.scss
├── src
├── chain.js
├── chain
│ ├── actionItem.js
│ ├── componentActionItem.js
│ ├── componentItem.js
│ └── item.js
├── drivers
│ ├── extjs
│ │ ├── components
│ │ │ ├── base.js
│ │ │ ├── button.js
│ │ │ ├── cellEditor.js
│ │ │ ├── checkBox.js
│ │ │ ├── comboBox.js
│ │ │ ├── dataview.js
│ │ │ ├── grid.js
│ │ │ ├── numberField.js
│ │ │ ├── radio.js
│ │ │ ├── tab.js
│ │ │ ├── textField.js
│ │ │ └── window.js
│ │ └── driver.js
│ └── html
│ │ └── components
│ │ └── base.js
├── mochaUI.js
├── mochaUi
│ └── cursor.js
└── utils
│ ├── set.js
│ └── utils.js
└── test
├── sandbox
├── .sencha
│ ├── .cvsignore
│ ├── .gitignore
│ ├── app
│ │ ├── Boot.js
│ │ ├── Microloader.js
│ │ ├── app.defaults.json
│ │ ├── bootstrap-impl.xml
│ │ ├── build-impl.xml
│ │ ├── build.properties
│ │ ├── codegen.json
│ │ ├── cordova-impl.xml
│ │ ├── cordova.defaults.properties
│ │ ├── defaults.properties
│ │ ├── development.defaults.properties
│ │ ├── development.properties
│ │ ├── ext.properties
│ │ ├── find-cmd-impl.xml
│ │ ├── init-impl.xml
│ │ ├── js-impl.xml
│ │ ├── native.defaults.properties
│ │ ├── native.properties
│ │ ├── package.defaults.properties
│ │ ├── package.properties
│ │ ├── packager-impl.xml
│ │ ├── page-impl.xml
│ │ ├── phonegap-impl.xml
│ │ ├── phonegap.defaults.properties
│ │ ├── plugin.xml
│ │ ├── production.defaults.properties
│ │ ├── production.properties
│ │ ├── refresh-impl.xml
│ │ ├── resolve-impl.xml
│ │ ├── resources-impl.xml
│ │ ├── sass-impl.xml
│ │ ├── sencha.cfg
│ │ ├── slice-impl.xml
│ │ ├── testing.defaults.properties
│ │ ├── testing.properties
│ │ └── watch-impl.xml
│ └── workspace
│ │ ├── plugin.xml
│ │ └── sencha.cfg
├── app.js
├── app.json
├── app
│ ├── Application.js
│ └── view
│ │ └── main
│ │ ├── Main.js
│ │ ├── MainController.js
│ │ ├── MainModel.js
│ │ ├── SuitePanel.js
│ │ ├── custom
│ │ ├── Button.js
│ │ ├── Dataview.js
│ │ └── Grid.js
│ │ └── tab
│ │ ├── Buttons.js
│ │ ├── Content.js
│ │ ├── Dataview.js
│ │ ├── Fields.js
│ │ ├── Grids.js
│ │ ├── LoadMasks.js
│ │ └── Windows.js
├── bootstrap.css
├── bootstrap.js
├── bootstrap.json
├── build.xml
├── classic.json
├── index.html
└── workspace.json
└── suites
├── 010-environment.js
├── 020-buttons.js
├── 030-windows.js
├── 040-fields.js
├── 050-grids.js
├── 060-dataview.js
├── 070-loadmasks.js
└── 080-content.js
/.bithoundrc:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "**/node_modules/**",
4 | "**/dist/**",
5 | "**/test/sandbox/.sencha/**",
6 | "**/test/sandbox/build/**",
7 | "**/test/sandbox/ext/**",
8 | "**/test/sandbox/*.js",
9 | "**/test/sandbox/*.json",
10 | "**/test/sandbox/*.css",
11 | "**/test/sandbox/*.xml",
12 | "**/test/sandbox/*.html"
13 | ],
14 | "test": [
15 | "**/test/suites/**"
16 | ],
17 | "critics": {
18 | "lint": {
19 | "engine": "standard"
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .sass-cache
3 |
4 | *.log
5 |
6 | /node_modules
7 |
8 | /test/sandbox/ext
9 | /test/sandbox/overrides
10 | /test/sandbox/packages
11 | /test/sandbox/resources
12 | /test/sandbox/sass
13 |
14 | /test/sandbox/build
15 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "5.10.1"
4 | before_script:
5 | - npm run lint
6 | - cd test/sandbox
7 | - wget https://dl.dropboxusercontent.com/u/21095169/archive/sencha-extjs-6.0.1.250.tar.gz
8 | - tar -zxf sencha-extjs-6.0.1.250.tar.gz
9 | - wget https://dl.dropboxusercontent.com/u/21095169/archive/sencha-cmd-6.1.2.15.tar.gz
10 | - tar -zxf sencha-cmd-6.1.2.15.tar.gz
11 | - ./6.1.2.15/sencha app build
12 | - cd ../../
13 | - npm install mocha-phantomjs@4.0.2 mocha-phantomjs-core@2.0.1 phantomjs-prebuilt@2.1.7
14 | - npm run fix-deps
15 | - ./node_modules/.bin/phantomjs --version
16 | - npm start &
17 | - sleep 20
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Anton Fisher
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # mocha-extjs
2 |
3 | [](https://www.npmjs.com/package/mocha-extjs)
4 | [](http://standardjs.com/)
5 | [](https://github.com/antonfisher/node-mocha-extjs/blob/master/LICENSE)
6 | 
7 |
8 | ExtJs applications testing framework which simulates user actions.
9 |
10 | [Online demo](http://antonfisher.com/demo/mocha-extjs/)
11 |
12 | 
13 |
14 | Component search by _title_, _fieldLabel_, _reference_, _boxLabel_, _xtype_, _text_ properties:
15 |
16 | ```javascript
17 | // click on "Save" button
18 | eTT().button('Save').click(done);
19 |
20 | // select first item in the combobox with "Country" fieldLabel.
21 | eTT().combobox('Country').select(1, done);
22 | ```
23 |
24 | ## Getting Started:
25 |
26 | Update _index.html_:
27 |
28 | ```html
29 |
30 | ...
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
48 |
49 |
50 |
51 |
52 |
53 |
65 |
66 | ```
67 | Done. Run your application!
68 |
69 | ## PhantomJs
70 |
71 | It works now, but some hack is needed.
72 | First of all you will need _PhantonJs_ version 2 and `mocha-phantomjs` library.
73 | After `mocha-phantomjs` installation, upgrade one of its dependency to the latest version:
74 |
75 | ```bash
76 | $ npm install mocha-phantomjs@4.0.2 mocha-phantomjs-core@2.0.1 phantomjs-prebuilt@2.1.7
77 | $ rm -rf ./node_modules/mocha-phantomjs/node_modules/mocha-phantomjs-core
78 |
79 | # check PhantonJs version, should be like this:
80 | $ ./node_modules/.bin/phantomjs --version
81 | 2.1.1
82 | ```
83 |
84 | Run tests in console:
85 |
86 | ```bash
87 | # http://localhost:3000 - application address
88 | $ ./node_modules/.bin/mocha-phantomjs --timeout 15000 --path ./node_modules/.bin/phantomjs --setting disk-cache=false --view 1024x768 http://localhost:3000
89 | ```
90 |
91 | Library's self test with _PhantonJs_:
92 |
93 | ```bash
94 | $ npm test
95 | ```
96 |
97 | ## Usage
98 |
99 | ### Init the library before running MochaJs
100 |
101 | ```javascript
102 | var eTT = new MochaExtJs(); // init testing framework
103 | ```
104 |
105 | ### Add test suite:
106 |
107 | ```javascript
108 | // tests/suites/020-buttons.js
109 | describe('Buttons', function () {
110 | this.bail(true); // exit when first test fails
111 | this.timeout(20 * 1000); // necessary timeout for ui operations
112 |
113 | it('Switch to "Buttons" tab', function (done) { // done - async tests callback
114 | eTT().tab('Buttons').click(done);
115 | });
116 |
117 | it('Click "Simple button" button', function (done) {
118 | eTT().button('Simple button').isEnabled().click(done);
119 | });
120 | });
121 | ```
122 |
123 | ### Supported components and methods:
124 |
125 | ```
126 | var eTT = new MochaExtJs();
127 |
128 | eTT() -->--->|------->--->|- button ---> (|- '%title%' )----.
129 | | | | |- window |- '%fieldLabel%' |
130 | | |- no --' |- numberfield |- '%reference%' |
131 | | | |- textfield |- '%boxLabel%' |
132 | | | |- checkbox |- '%xtype%' |
133 | | | |- combobox `- '%text%' |
134 | | | |- dataview |
135 | | | |- radio |
136 | | | |- grid .----------------------x----------------------.
137 | | | `- tab | |
138 | | | |-->|- click -------> (...) ------------------v
139 | | | | |- isEnabled |
140 | | |- waitLoadMask() ------. | |- isDisabled |
141 | | | | | |- isHidden |
142 | | `- waitText('%text%')---v | |- isVisible |
143 | | | | |- select |
144 | | | | |- checkRowsCount |
145 | | | | |- clickAction |
146 | | | | |- edit |
147 | | | | `- fill |
148 | | | | |
149 | | | `--> cellEditor() --->|- select ---> (...) ---v
150 | | | |- click |
151 | | | `- fill |
152 | | | |
153 | x----------------------------<-------------------------------------------------'
154 | |
155 | |
156 | `--> done.
157 | ```
158 |
159 | Examples:
160 |
161 | ```javascript
162 | eTT().button('Simple button').isEnabled().click(done);
163 | eTT().button('Hide me').click().isHidden(done);
164 | eTT().tab('Windows').click(done);
165 | eTT().window('Confirm').button('Yes').isEnabled().click(done);
166 | eTT().no.window('Confirm', done);
167 | eTT().textfield('Name').fill('my text', done);
168 | eTT().numberfield('Count').fill(13, done);
169 | eTT().checkbox('include').click(done);
170 | eTT().radio('check B').click(done);
171 | eTT().combobox('Select in list').select(1, done);
172 | eTT().grid('Names').select(1, 1, done);
173 | eTT().grid('Names').checkRowsCount(2, done);
174 | eTT().grid('Names').clickAction(0, 2, 1, done); // row, coll, action index
175 | eTT().grid('Cell editing').cellEditor(1, 0).select(0, done);
176 | eTT().grid('Cell editing').cellEditor(0, 2).fill('test1', done);
177 | eTT().grid('Cell editing').cellEditor(0, 3).click(done);
178 | eTT().grid('customDataviewReference').select(1, done);
179 | eTT().waitLoadMask(done);
180 | eTT().waitText('Result is here!', done);
181 | ```
182 |
183 | ### Taking screenshots
184 |
185 | ```javascript
186 | MochaExtJs.screenshot();
187 | MochaExtJs.screenshot('./mypath/');
188 | ```
189 |
190 | ## Installation
191 |
192 | - `$ npm install mocha-extjs`
193 | - use files from `./dist` folder.
194 |
195 | ## Development
196 |
197 | - install _NodeJs v5.10.1_ or newer
198 | - clone repository `$ git clone https://github.com/antonfisher/node-mocha-extjs.git`
199 | - copy _ExtJs v5_ or _v6_ framework to `./test/sandbox/ext` folder
200 | - build _Sandbox_ application
201 | ```bash
202 | $ cd ./node-mocha-extjs/test/sandbox
203 | $ sencha app build
204 | ```
205 | - install dependencies `$ npm install`
206 | - run _lint_: `$ npm run lint`
207 | - run _gulp_: `$ npm start`.
208 |
209 | ## Contributing
210 |
211 | Please take care to maintain the existing coding style, tests for any changed functionality.
212 | `npm test` and `npm run lint` your code.
213 | Push your changes without `./dist/mocha-extjs.*` files, to keep commits cleaner between library releases.
214 | Thank you!
215 |
216 | ## Releases History
217 |
218 | * 0.2.0 New grid method - clickAction
219 | * 0.1.7 Move to _PhantomJs v2_, _ExtJs v6_, add _DataView_ support (thanks [@vadimpopa](https://github.com/antonfisher/node-mocha-extjs/pull/1))
220 | * 0.1.6 _CellEditing_ plugin support in _PhantomJs_
221 | * 0.1.5 Update click method, minor fixes
222 | * 0.1.4 New grid cell editor methods
223 | * 0.1.3 Fix previous release trouble
224 | * 0.1.2 Update documentation
225 | * ES2015
226 | * standardjs
227 | * grid select rows and cells
228 | * 0.1.1 Update documentation
229 | * 0.1.0 Initial Alpha release
230 |
231 | ## ToDo
232 |
233 | - [x] update Mocha UI style
234 | - [x] Self tests
235 | - [ ] Migrate to WebPack
236 | - [ ] Use Sencha test env
237 | - [ ] New components
238 | - [ ] Documentation
239 |
240 | ## License
241 |
242 | Copyright (c) 2016 Anton Fisher
243 |
244 | MIT License. Free use and change.
245 |
--------------------------------------------------------------------------------
/dist/mocha-extjs.css:
--------------------------------------------------------------------------------
1 | #mocha {
2 | top: 0;
3 | right: 0;
4 | margin: 0;
5 | height: 100%;
6 | opacity: 0.87;
7 | overflow: auto;
8 | z-index: 100000;
9 | min-width: 300px;
10 | background: #FFF;
11 | position: absolute;
12 | padding-right: 15px;
13 | border-left: 1px solid #f0f0f0; }
14 | #mocha #mocha-stats {
15 | padding: 5px 10px 0 5px;
16 | border: 1px dashed #cccccc; }
17 | #mocha #mocha-report {
18 | height: 100%;
19 | padding: 60px 0 0 0; }
20 | #mocha #mocha-report li.suite:last-child {
21 | padding-bottom: 25px; }
22 | #mocha .test pre.error {
23 | font-size: 10px;
24 | max-width: 500px;
25 | box-shadow: none;
26 | border-radius: 0;
27 | line-height: 11px; }
28 | #mocha .test.pass.slow .duration {
29 | background: none;
30 | color: #b94a48;
31 | border: 1px solid #b94a48; }
32 | #mocha .test.pass.medium .duration {
33 | background: none;
34 | color: #c09853;
35 | border: 1px solid #c09853; }
36 |
37 | #mocha-error {
38 | top: 50px;
39 | left: 50px;
40 | opacity: 0.9;
41 | padding: 20px;
42 | color: #ff6666;
43 | z-index: 100000;
44 | font-size: 16px;
45 | position: absolute;
46 | background: #ffdddd;
47 | border: 5px solid #ff6666; }
48 |
49 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jaGEtZXh0anMuY3NzIiwic291cmNlcyI6WyJtb2NoYS1leHRqcy5zY3NzIl0sInNvdXJjZXNDb250ZW50IjpbIiRjb2xvckVycm9yOiAjYjk0YTQ4O1xuJGNvbG9yV2FybmluZzogI2MwOTg1MztcblxuI21vY2hhIHtcbiAgICB0b3A6IDA7XG4gICAgcmlnaHQ6IDA7XG4gICAgbWFyZ2luOiAwO1xuICAgIGhlaWdodDogMTAwJTtcbiAgICBvcGFjaXR5OiAwLjg3O1xuICAgIG92ZXJmbG93OiBhdXRvO1xuICAgIHotaW5kZXg6IDEwMDAwMDtcbiAgICBtaW4td2lkdGg6IDMwMHB4O1xuICAgIGJhY2tncm91bmQ6ICNGRkY7XG4gICAgcG9zaXRpb246IGFic29sdXRlO1xuICAgIHBhZGRpbmctcmlnaHQ6IDE1cHg7XG4gICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCAjZjBmMGYwO1xuXG4gICAgI21vY2hhLXN0YXRzIHtcbiAgICAgICAgcGFkZGluZzogNXB4IDEwcHggMCA1cHg7XG4gICAgICAgIGJvcmRlcjogMXB4IGRhc2hlZCAjY2NjY2NjO1xuICAgIH1cblxuICAgICNtb2NoYS1yZXBvcnQge1xuICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIHBhZGRpbmc6IDYwcHggMCAwIDA7XG5cbiAgICAgICAgbGkuc3VpdGU6bGFzdC1jaGlsZCB7XG4gICAgICAgICAgICBwYWRkaW5nLWJvdHRvbTogMjVweDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC50ZXN0IHByZS5lcnJvciB7XG4gICAgICAgIGZvbnQtc2l6ZTogMTBweDtcbiAgICAgICAgbWF4LXdpZHRoOiA1MDBweDtcbiAgICAgICAgYm94LXNoYWRvdzogbm9uZTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogMDtcbiAgICAgICAgbGluZS1oZWlnaHQ6IDExcHg7XG4gICAgfVxuXG4gICAgLnRlc3QucGFzcy5zbG93IC5kdXJhdGlvbiB7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIGNvbG9yOiAkY29sb3JFcnJvcjtcbiAgICAgICAgYm9yZGVyOiAxcHggc29saWQgJGNvbG9yRXJyb3I7XG4gICAgfVxuICAgIC50ZXN0LnBhc3MubWVkaXVtIC5kdXJhdGlvbiB7XG4gICAgICAgIGJhY2tncm91bmQ6IG5vbmU7XG4gICAgICAgIGNvbG9yOiAkY29sb3JXYXJuaW5nO1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCAkY29sb3JXYXJuaW5nO1xuICAgIH1cbn1cblxuI21vY2hhLWVycm9yIHtcbiAgICB0b3A6IDUwcHg7XG4gICAgbGVmdDogNTBweDtcbiAgICBvcGFjaXR5OiAwLjk7XG4gICAgcGFkZGluZzogMjBweDtcbiAgICBjb2xvcjogI2ZmNjY2NjtcbiAgICB6LWluZGV4OiAxMDAwMDA7XG4gICAgZm9udC1zaXplOiAxNnB4O1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICBiYWNrZ3JvdW5kOiAjZmZkZGRkO1xuICAgIGJvcmRlcjogNXB4IHNvbGlkICNmZjY2NjY7XG59XG4iXSwibWFwcGluZ3MiOiJBQUdBLEFBQUEsTUFBTSxDQUFDO0VBQ0gsR0FBRyxFQUFFLENBQUU7RUFDUCxLQUFLLEVBQUUsQ0FBRTtFQUNULE1BQU0sRUFBRSxDQUFFO0VBQ1YsTUFBTSxFQUFFLElBQUs7RUFDYixPQUFPLEVBQUUsSUFBSztFQUNkLFFBQVEsRUFBRSxJQUFLO0VBQ2YsT0FBTyxFQUFFLE1BQU87RUFDaEIsU0FBUyxFQUFFLEtBQU07RUFDakIsVUFBVSxFQUFFLElBQUs7RUFDakIsUUFBUSxFQUFFLFFBQVM7RUFDbkIsYUFBYSxFQUFFLElBQUs7RUFDcEIsV0FBVyxFQUFFLGlCQUFrQixHQWtDbEM7RUE5Q0QsQUFjSSxNQWRFLENBY0YsWUFBWSxDQUFDO0lBQ1QsT0FBTyxFQUFFLGNBQWU7SUFDeEIsTUFBTSxFQUFFLGtCQUFtQixHQUM5QjtFQWpCTCxBQW1CSSxNQW5CRSxDQW1CRixhQUFhLENBQUM7SUFDVixNQUFNLEVBQUUsSUFBSztJQUNiLE9BQU8sRUFBRSxVQUFXLEdBS3ZCO0lBMUJMLEFBdUJnQixNQXZCVixDQW1CRixhQUFhLENBSVQsRUFBRSxBQUFBLE1BQU0sQUFBQSxXQUFXLENBQUM7TUFDaEIsY0FBYyxFQUFFLElBQUssR0FDeEI7RUF6QlQsQUE0QmEsTUE1QlAsQ0E0QkYsS0FBSyxDQUFDLEdBQUcsQUFBQSxNQUFNLENBQUM7SUFDWixTQUFTLEVBQUUsSUFBSztJQUNoQixTQUFTLEVBQUUsS0FBTTtJQUNqQixVQUFVLEVBQUUsSUFBSztJQUNqQixhQUFhLEVBQUUsQ0FBRTtJQUNqQixXQUFXLEVBQUUsSUFBSyxHQUNyQjtFQWxDTCxBQW9Db0IsTUFwQ2QsQ0FvQ0YsS0FBSyxBQUFBLEtBQUssQUFBQSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ3RCLFVBQVUsRUFBRSxJQUFLO0lBQ2pCLEtBQUssRUF6Q0EsT0FBTztJQTBDWixNQUFNLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0ExQ1osT0FBTyxHQTJDZjtFQXhDTCxBQXlDc0IsTUF6Q2hCLENBeUNGLEtBQUssQUFBQSxLQUFLLEFBQUEsT0FBTyxDQUFDLFNBQVMsQ0FBQztJQUN4QixVQUFVLEVBQUUsSUFBSztJQUNqQixLQUFLLEVBN0NFLE9BQU87SUE4Q2QsTUFBTSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBOUNWLE9BQU8sR0ErQ2pCOztBQUdMLEFBQUEsWUFBWSxDQUFDO0VBQ1QsR0FBRyxFQUFFLElBQUs7RUFDVixJQUFJLEVBQUUsSUFBSztFQUNYLE9BQU8sRUFBRSxHQUFJO0VBQ2IsT0FBTyxFQUFFLElBQUs7RUFDZCxLQUFLLEVBQUUsT0FBUTtFQUNmLE9BQU8sRUFBRSxNQUFPO0VBQ2hCLFNBQVMsRUFBRSxJQUFLO0VBQ2hCLFFBQVEsRUFBRSxRQUFTO0VBQ25CLFVBQVUsRUFBRSxPQUFRO0VBQ3BCLE1BQU0sRUFBRSxpQkFBa0IsR0FDN0IiLCJuYW1lcyI6W119 */
50 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | var gulp = require('gulp')
4 | var sass = require('gulp-sass')
5 | var webpack = require('webpack-stream')
6 | var sourcemaps = require('gulp-sourcemaps')
7 | var browserSync = require('browser-sync').create()
8 |
9 | gulp.task('css', () => {
10 | return gulp
11 | .src('./scss/**/*.scss')
12 | .pipe(sourcemaps.init())
13 | .pipe(sass().on('error', sass.logError))
14 | .pipe(sourcemaps.write())
15 | .pipe(gulp.dest('./dist'))
16 | })
17 |
18 | gulp.task('js', () => {
19 | return gulp
20 | .src('./mocha-extjs.js')
21 | .pipe(webpack({
22 | resolveLoader: {
23 | root: './'
24 | },
25 | module: {
26 | loaders: [{
27 | test: /\.js$/,
28 | exclude: /node_modules/,
29 | loader: 'babel-loader',
30 | query: {
31 | presets: ['es2015']
32 | }
33 | }]
34 | },
35 | output: {
36 | filename: 'mocha-extjs.js'
37 | }
38 | }))
39 | .pipe(gulp.dest('./dist/'))
40 | })
41 |
42 | gulp.task('default', ['css', 'js'], () => {
43 | browserSync.init({
44 | server: {
45 | baseDir: ['./test/sandbox', './']
46 | }
47 | })
48 |
49 | gulp.watch(['./mocha-extjs.js', './src/**/*', './test/suites/**/*', './test/sandbox/app/**/*'], ['js'])
50 | gulp.watch('./scss/*.scss', ['css'])
51 | gulp.watch(['./dist/*'], browserSync.reload)
52 | })
53 |
--------------------------------------------------------------------------------
/mocha-extjs.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import 'babel-polyfill'
4 |
5 | import {Chain} from './src/chain.js'
6 | import {MochaUI} from './src/mochaUI.js'
7 | import {ExtJsDriver} from './src/drivers/extjs/driver.js'
8 |
9 | export class MochaExtJs {
10 |
11 | constructor ({driver} = {driver: new ExtJsDriver({mochaUi: new MochaUI()})}) {
12 | return function () {
13 | return new Chain({driver})
14 | }
15 | }
16 |
17 | static screenshot (path = '/tmp/') {
18 | if (window.callPhantom) {
19 | const filename = (path + (new Date()).getTime())
20 | console.log('Taking screenshot: ' + filename)
21 | window.callPhantom({'screenshot': filename})
22 | }
23 | }
24 |
25 | }
26 |
27 | // browserify
28 | if (window) {
29 | window.MochaExtJs = MochaExtJs
30 | }
31 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mocha-extjs",
3 | "version": "0.2.0",
4 | "description": "ExtJs Test Framework for Mocha",
5 | "main": "mocha-extjs.js",
6 | "directories": {
7 | "test": "test"
8 | },
9 | "scripts": {
10 | "start": "./node_modules/.bin/gulp",
11 | "test": "npm run clear-phantomjs-cache && ./node_modules/.bin/mocha-phantomjs --timeout 15000 --path ./node_modules/.bin/phantomjs --setting disk-cache=false --view 1024x768 http://localhost:3000",
12 | "test-remote": "npm run clear-phantomjs-cache && ./node_modules/.bin/mocha-phantomjs --timeout 15000 --path ./node_modules/.bin/phantomjs --setting disk-cache=false --view 1024x768 http://antonfisher.com/demo/mocha-extjs/",
13 | "lint": "./node_modules/.bin/standard 'gulpfile.js' 'mocha-extjs.js' './src/**/*.js' './test/suites/**/*.js' './test/sandbox/app/**/*.js' | ./node_modules/.bin/snazzy",
14 | "copy-demo": "./scripts/copy-demo.sh",
15 | "fix-deps": "rm -rf ./node_modules/mocha-phantomjs/node_modules/mocha-phantomjs-core",
16 | "clear-phantomjs-cache": "rm -rf ~/.qws/share/data/Ofi\\ Labs/PhantomJS ~/.local/share/Ofi\\ Labs/PhantomJS",
17 | "postinstall": "npm run fix-deps"
18 | },
19 | "standard": {
20 | "globals": [
21 | "describe",
22 | "it",
23 | "expect",
24 | "eTT",
25 | "Ext",
26 | "Sandbox"
27 | ]
28 | },
29 | "repository": {
30 | "type": "git",
31 | "url": "https://github.com/antonfisher/node-mocha-extjs.git"
32 | },
33 | "keywords": [
34 | "extjs",
35 | "sencha",
36 | "mocha",
37 | "test framework"
38 | ],
39 | "author": "Anton Fisher (http://antonfisher.com)",
40 | "license": "MIT",
41 | "bugs": {
42 | "url": "https://github.com/antonfisher/node-mocha-extjs/issues"
43 | },
44 | "homepage": "https://github.com/antonfisher/node-mocha-extjs",
45 | "devDependencies": {
46 | "babel-core": "6.x",
47 | "babel-loader": "6.x",
48 | "babel-polyfill": "6.13.0",
49 | "babel-preset-es2015": "6.x",
50 | "browser-sync": "2.x",
51 | "gulp": "3.x",
52 | "gulp-sass": "2.x",
53 | "gulp-sourcemaps": "1.x",
54 | "mocha-phantomjs": "4.0.2",
55 | "mocha-phantomjs-core": "2.0.1",
56 | "phantomjs-prebuilt": "2.1.12",
57 | "snazzy": "5.0.0",
58 | "standard": "8.1.0",
59 | "webpack-stream": "3.x"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/scripts/copy-demo.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | DEMO_DEST="../antonfisher.github.io/demo/mocha-extjs";
4 |
5 | cd test/sandbox/ \
6 | && sencha app build \
7 | && cd - \
8 | && mkdir -p ./"${DEMO_DEST}" \
9 | && rm -rf ./"${DEMO_DEST}"/* \
10 | && cp -r ./test/sandbox/build/production/Sandbox/* ./"${DEMO_DEST}"/ \
11 | && mkdir -p ./"${DEMO_DEST}"/test/ \
12 | && cp -r test/suites/ ./"${DEMO_DEST}"/test;
13 | exit_code="${?}";
14 |
15 | if [[ "${exit_code}" == 0 ]]; then
16 | cd ./"${DEMO_DEST}";
17 | python -m SimpleHTTPServer 3333;
18 | fi;
19 |
20 | exit "${exit_code}";
21 |
--------------------------------------------------------------------------------
/scss/mocha-extjs.scss:
--------------------------------------------------------------------------------
1 | $colorError: #b94a48;
2 | $colorWarning: #c09853;
3 |
4 | #mocha {
5 | top: 0;
6 | right: 0;
7 | margin: 0;
8 | height: 100%;
9 | opacity: 0.87;
10 | overflow: auto;
11 | z-index: 100000;
12 | min-width: 300px;
13 | background: #FFF;
14 | position: absolute;
15 | padding-right: 15px;
16 | border-left: 1px solid #f0f0f0;
17 |
18 | #mocha-stats {
19 | padding: 5px 10px 0 5px;
20 | border: 1px dashed #cccccc;
21 | }
22 |
23 | #mocha-report {
24 | height: 100%;
25 | padding: 60px 0 0 0;
26 |
27 | li.suite:last-child {
28 | padding-bottom: 25px;
29 | }
30 | }
31 |
32 | .test pre.error {
33 | font-size: 10px;
34 | max-width: 500px;
35 | box-shadow: none;
36 | border-radius: 0;
37 | line-height: 11px;
38 | }
39 |
40 | .test.pass.slow .duration {
41 | background: none;
42 | color: $colorError;
43 | border: 1px solid $colorError;
44 | }
45 | .test.pass.medium .duration {
46 | background: none;
47 | color: $colorWarning;
48 | border: 1px solid $colorWarning;
49 | }
50 | }
51 |
52 | #mocha-error {
53 | top: 50px;
54 | left: 50px;
55 | opacity: 0.9;
56 | padding: 20px;
57 | color: #ff6666;
58 | z-index: 100000;
59 | font-size: 16px;
60 | position: absolute;
61 | background: #ffdddd;
62 | border: 5px solid #ff6666;
63 | }
64 |
--------------------------------------------------------------------------------
/src/chain.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {Set} from './utils/set.js'
4 | import {ChainActionItem} from './chain/actionItem.js'
5 | import {ChainComponentItem} from './chain/componentItem.js'
6 | import {ChainComponentActionItem} from './chain/componentActionItem.js'
7 |
8 | export class Chain {
9 |
10 | constructor ({driver, itemsRunDelay = 50}) {
11 | this._itemsSet = new Set()
12 |
13 | this._chainRunned = false
14 | this._chainCallback = () => {
15 | throw new Error('Chain callback is not presented.')
16 | }
17 |
18 | this.driver = driver
19 | this.itemsRunDelay = itemsRunDelay
20 | this.no = {}
21 |
22 | // entrance actions
23 |
24 | for (let component of driver.supportedComponents) {
25 | this[component] = this.createActionFunction(component)
26 | this.no[component] = this.createActionFunction(component, true)
27 | }
28 |
29 | for (let action of driver.supportedComponentActions) {
30 | this[action] = this.createActionFunction(action)
31 | }
32 |
33 | for (let action of driver.supportedActions) {
34 | this[action] = this.createActionFunction(action)
35 | }
36 |
37 | return this
38 | }
39 |
40 | createActionFunction (actionType, invert) {
41 | return (...args) => {
42 | if (this._chainRunned) {
43 | throw new Error('Cannot add an action after the action which calls Mocha test callback.')
44 | }
45 |
46 | let actionArgs = []
47 | for (let arg of args) {
48 | if (typeof arg === 'function') {
49 | this._chainRunned = true
50 | this._chainCallback = arg
51 | break
52 | }
53 | actionArgs.push(arg)
54 | }
55 |
56 | const chainProperties = {
57 | type: actionType,
58 | chain: this,
59 | invert: invert,
60 | callArgs: actionArgs
61 | }
62 |
63 | if (this.driver.supportedComponents.includes(actionType)) {
64 | this._itemsSet.push(new ChainComponentItem(chainProperties))
65 | } else if (this.driver.supportedComponentActions.includes(actionType)) {
66 | this._itemsSet.push(new ChainComponentActionItem(chainProperties))
67 | } else if (this.driver.supportedActions.includes(actionType)) {
68 | this._itemsSet.push(new ChainActionItem(chainProperties))
69 | }
70 |
71 | if (this._chainRunned) {
72 | this.run()
73 | }
74 |
75 | return this
76 | }
77 | }
78 |
79 | run () {
80 | const itemsGenerator = this._itemsSet.items()
81 |
82 | const runNextAction = () => {
83 | const item = itemsGenerator.next()
84 |
85 | if (item.done) {
86 | return this._chainCallback(null)
87 | } else {
88 | return item.value.run((err) => {
89 | if (err) {
90 | return this._chainCallback(err)
91 | }
92 |
93 | setTimeout(() => {
94 | runNextAction()
95 | }, this.itemsRunDelay)
96 | })
97 | }
98 | }
99 |
100 | runNextAction()
101 | }
102 |
103 | get lastComponent () {
104 | for (let item of this._itemsSet.reversedItems()) {
105 | if (item.component) {
106 | return item.component
107 | }
108 | }
109 |
110 | return null
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/src/chain/actionItem.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ChainItem} from './item.js'
4 | import {waitForFn} from '../utils/utils.js'
5 |
6 | export class ChainActionItem extends ChainItem {
7 |
8 | run (callback) {
9 | return waitForFn(
10 | (done) => {
11 | this.chain.driver[this.type](done, ...this.callArgs)
12 | },
13 | callback
14 | )
15 | }
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/src/chain/componentActionItem.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ChainItem} from './item.js'
4 | import {waitForFn} from '../utils/utils.js'
5 |
6 | export class ChainComponentActionItem extends ChainItem {
7 |
8 | run (callback) {
9 | const lastComponent = this.chain.lastComponent
10 |
11 | if (!lastComponent) {
12 | return callback(`No "${this.type}" action target.`)
13 | }
14 |
15 | const action = lastComponent[this.type]
16 |
17 | if (!action) {
18 | return callback(
19 | `Component "${lastComponent.constructor.name.replace(/.*Component/, '').toLowerCase()}" ` +
20 | `does not support action "${this.type}".`
21 | )
22 | }
23 |
24 | return waitForFn(
25 | (done) => {
26 | lastComponent[this.type](done, ...this.callArgs)
27 | },
28 | callback
29 | )
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/chain/componentItem.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ChainItem} from './item.js'
4 | import {waitForFn} from '../utils/utils.js'
5 |
6 | export class ChainComponentItem extends ChainItem {
7 |
8 | constructor (...args) {
9 | super(...args)
10 |
11 | this.component = null
12 | }
13 |
14 | run (callback) {
15 | const type = this.type
16 | const chain = this.chain
17 | const callArgs = this.callArgs
18 |
19 | return waitForFn(
20 | (done) => {
21 | this.chain.driver.getComponent(
22 | (err, result) => {
23 | if (this.invert) {
24 | return done(err ? null : `Component ${this.type} "${this.callArgs[0]}" still presented.`)
25 | } else {
26 | return done(err, result)
27 | }
28 | },
29 | {type, callArgs, chain}
30 | )
31 | },
32 | (err, component) => {
33 | this.component = component
34 | return callback(err)
35 | }
36 | )
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/chain/item.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export class ChainItem {
4 |
5 | constructor ({chain, type, invert = false, callArgs = []}) {
6 | if (!chain) {
7 | throw new Error(`Class ${this.constructor.name} created with undefined property "chain".`)
8 | }
9 |
10 | if (!type) {
11 | throw new Error(`Class ${this.constructor.name} created with undefined property "type".`)
12 | }
13 |
14 | this.type = type
15 | this.chain = chain
16 | this.invert = invert
17 | this.callArgs = callArgs
18 | }
19 |
20 | run () {
21 | console.error(`called on implemented method: ${this.constructor.name}.run()`)
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/base.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {HTMLComponentBase} from '../../html/components/base.js'
4 |
5 | export class ExtJsComponentBase {
6 |
7 | constructor ({driver, chain}) {
8 | this.chain = chain
9 | this.driver = driver
10 | this.selectors = []
11 |
12 | this._htmlComponent = null
13 | }
14 |
15 | get htmlComponent () {
16 | if (!this._htmlComponent && this.extJsComponent) {
17 | let htmlElement = null
18 |
19 | if (this.extJsComponent.inputEl) {
20 | htmlElement = this.extJsComponent.inputEl.dom
21 | } else if (this.extJsComponent.el) {
22 | htmlElement = this.extJsComponent.el.dom
23 | }
24 |
25 | if (htmlElement) {
26 | this._htmlComponent = new HTMLComponentBase({
27 | driver: this.driver,
28 | htmlElement
29 | })
30 | }
31 | }
32 |
33 | return this._htmlComponent
34 | }
35 |
36 | get componentType () {
37 | return (this.constructor.name.replace(/.*Component/, '').toLowerCase())
38 | }
39 |
40 | get titleProperties () {
41 | return ['tooltip', 'xtype']
42 | }
43 |
44 | generateSelectors (titleOrSelector) {
45 | return [
46 | `${this.componentType}[tooltip~="${titleOrSelector}"]`,
47 | `${this.componentType}[reference="${titleOrSelector}"]`,
48 | `${this.componentType}[xtype="${titleOrSelector}"]`
49 | ]
50 | }
51 |
52 | getComponent (callback, {callArgs}) {
53 | let selectors = []
54 | let extJsComponent = null
55 | const titleOrSelector = callArgs[0]
56 |
57 | if (titleOrSelector[0] === '#') {
58 | selectors = [titleOrSelector]
59 | } else {
60 | selectors = this.generateSelectors(titleOrSelector)
61 | }
62 |
63 | selectors.every((item) => {
64 | extJsComponent = this.getVisibleComponents(item)[0]
65 | return !extJsComponent
66 | })
67 |
68 | if (!extJsComponent) {
69 | (Ext.ComponentQuery.query(this.componentType) || []).every((item) => {
70 | this.titleProperties.every((prop) => {
71 | let title = item[prop]
72 | const fnName = `get${prop[0].toUpperCase()}${prop.slice(1)}`
73 | if (fnName && item[fnName] && typeof item[fnName] === 'function') {
74 | title = item[fnName]()
75 | }
76 | if ((new RegExp(titleOrSelector, 'g')).test(title)) {
77 | extJsComponent = item
78 | }
79 | return !extJsComponent
80 | })
81 | return !extJsComponent
82 | })
83 | }
84 |
85 | if (!extJsComponent) {
86 | return callback(new Error(`Selector "${selectors.join(', ')}" not found.`))
87 | } else if (!extJsComponent.el || !extJsComponent.el.dom) {
88 | return callback(new Error(`No existing HTML element for selector "${selectors.join(', ')}".`))
89 | }
90 |
91 | // TODO to method
92 | const rect = extJsComponent.el.dom.getBoundingClientRect()
93 | if (rect.left + rect.width < 0 || rect.top + rect.height < 0) {
94 | return callback(new Error(
95 | `No visible HTML element for selector "${selectors.join(', ')}", ` +
96 | `offset: ${rect.left},${rect.top}, size: ${rect.width},${rect.height}.`
97 | ))
98 | }
99 |
100 | this.selectors = selectors
101 | this.extJsComponent = extJsComponent
102 |
103 | return callback(null, this)
104 | }
105 |
106 | // BUG does not work properly
107 | getVisibleComponents (selector) {
108 | try {
109 | return Ext.ComponentQuery.query(selector).filter((item) => {
110 | if (!item.el || !item.el.dom) {
111 | return false
112 | }
113 |
114 | const r = item.el.dom.getBoundingClientRect()
115 | const x = (r.left + r.width / 2)
116 | const y = (r.top + r.height / 2)
117 |
118 | if (!window.document.elementsFromPoint) {
119 | return true
120 | }
121 |
122 | // this.mochaUi.hide()
123 | this.driver.mochaUi.hide()
124 | const visible = (window.document.elementsFromPoint(x, y) || []).filter((dom) => {
125 | return (dom === item.el.dom)
126 | })
127 | // this.mochaUi.show()
128 | this.driver.mochaUi.show()
129 |
130 | return (visible.length > 0)
131 | })
132 | } catch (e) {
133 | throw new Error(`${e}. Selector: ${selector}`)
134 | }
135 | }
136 |
137 | click (callback) {
138 | this.htmlComponent.click((err) => {
139 | if (err) {
140 | return callback(`cannot click on component "${this.componentType}": ${err}`)
141 | } else {
142 | return callback(null)
143 | }
144 | })
145 | }
146 |
147 | fill (callback, value) {
148 | this.click((err) => {
149 | if (!err) {
150 | try {
151 | this.extJsComponent.setValue(value)
152 | err = false
153 | } catch (e) {
154 | err = 'failed to call setValue() method'
155 | }
156 | }
157 |
158 | return callback(err ? new Error(`cannot fill component "${this.componentType}": ${err}`) : null)
159 | })
160 | }
161 |
162 | checkState ({stateFnName, expectedValue, callback}) {
163 | if (!this.extJsComponent[stateFnName]) {
164 | return callback(new Error(`ExtJs component does not have function "${stateFnName}".`))
165 | }
166 |
167 | const result = this.extJsComponent[stateFnName]()
168 |
169 | if (result === expectedValue) {
170 | return callback(null)
171 | } else {
172 | return callback(new Error(
173 | `state of "${this.componentType}" function "${stateFnName}" expected to be "${expectedValue}" ` +
174 | `instead of "${result}"`
175 | ))
176 | }
177 | }
178 |
179 | isEnabled (callback) {
180 | return this.checkState({
181 | stateFnName: 'isDisabled',
182 | expectedValue: false,
183 | callback: callback
184 | })
185 | }
186 |
187 | isDisabled (callback) {
188 | return this.checkState({
189 | stateFnName: 'isDisabled',
190 | expectedValue: true,
191 | callback: callback
192 | })
193 | }
194 |
195 | isVisible (callback) {
196 | return this.checkState({
197 | stateFnName: 'isHidden',
198 | expectedValue: false,
199 | callback: callback
200 | })
201 | }
202 |
203 | isHidden (callback) {
204 | return this.checkState({
205 | stateFnName: 'isHidden',
206 | expectedValue: true,
207 | callback: callback
208 | })
209 | }
210 |
211 | }
212 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/button.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentButton extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['text', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[text~="${titleOrSelector}"]`,
14 | ...super.generateSelectors(titleOrSelector)
15 | ]
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/cellEditor.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {HTMLComponentBase} from '../../html/components/base.js'
4 | import {ExtJsComponentBase} from './base.js'
5 |
6 | export class ExtJsComponentCellEditor extends ExtJsComponentBase {
7 |
8 | getComponent (callback, {callArgs}) {
9 | const rowIndex = callArgs[0]
10 | const colIndex = callArgs[1]
11 | const cmp = this.chain.lastComponent.extJsComponent
12 | let htmlElement = null
13 |
14 | try {
15 | htmlElement = document
16 | .getElementById(cmp.el.id)
17 | .getElementsByClassName('x-grid-item')[rowIndex]
18 | .getElementsByClassName('x-grid-cell')[colIndex]
19 | } catch (e) {
20 | return callback(new Error(
21 | `Failed to find cell element of "${this.componentType}" row:#${rowIndex}, col:#${colIndex}`,
22 | e
23 | ))
24 | }
25 |
26 | new HTMLComponentBase({htmlElement, driver: this.driver}).click((err) => {
27 | if (err) {
28 | return callback(new Error(
29 | `Failed to click on cell element of "${this.componentType}" row: #${rowIndex}, col: #${colIndex}: ${err}`
30 | ))
31 | }
32 |
33 | let fieldElement = null
34 | try {
35 | const editorElements = document.getElementById(cmp.el.id).getElementsByClassName('x-editor')
36 |
37 | // "editorElements.item(i)" doesn't work in PhantonJS
38 | for (let i = 0; i < editorElements.length; i++) {
39 | const editorElement = editorElements[i]
40 | if (this.driver.isVisibleElement(editorElement)) {
41 | fieldElement = editorElement.getElementsByClassName('x-field')[0]
42 | break
43 | }
44 | }
45 |
46 | if (!fieldElement) {
47 | throw new Error('no "x-field" element found')
48 | }
49 | } catch (e) {
50 | return callback(new Error(
51 | `Failed to get editor element of "${this.componentType}" row:#${rowIndex}, col:#${colIndex}: ${e}`
52 | ))
53 | }
54 |
55 | this.selectors = `#${fieldElement.id}`
56 | this.extJsComponent = Ext.ComponentQuery.query(this.selectors)[0]
57 |
58 | if (!this.selectors) {
59 | return callback(new Error(
60 | `Failed to get editor component of "${this.componentType}" row:#${rowIndex}, col:#${colIndex}`
61 | ))
62 | }
63 |
64 | return callback(null, this)
65 | })
66 | }
67 |
68 | select (callback, index = 0) {
69 | this.driver.getComponent(
70 | (err, fieldComponent) => {
71 | if (err) {
72 | return callback(new Error(`Failed to get editor combobox component of "${this.componentType}"`, err))
73 | }
74 |
75 | fieldComponent.select((err) => {
76 | if (err) {
77 | return callback(new Error(`Failed to select editor combobox of "${this.componentType}"`, err))
78 | }
79 |
80 | return callback(null)
81 | }, index)
82 | },
83 | {
84 | type: 'comboBox',
85 | callArgs: [`#${this.extJsComponent.id}`],
86 | chain: this.chain
87 | }
88 | )
89 | }
90 |
91 | fill (callback, value = '') {
92 | this.driver.getComponent(
93 | (err, fieldComponent) => {
94 | if (err) {
95 | return callback(new Error(`Failed to fill editor textfield component of "${this.componentType}"`, err))
96 | }
97 |
98 | fieldComponent.fill((err) => {
99 | if (err) {
100 | return callback(new Error(`Failed to fill editor textfield component of "${this.componentType}"`, err))
101 | }
102 |
103 | return callback(null)
104 | }, value)
105 | },
106 | {
107 | type: 'textField',
108 | callArgs: [`#${this.extJsComponent.id}`],
109 | chain: this.chain
110 | }
111 | )
112 | }
113 |
114 | click (callback) {
115 | this.driver.getComponent(
116 | (err, fieldComponent) => {
117 | if (err) {
118 | return callback(new Error(`Failed to click editor checkbox component of "${this.componentType}"`, err))
119 | }
120 |
121 | fieldComponent.click((err) => {
122 | if (err) {
123 | return callback(new Error(`Failed to click editor checkbox component of "${this.componentType}"`, err))
124 | }
125 |
126 | return callback(null)
127 | })
128 | },
129 | {
130 | type: 'checkBox',
131 | callArgs: [`#${this.extJsComponent.id}`],
132 | chain: this.chain
133 | }
134 | )
135 | }
136 |
137 | }
138 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/checkBox.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentCheckBox extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['fieldLabel', 'boxLabel', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[boxLabel~="${titleOrSelector}"]`,
14 | `${this.componentType}[fieldLabel~="${titleOrSelector}"]`,
15 | ...super.generateSelectors(titleOrSelector)
16 | ]
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/comboBox.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {HTMLComponentBase} from '../../html/components/base.js'
4 | import {ExtJsComponentBase} from './base.js'
5 |
6 | export class ExtJsComponentComboBox extends ExtJsComponentBase {
7 |
8 | get titleProperties () {
9 | return ['fieldLabel', ...super.titleProperties]
10 | }
11 |
12 | generateSelectors (titleOrSelector) {
13 | return [`${this.componentType}[fieldLabel~="${titleOrSelector}"]`, ...super.generateSelectors(titleOrSelector)]
14 | }
15 |
16 | select (callback, index) {
17 | const cmp = this.extJsComponent
18 |
19 | this.click((err) => {
20 | if (err) {
21 | return callback(`cannot select item #${index} in component "${this.componentType}": ${err}`)
22 | }
23 |
24 | // TODO add validation method
25 | if (!cmp || !cmp.picker || !cmp.picker.el || !cmp.picker.el.id) {
26 | return callback(`cannot find picker of component "${this.componentType}"`)
27 | }
28 |
29 | let htmlElement = null
30 |
31 | try {
32 | htmlElement = document
33 | .getElementById(cmp.picker.el.id)
34 | .getElementsByClassName('x-boundlist-item')[index]
35 | } catch (e) {
36 | return callback(`Failed to get element of "${this.componentType}" row #${index}": ${e}`)
37 | }
38 |
39 | new HTMLComponentBase({htmlElement, driver: this.driver}).click((err) => {
40 | return callback(err ? `Failed to click on item #${index} of "${this.componentType}" ": ${err}` : null)
41 | })
42 | })
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/dataview.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {HTMLComponentBase} from '../../html/components/base.js'
4 | import {ExtJsComponentBase} from './base.js'
5 |
6 | export class ExtJsComponentDataView extends ExtJsComponentBase {
7 | select (callback, index) {
8 | const cmp = this.extJsComponent
9 | let htmlElement = null
10 |
11 | try {
12 | htmlElement = document
13 | .getElementById(cmp.el.id)
14 | .getElementsByClassName(cmp.itemCls)[index]
15 | } catch (e) {
16 | return callback(`Failed to get element of "${this.componentType}" index #${index}": ${e}`)
17 | }
18 |
19 | new HTMLComponentBase({htmlElement, driver: this.driver}).click((err) => {
20 | return callback(err ? `Failed to click on item index #${index} of "${this.componentType}" ": ${err}` : null)
21 | })
22 | }
23 | }
24 |
25 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/grid.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {HTMLComponentBase} from '../../html/components/base.js'
4 | import {ExtJsComponentBase} from './base.js'
5 |
6 | export class ExtJsComponentGrid extends ExtJsComponentBase {
7 |
8 | get titleProperties () {
9 | return ['title', ...super.titleProperties]
10 | }
11 |
12 | generateSelectors (titleOrSelector) {
13 | return [`${this.componentType}[text~="${titleOrSelector}"]`, ...super.generateSelectors(titleOrSelector)]
14 | }
15 |
16 | select (callback, rowIndex = 0, colIndex = 0) {
17 | const cmp = this.extJsComponent
18 | let htmlElement = null
19 |
20 | try {
21 | htmlElement = document
22 | .getElementById(cmp.el.id)
23 | .getElementsByClassName('x-grid-item')[rowIndex]
24 | .getElementsByClassName('x-grid-cell')[colIndex]
25 | } catch (e) {
26 | return callback(`Failed to get element of "${this.componentType}" row #${rowIndex}": ${e}`)
27 | }
28 |
29 | new HTMLComponentBase({htmlElement, driver: this.driver}).click((err) => {
30 | return callback(err ? `Failed to click on item row #${rowIndex} of "${this.componentType}" ": ${err}` : null)
31 | })
32 | }
33 |
34 | checkRowsCount (callback, countExpected) {
35 | const cmp = this.extJsComponent
36 |
37 | if (!cmp.getStore || !cmp.getStore()) {
38 | return callback(`No store binded to "${this.componentType}" (${this.selectors}).`)
39 | }
40 |
41 | const count = cmp.getStore().getCount()
42 |
43 | if (count === countExpected) {
44 | return callback(null)
45 | } else {
46 | return callback(
47 | `No store binded to "${this.componentType}" (selectors: ${this.selectors}):` +
48 | ` count of rows expected to be equal "${countExpected}" instead of "${count}".`
49 | )
50 | }
51 | }
52 |
53 | clickAction (callback, rowIndex = 0, colIndex = 0, actionIndex = 0) {
54 | const cmp = this.extJsComponent
55 | let htmlElement = null
56 |
57 | try {
58 | htmlElement = document
59 | .getElementById(cmp.el.id)
60 | .getElementsByClassName('x-grid-item')[rowIndex]
61 | .getElementsByClassName('x-grid-cell')[colIndex]
62 | .getElementsByClassName('x-action-col-icon')[actionIndex]
63 | } catch (e) {
64 | return callback(`Failed to get element of "${this.componentType}" row #${rowIndex}": ${e}`)
65 | }
66 |
67 | new HTMLComponentBase({htmlElement, driver: this.driver}).click((err) => {
68 | return callback(err ? `Failed to click on action item in row #${rowIndex} of "${this.componentType}" ": ${err}` : null)
69 | })
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/numberField.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentNumberField extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['fieldLabel', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[fieldLabel~="${titleOrSelector}"]`,
14 | ...super.generateSelectors(titleOrSelector)
15 | ]
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/radio.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentRadio extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['fieldLabel', 'boxLabel', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[boxLabel~="${titleOrSelector}"]`,
14 | `${this.componentType}[fieldLabel~="${titleOrSelector}"]`,
15 | ...super.generateSelectors(titleOrSelector)
16 | ]
17 | }
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/tab.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentTab extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['title', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[title~="${titleOrSelector}"]`,
14 | ...super.generateSelectors(titleOrSelector)
15 | ]
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/textField.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentTextField extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['fieldLabel', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[fieldLabel~="${titleOrSelector}"]`,
14 | ...super.generateSelectors(titleOrSelector)
15 | ]
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/drivers/extjs/components/window.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {ExtJsComponentBase} from './base.js'
4 |
5 | export class ExtJsComponentWindow extends ExtJsComponentBase {
6 |
7 | get titleProperties () {
8 | return ['title', ...super.titleProperties]
9 | }
10 |
11 | generateSelectors (titleOrSelector) {
12 | return [
13 | `${this.componentType}[text~="${titleOrSelector}"]`,
14 | ...super.generateSelectors(titleOrSelector)
15 | ]
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/src/drivers/extjs/driver.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {waitForFn} from '../../utils/utils.js'
4 |
5 | import {ExtJsComponentTab} from './components/tab.js'
6 | import {ExtJsComponentGrid} from './components/grid.js'
7 | import {ExtJsComponentDataView} from './components/dataview.js'
8 | import {ExtJsComponentRadio} from './components/radio.js'
9 | import {ExtJsComponentButton} from './components/button.js'
10 | import {ExtJsComponentWindow} from './components/window.js'
11 | import {ExtJsComponentCheckBox} from './components/checkBox.js'
12 | import {ExtJsComponentComboBox} from './components/comboBox.js'
13 | import {ExtJsComponentTextField} from './components/textField.js'
14 | import {ExtJsComponentCellEditor} from './components/cellEditor.js'
15 | import {ExtJsComponentNumberField} from './components/numberField.js'
16 |
17 | export class ExtJsDriver {
18 |
19 | constructor ({mochaUi}) {
20 | if (!mochaUi) {
21 | throw new Error(`Class ${this.constructor.name} created with undefined property "mochaUi".`)
22 | }
23 |
24 | this.mochaUi = mochaUi
25 | }
26 |
27 | get supportedComponents () {
28 | return [
29 | 'tab', 'grid', 'radio', 'button', 'window', 'checkBox', 'comboBox', 'textField', 'numberField',
30 | 'cellEditor', 'dataview'
31 | ]
32 | }
33 |
34 | get supportedComponentActions () {
35 | return [
36 | 'click', 'fill', 'select', 'isEnabled', 'isDisabled', 'isHidden', 'isVisible', 'checkRowsCount', 'edit', 'clickAction'
37 | ]
38 | }
39 |
40 | get supportedActions () {
41 | return [
42 | 'waitText', 'waitLoadMask'
43 | ]
44 | }
45 |
46 | getComponent (callback, {type, callArgs, chain}) {
47 | let componentObject = null
48 | const properties = {
49 | driver: this,
50 | chain: chain
51 | }
52 |
53 | if (type === 'tab') {
54 | componentObject = new ExtJsComponentTab(properties)
55 | } else if (type === 'grid') {
56 | componentObject = new ExtJsComponentGrid(properties)
57 | } else if (type === 'radio') {
58 | componentObject = new ExtJsComponentRadio(properties)
59 | } else if (type === 'button') {
60 | componentObject = new ExtJsComponentButton(properties)
61 | } else if (type === 'window') {
62 | componentObject = new ExtJsComponentWindow(properties)
63 | } else if (type === 'checkBox') {
64 | componentObject = new ExtJsComponentCheckBox(properties)
65 | } else if (type === 'comboBox') {
66 | componentObject = new ExtJsComponentComboBox(properties)
67 | } else if (type === 'textField') {
68 | componentObject = new ExtJsComponentTextField(properties)
69 | } else if (type === 'cellEditor') {
70 | componentObject = new ExtJsComponentCellEditor(properties)
71 | } else if (type === 'numberField') {
72 | componentObject = new ExtJsComponentNumberField(properties)
73 | } else if (type === 'dataview') {
74 | componentObject = new ExtJsComponentDataView(properties)
75 | }
76 |
77 | if (!componentObject) {
78 | return callback(new Error(`Type "${type}" is not supported by driver`))
79 | }
80 |
81 | return componentObject.getComponent(callback, {callArgs})
82 | }
83 |
84 | isVisibleElement (element) {
85 | const style = window.getComputedStyle(element)
86 | return (
87 | Boolean(style) &&
88 | (typeof style.opacity === 'undefined' || style.opacity !== 0) &&
89 | (typeof style.display === 'undefined' || style.display !== 'none') &&
90 | (typeof style.visibility === 'undefined' || style.visibility !== 'hidden')
91 | )
92 | }
93 |
94 | waitLoadMask (callback) {
95 | return waitForFn(
96 | (done) => {
97 | const maskDisplayed = Ext.ComponentManager.getAll()
98 | .filter((item) => {
99 | return (item.xtype === 'loadmask' && item.isHidden() === false)
100 | }).length > 0
101 |
102 | if (maskDisplayed) {
103 | done('Load mask is still presented.')
104 | } else {
105 | // LoadMask need sone time to be hidden
106 | setTimeout(() => {
107 | done(null)
108 | }, 500)
109 | }
110 | },
111 | callback,
112 | {
113 | delay: 500 // wait load mask display delay
114 | }
115 | )
116 | }
117 |
118 | waitText (callback, text) {
119 | // TODO check parent
120 | return waitForFn(
121 | (done) => {
122 | let textPresented = false
123 |
124 | if (text instanceof RegExp) {
125 | textPresented = text.test(window.document.body.innerText)
126 | } else if (window.find) {
127 | textPresented = window.find(text, true, true, true) // arg aWholeWord - Unimplemented
128 | } else {
129 | textPresented = (new RegExp(text, 'g')).test(window.document.body.innerText)
130 | }
131 |
132 | done(textPresented ? null : `Text pattern "${text}" not found on page.`)
133 | },
134 | callback
135 | )
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/src/drivers/html/components/base.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export class HTMLComponentBase {
4 |
5 | constructor ({htmlElement, driver}) {
6 | this.driver = driver
7 | this.htmlElement = htmlElement
8 | }
9 |
10 | click (callback) {
11 | const el = this.htmlElement
12 |
13 | // for PhantomJs:
14 | // ./node_modules/mocha-phantomjs/node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js:116
15 | // add "page.sendEvent.apply(this, data.sendEvent)"
16 | //
17 | const rect = el.getBoundingClientRect()
18 | const x = Math.round(rect.left + rect.width / 2)
19 | const y = Math.round(rect.top + rect.height / 2)
20 |
21 | this.driver.mochaUi.cursor.moveTo(x + 1, y + 1, () => {
22 | let err
23 |
24 | this.driver.mochaUi.hide()
25 |
26 | // BUG hide cellEditor in PhantomJs
27 | // if (el.focus) {
28 | // el.focus()
29 | // }
30 |
31 | if (el.scrollIntoView) {
32 | el.scrollIntoView()
33 | }
34 |
35 | if (window.callPhantom) {
36 | window.callPhantom({sendEvent: ['mousemove', x - 1, y - 1]})
37 | window.callPhantom({sendEvent: ['mousemove', x, y]})
38 | err = !window.callPhantom({sendEvent: ['click', x, y]})
39 | } else {
40 | try {
41 | window.document.elementFromPoint(x, y).click()
42 | err = false
43 | } catch (e) {
44 | err = `[${x},${y}] (${e})`
45 | }
46 | }
47 |
48 | this.driver.mochaUi.show()
49 |
50 | return callback(err ? `cannot click on "${el.id}" ${err}` : null)
51 | })
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/src/mochaUI.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import {Cursor} from './mochaUi/cursor.js'
4 |
5 | export class MochaUI {
6 |
7 | constructor () {
8 | this.cursor = new Cursor()
9 | }
10 |
11 | get mochaElement () {
12 | return window.document.getElementById('mocha')
13 | }
14 |
15 | show () {
16 | if (this.mochaElement) {
17 | this.mochaElement.style.display = 'block'
18 | }
19 |
20 | this.cursor.show()
21 | }
22 |
23 | hide () {
24 | if (this.mochaElement) {
25 | this.mochaElement.style.display = 'none'
26 | }
27 |
28 | this.cursor.hide()
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/mochaUi/cursor.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export class Cursor {
4 |
5 | constructor () {
6 | this._size = 14
7 | this._timeout = 400
8 | this._initTransition = `all ${this._timeout}ms ease-in-out`
9 | this._position = {
10 | x: 0,
11 | y: 0
12 | }
13 |
14 | this._point = window.document.getElementById('mocha-extjs-testing-tool-pointer')
15 |
16 | if (!this._point) {
17 | this._point = document.createElement('div')
18 |
19 | this._point.id = 'mocha-extjs-testing-tool-pointer'
20 | this._point.style.top = `${this._position.y}px`
21 | this._point.style.left = `${this._position.x}px`
22 | this._point.style.width = `${this._size}px`
23 | this._point.style.zIndex = '90000'
24 | this._point.style.height = `${this._size}px`
25 | this._point.style.border = '2px solid #ffffff'
26 | this._point.style.opacity = '1'
27 | this._point.style.position = 'absolute'
28 | this._point.style.transition = this._initTransition
29 | this._point.style.borderRadius = `0 ${this._size / 2}px ${this._size / 2}px ${this._size / 2}px`
30 | this._point.style.backgroundColor = '#ee3300'
31 |
32 | window.document.body.appendChild(this._point)
33 | }
34 | }
35 |
36 | moveTo (x, y, callback) {
37 | if (window.callPhantom) {
38 | this._point.style.left = `${x}px`
39 | this._point.style.top = `${y}px`
40 | return callback(null)
41 | } else {
42 | const translate = `translate(${x}px, ${y}px)`
43 | this._point.style.transform = translate
44 | setTimeout(() => {
45 | this._point.style.transition = 'all 50ms ease-in-out'
46 | this._point.style.transform = `${translate} scale(0.5)`
47 | setTimeout(() => {
48 | this._point.style.transform = `${translate} scale(1)`
49 | setTimeout(() => {
50 | this._point.style.transition = this._initTransition
51 | return callback(null)
52 | }, 50)
53 | }, 50)
54 | }, this._timeout)
55 | }
56 | }
57 |
58 | hide () {
59 | this._point.style.display = 'none'
60 | }
61 |
62 | show () {
63 | this._point.style.display = 'block'
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/utils/set.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export class Set {
4 |
5 | constructor () {
6 | this._items = []
7 | }
8 |
9 | push (component) {
10 | this._items.push(component)
11 | }
12 |
13 | * items () {
14 | for (let item of this._items) {
15 | yield item
16 | }
17 | }
18 |
19 | * reversedItems () {
20 | for (let i = this._items.length - 1; i >= 0; i--) {
21 | yield this._items[i]
22 | }
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/utils/utils.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | export function waitForFn (waitFn, callback,
4 | {delay, timeout, ticInterval} = {delay: 10, timeout: 10 * 1000, ticInterval: 500}) {
5 | const startTimestamp = +(new Date())
6 | let interval
7 | let lastError = ''
8 | let exectution = false
9 |
10 | const intervalFn = () => {
11 | if ((+new Date() - startTimestamp) > timeout) {
12 | exectution = false
13 | clearInterval(interval)
14 | return callback(`Out of time: ${timeout / 1000}s (${lastError})`)
15 | }
16 |
17 | if (!exectution) {
18 | try {
19 | exectution = true
20 | waitFn((err, result) => {
21 | if (!exectution) {
22 | console.warn('waitForFn(): Operation finished after time out.')
23 | return
24 | }
25 | exectution = false
26 | if (err) {
27 | lastError = err
28 | } else {
29 | clearInterval(interval)
30 | return callback(null, result)
31 | }
32 | })
33 | } catch (e) {
34 | exectution = false
35 | throw e
36 | }
37 | }
38 | }
39 |
40 | setTimeout(() => {
41 | interval = setInterval(intervalFn, ticInterval)
42 | intervalFn()
43 | }, delay)
44 | }
45 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/.cvsignore:
--------------------------------------------------------------------------------
1 | /temp/
--------------------------------------------------------------------------------
/test/sandbox/.sencha/.gitignore:
--------------------------------------------------------------------------------
1 | /temp/
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/bootstrap-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 | @{launchcode}
33 |
34 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/build.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in these
3 | # lower priority files:
4 | #
5 | # - ext.properties
6 | # - *.defaults.properties
7 | # - defaults.properties
8 | #
9 | # To override a property based on build.environment instead add properties to
10 | # one of these higher priority files:
11 | #
12 | # - production.properties
13 | # - testing.properties
14 | # - native.properties
15 | # - package.properties
16 | #
17 | # IMPORTANT - Sencha Cmd will merge your changes with its own during upgrades.
18 | # To avoid potential merge conflicts avoid making large, sweeping changes to
19 | # this file.
20 | # =============================================================================
21 |
22 | skip.slice=1
23 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/codegen.json:
--------------------------------------------------------------------------------
1 | {
2 | "sources": {
3 | "build.properties.merge": {
4 | "d4613dc19be3ddb60e7ff5716e28c8b15d954f3a": "eJytUstOw0AMvPMVI/WGoB+AxAFx4sBD0B9ws05idbOOdp2E/j1OH6pEEKfuzR57POP1Co/XfDcrbFopqCUy+qyjBC6gBB05Zw/QqyRDrRmBaxqiYaQstI1e5xlJHCAJ1nJhZ4s6cXYm0Sy2P/CWh5uVI8A9+NvWPqXnbMLllLxdn5jLEvsTmUXrRSHhBO6xpeJyNGE7SAxrTqNkTR27A0nFmAIoBFzIYOpsmhhaHz2glab9x4L3hqEy0bRUa1xMUrMEEpmMvMz3VO2o4d/uXl4/3j83T28bL/niVLWE5y5gkhjRcW4Yex0yPJ8a9zCJtRAr0CkhDNklYOibTP6X6+OyaFRx32q+CqEzS6WpjlJ55xHvaDf3RnLwDmVi7uf4POewKzufy8x83Vv8AQy16fs\u003d"
5 | },
6 | "development.properties.merge": {
7 | "c45c602c9b6f6f73cace183e9f0bf09c00a3ccf6": "eJytkUuOAjEMBfec4one9w24wyy4QFDc0xbBjhyTEbcfp0F89mRny6l6liccvvl2E44rNyxcCNW0c6aGJNBOZlGgKotjUUOmJV2LoyfjdCoxFx0WymBBgJyas/zOj7k2B6+SOVObw0JtMzw6SEZQKTfwpap5UP5WEpyuXHJQgjecvhL2mToVrRcS34Oks6mMYt5NMfbzYr7l8edWns5DzGrst22vu+QtXjR8BAraFqloyoEZAT7l28cW3i9f4R+b7pUs"
8 | },
9 | "native.properties.merge": {
10 | "2c8c063f9588eecff09624782d7369a8a000d61c": "eJytkEsOwjAMRPecYkT3vQF3YMEFguJSi2BXjgni9rgfFQ5AdrEm743T4fTPc+hwGbli4EKYTBtnqkgCbWQWF0zK4hjUkGlIz+JoyThdS+RiwkIZLAiQJOdG/RarfeAmMmeqfUioLoJtgmQElfIGPyY1D8hrJMH1ySWz3AI3K30kHFfuESSNTeVB4v2hi8T5i/tp4vs+nu6zk9XY38tGK/+nWQx87hK0pU3RlAMzu3fv8qaG8s9f/wFV3ZB9"
11 | },
12 | "package.properties.merge": {
13 | "c6c1fb2fb1dda28480ad0f6e5caffc9b97d196ae": "eJytkUFygzAMRfc5hSZsOxygM11223aRCwgsQBNH8tiCTG5fGWjDAcLOsnjvS27g45XfqYHLxAUGjgQp68KBCqCALpSzHyApi8GgGQINOEeDBTNjF73PKywUgAUclLC/4kjt3lda5yXKxlRat1BZDXsFMBOoxAfwLWk2p9wnEuhmjoFldF512kRw3sFnIFk4q9xIrD013vLz5B2y2P9EhtcqZc1sj3WmTXCI5gWrYZy2xomKwTFV/hSvP5XN+fV9+Xzftjb7SDoc+jClWJmmIGi80N9SwnbVe1HlDUTdWfNvt1togpGEMkYoLP1K7tVfIHKXfeVU/S9+/V9rlbyW"
14 | },
15 | "production.properties.merge": {
16 | "cbdf9712e9b5d37cecb4d0530ba1fccd0ed004a3": "eJytkUEOwjAMBO+8YkXv/QF/4MAHAnGpRbArxy3i97gFQbk3t6ycmbXS4LDl2TU49VzRcSEMphNnqkgCncgsLhiUxdGpIVOXxuKYknE6l5iLhIUyWBCgeJ7Hi7NK+xmtbWQDmTPVNkRUF8knQTKCSnmC74OaB+jRk+A8csks10DOWu8J+x97D5KJTeVO4u2uianjD7lq5N+9PN1mL6uxP5fN3o5Vuwh87hO0pVHRlAMz+//cy7sa2o2/4QV6LJW9"
17 | },
18 | "sencha.cfg.tpl.merge": {
19 | "37e77998d0cc69cbe4c0c2d4481f2e6c43b55a8f": "eJytkMENwkAMBP9XxUp5Qwe8aIAWzMUhli7nk+0Qheq5gOgAf/xY72rHA2IWRzNtbLHDG2eZhB2ErMtCcG5kFDyiiAd0QqOYvas1SKrURxpg7Lpa7rbQrrT92DEz7quUEaMY51DbE7V2/h2fP0GXlIbLX6f3ua4euuD2xTpwTrgVyoz8UeRFIVoddy66fX9QpPJRm54qIxa2B/ekjjkVyeHYJGZU3tjwZPPDnt66VmnK"
20 | },
21 | "testing.properties.merge": {
22 | "360e715956c81757e53736789fe20be045acb544": "eJytkMENwjAMRe+d4oveuwE7cGCBoLjUItiVY4q6PW6pKAM0t1g/732nxfnI07S4DlzRcyGMphNnqkgCncgsLhiVxdGrIVOfXsUxJeN0K5GLCQtlsCBATtVZ7t2Wq13wRjJnql1YqK6GbYJkBJUyg5+jmgflPZDg9uKSgxK8xekD4bSBTyCZ2FSeJN41bUQuO++vi/828vRYpKzGPq87fQV/1WLgS5mgrXWKphyYRb6L10c1nAf//gdqIpHi"
23 | },
24 | "config.rb.tpl.merge": {
25 | "33f446bd02c3fd24eb27891582eff6a2e789796b": "eJxLLi2KT8ksUrBVcMvMSdUDMvMSc1M14uPdPH1c4+M1ufJLSwpKS+KLSypzUoGqrPJSi0tSU7gALskTcA\u003d\u003d"
26 | }
27 | },
28 | "targets": {
29 | ".sencha/app/build.properties": {
30 | "source": "build.properties.merge",
31 | "version": "d4613dc19be3ddb60e7ff5716e28c8b15d954f3a",
32 | "parameters": {
33 | "appControllers": "",
34 | "appModels": "",
35 | "appName": "Sandbox",
36 | "appStores": "",
37 | "appViews": "",
38 | "classic": false,
39 | "controllerFileName": "Main",
40 | "controllerName": "Main",
41 | "controllerNamespace": "Sandbox.controller",
42 | "frameworkKey": "ext",
43 | "frameworkName": "ext",
44 | "frameworkPath": "ext",
45 | "modelNamespace": "Sandbox.model",
46 | "modern": false,
47 | "name": "Sandbox",
48 | "packagesRelPath": "ext/packages/",
49 | "senchadir": ".sencha",
50 | "themeName": "default",
51 | "toolkit": "",
52 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
53 | "universal": true,
54 | "viewFileName": "Main",
55 | "viewName": "Main",
56 | "viewNamespace": "Sandbox.view"
57 | }
58 | },
59 | ".sencha/app/development.properties": {
60 | "source": "development.properties.merge",
61 | "version": "c45c602c9b6f6f73cace183e9f0bf09c00a3ccf6",
62 | "parameters": {
63 | "appControllers": "",
64 | "appModels": "",
65 | "appName": "Sandbox",
66 | "appStores": "",
67 | "appViews": "",
68 | "classic": false,
69 | "controllerFileName": "Main",
70 | "controllerName": "Main",
71 | "controllerNamespace": "Sandbox.controller",
72 | "frameworkKey": "ext",
73 | "frameworkName": "ext",
74 | "frameworkPath": "ext",
75 | "modelNamespace": "Sandbox.model",
76 | "modern": false,
77 | "name": "Sandbox",
78 | "packagesRelPath": "ext/packages/",
79 | "senchadir": ".sencha",
80 | "themeName": "default",
81 | "toolkit": "",
82 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
83 | "universal": true,
84 | "viewFileName": "Main",
85 | "viewName": "Main",
86 | "viewNamespace": "Sandbox.view"
87 | }
88 | },
89 | ".sencha/app/native.properties": {
90 | "source": "native.properties.merge",
91 | "version": "2c8c063f9588eecff09624782d7369a8a000d61c",
92 | "parameters": {
93 | "appControllers": "",
94 | "appModels": "",
95 | "appName": "Sandbox",
96 | "appStores": "",
97 | "appViews": "",
98 | "classic": false,
99 | "controllerFileName": "Main",
100 | "controllerName": "Main",
101 | "controllerNamespace": "Sandbox.controller",
102 | "frameworkKey": "ext",
103 | "frameworkName": "ext",
104 | "frameworkPath": "ext",
105 | "modelNamespace": "Sandbox.model",
106 | "modern": false,
107 | "name": "Sandbox",
108 | "packagesRelPath": "ext/packages/",
109 | "senchadir": ".sencha",
110 | "themeName": "default",
111 | "toolkit": "",
112 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
113 | "universal": true,
114 | "viewFileName": "Main",
115 | "viewName": "Main",
116 | "viewNamespace": "Sandbox.view"
117 | }
118 | },
119 | ".sencha/app/package.properties": {
120 | "source": "package.properties.merge",
121 | "version": "c6c1fb2fb1dda28480ad0f6e5caffc9b97d196ae",
122 | "parameters": {
123 | "appControllers": "",
124 | "appModels": "",
125 | "appName": "Sandbox",
126 | "appStores": "",
127 | "appViews": "",
128 | "classic": false,
129 | "controllerFileName": "Main",
130 | "controllerName": "Main",
131 | "controllerNamespace": "Sandbox.controller",
132 | "frameworkKey": "ext",
133 | "frameworkName": "ext",
134 | "frameworkPath": "ext",
135 | "modelNamespace": "Sandbox.model",
136 | "modern": false,
137 | "name": "Sandbox",
138 | "packagesRelPath": "ext/packages/",
139 | "senchadir": ".sencha",
140 | "themeName": "default",
141 | "toolkit": "",
142 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
143 | "universal": true,
144 | "viewFileName": "Main",
145 | "viewName": "Main",
146 | "viewNamespace": "Sandbox.view"
147 | }
148 | },
149 | ".sencha/app/production.properties": {
150 | "source": "production.properties.merge",
151 | "version": "cbdf9712e9b5d37cecb4d0530ba1fccd0ed004a3",
152 | "parameters": {
153 | "appControllers": "",
154 | "appModels": "",
155 | "appName": "Sandbox",
156 | "appStores": "",
157 | "appViews": "",
158 | "classic": false,
159 | "controllerFileName": "Main",
160 | "controllerName": "Main",
161 | "controllerNamespace": "Sandbox.controller",
162 | "frameworkKey": "ext",
163 | "frameworkName": "ext",
164 | "frameworkPath": "ext",
165 | "modelNamespace": "Sandbox.model",
166 | "modern": false,
167 | "name": "Sandbox",
168 | "packagesRelPath": "ext/packages/",
169 | "senchadir": ".sencha",
170 | "themeName": "default",
171 | "toolkit": "",
172 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
173 | "universal": true,
174 | "viewFileName": "Main",
175 | "viewName": "Main",
176 | "viewNamespace": "Sandbox.view"
177 | }
178 | },
179 | ".sencha/app/sencha.cfg": {
180 | "source": "sencha.cfg.tpl.merge",
181 | "version": "37e77998d0cc69cbe4c0c2d4481f2e6c43b55a8f",
182 | "parameters": {
183 | "appControllers": "",
184 | "appModels": "",
185 | "appName": "Sandbox",
186 | "appStores": "",
187 | "appViews": "",
188 | "classic": false,
189 | "controllerFileName": "Main",
190 | "controllerName": "Main",
191 | "controllerNamespace": "Sandbox.controller",
192 | "frameworkKey": "ext",
193 | "frameworkName": "ext",
194 | "frameworkPath": "ext",
195 | "modelNamespace": "Sandbox.model",
196 | "modern": false,
197 | "name": "Sandbox",
198 | "packagesRelPath": "ext/packages/",
199 | "senchadir": ".sencha",
200 | "themeName": "default",
201 | "toolkit": "",
202 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
203 | "universal": true,
204 | "viewFileName": "Main",
205 | "viewName": "Main",
206 | "viewNamespace": "Sandbox.view"
207 | }
208 | },
209 | ".sencha/app/testing.properties": {
210 | "source": "testing.properties.merge",
211 | "version": "360e715956c81757e53736789fe20be045acb544",
212 | "parameters": {
213 | "appControllers": "",
214 | "appModels": "",
215 | "appName": "Sandbox",
216 | "appStores": "",
217 | "appViews": "",
218 | "classic": false,
219 | "controllerFileName": "Main",
220 | "controllerName": "Main",
221 | "controllerNamespace": "Sandbox.controller",
222 | "frameworkKey": "ext",
223 | "frameworkName": "ext",
224 | "frameworkPath": "ext",
225 | "modelNamespace": "Sandbox.model",
226 | "modern": false,
227 | "name": "Sandbox",
228 | "packagesRelPath": "ext/packages/",
229 | "senchadir": ".sencha",
230 | "themeName": "default",
231 | "toolkit": "",
232 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
233 | "universal": true,
234 | "viewFileName": "Main",
235 | "viewName": "Main",
236 | "viewNamespace": "Sandbox.view"
237 | }
238 | },
239 | "sass/config.rb": {
240 | "source": "config.rb.tpl.merge",
241 | "version": "33f446bd02c3fd24eb27891582eff6a2e789796b",
242 | "parameters": {
243 | "appControllers": "",
244 | "appModels": "",
245 | "appName": "Sandbox",
246 | "appStores": "",
247 | "appViews": "",
248 | "classic": false,
249 | "controllerFileName": "Main",
250 | "controllerName": "Main",
251 | "controllerNamespace": "Sandbox.controller",
252 | "frameworkKey": "ext",
253 | "frameworkName": "ext",
254 | "frameworkPath": "ext",
255 | "modelNamespace": "Sandbox.model",
256 | "modern": false,
257 | "name": "Sandbox",
258 | "packagesRelPath": "ext/packages/",
259 | "senchadir": ".sencha",
260 | "themeName": "default",
261 | "toolkit": "",
262 | "uniqueId": "2afda357-f450-492c-a287-79bdcccf29b1",
263 | "universal": true,
264 | "viewFileName": "Main",
265 | "viewName": "Main",
266 | "viewNamespace": "Sandbox.view"
267 | }
268 | }
269 | }
270 | }
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/cordova-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | cordova ${cordova.cli.options} create "${app.cordova.config.path}" ${app.cordova.config.id} "${app.cordova.config.name}"
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | cordova ${cordova.cli.options} prepare ${cordova.platforms.clean}
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | cordova ${cordova.cli.options} emulate ${cordova.platforms.clean} --target=${app.cordova.config.target}
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | cordova ${cordova.cli.options} run ${cordova.platforms.clean} --target=${app.cordova.config.target}
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | cordova ${cordova.cli.options} build ${cordova.platforms.clean}
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
108 |
109 |
110 | cordova ${cordova.cli.options} platform list
111 |
112 |
113 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | cordova ${cordova.cli.options} platform add ${cordova.platforms.missing}
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/cordova.defaults.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2012-2014. Sencha Inc.
3 | #
4 |
5 | # Legacy support here for old build workflow.
6 | cordova.platforms=${app.cordova.config.platforms}
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/development.defaults.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to the "development" build
3 | # environment.
4 | #
5 | # Please use testing.properties to customize these properties unless you want
6 | # your customizations to be for all environments. In that case, you can instead
7 | # override these properties in build.properties.
8 | #
9 | # The properties defined in this file take priority over defaults.properties
10 | # but are lower priority than build.properties which in turn is lower priority
11 | # than development.properties.
12 | #
13 | # IMPORTANT - This file should not be modified by an app as it is overwritten
14 | # during each app upgrade.
15 | # =============================================================================
16 |
17 | build.options.logger=yes
18 |
19 | build.options.debug=true
20 |
21 | build.css.compress=false
22 |
23 | build.include.all.scss=true
24 |
25 | # By default we don't need to build an "all.js" file, or a new markup page or
26 | # slice images for IE8/9. These can be added to "development.properties" and
27 | # set to 0 to enable them if needed.
28 | skip.page=1
29 | skip.js=1
30 | skip.slice=1
31 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/development.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in
3 | # testing.defaults.properties. These properties are only imported when building
4 | # for the "development" environment.
5 | #
6 | # Properties defined in this file take priority over build.properties but are
7 | # only loaded for "development" builds.
8 | # =============================================================================
9 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/ext.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to all builds based on
3 | # Ext JS 5.x framework.
4 | #
5 | # Please use build.properties to customize these properties.
6 | #
7 | # To override a property based on build.environment instead add properties to
8 | # one of these higher priority files:
9 | #
10 | # - production.properties
11 | # - testing.properties
12 | # - native.properties
13 | # - package.properties
14 | #
15 | # The properties defined in this file take priority over defaults.properties
16 | # and *.defaults.properties.
17 | #
18 | # IMPORTANT - This file should not be modified by an app as it is overwritten
19 | # during each app upgrade.
20 | # =============================================================================
21 |
22 | enable.ext42.themes=true
23 |
24 | enable.sencha-core.filter=true
25 |
26 | build.options.product=ext
27 |
28 | build.options.minVersion=5
29 |
30 | bootstrap.include.boot=true
31 | bootstrap.override.tpl=Ext.Loader.loadScriptsSync
32 | bootstrap.override.tpltype=jsonp
33 |
34 | app.microloader.name=Microloader.js
35 | app.microloader.dir=${app.config.dir}
36 | app.microloader.bootstrap=${app.microloader.dir}/${app.microloader.name}
37 | app.microloader.path=${app.microloader.dir}/${app.microloader.name}
38 |
39 | build.microloader.json.tpl.embedded=var Ext = Ext || '{' '}'; Ext.manifest = Ext.manifest || {0};
40 | build.microloader.manifest.name=${app.manifest.name}
41 | build.microloader.json.tpl.external=var Ext = Ext || '{' '}'; Ext.manifest = Ext.manifest || "${build.microloader.manifest.name}";
42 |
43 | build.skip.versions.file=true
44 | build.enable.appmanifest=true
45 | compass.compile.force=false
46 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/find-cmd-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
27 |
28 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
50 |
51 |
52 | source ~/.bash_profile; sencha which -p cmd.dir -o '$cmddir$'
53 |
54 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/js-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
27 |
80 |
81 |
82 |
83 |
84 |
100 |
101 |
102 |
103 |
104 |
105 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/native.defaults.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to the "native" build
3 | # environment.
4 | #
5 | # Please use native.properties to customize these properties unless you want
6 | # your customizations to be for all environments. In that case, you can instead
7 | # override these properties in build.properties.
8 | #
9 | # The properties defined in this file take priority over defaults.properties
10 | # but are lower priority than build.properties which in turn is lower priority
11 | # than native.properties.
12 | #
13 | # IMPORTANT - This file should not be modified by an app as it is overwritten
14 | # during each app upgrade.
15 | # =============================================================================
16 |
17 | build.options.logger=no
18 |
19 | build.options.debug=false
20 |
21 | # enable yui compression
22 | build.compression.yui=1
23 |
24 | enable.standalone.manifest=true
25 |
26 | app.microloader.name=testing.js
27 |
28 | skip.native-package=false
29 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/native.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in
3 | # native.defaults.properties. These properties are only imported when building
4 | # for the "native" environment.
5 | #
6 | # Properties defined in this file take priority over build.properties but are
7 | # only loaded for "native" builds.
8 | # =============================================================================
9 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/package.defaults.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to the "package" build
3 | # environment.
4 | #
5 | # Please use package.properties to customize these properties unless you want
6 | # your customizations to be for all environments. In that case, you can instead
7 | # override these properties in build.properties.
8 | #
9 | # The properties defined in this file take priority over defaults.properties
10 | # but are lower priority than build.properties which in turn is lower priority
11 | # than package.properties.
12 | #
13 | # IMPORTANT - This file should not be modified by an app as it is overwritten
14 | # during each app upgrade.
15 | #
16 | # NOTE: This use of "package" applies to native packaged application, not a
17 | # Package in the general since of code libraries.
18 | # =============================================================================
19 |
20 | build.options.logger=no
21 |
22 | build.options.debug=false
23 |
24 | # enable yui compression
25 | build.compression.yui=1
26 |
27 | app.microloader.name=testing.js
28 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/package.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in
3 | # package.defaults.properties. These properties are only imported when building
4 | # for the "package" environment.
5 | #
6 | # Properties defined in this file take priority over build.properties but are
7 | # only loaded for "package" builds.
8 | #
9 | # NOTE: This use of "package" applies to native packaged application, not a
10 | # Package in the general since of code libraries.
11 | # =============================================================================
12 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/packager-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/page-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
72 |
73 |
74 |
75 |
76 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
130 |
131 |
132 |
133 |
134 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
298 |
299 |
302 |
303 |
304 |
305 |
308 |
309 |
310 |
311 |
316 |
317 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/phonegap-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | phonegap ${phonegap.cli.options} create "${app.phonegap.config.path}" ${app.phonegap.config.id} ${app.phonegap.config.name}
47 |
48 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | Phonegap Build login credentials were was not found. If you have not logged in prior to running this command.
151 | Please either login via "phonegap remote login" or edit your [APP_ROOT]/local.properties and set "phonegap.username" and "phonegap.password" appropriately
152 |
153 |
154 |
155 |
156 |
157 | phonegap ${phonegap.cli.options} remote login --username="${phonegap.build.remote.username}" --password="${phonegap.build.remote.password}"
158 |
159 |
160 |
161 |
162 |
163 |
164 | phonegap ${phonegap.cli.options} remote build ${phonegap.platform}
165 |
166 |
167 |
168 |
169 |
170 |
171 | phonegap ${phonegap.cli.options} remote run ${phonegap.platform}
172 |
173 |
174 |
175 |
176 |
177 |
178 | phonegap ${phonegap.cli.options} remote run ${phonegap.platform} --emulator
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | phonegap ${phonegap.cli.options} local build ${phonegap.platform}
187 |
188 |
189 |
190 |
191 |
192 |
193 | phonegap ${phonegap.cli.options} local run ${phonegap.platform}
194 |
195 |
196 |
197 |
198 |
199 |
200 | phonegap ${phonegap.cli.options} local run ${phonegap.platform} --emulator
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/phonegap.defaults.properties:
--------------------------------------------------------------------------------
1 | #
2 | # Copyright (c) 2012-2014. Sencha Inc.
3 | #
4 |
5 | # Original PhoneGap Packager used the following properties
6 | # here we map in the app space properties to allow for app.json
7 | # setting of these instead of properties files
8 | phonegap.platform=${app.phonegap.config.platform}
9 | phonegap.build.remote=${app.phonegap.config.remote}
10 |
11 | # These are simply shorthanded as the user must specify them in
12 | # a local.properties file anyway.
13 | # No need for the user to type all this out.
14 | phonegap.build.remote.username=${phonegap.username}
15 | phonegap.build.remote.password=${phonegap.password}
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
24 |
32 |
33 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/production.defaults.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to the "production" build
3 | # environment.
4 | #
5 | # Please use production.properties to customize these properties unless you want
6 | # your customizations to be for all environments. In that case, you can instead
7 | # override these properties in build.properties.
8 | #
9 | # The properties defined in this file take priority over defaults.properties
10 | # but are lower priority than build.properties which in turn is lower priority
11 | # than production.properties.
12 | #
13 | # IMPORTANT - This file should not be modified by an app as it is overwritten
14 | # during each app upgrade.
15 | # =============================================================================
16 |
17 | build.options.logger=no
18 |
19 | build.options.debug=false
20 |
21 | # enable the full class system optimizer
22 | app.output.js.optimize=true
23 | build.optimize=${build.optimize.enable}
24 |
25 | enable.resource.compression=true
26 |
27 | build.embedded.microloader.compressor=-closure
28 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/production.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in
3 | # production.defaults.properties. These properties are only imported when building
4 | # for the "production" environment.
5 | #
6 | # Properties defined in this file take priority over build.properties but are
7 | # only loaded for "production" builds.
8 | # =============================================================================
9 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/refresh-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
47 |
48 |
49 |
50 |
51 |
58 |
59 |
60 |
61 |
62 |
65 |
66 | var Ext = Ext || {};
67 | Ext.manifest = Ext.manifest || "${build.json.bootstrap.rel.path}";
68 |
69 |
70 |
71 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
101 |
102 |
106 |
107 |
108 | /**
109 | * This file is generated by Sencha Cmd and should NOT be edited. It is a
110 | * combination of content from app.json, and all required package's package.json
111 | * files. Customizations should be placed in app.json.
112 | */
113 |
114 |
115 |
124 |
125 |
126 |
127 |
131 |
135 |
136 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/resolve-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
37 |
39 |
40 |
41 |
49 |
50 |
51 |
52 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
83 |
84 |
85 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/resources-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/sass-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 | include
22 | -all
23 |
24 |
25 |
26 |
27 | restore
28 | page
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
119 |
120 |
121 |
122 |
130 |
131 |
132 |
133 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
161 |
162 |
163 |
164 | Preprocessing @{cssfile} to ${css.output.name}
165 |
169 |
170 |
171 |
172 |
173 |
174 | Compressing @{cssfile} to ${css.output.name}
175 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
203 |
204 |
205 |
211 |
212 |
213 | fashion
214 | -compress=${build.css.compress}
215 | -split=${build.css.selector.limit}
216 | -saveFile=${app.dir}/${app.sass.save}
217 | ${app.out.scss}
218 | ${app.out.css}
219 |
220 |
221 |
223 |
224 |
225 |
226 |
227 |
236 |
237 |
241 |
242 |
243 |
244 |
245 |
246 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
271 |
272 |
273 |
274 |
275 | Compiling sass directory : @{theme}/sass
276 |
282 |
283 |
285 |
286 |
287 |
288 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
309 |
310 |
311 |
317 |
318 |
319 |
320 |
324 |
328 |
329 |
332 |
333 |
334 |
335 |
336 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/sencha.cfg:
--------------------------------------------------------------------------------
1 | # this property specifies a comma separated list of paths containing
2 | # resources to copy to the build directory
3 | app.resource.paths=
4 |
5 | #==============================================================================
6 | # Custom Properties - Place customizations below this line to avoid merge
7 | # conflicts with newer versions
8 |
9 | app.framework.version=6.0.1.250
10 |
11 | app.cmd.version=6.1.2.15
12 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/slice-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
74 |
75 |
76 |
77 |
86 |
87 |
88 |
89 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 | fashion
106 | -compress=${build.css.compress}
107 | -split=${build.css.selector.limit}
108 | ${app.example.build.dir}
109 | ${app.example.build.dir}
110 |
111 |
112 |
113 |
114 |
115 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
133 |
134 |
141 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | exclude
166 | -tag=framework,package-sencha-core,package-core,package-${toolkit.name}
167 |
168 |
169 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
197 |
198 |
199 |
200 |
201 | Capture theme image to ${build.capture.png}
202 |
203 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | Capture theme image to ${build.capture.png}
221 |
224 |
225 |
226 |
227 |
228 |
229 | Slicing theme images to ${build.resources.dir}
230 |
231 |
239 |
240 |
241 |
242 |
243 |
247 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 | Copying base framework images from ${framework.theme.dir} to ${tmp.img.dir}
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 | Building sass for theme ${theme.name}
291 |
292 |
293 |
294 |
295 |
296 | Slicing images for theme ${theme.name} to ${tmp.img.dir}
297 |
298 |
306 |
307 |
308 |
309 |
310 |
311 | Copying user defined images from @{theme}/images to ${tmp.img.dir}
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
325 |
326 |
327 |
328 |
330 |
331 |
332 |
335 |
336 |
337 |
339 |
340 |
341 |
342 |
343 |
347 |
348 | Processing theme directories from ${app.theme.dir}
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/testing.defaults.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file defines default property values that apply to the "testing" build
3 | # environment.
4 | #
5 | # Please use testing.properties to customize these properties unless you want
6 | # your customizations to be for all environments. In that case, you can instead
7 | # override these properties in build.properties.
8 | #
9 | # The properties defined in this file take priority over defaults.properties
10 | # but are lower priority than build.properties which in turn is lower priority
11 | # than testing.properties.
12 | #
13 | # IMPORTANT - This file should not be modified by an app as it is overwritten
14 | # during each app upgrade.
15 | # =============================================================================
16 |
17 | build.options.logger=yes
18 |
19 | build.options.debug=true
20 |
21 | build.css.compress=false
22 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/testing.properties:
--------------------------------------------------------------------------------
1 | # =============================================================================
2 | # This file provides an override point for default variables defined in
3 | # testing.defaults.properties. These properties are only imported when building
4 | # for the "testing" environment.
5 | #
6 | # Properties defined in this file take priority over build.properties but are
7 | # only loaded for "testing" builds.
8 | # =============================================================================
9 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/app/watch-impl.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
28 |
29 |
30 |
31 |
32 |
33 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/workspace/plugin.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/test/sandbox/.sencha/workspace/sencha.cfg:
--------------------------------------------------------------------------------
1 | #Sat, 09 Jan 2016 22:51:46 -0800
2 | # -----------------------------------------------------------------------------
3 | # This file contains configuration options that apply to all applications in
4 | # the workspace. By convention, these options start with "workspace." but any
5 | # option can be set here. Options specified in an application's sencha.cfg will
6 | # take priority over those values contained in this file. These options will
7 | # take priority over configuration values in Sencha Cmd or a framework plugin.
8 |
9 | # -----------------------------------------------------------------------------
10 | # This configuration property (if set) is included by default in all compile
11 | # commands executed according to this formulation:
12 | #
13 | # sencha compile -classpath=...,${framework.classpath},${workspace.classpath},${app.classpath}
14 |
15 | #workspace.classpath=
16 |
17 | #------------------------------------------------------------------------------
18 | # This is the folder for build outputs in the workspace
19 |
20 | workspace.build.dir=${workspace.dir}/build
21 |
22 | #------------------------------------------------------------------------------
23 | # This folder contains all generated and extracted packages.
24 |
25 | workspace.packages.dir=${workspace.dir}/packages
26 |
27 | workspace.theme.dir=${workspace.packages.dir}/${args.themeName}
28 |
29 | # =============================================================================
30 | # Customizations go below this divider to avoid merge conflicts on upgrade
31 | # =============================================================================
32 |
33 | workspace.cmd.version=6.0.2.14
34 |
35 | ext.dir=${workspace.dir}/ext
36 |
--------------------------------------------------------------------------------
/test/sandbox/app.js:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is generated and updated by Sencha Cmd. You can edit this file as
3 | * needed for your application, but these edits will have to be merged by
4 | * Sencha Cmd when upgrading.
5 | */
6 | Ext.application({
7 | name: 'Sandbox',
8 |
9 | extend: 'Sandbox.Application',
10 |
11 | autoCreateViewport: 'Sandbox.view.main.Main'
12 |
13 | //-------------------------------------------------------------------------
14 | // Most customizations should be made to Sandbox.Application. If you need to
15 | // customize this file, doing so below this section reduces the likelihood
16 | // of merge conflicts when upgrading to new versions of Sencha Cmd.
17 | //-------------------------------------------------------------------------
18 | })
19 |
--------------------------------------------------------------------------------
/test/sandbox/app/Application.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.Application', {
2 | extend: 'Ext.app.Application',
3 | name: 'Sandbox'
4 | })
5 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/Main.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.Main', {
2 | extend: 'Ext.container.Container',
3 |
4 | requires: [
5 | 'Ext.layout.container.VBox',
6 | 'Ext.layout.container.HBox',
7 | 'Sandbox.view.main.MainModel',
8 | 'Sandbox.view.main.MainController',
9 | 'Sandbox.view.main.tab.LoadMasks',
10 | 'Sandbox.view.main.tab.Buttons',
11 | 'Sandbox.view.main.tab.Windows',
12 | 'Sandbox.view.main.tab.Content',
13 | 'Sandbox.view.main.tab.Fields',
14 | 'Sandbox.view.main.tab.Grids',
15 | 'Sandbox.view.main.tab.Dataview'
16 | ],
17 |
18 | controller: 'main',
19 | viewModel: {
20 | type: 'main'
21 | },
22 |
23 | layout: {
24 | type: 'fit'
25 | },
26 |
27 | items: {
28 | xtype: 'tabpanel',
29 | bodyPadding: 5,
30 | defaults: {
31 | xtype: 'container',
32 | layout: 'vbox',
33 | defaults: {
34 | margin: 5
35 | }
36 | },
37 | items: [{
38 | xtype: 'tabButtons'
39 | }, {
40 | xtype: 'tabWindows'
41 | }, {
42 | xtype: 'tabFields'
43 | }, {
44 | xtype: 'tabGrids'
45 | }, {
46 | xtype: 'tabDataview'
47 | }, {
48 | xtype: 'tabLoadMasks'
49 | }, {
50 | xtype: 'tabContent'
51 | }]
52 | }
53 | })
54 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/MainController.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.MainController', {
2 | extend: 'Ext.app.ViewController',
3 | alias: 'controller.main',
4 |
5 | requires: [
6 | 'Ext.window.MessageBox'
7 | ],
8 |
9 | // buttons
10 |
11 | onButtonsSimpleButtonClick: function (btn) {
12 | btn.setDisabled(true)
13 | btn.setText(btn.getText() + ' [done]')
14 | },
15 |
16 | onButtonsDisableButtonClick: function (btn) {
17 | btn.setDisabled(true)
18 | btn.setText('Wait for 1s..')
19 | setTimeout(function () {
20 | btn.setText(btn.getText() + ' [done]')
21 | btn.setDisabled(false)
22 | }, 1000)
23 | },
24 |
25 | onButtonsSelectMeByTooltipButtonClick: function (btn) {
26 | btn.setDisabled(true)
27 | btn.setText(btn.getText() + ' [done]')
28 | },
29 |
30 | onButtonsSelectMeByCustomXtypeButtonClick: function (btn) {
31 | btn.setDisabled(true)
32 | btn.setText(btn.getText() + ' [done]')
33 | },
34 |
35 | // windows
36 |
37 | onWindowsShowConfirmButtonClick: function (btn) {
38 | Ext.getBody().mask('Wait window...')
39 | setTimeout(function () {
40 | Ext.getBody().unmask()
41 | Ext.Msg.confirm('Confirm', 'Are you sure?', function () {
42 | btn.setText(btn.getText() + ' [done]')
43 | })
44 | }, 1000)
45 | },
46 |
47 | // loadMasks
48 |
49 | onLoadMasksShowGlobalButtonClick: function (btn) {
50 | Ext.getBody().mask('Wait load mask...')
51 | setTimeout(function () {
52 | Ext.getBody().unmask()
53 | btn.setText(btn.getText() + ' [done]')
54 | }, 1000)
55 | },
56 |
57 | onLoadMasksShowComponentButtonClick: function (btn) {
58 | var tab = btn.up('tabpanel')
59 | tab.setLoading('Wait setLoading load mask...')
60 | setTimeout(function () {
61 | tab.setLoading(false)
62 | btn.setText(btn.getText() + ' [done]')
63 | }, 1000)
64 | },
65 |
66 | // content
67 |
68 | onTextsShowTextButtonClick: function (btn) {
69 | var self = this
70 | Ext.getBody().mask('Wait for text appears...')
71 | btn.setText('Wait for text appears...')
72 | setTimeout(function () {
73 | Ext.getBody().unmask()
74 | self.getViewModel().set('buttonResultText', 'Result is here!')
75 | btn.setText(btn.getText() + ' [done]')
76 | }, 1000)
77 | },
78 |
79 | onContentHideMeButtonClick: function (btn) {
80 | Ext.getBody().mask('Hide button...')
81 | setTimeout(function () {
82 | btn.hide()
83 | Ext.getBody().mask('Show button...')
84 | setTimeout(function () {
85 | Ext.getBody().unmask()
86 | btn.show()
87 | }, 1000)
88 | }, 1000)
89 | }
90 |
91 | })
92 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/MainModel.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.MainModel', {
2 | extend: 'Ext.app.ViewModel',
3 | alias: 'viewmodel.main',
4 |
5 | data: {
6 | buttonResultText: ''
7 | }
8 |
9 | })
10 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/SuitePanel.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.SuitePanel', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'suitePanel',
4 |
5 | layout: 'hbox',
6 | minHeight: 40,
7 |
8 | initComponent: function () {
9 | var self = this
10 |
11 | if (Ext.isArray(self.suiteCode)) {
12 | self.suiteCode = self.suiteCode.join('\n')
13 | }
14 |
15 | self.suiteWidth = (self.suiteWidth || 250)
16 |
17 | self.items = [{
18 | width: self.suiteWidth,
19 | defaults: {
20 | width: (self.suiteWidth - 20),
21 | labelWidth: 80
22 | },
23 | items: self.suiteItems
24 | }, {
25 | html: '' + self.suiteCode + '
',
26 | flex: 1
27 | }]
28 |
29 | self.callParent(arguments)
30 | }
31 |
32 | })
33 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/custom/Button.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.custom.Button', {
2 | extend: 'Ext.button.Button',
3 | xtype: 'customButton'
4 | })
5 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/custom/Dataview.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.custom.Dataview', {
2 | extend: 'Ext.view.View',
3 | xtype: 'customDataview',
4 |
5 | width: 300,
6 | height: 150,
7 | border: true,
8 | itemTpl: '{name}
',
9 |
10 | store: Ext.create('Ext.data.Store', {
11 | fields: ['name', 'count'],
12 | data: [{
13 | name: 'Jhon Lennon',
14 | count: 3
15 | }, {
16 | name: 'Bruce Lee',
17 | count: 5
18 | }]
19 | })
20 | })
21 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/custom/Grid.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.custom.Grid', {
2 | extend: 'Ext.grid.Panel',
3 | xtype: 'customGrid',
4 |
5 | width: 300,
6 | height: 150,
7 | border: true,
8 | selModel: 'cellmodel',
9 | plugins: {
10 | ptype: 'cellediting',
11 | clicksToEdit: 1
12 | },
13 |
14 | columns: [{
15 | header: 'Name',
16 | dataIndex: 'name',
17 | flex: 1
18 | }, {
19 | header: 'Count',
20 | dataIndex: 'count'
21 | }, {
22 | header: 'Actions',
23 | xtype: 'actioncolumn',
24 | items: [{
25 | iconCls: 'x-fa fa-check',
26 | handler: function () {
27 | Ext.Msg.alert('Alert', 'Test Action Column')
28 | }
29 | }, {
30 | iconCls: 'x-fa fa-car'
31 | }]
32 | }],
33 |
34 | store: Ext.create('Ext.data.Store', {
35 | fields: ['name', 'count'],
36 | data: [{
37 | name: 'Aaa',
38 | count: 3
39 | }, {
40 | name: 'Bbb',
41 | count: 5
42 | }]
43 | })
44 | })
45 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Buttons.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Buttons', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabButtons',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel',
7 | 'Sandbox.view.main.custom.Button'
8 | ],
9 |
10 | title: 'Buttons',
11 |
12 | items: [{
13 | xtype: 'suitePanel',
14 | suiteCode: 'eTT().button(\'Simple button\').isEnabled().click(done)',
15 | suiteItems: {
16 | text: 'Simple button',
17 | xtype: 'button',
18 | handler: 'onButtonsSimpleButtonClick'
19 | }
20 | }, {
21 | xtype: 'suitePanel',
22 | suiteCode: 'eTT().button(\'Disable\').click().isDisabled().isEnabled(done)',
23 | suiteItems: {
24 | text: 'Disable',
25 | xtype: 'button',
26 | handler: 'onButtonsDisableButtonClick'
27 | }
28 | }, {
29 | xtype: 'suitePanel',
30 | suiteCode: 'eTT().button(\'Button tooltip\').click().isDisabled(done)',
31 | suiteItems: {
32 | text: 'Select me by tooltip',
33 | xtype: 'button',
34 | tooltip: 'Button tooltip',
35 | handler: 'onButtonsSelectMeByTooltipButtonClick'
36 | }
37 | }, {
38 | xtype: 'suitePanel',
39 | suiteCode: 'eTT().button(\'customButton\').click().isDisabled(done)',
40 | suiteItems: {
41 | text: 'Select me by custom xtype',
42 | xtype: 'customButton',
43 | handler: 'onButtonsSelectMeByCustomXtypeButtonClick'
44 | }
45 | }]
46 | })
47 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Content.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Content', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabContent',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel'
7 | ],
8 |
9 | title: 'Content',
10 |
11 | items: [{
12 | xtype: 'suitePanel',
13 | suiteWidth: 280,
14 | suiteCode: [
15 | 'eTT().button(\'Show result\').click(done)'
16 | ],
17 | suiteItems: [{
18 | xtype: 'button',
19 | text: 'Show result',
20 | handler: 'onTextsShowTextButtonClick'
21 | }, {
22 | xtype: 'displayfield',
23 | labelWidth: 145,
24 | fieldLabel: 'Wait new content here',
25 | bind: {
26 | value: '{buttonResultText}'
27 | }
28 | }]
29 | }, {
30 | xtype: 'suitePanel',
31 | suiteWidth: 280,
32 | suiteCode: [
33 | 'eTT().button(\'Hide me\').click().isHidden(done)',
34 | 'eTT().button(\'Hide me\').isVisible(done)'
35 | ],
36 | suiteItems: {
37 | xtype: 'button',
38 | text: 'Hide me',
39 | handler: 'onContentHideMeButtonClick'
40 | }
41 | }]
42 | })
43 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Dataview.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Dataview', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabDataview',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel',
7 | 'Sandbox.view.main.custom.Dataview'
8 | ],
9 |
10 | title: 'Dataview',
11 |
12 | items: [{
13 | xtype: 'suitePanel',
14 | title: 'customDataview with default itemCls',
15 | suiteWidth: 400,
16 | suiteCode: [
17 | 'eTT().grid(\'customDataviewReference\').select(1, done)'
18 | ],
19 | suiteItems: {
20 | xtype: 'customDataview',
21 | reference: 'customDataviewReference'
22 | }
23 | }, {
24 | xtype: 'suitePanel',
25 | title: 'customDataview with itemCls = "name-item"',
26 | suiteWidth: 400,
27 | suiteCode: [
28 | 'eTT().grid(\'customDataviewReference1\').select(0, done)'
29 | ],
30 | suiteItems: {
31 | xtype: 'customDataview',
32 | itemCls: 'name-item',
33 | reference: 'customDataviewReference1'
34 | }
35 | }]
36 | })
37 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Fields.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Fields', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabFields',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel'
7 | ],
8 |
9 | title: 'Fields',
10 |
11 | items: [{
12 | xtype: 'suitePanel',
13 | suiteCode: 'eTT().textField(\'Name\').fill(\'my text\', done)',
14 | suiteItems: {
15 | xtype: 'textfield',
16 | fieldLabel: 'Name'
17 | }
18 | }, {
19 | xtype: 'suitePanel',
20 | suiteCode: 'eTT().numberField(\'Count\').fill(13, done)',
21 | suiteItems: {
22 | xtype: 'numberfield',
23 | fieldLabel: 'Count'
24 | }
25 | }, {
26 | xtype: 'suitePanel',
27 | suiteCode: 'eTT().checkBox(\'include\').click(done)',
28 | suiteItems: {
29 | xtype: 'checkbox',
30 | boxLabel: 'include'
31 | }
32 | }, {
33 | xtype: 'suitePanel',
34 | suiteCode: [
35 | 'eTT().radio(\'check B\').click(done)',
36 | 'eTT().radio(\'check A\').click(done)'
37 | ],
38 | suiteItems: [{
39 | xtype: 'radio',
40 | boxLabel: 'check A',
41 | name: 'checkMe',
42 | value: 'a'
43 | }, {
44 | xtype: 'radio',
45 | boxLabel: 'check B',
46 | name: 'checkMe',
47 | value: 'b'
48 | }]
49 | }, {
50 | xtype: 'suitePanel',
51 | suiteCode: 'eTT().comboBox(\'Select in list\').select(1, done)',
52 | suiteItems: {
53 | xtype: 'combobox',
54 | fieldLabel: 'Select in list',
55 | editable: false,
56 | store: [
57 | ['a', 'Position A'],
58 | ['b', 'Position B']
59 | ]
60 | }
61 | }]
62 | })
63 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Grids.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Grids', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabGrids',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel',
7 | 'Sandbox.view.main.custom.Grid'
8 | ],
9 |
10 | title: 'Grids',
11 |
12 | items: [{
13 | xtype: 'suitePanel',
14 | suiteWidth: 400,
15 | suiteCode: [
16 | 'eTT().grid(\'Names\').select(1, done)',
17 | 'eTT().grid(\'Names\').select(0, done)',
18 | 'eTT().grid(\'Names\').checkRowsCount(2, done)'
19 | ],
20 | suiteItems: {
21 | xtype: 'customGrid',
22 | title: 'Names'
23 | }
24 | }, {
25 | xtype: 'suitePanel',
26 | suiteWidth: 400,
27 | suiteCode: 'eTT().grid(\'customGridReference\').select(0, 0).select(0, 1).select(1, 1).select(1, 0, done)',
28 | suiteItems: {
29 | xtype: 'customGrid',
30 | reference: 'customGridReference'
31 | }
32 | }, {
33 | xtype: 'suitePanel',
34 | suiteWidth: 400,
35 | suiteCode: [
36 | 'eTT().grid(\'Cell editing\').cellEditor(1, 0).select(0, done)',
37 | 'eTT().grid(\'Cell editing\').cellEditor(0, 0).select(2, done)',
38 | 'eTT().grid(\'Cell editing\').cellEditor(0, 2).fill(\'test1\', done)',
39 | 'eTT().grid(\'Cell editing\').cellEditor(1, 2).fill(\'test2\', done)',
40 | 'eTT().grid(\'Cell editing\').cellEditor(0, 3).click(done)',
41 | 'eTT().grid(\'Cell editing\').cellEditor(1, 3).click(done)'
42 | ],
43 | suiteItems: {
44 | title: 'Cell editing',
45 | xtype: 'customGrid',
46 | columns: [{
47 | header: 'Name',
48 | dataIndex: 'name',
49 | flex: 1,
50 | editor: {
51 | xtype: 'combobox',
52 | store: [['Aaa', 'Aaa'], ['Bbb', 'Bbb'], ['Ccc', 'Ccc']],
53 | editable: false
54 | }
55 | }, {
56 | header: 'Count',
57 | dataIndex: 'count'
58 | }, {
59 | header: 'Comment',
60 | dataIndex: 'comment',
61 | editor: {
62 | xtype: 'textfield'
63 | }
64 | }, {
65 | header: 'Enabled',
66 | dataIndex: 'enabled',
67 | editor: {
68 | xtype: 'checkbox'
69 | }
70 | }]
71 | }
72 | }]
73 | })
74 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/LoadMasks.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.LoadMasks', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabLoadMasks',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel'
7 | ],
8 |
9 | title: 'LoadMasks',
10 |
11 | items: [{
12 | xtype: 'suitePanel',
13 | suiteCode: [
14 | 'eTT().button(\'Show component\').click(done)',
15 | 'eTT().waitLoadMask(done)'
16 | ],
17 | suiteItems: {
18 | xtype: 'button',
19 | text: 'Show global',
20 | handler: 'onLoadMasksShowGlobalButtonClick'
21 | }
22 | }, {
23 | xtype: 'suitePanel',
24 | suiteCode: [
25 | 'eTT().button(\'Show global\').click(done)',
26 | 'eTT().waitLoadMask(done)'
27 | ],
28 | suiteItems: {
29 | xtype: 'button',
30 | text: 'Show component',
31 | handler: 'onLoadMasksShowComponentButtonClick'
32 | }
33 | }]
34 | })
35 |
--------------------------------------------------------------------------------
/test/sandbox/app/view/main/tab/Windows.js:
--------------------------------------------------------------------------------
1 | Ext.define('Sandbox.view.main.tab.Windows', {
2 | extend: 'Ext.panel.Panel',
3 | xtype: 'tabWindows',
4 |
5 | requires: [
6 | 'Sandbox.view.main.SuitePanel'
7 | ],
8 |
9 | title: 'Windows',
10 |
11 | items: [{
12 | xtype: 'suitePanel',
13 | suiteCode: [
14 | 'eTT().button(\'Show confirm\').click(done)',
15 | 'eTT().window(\'Confirm\', done)',
16 | 'eTT().window(\'Confirm\').button(\'Yes\').isEnabled().click(done)',
17 | 'eTT().no.window(\'Confirm\', done)'
18 | ],
19 | suiteItems: {
20 | xtype: 'button',
21 | text: 'Show confirm',
22 | handler: 'onWindowsShowConfirmButtonClick'
23 | }
24 | }, {
25 | xtype: 'button',
26 | text: 'Yes'
27 | }]
28 | })
29 |
--------------------------------------------------------------------------------
/test/sandbox/bootstrap.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | /*
4 | * This file is generated by Sencha Cmd and should NOT be edited. It redirects
5 | * to the most recently built CSS file for the application to allow index.html
6 | * in the development directory to load properly (i.e., "dev mode").
7 | */
8 | @import 'build/production/Sandbox/classic/resources/Sandbox-all.css';
9 |
10 |
--------------------------------------------------------------------------------
/test/sandbox/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/sandbox/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Sandbox
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/test/sandbox/workspace.json:
--------------------------------------------------------------------------------
1 | {
2 | /**
3 | * An object containing key value pair framework descriptors.
4 | *
5 | * The value can be a string or an object containing at least one of "dir" or "pkg",
6 | * where "dir" can be a filesystem path to the framework sources and "pkg" can be a
7 | * package name. For example:
8 | *
9 | * "frameworks": {
10 | *
11 | * "ext-x": "/absolute/path/to/ext",
12 | * "ext-y": {
13 | * "source": "../relative/path/to/ext",
14 | * "path": "ext"
15 | * },
16 | * "ext-z": {
17 | * "package": "ext@n.n.n",
18 | * "path": "ext-n.n.n"
19 | * },
20 | * "touch": "touch"
21 | * }
22 | *
23 | */
24 | "frameworks": {
25 | "ext": "ext"
26 |
27 | },
28 |
29 | /**
30 | * This is the folder for build outputs in the workspace.
31 | */
32 | "build": {
33 | "dir": "${workspace.dir}/build"
34 | },
35 |
36 | /**
37 | * These configs determine where packages are generated and extracted to (when downloaded).
38 | */
39 | "packages": {
40 | /**
41 | * This folder contains all local packages.
42 | * If a comma-separated string is used as value the first path will be used as the path to generate new packages.
43 | */
44 | "dir": "${workspace.dir}/packages/local,${workspace.dir}/packages",
45 |
46 | /**
47 | * This folder contains all extracted (remote) packages.
48 | */
49 | "extract": "${workspace.dir}/packages/remote"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/suites/010-environment.js:
--------------------------------------------------------------------------------
1 | describe('Check environment', function () {
2 | it('Ext', function () {
3 | expect(Ext).to.be.an('object')
4 | })
5 |
6 | it('Sandbox', function () {
7 | expect(Sandbox).to.be.an('object')
8 | })
9 | })
10 |
--------------------------------------------------------------------------------
/test/suites/020-buttons.js:
--------------------------------------------------------------------------------
1 | describe('Buttons', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "Buttons" tab', function (done) {
6 | eTT().tab('Buttons').click(done)
7 | })
8 |
9 | it('Click "Simple button" button', function (done) {
10 | eTT().button('Simple button').isEnabled().click(done)
11 | })
12 |
13 | it('Click "Disable" button and wait state changed to "enabled"', function (done) {
14 | eTT().button('Disable').click().isDisabled().isEnabled(done)
15 | })
16 |
17 | it('Click "Select me by tooltip" button and wait state changed to "disabled"', function (done) {
18 | eTT().button('Button tooltip').click().isDisabled(done)
19 | })
20 |
21 | it('Click "Select me by custom xtype" button and wait state changed to "disabled"', function (done) {
22 | eTT().button('customButton').click().isDisabled(done)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/test/suites/030-windows.js:
--------------------------------------------------------------------------------
1 | describe('Windows', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "Windows" tab', function (done) {
6 | eTT().tab('Windows').click(done)
7 | })
8 |
9 | it('Click "Show confirm" button', function (done) {
10 | eTT().button('Show confirm').click(done)
11 | })
12 |
13 | it('window "Confirm" should be presented', function (done) {
14 | eTT().window('Confirm', done)
15 | })
16 |
17 | it('click on "Yes" button in "Confirm" window', function (done) {
18 | eTT().window('Confirm').button('Yes').isEnabled().click(done)
19 | })
20 |
21 | it('window "Confirm" should be hidden', function (done) {
22 | eTT().no.window('Confirm', done)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/test/suites/040-fields.js:
--------------------------------------------------------------------------------
1 | describe('Fields', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "Fields" tab', function (done) {
6 | eTT().tab('Fields').click(done)
7 | })
8 |
9 | it('Fill "Text" filed', function (done) {
10 | eTT().textField('Name').fill('my text', done)
11 | })
12 |
13 | it('Fill "Number" filed', function (done) {
14 | eTT().numberField('Count').fill(13, done)
15 | })
16 |
17 | it('Click on checkbox "include"', function (done) {
18 | eTT().checkBox('include').click(done)
19 | })
20 |
21 | it('Click on radio "check B"', function (done) {
22 | eTT().radio('check B').click(done)
23 | })
24 |
25 | it('Click on radio "check A"', function (done) {
26 | eTT().radio('check A').click(done)
27 | })
28 |
29 | it('Click on combobox "Select in list"', function (done) {
30 | eTT().comboBox('Select in list').select(1, done)
31 | })
32 | })
33 |
--------------------------------------------------------------------------------
/test/suites/050-grids.js:
--------------------------------------------------------------------------------
1 | describe('Grids', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "Grids" tab', function (done) {
6 | eTT().tab('Grids').click(done)
7 | })
8 |
9 | it('Click on second "Names" grid row', function (done) {
10 | eTT().grid('Names').select(1, done)
11 | })
12 |
13 | it('Click on first "Names" grid row', function (done) {
14 | eTT().grid('Names').select(0, done)
15 | })
16 |
17 | it('Rows number should be equal 2', function (done) {
18 | eTT().grid('Names').checkRowsCount(2, done)
19 | })
20 |
21 | it('Click on first action in first row of "Names" grid', function (done) {
22 | eTT().grid('Names').clickAction(0, 2, 0, function () {
23 | eTT().button('OK').click(done)
24 | })
25 | })
26 |
27 | it('Click on second action in first row of "Names" grid', function (done) {
28 | eTT().grid('Names').clickAction(0, 2, 1, done)
29 | })
30 |
31 | it('Click on second action in second row of "Names" grid', function (done) {
32 | eTT().grid('Names').clickAction(1, 2, 1, done)
33 | })
34 |
35 | it('Click on cells of second grid', function (done) {
36 | eTT().grid('customGridReference').select(0, 0).select(0, 1).select(1, 1).select(1, 0, done)
37 | })
38 |
39 | it('Edit "Cell editing" grid row #2, select item #1', function (done) {
40 | eTT().grid('Cell editing').cellEditor(1, 0).select(0, done)
41 | })
42 |
43 | it('Edit "Cell editing" grid #1 row, select item #3', function (done) {
44 | eTT().grid('Cell editing').cellEditor(0, 0).select(2, done)
45 | })
46 |
47 | it('Edit "Cell editing" grid #1 row, fill column #3 with "test1"', function (done) {
48 | eTT().grid('Cell editing').cellEditor(0, 2).fill('test1', done)
49 | })
50 |
51 | it('Edit "Cell editing" grid #2 row, fill column #3 with "test2"', function (done) {
52 | eTT().grid('Cell editing').cellEditor(1, 2).fill('test2', done)
53 | })
54 |
55 | it('Edit "Cell editing" grid #1 row, check column #3', function (done) {
56 | eTT().grid('Cell editing').cellEditor(0, 3).click(done)
57 | })
58 |
59 | it('Edit "Cell editing" grid #2 row, check column #3', function (done) {
60 | eTT().grid('Cell editing').cellEditor(1, 3).click(done)
61 | })
62 | })
63 |
--------------------------------------------------------------------------------
/test/suites/060-dataview.js:
--------------------------------------------------------------------------------
1 | describe('Dataview', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "Dataview" tab', function (done) {
6 | eTT().tab('Dataview').click(done)
7 | })
8 |
9 | it('Click on second "customDataviewReference" dataview item', function (done) {
10 | eTT().dataview('customDataviewReference').select(1, done)
11 | })
12 |
13 | it('Click on first "customDataviewReference1" dataview item with itemCls', function (done) {
14 | eTT().dataview('customDataviewReference1').select(0, done)
15 | })
16 | })
17 |
18 |
--------------------------------------------------------------------------------
/test/suites/070-loadmasks.js:
--------------------------------------------------------------------------------
1 | describe('LoadMasks', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch to "LoadMasks" tab', function (done) {
6 | eTT().tab('LoadMasks').click(done)
7 | })
8 |
9 | it('Click on "Show component" button', function (done) {
10 | eTT().button('Show component').click(done)
11 | })
12 |
13 | it('Load mask should disappear in 10s', function (done) {
14 | eTT().waitLoadMask(done)
15 | })
16 |
17 | it('Click on "Show global" button', function (done) {
18 | eTT().button('Show global').click(done)
19 | })
20 |
21 | it('Load mask should disappear in 10s', function (done) {
22 | eTT().waitLoadMask(done)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------
/test/suites/080-content.js:
--------------------------------------------------------------------------------
1 | describe('Content', function () {
2 | this.bail(true)
3 | this.timeout(20 * 1000)
4 |
5 | it('Switch ot "Content" tab', function (done) {
6 | eTT().tab('Content').click(done)
7 | })
8 |
9 | it('Click on "Show result" button', function (done) {
10 | eTT().button('Show result').click(done)
11 | })
12 |
13 | it('Text "Result is here!" should appears in 1s', function (done) {
14 | eTT().waitText('Result is here!', done)
15 | })
16 |
17 | it('"Hide me" button should be hidden after click', function (done) {
18 | eTT().button('Hide me').click().isHidden(done)
19 | })
20 |
21 | it('"Hide me" button should be visible again', function (done) {
22 | eTT().button('Hide me').isVisible(done)
23 | })
24 | })
25 |
--------------------------------------------------------------------------------