##// END OF EJS Templates
Merge pull request #4953 from minrk/wait-for-idle...
Thomas Kluyver -
r14938:b91d6a65 merge
parent child Browse files
Show More
@@ -1,222 +1,240 b''
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
4
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 casper.get_notebook_server = function () {
6 casper.get_notebook_server = function () {
7 port = casper.cli.get("port")
7 port = casper.cli.get("port")
8 port = (typeof port === 'undefined') ? '8888' : port;
8 port = (typeof port === 'undefined') ? '8888' : port;
9 return 'http://127.0.0.1:' + port
9 return 'http://127.0.0.1:' + port
10 };
10 };
11
11
12 // Create and open a new notebook.
12 // Create and open a new notebook.
13 casper.open_new_notebook = function () {
13 casper.open_new_notebook = function () {
14 var baseUrl = this.get_notebook_server();
14 var baseUrl = this.get_notebook_server();
15 this.start(baseUrl);
15 this.start(baseUrl);
16 this.thenClick('button#new_notebook');
16 this.thenClick('button#new_notebook');
17 this.waitForPopup('');
17 this.waitForPopup('');
18
18
19 this.withPopup('', function () {this.waitForSelector('.CodeMirror-code');});
19 this.withPopup('', function () {this.waitForSelector('.CodeMirror-code');});
20 this.then(function () {
20 this.then(function () {
21 // XXX: Kind of odd, the next line works for one test, but not when
21 // XXX: Kind of odd, the next line works for one test, but not when
22 // running multiple tests back-to-back, so we will just point the main
22 // running multiple tests back-to-back, so we will just point the main
23 // casper browser to the same URL as the popup we just grabbed.
23 // casper browser to the same URL as the popup we just grabbed.
24
24
25 //this.page = this.popups[0];
25 //this.page = this.popups[0];
26 this.open(this.popups[0].url);
26 this.open(this.popups[0].url);
27 });
27 });
28
28
29 // initially, the cells aren't created, so wait for them to appear
29 // initially, the cells aren't created, so wait for them to appear
30 this.waitForSelector('.CodeMirror-code');
30 this.waitForSelector('.CodeMirror-code');
31 // and make sure the kernel has started
31 // and make sure the kernel has started
32 this.waitFor( this.kernel_running );
32 this.waitFor( this.kernel_running );
33 // track the IPython busy/idle state
34 this.thenEvaluate(function () {
35 $([IPython.events]).on('status_idle.Kernel',function () {
36 IPython._status = 'idle';
37 });
38 $([IPython.events]).on('status_busy.Kernel',function () {
39 IPython._status = 'busy';
40 });
41 });
33 };
42 };
34
43
35 // return whether or not the kernel is running
44 // return whether or not the kernel is running
36 casper.kernel_running = function kernel_running() {
45 casper.kernel_running = function kernel_running() {
37 return this.evaluate(function kernel_running() {
46 return this.evaluate(function kernel_running() {
38 return IPython.notebook.kernel.running;
47 return IPython.notebook.kernel.running;
39 });
48 });
40 };
49 };
41
50
42 // Shut down the current notebook's kernel.
51 // Shut down the current notebook's kernel.
43 casper.shutdown_current_kernel = function () {
52 casper.shutdown_current_kernel = function () {
44 this.thenEvaluate(function() {
53 this.thenEvaluate(function() {
45 IPython.notebook.kernel.kill();
54 IPython.notebook.kernel.kill();
46 });
55 });
47 };
56 };
48
57
49 // Delete created notebook.
58 // Delete created notebook.
50 casper.delete_current_notebook = function () {
59 casper.delete_current_notebook = function () {
51 this.thenEvaluate(function() {
60 this.thenEvaluate(function() {
52 var nbData = $('body').data();
61 var nbData = $('body').data();
53 var url = nbData.baseProjectUrl + 'notebooks/' + nbData.notebookId;
62 var url = nbData.baseProjectUrl + 'notebooks/' + nbData.notebookId;
54 $.ajax(url, {
63 $.ajax(url, {
55 type: 'DELETE',
64 type: 'DELETE',
56 });
65 });
57 });
66 });
58 };
67 };
59
68
69 casper.wait_for_idle = function () {
70 this.waitFor(function () {
71 return this.evaluate(function () {
72 return IPython._status == 'idle';
73 });
74 });
75 };
76
60 // wait for the nth output in a given cell
77 // wait for the nth output in a given cell
61 casper.wait_for_output = function (cell_num, out_num) {
78 casper.wait_for_output = function (cell_num, out_num) {
79 this.wait_for_idle();
62 out_num = out_num || 0;
80 out_num = out_num || 0;
63 this.then(function() {
81 this.then(function() {
64 this.waitFor(function (c, o) {
82 this.waitFor(function (c, o) {
65 return this.evaluate(function get_output(c, o) {
83 return this.evaluate(function get_output(c, o) {
66 var cell = IPython.notebook.get_cell(c);
84 var cell = IPython.notebook.get_cell(c);
67 return cell.output_area.outputs.length > o;
85 return cell.output_area.outputs.length > o;
68 },
86 },
69 // pass parameter from the test suite js to the browser code js
87 // pass parameter from the test suite js to the browser code js
70 {c : cell_num, o : out_num});
88 {c : cell_num, o : out_num});
71 });
89 });
72 },
90 },
73 function then() { },
91 function then() { },
74 function timeout() {
92 function timeout() {
75 this.echo("wait_for_output timed out!");
93 this.echo("wait_for_output timed out!");
76 });
94 });
77 };
95 };
78
96
79 // return an output of a given cell
97 // return an output of a given cell
80 casper.get_output_cell = function (cell_num, out_num) {
98 casper.get_output_cell = function (cell_num, out_num) {
81 out_num = out_num || 0;
99 out_num = out_num || 0;
82 var result = casper.evaluate(function (c, o) {
100 var result = casper.evaluate(function (c, o) {
83 var cell = IPython.notebook.get_cell(c);
101 var cell = IPython.notebook.get_cell(c);
84 return cell.output_area.outputs[o];
102 return cell.output_area.outputs[o];
85 },
103 },
86 {c : cell_num, o : out_num});
104 {c : cell_num, o : out_num});
87 if (!result) {
105 if (!result) {
88 var num_outputs = casper.evaluate(function (c) {
106 var num_outputs = casper.evaluate(function (c) {
89 var cell = IPython.notebook.get_cell(c);
107 var cell = IPython.notebook.get_cell(c);
90 return cell.output_area.outputs.length;
108 return cell.output_area.outputs.length;
91 },
109 },
92 {c : cell_num});
110 {c : cell_num});
93 this.test.assertTrue(false,
111 this.test.assertTrue(false,
94 "Cell " + cell_num + " has no output #" + out_num + " (" + num_outputs + " total)"
112 "Cell " + cell_num + " has no output #" + out_num + " (" + num_outputs + " total)"
95 );
113 );
96 } else {
114 } else {
97 return result;
115 return result;
98 }
116 }
99 };
117 };
100
118
101 // return the number of cells in the notebook
119 // return the number of cells in the notebook
102 casper.get_cells_length = function () {
120 casper.get_cells_length = function () {
103 var result = casper.evaluate(function () {
121 var result = casper.evaluate(function () {
104 return IPython.notebook.get_cells().length;
122 return IPython.notebook.get_cells().length;
105 })
123 })
106 return result;
124 return result;
107 };
125 };
108
126
109 // Set the text content of a cell.
127 // Set the text content of a cell.
110 casper.set_cell_text = function(index, text){
128 casper.set_cell_text = function(index, text){
111 this.evaluate(function (index, text) {
129 this.evaluate(function (index, text) {
112 var cell = IPython.notebook.get_cell(index);
130 var cell = IPython.notebook.get_cell(index);
113 cell.set_text(text);
131 cell.set_text(text);
114 }, index, text);
132 }, index, text);
115 };
133 };
116
134
117 // Inserts a cell at the bottom of the notebook
135 // Inserts a cell at the bottom of the notebook
118 // Returns the new cell's index.
136 // Returns the new cell's index.
119 casper.insert_cell_at_bottom = function(cell_type){
137 casper.insert_cell_at_bottom = function(cell_type){
120 if (cell_type===undefined) {
138 if (cell_type===undefined) {
121 cell_type = 'code';
139 cell_type = 'code';
122 }
140 }
123
141
124 return this.evaluate(function (cell_type) {
142 return this.evaluate(function (cell_type) {
125 var cell = IPython.notebook.insert_cell_at_bottom(cell_type);
143 var cell = IPython.notebook.insert_cell_at_bottom(cell_type);
126 return IPython.notebook.find_cell_index(cell);
144 return IPython.notebook.find_cell_index(cell);
127 }, cell_type);
145 }, cell_type);
128 };
146 };
129
147
130 // Insert a cell at the bottom of the notebook and set the cells text.
148 // Insert a cell at the bottom of the notebook and set the cells text.
131 // Returns the new cell's index.
149 // Returns the new cell's index.
132 casper.append_cell = function(text, cell_type) {
150 casper.append_cell = function(text, cell_type) {
133 var index = this.insert_cell_at_bottom(cell_type);
151 var index = this.insert_cell_at_bottom(cell_type);
134 if (text !== undefined) {
152 if (text !== undefined) {
135 this.set_cell_text(index, text);
153 this.set_cell_text(index, text);
136 }
154 }
137 return index;
155 return index;
138 };
156 };
139
157
140 // Asynchronously executes a cell by index.
158 // Asynchronously executes a cell by index.
141 // Returns the cell's index.
159 // Returns the cell's index.
142 casper.execute_cell = function(index){
160 casper.execute_cell = function(index){
143 var that = this;
161 var that = this;
144 this.then(function(){
162 this.then(function(){
145 that.evaluate(function (index) {
163 that.evaluate(function (index) {
146 var cell = IPython.notebook.get_cell(index);
164 var cell = IPython.notebook.get_cell(index);
147 cell.execute();
165 cell.execute();
148 }, index);
166 }, index);
149 });
167 });
150 return index;
168 return index;
151 };
169 };
152
170
153 // Synchronously executes a cell by index.
171 // Synchronously executes a cell by index.
154 // Optionally accepts a then_callback parameter. then_callback will get called
172 // Optionally accepts a then_callback parameter. then_callback will get called
155 // when the cell has finished executing.
173 // when the cell has finished executing.
156 // Returns the cell's index.
174 // Returns the cell's index.
157 casper.execute_cell_then = function(index, then_callback) {
175 casper.execute_cell_then = function(index, then_callback) {
158 var return_val = this.execute_cell(index);
176 var return_val = this.execute_cell(index);
159
177
160 this.wait_for_output(index);
178 this.wait_for_idle();
161
179
162 var that = this;
180 var that = this;
163 this.then(function(){
181 this.then(function(){
164 if (then_callback!==undefined) {
182 if (then_callback!==undefined) {
165 then_callback.apply(that, [index]);
183 then_callback.apply(that, [index]);
166 }
184 }
167 });
185 });
168
186
169 return return_val;
187 return return_val;
170 };
188 };
171
189
172 // Utility function that allows us to easily check if an element exists
190 // Utility function that allows us to easily check if an element exists
173 // within a cell. Uses JQuery selector to look for the element.
191 // within a cell. Uses JQuery selector to look for the element.
174 casper.cell_element_exists = function(index, selector){
192 casper.cell_element_exists = function(index, selector){
175 return casper.evaluate(function (index, selector) {
193 return casper.evaluate(function (index, selector) {
176 var $cell = IPython.notebook.get_cell(index).element;
194 var $cell = IPython.notebook.get_cell(index).element;
177 return $cell.find(selector).length > 0;
195 return $cell.find(selector).length > 0;
178 }, index, selector);
196 }, index, selector);
179 };
197 };
180
198
181 // Utility function that allows us to execute a jQuery function on an
199 // Utility function that allows us to execute a jQuery function on an
182 // element within a cell.
200 // element within a cell.
183 casper.cell_element_function = function(index, selector, function_name, function_args){
201 casper.cell_element_function = function(index, selector, function_name, function_args){
184 return casper.evaluate(function (index, selector, function_name, function_args) {
202 return casper.evaluate(function (index, selector, function_name, function_args) {
185 var $cell = IPython.notebook.get_cell(index).element;
203 var $cell = IPython.notebook.get_cell(index).element;
186 var $el = $cell.find(selector);
204 var $el = $cell.find(selector);
187 return $el[function_name].apply($el, function_args);
205 return $el[function_name].apply($el, function_args);
188 }, index, selector, function_name, function_args);
206 }, index, selector, function_name, function_args);
189 };
207 };
190
208
191 // Wrap a notebook test to reduce boilerplate.
209 // Wrap a notebook test to reduce boilerplate.
192 casper.notebook_test = function(test) {
210 casper.notebook_test = function(test) {
193 this.open_new_notebook();
211 this.open_new_notebook();
194 this.then(test);
212 this.then(test);
195 //XXX: we get sporadic error messages when shutting down some of the tests.
213 //XXX: we get sporadic error messages when shutting down some of the tests.
196 // Since the entire server will go down at the end of running the test
214 // Since the entire server will go down at the end of running the test
197 // suite, it's ok for now to not try to shut anything down.
215 // suite, it's ok for now to not try to shut anything down.
198 this.shutdown_current_kernel();
216 this.shutdown_current_kernel();
199
217
200 //XXX: the implementation of delete_current_notebook is currently broken
218 //XXX: the implementation of delete_current_notebook is currently broken
201 // it's not a big deal, since the notebook directory will be deleted on
219 // it's not a big deal, since the notebook directory will be deleted on
202 // cleanup, but we should add tests for deleting the notebook separately
220 // cleanup, but we should add tests for deleting the notebook separately
203 //this.delete_current_notebook();
221 //this.delete_current_notebook();
204
222
205 // Run the browser automation.
223 // Run the browser automation.
206 this.run(function() {
224 this.run(function() {
207 this.test.done();
225 this.test.done();
208 });
226 });
209 };
227 };
210
228
211 casper.options.waitTimeout=10000
229 casper.options.waitTimeout=10000
212 casper.on('waitFor.timeout', function onWaitForTimeout(timeout) {
230 casper.on('waitFor.timeout', function onWaitForTimeout(timeout) {
213 this.echo("Timeout for " + casper.get_notebook_server());
231 this.echo("Timeout for " + casper.get_notebook_server());
214 this.echo("Is the notebook server running?");
232 this.echo("Is the notebook server running?");
215 });
233 });
216
234
217 // Pass `console.log` calls from page JS to casper.
235 // Pass `console.log` calls from page JS to casper.
218 casper.printLog = function () {
236 casper.printLog = function () {
219 this.on('remote.message', function(msg) {
237 this.on('remote.message', function(msg) {
220 this.echo('Remote message caught: ' + msg);
238 this.echo('Remote message caught: ' + msg);
221 });
239 });
222 };
240 };
General Comments 0
You need to be logged in to leave comments. Login now