##// END OF EJS Templates
Moved is_cell_rendered into base
Jonathan Frederic -
Show More
@@ -1,43 +1,37
1
1
2 // Test
2 // Test
3 casper.notebook_test(function () {
3 casper.notebook_test(function () {
4 this.is_rendered = function(i) {
5 return this.evaluate(function(i) {
6 return !!IPython.notebook.get_cell(i).rendered;
7 }, {i:i});
8 };
9
10 var a = 'print("a")';
4 var a = 'print("a")';
11 var index = this.append_cell(a);
5 var index = this.append_cell(a);
12 this.execute_cell_then(index, function(index) {
6 this.execute_cell_then(index, function(index) {
13 // Markdown rendering / unredering
7 // Markdown rendering / unredering
14 this.select_cell(index);
8 this.select_cell(index);
15 this.validate_notebook_state('select ' + index, 'command', index);
9 this.validate_notebook_state('select ' + index, 'command', index);
16 this.trigger_keydown('m');
10 this.trigger_keydown('m');
17 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', 'm; cell is markdown');
11 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', 'm; cell is markdown');
18 this.test.assert(!this.is_rendered(index), 'm; cell is unrendered');
12 this.test.assert(!this.is_cell_rendered(index), 'm; cell is unrendered');
19 this.trigger_keydown('enter');
13 this.trigger_keydown('enter');
20 this.test.assert(!this.is_rendered(index), 'enter; cell is unrendered');
14 this.test.assert(!this.is_cell_rendered(index), 'enter; cell is unrendered');
21 this.validate_notebook_state('enter', 'edit', index);
15 this.validate_notebook_state('enter', 'edit', index);
22 this.trigger_keydown('ctrl-enter');
16 this.trigger_keydown('ctrl-enter');
23 this.test.assert(this.is_rendered(index), 'ctrl-enter; cell is rendered');
17 this.test.assert(this.is_cell_rendered(index), 'ctrl-enter; cell is rendered');
24 this.validate_notebook_state('enter', 'command', index);
18 this.validate_notebook_state('enter', 'command', index);
25 this.trigger_keydown('enter');
19 this.trigger_keydown('enter');
26 this.test.assert(!this.is_rendered(index), 'enter; cell is unrendered');
20 this.test.assert(!this.is_cell_rendered(index), 'enter; cell is unrendered');
27 this.select_cell(index-1);
21 this.select_cell(index-1);
28 this.test.assert(!this.is_rendered(index), 'select ' + (index-1) + '; cell ' + index + ' is still unrendered');
22 this.test.assert(!this.is_cell_rendered(index), 'select ' + (index-1) + '; cell ' + index + ' is still unrendered');
29 this.validate_notebook_state('select ' + (index-1), 'command', index-1);
23 this.validate_notebook_state('select ' + (index-1), 'command', index-1);
30 this.select_cell(index);
24 this.select_cell(index);
31 this.validate_notebook_state('select ' + index, 'command', index);
25 this.validate_notebook_state('select ' + index, 'command', index);
32 this.trigger_keydown('ctrl-enter');
26 this.trigger_keydown('ctrl-enter');
33 this.test.assert(this.is_rendered(index), 'ctrl-enter; cell is rendered');
27 this.test.assert(this.is_cell_rendered(index), 'ctrl-enter; cell is rendered');
34 this.select_cell(index-1);
28 this.select_cell(index-1);
35 this.validate_notebook_state('select ' + (index-1), 'command', index-1);
29 this.validate_notebook_state('select ' + (index-1), 'command', index-1);
36 this.trigger_keydown('shift-enter');
30 this.trigger_keydown('shift-enter');
37 this.validate_notebook_state('shift-enter', 'command', index);
31 this.validate_notebook_state('shift-enter', 'command', index);
38 this.test.assert(this.is_rendered(index), 'shift-enter; cell is rendered');
32 this.test.assert(this.is_cell_rendered(index), 'shift-enter; cell is rendered');
39 this.trigger_keydown('shift-enter'); // Creates one cell
33 this.trigger_keydown('shift-enter'); // Creates one cell
40 this.validate_notebook_state('shift-enter', 'edit', index+1);
34 this.validate_notebook_state('shift-enter', 'edit', index+1);
41 this.test.assert(this.is_rendered(index), 'shift-enter; cell is rendered');
35 this.test.assert(this.is_cell_rendered(index), 'shift-enter; cell is rendered');
42 });
36 });
43 }); No newline at end of file
37 });
@@ -1,533 +1,539
1 //
1 //
2 // Utility functions for the HTML notebook's CasperJS tests.
2 // Utility functions for the HTML notebook's CasperJS tests.
3 //
3 //
4 casper.get_notebook_server = function () {
4 casper.get_notebook_server = function () {
5 // Get the URL of a notebook server on which to run tests.
5 // Get the URL of a notebook server on which to run tests.
6 port = casper.cli.get("port");
6 port = casper.cli.get("port");
7 port = (typeof port === 'undefined') ? '8888' : port;
7 port = (typeof port === 'undefined') ? '8888' : port;
8 return 'http://127.0.0.1:' + port;
8 return 'http://127.0.0.1:' + port;
9 };
9 };
10
10
11 casper.open_new_notebook = function () {
11 casper.open_new_notebook = function () {
12 // Create and open a new notebook.
12 // Create and open a new notebook.
13 var baseUrl = this.get_notebook_server();
13 var baseUrl = this.get_notebook_server();
14 this.start(baseUrl);
14 this.start(baseUrl);
15 this.thenClick('button#new_notebook');
15 this.thenClick('button#new_notebook');
16 this.waitForPopup('');
16 this.waitForPopup('');
17
17
18 this.withPopup('', function () {this.waitForSelector('.CodeMirror-code');});
18 this.withPopup('', function () {this.waitForSelector('.CodeMirror-code');});
19 this.then(function () {
19 this.then(function () {
20 this.open(this.popups[0].url);
20 this.open(this.popups[0].url);
21 });
21 });
22
22
23 // Make sure the kernel has started
23 // Make sure the kernel has started
24 this.waitFor( this.kernel_running );
24 this.waitFor( this.kernel_running );
25 // track the IPython busy/idle state
25 // track the IPython busy/idle state
26 this.thenEvaluate(function () {
26 this.thenEvaluate(function () {
27 $([IPython.events]).on('status_idle.Kernel',function () {
27 $([IPython.events]).on('status_idle.Kernel',function () {
28 IPython._status = 'idle';
28 IPython._status = 'idle';
29 });
29 });
30 $([IPython.events]).on('status_busy.Kernel',function () {
30 $([IPython.events]).on('status_busy.Kernel',function () {
31 IPython._status = 'busy';
31 IPython._status = 'busy';
32 });
32 });
33 });
33 });
34
34
35 // Because of the asynchronous nature of SlimerJS (Gecko), we need to make
35 // Because of the asynchronous nature of SlimerJS (Gecko), we need to make
36 // sure the notebook has actually been loaded into the IPython namespace
36 // sure the notebook has actually been loaded into the IPython namespace
37 // before running any tests.
37 // before running any tests.
38 this.waitFor(function() {
38 this.waitFor(function() {
39 return this.evaluate(function () {
39 return this.evaluate(function () {
40 return IPython.notebook;
40 return IPython.notebook;
41 });
41 });
42 });
42 });
43 };
43 };
44
44
45 casper.kernel_running = function kernel_running() {
45 casper.kernel_running = function kernel_running() {
46 // Return whether or not the kernel is running.
46 // Return whether or not the kernel is running.
47 return this.evaluate(function kernel_running() {
47 return this.evaluate(function kernel_running() {
48 return IPython.notebook.kernel.running;
48 return IPython.notebook.kernel.running;
49 });
49 });
50 };
50 };
51
51
52 casper.shutdown_current_kernel = function () {
52 casper.shutdown_current_kernel = function () {
53 // Shut down the current notebook's kernel.
53 // Shut down the current notebook's kernel.
54 this.thenEvaluate(function() {
54 this.thenEvaluate(function() {
55 IPython.notebook.kernel.kill();
55 IPython.notebook.kernel.kill();
56 });
56 });
57 // We close the page right after this so we need to give it time to complete.
57 // We close the page right after this so we need to give it time to complete.
58 this.wait(1000);
58 this.wait(1000);
59 };
59 };
60
60
61 casper.delete_current_notebook = function () {
61 casper.delete_current_notebook = function () {
62 // Delete created notebook.
62 // Delete created notebook.
63
63
64 // For some unknown reason, this doesn't work?!?
64 // For some unknown reason, this doesn't work?!?
65 this.thenEvaluate(function() {
65 this.thenEvaluate(function() {
66 IPython.notebook.delete();
66 IPython.notebook.delete();
67 });
67 });
68 };
68 };
69
69
70 casper.wait_for_busy = function () {
70 casper.wait_for_busy = function () {
71 // Waits for the notebook to enter a busy state.
71 // Waits for the notebook to enter a busy state.
72 this.waitFor(function () {
72 this.waitFor(function () {
73 return this.evaluate(function () {
73 return this.evaluate(function () {
74 return IPython._status == 'busy';
74 return IPython._status == 'busy';
75 });
75 });
76 });
76 });
77 };
77 };
78
78
79 casper.wait_for_idle = function () {
79 casper.wait_for_idle = function () {
80 // Waits for the notebook to idle.
80 // Waits for the notebook to idle.
81 this.waitFor(function () {
81 this.waitFor(function () {
82 return this.evaluate(function () {
82 return this.evaluate(function () {
83 return IPython._status == 'idle';
83 return IPython._status == 'idle';
84 });
84 });
85 });
85 });
86 };
86 };
87
87
88 casper.wait_for_output = function (cell_num, out_num) {
88 casper.wait_for_output = function (cell_num, out_num) {
89 // wait for the nth output in a given cell
89 // wait for the nth output in a given cell
90 this.wait_for_idle();
90 this.wait_for_idle();
91 out_num = out_num || 0;
91 out_num = out_num || 0;
92 this.then(function() {
92 this.then(function() {
93 this.waitFor(function (c, o) {
93 this.waitFor(function (c, o) {
94 return this.evaluate(function get_output(c, o) {
94 return this.evaluate(function get_output(c, o) {
95 var cell = IPython.notebook.get_cell(c);
95 var cell = IPython.notebook.get_cell(c);
96 return cell.output_area.outputs.length > o;
96 return cell.output_area.outputs.length > o;
97 },
97 },
98 // pass parameter from the test suite js to the browser code js
98 // pass parameter from the test suite js to the browser code js
99 {c : cell_num, o : out_num});
99 {c : cell_num, o : out_num});
100 });
100 });
101 },
101 },
102 function then() { },
102 function then() { },
103 function timeout() {
103 function timeout() {
104 this.echo("wait_for_output timed out!");
104 this.echo("wait_for_output timed out!");
105 });
105 });
106 };
106 };
107
107
108 casper.wait_for_widget = function (widget_info) {
108 casper.wait_for_widget = function (widget_info) {
109 // wait for a widget msg que to reach 0
109 // wait for a widget msg que to reach 0
110 //
110 //
111 // Parameters
111 // Parameters
112 // ----------
112 // ----------
113 // widget_info : object
113 // widget_info : object
114 // Object which contains info related to the widget. The model_id property
114 // Object which contains info related to the widget. The model_id property
115 // is used to identify the widget.
115 // is used to identify the widget.
116 this.waitFor(function () {
116 this.waitFor(function () {
117 var pending = this.evaluate(function (m) {
117 var pending = this.evaluate(function (m) {
118 return IPython.notebook.kernel.widget_manager.get_model(m).pending_msgs;
118 return IPython.notebook.kernel.widget_manager.get_model(m).pending_msgs;
119 }, {m: widget_info.model_id});
119 }, {m: widget_info.model_id});
120
120
121 if (pending === 0) {
121 if (pending === 0) {
122 return true;
122 return true;
123 } else {
123 } else {
124 return false;
124 return false;
125 }
125 }
126 });
126 });
127 };
127 };
128
128
129 casper.get_output_cell = function (cell_num, out_num) {
129 casper.get_output_cell = function (cell_num, out_num) {
130 // return an output of a given cell
130 // return an output of a given cell
131 out_num = out_num || 0;
131 out_num = out_num || 0;
132 var result = casper.evaluate(function (c, o) {
132 var result = casper.evaluate(function (c, o) {
133 var cell = IPython.notebook.get_cell(c);
133 var cell = IPython.notebook.get_cell(c);
134 return cell.output_area.outputs[o];
134 return cell.output_area.outputs[o];
135 },
135 },
136 {c : cell_num, o : out_num});
136 {c : cell_num, o : out_num});
137 if (!result) {
137 if (!result) {
138 var num_outputs = casper.evaluate(function (c) {
138 var num_outputs = casper.evaluate(function (c) {
139 var cell = IPython.notebook.get_cell(c);
139 var cell = IPython.notebook.get_cell(c);
140 return cell.output_area.outputs.length;
140 return cell.output_area.outputs.length;
141 },
141 },
142 {c : cell_num});
142 {c : cell_num});
143 this.test.assertTrue(false,
143 this.test.assertTrue(false,
144 "Cell " + cell_num + " has no output #" + out_num + " (" + num_outputs + " total)"
144 "Cell " + cell_num + " has no output #" + out_num + " (" + num_outputs + " total)"
145 );
145 );
146 } else {
146 } else {
147 return result;
147 return result;
148 }
148 }
149 };
149 };
150
150
151 casper.get_cells_length = function () {
151 casper.get_cells_length = function () {
152 // return the number of cells in the notebook
152 // return the number of cells in the notebook
153 var result = casper.evaluate(function () {
153 var result = casper.evaluate(function () {
154 return IPython.notebook.get_cells().length;
154 return IPython.notebook.get_cells().length;
155 });
155 });
156 return result;
156 return result;
157 };
157 };
158
158
159 casper.set_cell_text = function(index, text){
159 casper.set_cell_text = function(index, text){
160 // Set the text content of a cell.
160 // Set the text content of a cell.
161 this.evaluate(function (index, text) {
161 this.evaluate(function (index, text) {
162 var cell = IPython.notebook.get_cell(index);
162 var cell = IPython.notebook.get_cell(index);
163 cell.set_text(text);
163 cell.set_text(text);
164 }, index, text);
164 }, index, text);
165 };
165 };
166
166
167 casper.get_cell_text = function(index){
167 casper.get_cell_text = function(index){
168 // Get the text content of a cell.
168 // Get the text content of a cell.
169 return this.evaluate(function (index) {
169 return this.evaluate(function (index) {
170 var cell = IPython.notebook.get_cell(index);
170 var cell = IPython.notebook.get_cell(index);
171 return cell.get_text();
171 return cell.get_text();
172 }, index);
172 }, index);
173 };
173 };
174
174
175 casper.insert_cell_at_bottom = function(cell_type){
175 casper.insert_cell_at_bottom = function(cell_type){
176 // Inserts a cell at the bottom of the notebook
176 // Inserts a cell at the bottom of the notebook
177 // Returns the new cell's index.
177 // Returns the new cell's index.
178 return this.evaluate(function (cell_type) {
178 return this.evaluate(function (cell_type) {
179 var cell = IPython.notebook.insert_cell_at_bottom(cell_type);
179 var cell = IPython.notebook.insert_cell_at_bottom(cell_type);
180 return IPython.notebook.find_cell_index(cell);
180 return IPython.notebook.find_cell_index(cell);
181 }, cell_type);
181 }, cell_type);
182 };
182 };
183
183
184 casper.append_cell = function(text, cell_type) {
184 casper.append_cell = function(text, cell_type) {
185 // Insert a cell at the bottom of the notebook and set the cells text.
185 // Insert a cell at the bottom of the notebook and set the cells text.
186 // Returns the new cell's index.
186 // Returns the new cell's index.
187 var index = this.insert_cell_at_bottom(cell_type);
187 var index = this.insert_cell_at_bottom(cell_type);
188 if (text !== undefined) {
188 if (text !== undefined) {
189 this.set_cell_text(index, text);
189 this.set_cell_text(index, text);
190 }
190 }
191 return index;
191 return index;
192 };
192 };
193
193
194 casper.execute_cell = function(index){
194 casper.execute_cell = function(index){
195 // Asynchronously executes a cell by index.
195 // Asynchronously executes a cell by index.
196 // Returns the cell's index.
196 // Returns the cell's index.
197 var that = this;
197 var that = this;
198 this.then(function(){
198 this.then(function(){
199 that.evaluate(function (index) {
199 that.evaluate(function (index) {
200 var cell = IPython.notebook.get_cell(index);
200 var cell = IPython.notebook.get_cell(index);
201 cell.execute();
201 cell.execute();
202 }, index);
202 }, index);
203 });
203 });
204 return index;
204 return index;
205 };
205 };
206
206
207 casper.execute_cell_then = function(index, then_callback) {
207 casper.execute_cell_then = function(index, then_callback) {
208 // Synchronously executes a cell by index.
208 // Synchronously executes a cell by index.
209 // Optionally accepts a then_callback parameter. then_callback will get called
209 // Optionally accepts a then_callback parameter. then_callback will get called
210 // when the cell has finished executing.
210 // when the cell has finished executing.
211 // Returns the cell's index.
211 // Returns the cell's index.
212 var return_val = this.execute_cell(index);
212 var return_val = this.execute_cell(index);
213
213
214 this.wait_for_idle();
214 this.wait_for_idle();
215
215
216 var that = this;
216 var that = this;
217 this.then(function(){
217 this.then(function(){
218 if (then_callback!==undefined) {
218 if (then_callback!==undefined) {
219 then_callback.apply(that, [index]);
219 then_callback.apply(that, [index]);
220 }
220 }
221 });
221 });
222
222
223 return return_val;
223 return return_val;
224 };
224 };
225
225
226 casper.cell_element_exists = function(index, selector){
226 casper.cell_element_exists = function(index, selector){
227 // Utility function that allows us to easily check if an element exists
227 // Utility function that allows us to easily check if an element exists
228 // within a cell. Uses JQuery selector to look for the element.
228 // within a cell. Uses JQuery selector to look for the element.
229 return casper.evaluate(function (index, selector) {
229 return casper.evaluate(function (index, selector) {
230 var $cell = IPython.notebook.get_cell(index).element;
230 var $cell = IPython.notebook.get_cell(index).element;
231 return $cell.find(selector).length > 0;
231 return $cell.find(selector).length > 0;
232 }, index, selector);
232 }, index, selector);
233 };
233 };
234
234
235 casper.cell_element_function = function(index, selector, function_name, function_args){
235 casper.cell_element_function = function(index, selector, function_name, function_args){
236 // Utility function that allows us to execute a jQuery function on an
236 // Utility function that allows us to execute a jQuery function on an
237 // element within a cell.
237 // element within a cell.
238 return casper.evaluate(function (index, selector, function_name, function_args) {
238 return casper.evaluate(function (index, selector, function_name, function_args) {
239 var $cell = IPython.notebook.get_cell(index).element;
239 var $cell = IPython.notebook.get_cell(index).element;
240 var $el = $cell.find(selector);
240 var $el = $cell.find(selector);
241 return $el[function_name].apply($el, function_args);
241 return $el[function_name].apply($el, function_args);
242 }, index, selector, function_name, function_args);
242 }, index, selector, function_name, function_args);
243 };
243 };
244
244
245 casper.validate_notebook_state = function(message, mode, cell_index) {
245 casper.validate_notebook_state = function(message, mode, cell_index) {
246 // Validate the entire dual mode state of the notebook. Make sure no more than
246 // Validate the entire dual mode state of the notebook. Make sure no more than
247 // one cell is selected, focused, in edit mode, etc...
247 // one cell is selected, focused, in edit mode, etc...
248
248
249 // General tests.
249 // General tests.
250 this.test.assertEquals(this.get_keyboard_mode(), this.get_notebook_mode(),
250 this.test.assertEquals(this.get_keyboard_mode(), this.get_notebook_mode(),
251 message + '; keyboard and notebook modes match');
251 message + '; keyboard and notebook modes match');
252 // Is the selected cell the only cell that is selected?
252 // Is the selected cell the only cell that is selected?
253 if (cell_index!==undefined) {
253 if (cell_index!==undefined) {
254 this.test.assert(this.is_only_cell_selected(cell_index),
254 this.test.assert(this.is_only_cell_selected(cell_index),
255 message + '; cell ' + cell_index + ' is the only cell selected');
255 message + '; cell ' + cell_index + ' is the only cell selected');
256 }
256 }
257
257
258 // Mode specific tests.
258 // Mode specific tests.
259 if (mode==='command') {
259 if (mode==='command') {
260 // Are the notebook and keyboard manager in command mode?
260 // Are the notebook and keyboard manager in command mode?
261 this.test.assertEquals(this.get_keyboard_mode(), 'command',
261 this.test.assertEquals(this.get_keyboard_mode(), 'command',
262 message + '; in command mode');
262 message + '; in command mode');
263 // Make sure there isn't a single cell in edit mode.
263 // Make sure there isn't a single cell in edit mode.
264 this.test.assert(this.is_only_cell_edit(null),
264 this.test.assert(this.is_only_cell_edit(null),
265 message + '; all cells in command mode');
265 message + '; all cells in command mode');
266 this.test.assert(this.is_cell_editor_focused(null),
266 this.test.assert(this.is_cell_editor_focused(null),
267 message + '; no cell editors are focused while in command mode');
267 message + '; no cell editors are focused while in command mode');
268
268
269 } else if (mode==='edit') {
269 } else if (mode==='edit') {
270 // Are the notebook and keyboard manager in edit mode?
270 // Are the notebook and keyboard manager in edit mode?
271 this.test.assertEquals(this.get_keyboard_mode(), 'edit',
271 this.test.assertEquals(this.get_keyboard_mode(), 'edit',
272 message + '; in edit mode');
272 message + '; in edit mode');
273 if (cell_index!==undefined) {
273 if (cell_index!==undefined) {
274 // Is the specified cell the only cell in edit mode?
274 // Is the specified cell the only cell in edit mode?
275 this.test.assert(this.is_only_cell_edit(cell_index),
275 this.test.assert(this.is_only_cell_edit(cell_index),
276 message + '; cell ' + cell_index + ' is the only cell in edit mode');
276 message + '; cell ' + cell_index + ' is the only cell in edit mode');
277 // Is the specified cell the only cell with a focused code mirror?
277 // Is the specified cell the only cell with a focused code mirror?
278 this.test.assert(this.is_cell_editor_focused(cell_index),
278 this.test.assert(this.is_cell_editor_focused(cell_index),
279 message + '; cell ' + cell_index + '\'s editor is appropriately focused');
279 message + '; cell ' + cell_index + '\'s editor is appropriately focused');
280 }
280 }
281
281
282 } else {
282 } else {
283 this.test.assert(false, message + '; ' + mode + ' is an unknown mode');
283 this.test.assert(false, message + '; ' + mode + ' is an unknown mode');
284 }
284 }
285 };
285 };
286
286
287 casper.select_cell = function(index) {
287 casper.select_cell = function(index) {
288 // Select a cell in the notebook.
288 // Select a cell in the notebook.
289 this.evaluate(function (i) {
289 this.evaluate(function (i) {
290 IPython.notebook.select(i);
290 IPython.notebook.select(i);
291 }, {i: index});
291 }, {i: index});
292 };
292 };
293
293
294 casper.click_cell_editor = function(index) {
294 casper.click_cell_editor = function(index) {
295 // Emulate a click on a cell's editor.
295 // Emulate a click on a cell's editor.
296
296
297 // Code Mirror does not play nicely with emulated brower events.
297 // Code Mirror does not play nicely with emulated brower events.
298 // Instead of trying to emulate a click, here we run code similar to
298 // Instead of trying to emulate a click, here we run code similar to
299 // the code used in Code Mirror that handles the mousedown event on a
299 // the code used in Code Mirror that handles the mousedown event on a
300 // region of codemirror that the user can focus.
300 // region of codemirror that the user can focus.
301 this.evaluate(function (i) {
301 this.evaluate(function (i) {
302 var cm = IPython.notebook.get_cell(i).code_mirror;
302 var cm = IPython.notebook.get_cell(i).code_mirror;
303 if (cm.options.readOnly != "nocursor" && (document.activeElement != cm.display.input))
303 if (cm.options.readOnly != "nocursor" && (document.activeElement != cm.display.input))
304 cm.display.input.focus();
304 cm.display.input.focus();
305 }, {i: index});
305 }, {i: index});
306 };
306 };
307
307
308 casper.set_cell_editor_cursor = function(index, line_index, char_index) {
308 casper.set_cell_editor_cursor = function(index, line_index, char_index) {
309 // Set the Code Mirror instance cursor's location.
309 // Set the Code Mirror instance cursor's location.
310 this.evaluate(function (i, l, c) {
310 this.evaluate(function (i, l, c) {
311 IPython.notebook.get_cell(i).code_mirror.setCursor(l, c);
311 IPython.notebook.get_cell(i).code_mirror.setCursor(l, c);
312 }, {i: index, l: line_index, c: char_index});
312 }, {i: index, l: line_index, c: char_index});
313 };
313 };
314
314
315 casper.focus_notebook = function() {
315 casper.focus_notebook = function() {
316 // Focus the notebook div.
316 // Focus the notebook div.
317 this.evaluate(function (){
317 this.evaluate(function (){
318 $('#notebook').focus();
318 $('#notebook').focus();
319 }, {});
319 }, {});
320 };
320 };
321
321
322 casper.trigger_keydown = function() {
322 casper.trigger_keydown = function() {
323 // Emulate a keydown in the notebook.
323 // Emulate a keydown in the notebook.
324 for (var i = 0; i < arguments.length; i++) {
324 for (var i = 0; i < arguments.length; i++) {
325 this.evaluate(function (k) {
325 this.evaluate(function (k) {
326 var element = $(document);
326 var element = $(document);
327 var event = IPython.keyboard.shortcut_to_event(k, 'keydown');
327 var event = IPython.keyboard.shortcut_to_event(k, 'keydown');
328 element.trigger(event);
328 element.trigger(event);
329 }, {k: arguments[i]});
329 }, {k: arguments[i]});
330 }
330 }
331 };
331 };
332
332
333 casper.get_keyboard_mode = function() {
333 casper.get_keyboard_mode = function() {
334 // Get the mode of the keyboard manager.
334 // Get the mode of the keyboard manager.
335 return this.evaluate(function() {
335 return this.evaluate(function() {
336 return IPython.keyboard_manager.mode;
336 return IPython.keyboard_manager.mode;
337 }, {});
337 }, {});
338 };
338 };
339
339
340 casper.get_notebook_mode = function() {
340 casper.get_notebook_mode = function() {
341 // Get the mode of the notebook.
341 // Get the mode of the notebook.
342 return this.evaluate(function() {
342 return this.evaluate(function() {
343 return IPython.notebook.mode;
343 return IPython.notebook.mode;
344 }, {});
344 }, {});
345 };
345 };
346
346
347 casper.get_cell = function(index) {
347 casper.get_cell = function(index) {
348 // Get a single cell.
348 // Get a single cell.
349 //
349 //
350 // Note: Handles to DOM elements stored in the cell will be useless once in
350 // Note: Handles to DOM elements stored in the cell will be useless once in
351 // CasperJS context.
351 // CasperJS context.
352 return this.evaluate(function(i) {
352 return this.evaluate(function(i) {
353 var cell = IPython.notebook.get_cell(i);
353 var cell = IPython.notebook.get_cell(i);
354 if (cell) {
354 if (cell) {
355 return cell;
355 return cell;
356 }
356 }
357 return null;
357 return null;
358 }, {i : index});
358 }, {i : index});
359 };
359 };
360
360
361 casper.is_cell_editor_focused = function(index) {
361 casper.is_cell_editor_focused = function(index) {
362 // Make sure a cell's editor is the only editor focused on the page.
362 // Make sure a cell's editor is the only editor focused on the page.
363 return this.evaluate(function(i) {
363 return this.evaluate(function(i) {
364 var focused_textarea = $('#notebook .CodeMirror-focused textarea');
364 var focused_textarea = $('#notebook .CodeMirror-focused textarea');
365 if (focused_textarea.length > 1) { throw 'More than one Code Mirror editor is focused at once!'; }
365 if (focused_textarea.length > 1) { throw 'More than one Code Mirror editor is focused at once!'; }
366 if (i === null) {
366 if (i === null) {
367 return focused_textarea.length === 0;
367 return focused_textarea.length === 0;
368 } else {
368 } else {
369 var cell = IPython.notebook.get_cell(i);
369 var cell = IPython.notebook.get_cell(i);
370 if (cell) {
370 if (cell) {
371 return cell.code_mirror.getInputField() == focused_textarea[0];
371 return cell.code_mirror.getInputField() == focused_textarea[0];
372 }
372 }
373 }
373 }
374 return false;
374 return false;
375 }, {i : index});
375 }, {i : index});
376 };
376 };
377
377
378 casper.is_only_cell_selected = function(index) {
378 casper.is_only_cell_selected = function(index) {
379 // Check if a cell is the only cell selected.
379 // Check if a cell is the only cell selected.
380 // Pass null as the index to check if no cells are selected.
380 // Pass null as the index to check if no cells are selected.
381 return this.is_only_cell_on(index, 'selected', 'unselected');
381 return this.is_only_cell_on(index, 'selected', 'unselected');
382 };
382 };
383
383
384 casper.is_only_cell_edit = function(index) {
384 casper.is_only_cell_edit = function(index) {
385 // Check if a cell is the only cell in edit mode.
385 // Check if a cell is the only cell in edit mode.
386 // Pass null as the index to check if all of the cells are in command mode.
386 // Pass null as the index to check if all of the cells are in command mode.
387 return this.is_only_cell_on(index, 'edit_mode', 'command_mode');
387 return this.is_only_cell_on(index, 'edit_mode', 'command_mode');
388 };
388 };
389
389
390 casper.is_only_cell_on = function(i, on_class, off_class) {
390 casper.is_only_cell_on = function(i, on_class, off_class) {
391 // Check if a cell is the only cell with the `on_class` DOM class applied to it.
391 // Check if a cell is the only cell with the `on_class` DOM class applied to it.
392 // All of the other cells are checked for the `off_class` DOM class.
392 // All of the other cells are checked for the `off_class` DOM class.
393 // Pass null as the index to check if all of the cells have the `off_class`.
393 // Pass null as the index to check if all of the cells have the `off_class`.
394 var cells_length = this.get_cells_length();
394 var cells_length = this.get_cells_length();
395 for (var j = 0; j < cells_length; j++) {
395 for (var j = 0; j < cells_length; j++) {
396 if (j === i) {
396 if (j === i) {
397 if (this.cell_has_class(j, off_class) || !this.cell_has_class(j, on_class)) {
397 if (this.cell_has_class(j, off_class) || !this.cell_has_class(j, on_class)) {
398 return false;
398 return false;
399 }
399 }
400 } else {
400 } else {
401 if (!this.cell_has_class(j, off_class) || this.cell_has_class(j, on_class)) {
401 if (!this.cell_has_class(j, off_class) || this.cell_has_class(j, on_class)) {
402 return false;
402 return false;
403 }
403 }
404 }
404 }
405 }
405 }
406 return true;
406 return true;
407 };
407 };
408
408
409 casper.cell_has_class = function(index, classes) {
409 casper.cell_has_class = function(index, classes) {
410 // Check if a cell has a class.
410 // Check if a cell has a class.
411 return this.evaluate(function(i, c) {
411 return this.evaluate(function(i, c) {
412 var cell = IPython.notebook.get_cell(i);
412 var cell = IPython.notebook.get_cell(i);
413 if (cell) {
413 if (cell) {
414 return cell.element.hasClass(c);
414 return cell.element.hasClass(c);
415 }
415 }
416 return false;
416 return false;
417 }, {i : index, c: classes});
417 }, {i : index, c: classes});
418 };
418 };
419
419
420 casper.is_cell_rendered = function (index, msg) {
421 return this.evaluate(function(i) {
422 return !!IPython.notebook.get_cell(i).rendered;
423 }, {i:i});
424 };
425
420 casper.assert_colors_equal = function (hex_color, local_color, msg) {
426 casper.assert_colors_equal = function (hex_color, local_color, msg) {
421 // Tests to see if two colors are equal.
427 // Tests to see if two colors are equal.
422 //
428 //
423 // Parameters
429 // Parameters
424 // hex_color: string
430 // hex_color: string
425 // Hexadecimal color code, with or without preceeding hash character.
431 // Hexadecimal color code, with or without preceeding hash character.
426 // local_color: string
432 // local_color: string
427 // Local color representation. Can either be hexadecimal (default for
433 // Local color representation. Can either be hexadecimal (default for
428 // phantom) or rgb (default for slimer).
434 // phantom) or rgb (default for slimer).
429
435
430 // Remove parentheses, hashes, semi-colons, and space characters.
436 // Remove parentheses, hashes, semi-colons, and space characters.
431 hex_color = hex_color.replace(/[\(\); #]/, '');
437 hex_color = hex_color.replace(/[\(\); #]/, '');
432 local_color = local_color.replace(/[\(\); #]/, '');
438 local_color = local_color.replace(/[\(\); #]/, '');
433
439
434 // If the local color is rgb, clean it up and replace
440 // If the local color is rgb, clean it up and replace
435 if (local_color.substr(0,3).toLowerCase() == 'rgb') {
441 if (local_color.substr(0,3).toLowerCase() == 'rgb') {
436 components = local_color.substr(3).split(',');
442 components = local_color.substr(3).split(',');
437 local_color = '';
443 local_color = '';
438 for (var i = 0; i < components.length; i++) {
444 for (var i = 0; i < components.length; i++) {
439 var part = parseInt(components[i]).toString(16);
445 var part = parseInt(components[i]).toString(16);
440 while (part.length < 2) part = '0' + part;
446 while (part.length < 2) part = '0' + part;
441 local_color += part;
447 local_color += part;
442 }
448 }
443 }
449 }
444
450
445 this.test.assertEquals(hex_color.toUpperCase(), local_color.toUpperCase(), msg);
451 this.test.assertEquals(hex_color.toUpperCase(), local_color.toUpperCase(), msg);
446 };
452 };
447
453
448 casper.notebook_test = function(test) {
454 casper.notebook_test = function(test) {
449 // Wrap a notebook test to reduce boilerplate.
455 // Wrap a notebook test to reduce boilerplate.
450 //
456 //
451 // If you want to read parameters from the commandline, use the following
457 // If you want to read parameters from the commandline, use the following
452 // (i.e. value=):
458 // (i.e. value=):
453 // if (casper.cli.options.value) {
459 // if (casper.cli.options.value) {
454 // casper.exit(1);
460 // casper.exit(1);
455 // }
461 // }
456 this.open_new_notebook();
462 this.open_new_notebook();
457
463
458 // Echo whether or not we are running this test using SlimerJS
464 // Echo whether or not we are running this test using SlimerJS
459 if (this.evaluate(function(){
465 if (this.evaluate(function(){
460 return typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
466 return typeof InstallTrigger !== 'undefined'; // Firefox 1.0+
461 })) { console.log('This test is running in SlimerJS.'); }
467 })) { console.log('This test is running in SlimerJS.'); }
462
468
463 // Make sure to remove the onbeforeunload callback. This callback is
469 // Make sure to remove the onbeforeunload callback. This callback is
464 // responsable for the "Are you sure you want to quit?" type messages.
470 // responsable for the "Are you sure you want to quit?" type messages.
465 // PhantomJS ignores these prompts, SlimerJS does not which causes hangs.
471 // PhantomJS ignores these prompts, SlimerJS does not which causes hangs.
466 this.then(function(){
472 this.then(function(){
467 this.evaluate(function(){
473 this.evaluate(function(){
468 window.onbeforeunload = function(){};
474 window.onbeforeunload = function(){};
469 });
475 });
470 });
476 });
471
477
472 this.then(test);
478 this.then(test);
473
479
474 // Kill the kernel and delete the notebook.
480 // Kill the kernel and delete the notebook.
475 this.shutdown_current_kernel();
481 this.shutdown_current_kernel();
476 // This is still broken but shouldn't be a problem for now.
482 // This is still broken but shouldn't be a problem for now.
477 // this.delete_current_notebook();
483 // this.delete_current_notebook();
478
484
479 // This is required to clean up the page we just finished with. If we don't call this
485 // This is required to clean up the page we just finished with. If we don't call this
480 // casperjs will leak file descriptors of all the open WebSockets in that page. We
486 // casperjs will leak file descriptors of all the open WebSockets in that page. We
481 // have to set this.page=null so that next time casper.start runs, it will create a
487 // have to set this.page=null so that next time casper.start runs, it will create a
482 // new page from scratch.
488 // new page from scratch.
483 this.then(function () {
489 this.then(function () {
484 this.page.close();
490 this.page.close();
485 this.page = null;
491 this.page = null;
486 });
492 });
487
493
488 // Run the browser automation.
494 // Run the browser automation.
489 this.run(function() {
495 this.run(function() {
490 this.test.done();
496 this.test.done();
491 });
497 });
492 };
498 };
493
499
494 casper.wait_for_dashboard = function () {
500 casper.wait_for_dashboard = function () {
495 // Wait for the dashboard list to load.
501 // Wait for the dashboard list to load.
496 casper.waitForSelector('.list_item');
502 casper.waitForSelector('.list_item');
497 };
503 };
498
504
499 casper.open_dashboard = function () {
505 casper.open_dashboard = function () {
500 // Start casper by opening the dashboard page.
506 // Start casper by opening the dashboard page.
501 var baseUrl = this.get_notebook_server();
507 var baseUrl = this.get_notebook_server();
502 this.start(baseUrl);
508 this.start(baseUrl);
503 this.wait_for_dashboard();
509 this.wait_for_dashboard();
504 };
510 };
505
511
506 casper.dashboard_test = function (test) {
512 casper.dashboard_test = function (test) {
507 // Open the dashboard page and run a test.
513 // Open the dashboard page and run a test.
508 this.open_dashboard();
514 this.open_dashboard();
509 this.then(test);
515 this.then(test);
510
516
511 this.then(function () {
517 this.then(function () {
512 this.page.close();
518 this.page.close();
513 this.page = null;
519 this.page = null;
514 });
520 });
515
521
516 // Run the browser automation.
522 // Run the browser automation.
517 this.run(function() {
523 this.run(function() {
518 this.test.done();
524 this.test.done();
519 });
525 });
520 };
526 };
521
527
522 casper.options.waitTimeout=10000;
528 casper.options.waitTimeout=10000;
523 casper.on('waitFor.timeout', function onWaitForTimeout(timeout) {
529 casper.on('waitFor.timeout', function onWaitForTimeout(timeout) {
524 this.echo("Timeout for " + casper.get_notebook_server());
530 this.echo("Timeout for " + casper.get_notebook_server());
525 this.echo("Is the notebook server running?");
531 this.echo("Is the notebook server running?");
526 });
532 });
527
533
528 casper.print_log = function () {
534 casper.print_log = function () {
529 // Pass `console.log` calls from page JS to casper.
535 // Pass `console.log` calls from page JS to casper.
530 this.on('remote.message', function(msg) {
536 this.on('remote.message', function(msg) {
531 this.echo('Remote message caught: ' + msg);
537 this.echo('Remote message caught: ' + msg);
532 });
538 });
533 };
539 };
General Comments 0
You need to be logged in to leave comments. Login now