Merge pull request #5290 from jdfreder/dual_tests

Add dual mode JS tests
Thomas Kluyver 12 years ago
commit 982aab67ba

@ -128,15 +128,6 @@ IPython.keyboard = (function (IPython) {
return shortcut;
};
var trigger_keydown = function (shortcut, element) {
// Trigger shortcut keydown on an element
element = element || document;
element = $(element);
var event = shortcut_to_event(shortcut, 'keydown');
element.trigger(event);
};
// Shortcut manager class
var ShortcutManager = function (delay) {
@ -262,8 +253,7 @@ IPython.keyboard = (function (IPython) {
normalize_key : normalize_key,
normalize_shortcut : normalize_shortcut,
shortcut_to_event : shortcut_to_event,
event_to_shortcut : event_to_shortcut,
trigger_keydown : trigger_keydown
event_to_shortcut : event_to_shortcut
};
}(IPython));

@ -0,0 +1,78 @@
// Test the notebook dual mode feature.
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
var b = 'print("b")';
index = this.append_cell(b);
this.execute_cell_then(index);
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
this.then(function () {
this.validate_notebook_state('initial state', 'edit', 0);
this.trigger_keydown('esc');
this.validate_notebook_state('esc', 'command', 0);
this.trigger_keydown('down');
this.validate_notebook_state('down', 'command', 1);
this.trigger_keydown('enter');
this.validate_notebook_state('enter', 'edit', 1);
this.trigger_keydown('j');
this.validate_notebook_state('j in edit mode', 'edit', 1);
this.trigger_keydown('esc');
this.validate_notebook_state('esc', 'command', 1);
this.trigger_keydown('j');
this.validate_notebook_state('j in command mode', 'command', 2);
this.click_cell_editor(0);
this.validate_notebook_state('click cell 0', 'edit', 0);
this.click_cell_editor(3);
this.validate_notebook_state('click cell 3', 'edit', 3);
this.trigger_keydown('esc');
this.validate_notebook_state('esc', 'command', 3);
// Open keyboard help
this.evaluate(function(){
$('#keyboard_shortcuts a').click();
}, {});
this.trigger_keydown('k');
this.validate_notebook_state('k in command mode while keyboard help is up', 'command', 3);
// Close keyboard help
this.evaluate(function(){
$('div.modal button.close').click();
}, {});
this.trigger_keydown('k');
this.validate_notebook_state('k in command mode', 'command', 2);
this.click_cell_editor(0);
this.validate_notebook_state('click cell 0', 'edit', 0);
this.focus_notebook();
this.validate_notebook_state('focus #notebook', 'command', 0);
this.click_cell_editor(0);
this.validate_notebook_state('click cell 0', 'edit', 0);
this.focus_notebook();
this.validate_notebook_state('focus #notebook', 'command', 0);
this.click_cell_editor(3);
this.validate_notebook_state('click cell 3', 'edit', 3);
// Cell deletion
this.trigger_keydown('esc', 'd', 'd');
this.test.assertEquals(this.get_cells_length(), 3, 'dd actually deletes a cell');
this.validate_notebook_state('dd', 'command', 2);
// Make sure that if the time between d presses is too long, nothing gets removed.
this.trigger_keydown('d');
});
this.wait(1000);
this.then(function () {
this.trigger_keydown('d');
this.test.assertEquals(this.get_cells_length(), 3, "d, 1 second wait, d doesn't delete a cell");
this.validate_notebook_state('d, 1 second wait, d', 'command', 2);
});
});

@ -0,0 +1,51 @@
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
var b = 'print("b")';
index = this.append_cell(b);
this.execute_cell_then(index);
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
this.then(function () {
// Up and down in command mode
this.select_cell(3);
this.trigger_keydown('j');
this.validate_notebook_state('j at end of notebook', 'command', 3);
this.trigger_keydown('down');
this.validate_notebook_state('down at end of notebook', 'command', 3);
this.trigger_keydown('up');
this.validate_notebook_state('up', 'command', 2);
this.select_cell(0);
this.validate_notebook_state('select 0', 'command', 0);
this.trigger_keydown('k');
this.validate_notebook_state('k at top of notebook', 'command', 0);
this.trigger_keydown('up');
this.validate_notebook_state('up at top of notebook', 'command', 0);
this.trigger_keydown('down');
this.validate_notebook_state('down', 'command', 1);
// Up and down in edit mode
this.click_cell_editor(3);
this.validate_notebook_state('click cell 3', 'edit', 3);
this.trigger_keydown('down');
this.validate_notebook_state('down at end of notebook', 'edit', 3);
this.set_cell_editor_cursor(3, 0, 0);
this.trigger_keydown('up');
this.validate_notebook_state('up', 'edit', 2);
this.click_cell_editor(0);
this.validate_notebook_state('click 0', 'edit', 0);
this.trigger_keydown('up');
this.validate_notebook_state('up at top of notebook', 'edit', 0);
this.set_cell_editor_cursor(0, 0, 10);
this.trigger_keydown('down');
this.validate_notebook_state('down', 'edit', 1);
});
});

@ -0,0 +1,27 @@
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
var b = 'print("b")';
index = this.append_cell(b);
this.execute_cell_then(index);
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
this.then(function () {
// Cell insertion
this.select_cell(2);
this.trigger_keydown('a'); // Creates one cell
this.test.assertEquals(this.get_cell_text(2), '', 'a; New cell 2 text is empty');
this.validate_notebook_state('a', 'command', 2);
this.trigger_keydown('b'); // Creates one cell
this.test.assertEquals(this.get_cell_text(2), '', 'b; Cell 2 text is still empty');
this.test.assertEquals(this.get_cell_text(3), '', 'b; New cell 3 text is empty');
this.validate_notebook_state('b', 'command', 3);
});
});

@ -0,0 +1,28 @@
// Test keyboard shortcuts that change the cell's mode.
// Test
casper.notebook_test(function () {
this.then(function () {
// Cell mode change
this.select_cell(0);
this.trigger_keydown('esc','r');
this.test.assertEquals(this.get_cell(0).cell_type, 'raw', 'r; cell is raw');
this.trigger_keydown('1');
this.test.assertEquals(this.get_cell(0).cell_type, 'heading', '1; cell is heading');
this.test.assertEquals(this.get_cell(0).level, 1, '1; cell is level 1 heading');
this.trigger_keydown('2');
this.test.assertEquals(this.get_cell(0).level, 2, '2; cell is level 2 heading');
this.trigger_keydown('3');
this.test.assertEquals(this.get_cell(0).level, 3, '3; cell is level 3 heading');
this.trigger_keydown('4');
this.test.assertEquals(this.get_cell(0).level, 4, '4; cell is level 4 heading');
this.trigger_keydown('5');
this.test.assertEquals(this.get_cell(0).level, 5, '5; cell is level 5 heading');
this.trigger_keydown('6');
this.test.assertEquals(this.get_cell(0).level, 6, '6; cell is level 6 heading');
this.trigger_keydown('m');
this.test.assertEquals(this.get_cell(0).cell_type, 'markdown', 'm; cell is markdown');
this.trigger_keydown('y');
this.test.assertEquals(this.get_cell(0).cell_type, 'code', 'y; cell is code');
});
});

@ -0,0 +1,55 @@
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
var b = 'print("b")';
index = this.append_cell(b);
this.execute_cell_then(index);
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
this.then(function () {
// Copy/paste/cut
var num_cells = this.get_cells_length();
this.test.assertEquals(this.get_cell_text(1), a, 'Verify that cell 1 is a');
this.select_cell(1);
this.trigger_keydown('x'); // Cut
this.validate_notebook_state('x', 'command', 1);
this.test.assertEquals(this.get_cells_length(), num_cells-1, 'Verify that a cell was removed.');
this.test.assertEquals(this.get_cell_text(1), b, 'Verify that cell 2 is now where cell 1 was.');
this.select_cell(2);
this.trigger_keydown('v'); // Paste
this.validate_notebook_state('v', 'command', 3); // Selection should move to pasted cell, below current cell.
this.test.assertEquals(this.get_cell_text(3), a, 'Verify that cell 3 has the cut contents.');
this.test.assertEquals(this.get_cells_length(), num_cells, 'Verify a the cell was added.');
this.trigger_keydown('v'); // Paste
this.validate_notebook_state('v', 'command', 4); // Selection should move to pasted cell, below current cell.
this.test.assertEquals(this.get_cell_text(4), a, 'Verify that cell 4 has the cut contents.');
this.test.assertEquals(this.get_cells_length(), num_cells+1, 'Verify a the cell was added.');
this.select_cell(1);
this.trigger_keydown('c'); // Copy
this.validate_notebook_state('c', 'command', 1);
this.test.assertEquals(this.get_cell_text(1), b, 'Verify that cell 1 is b');
this.select_cell(2);
this.trigger_keydown('c'); // Copy
this.validate_notebook_state('c', 'command', 2);
this.test.assertEquals(this.get_cell_text(2), c, 'Verify that cell 2 is c');
this.select_cell(4);
this.trigger_keydown('v'); // Paste
this.validate_notebook_state('v', 'command', 5);
this.test.assertEquals(this.get_cell_text(2), c, 'Verify that cell 2 still has the copied contents.');
this.test.assertEquals(this.get_cell_text(5), c, 'Verify that cell 5 has the copied contents.');
this.test.assertEquals(this.get_cells_length(), num_cells+2, 'Verify a the cell was added.');
this.select_cell(0);
this.trigger_keydown('shift-v'); // Paste
this.validate_notebook_state('shift-v', 'command', 0);
this.test.assertEquals(this.get_cell_text(0), c, 'Verify that cell 0 has the copied contents.');
this.test.assertEquals(this.get_cells_length(), num_cells+3, 'Verify a the cell was added.');
});
});

@ -0,0 +1,72 @@
// Test keyboard invoked execution.
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
var b = 'print("b")';
index = this.append_cell(b);
this.execute_cell_then(index);
var c = 'print("c")';
index = this.append_cell(c);
this.execute_cell_then(index);
this.then(function () {
// shift-enter
// last cell in notebook
var base_index = 3;
this.select_cell(base_index);
this.trigger_keydown('shift-enter'); // Creates one cell
this.validate_notebook_state('shift-enter (no cell below)', 'edit', base_index + 1);
// not last cell in notebook & starts in edit mode
this.click_cell_editor(base_index);
this.validate_notebook_state('click cell ' + base_index, 'edit', base_index);
this.trigger_keydown('shift-enter');
this.validate_notebook_state('shift-enter (cell exists below)', 'command', base_index + 1);
// starts in command mode
this.trigger_keydown('k');
this.validate_notebook_state('k in comand mode', 'command', base_index);
this.trigger_keydown('shift-enter');
this.validate_notebook_state('shift-enter (start in command mode)', 'command', base_index + 1);
// ctrl-enter
// last cell in notebook
base_index++;
this.trigger_keydown('ctrl-enter');
this.validate_notebook_state('ctrl-enter (no cell below)', 'command', base_index);
// not last cell in notebook & starts in edit mode
this.click_cell_editor(base_index-1);
this.validate_notebook_state('click cell ' + (base_index-1), 'edit', base_index-1);
this.trigger_keydown('ctrl-enter');
this.validate_notebook_state('ctrl-enter (cell exists below)', 'command', base_index-1);
// starts in command mode
this.trigger_keydown('j');
this.validate_notebook_state('j in comand mode', 'command', base_index);
this.trigger_keydown('ctrl-enter');
this.validate_notebook_state('ctrl-enter (start in command mode)', 'command', base_index);
// alt-enter
// last cell in notebook
this.trigger_keydown('alt-enter'); // Creates one cell
this.validate_notebook_state('alt-enter (no cell below)', 'edit', base_index + 1);
// not last cell in notebook & starts in edit mode
this.click_cell_editor(base_index);
this.validate_notebook_state('click cell ' + base_index, 'edit', base_index);
this.trigger_keydown('alt-enter'); // Creates one cell
this.validate_notebook_state('alt-enter (cell exists below)', 'edit', base_index + 1);
// starts in command mode
this.trigger_keydown('esc', 'k');
this.validate_notebook_state('k in comand mode', 'command', base_index);
this.trigger_keydown('alt-enter'); // Creates one cell
this.validate_notebook_state('alt-enter (start in command mode)', 'edit', base_index + 1);
// Notebook will now have 8 cells, the index of the last cell will be 7.
this.test.assertEquals(this.get_cells_length(), 8, '*-enter commands added cells where needed.');
this.select_cell(7);
this.validate_notebook_state('click cell ' + 7 + ' and esc', 'command', 7);
});
});

@ -0,0 +1,39 @@
// Test
casper.notebook_test(function () {
var a = 'print("a")';
var index = this.append_cell(a);
this.execute_cell_then(index);
this.then(function () {
// Markdown rendering / unredering
this.select_cell(1);
this.validate_notebook_state('select 1', 'command', 1);
this.trigger_keydown('m');
this.test.assertEquals(this.get_cell(1).cell_type, 'markdown', 'm; cell is markdown');
this.test.assertEquals(this.get_cell(1).rendered, false, 'm; cell is rendered');
this.trigger_keydown('enter');
this.test.assertEquals(this.get_cell(1).rendered, false, 'enter; cell is unrendered');
this.validate_notebook_state('enter', 'edit', 1);
this.trigger_keydown('ctrl-enter');
this.test.assertEquals(this.get_cell(1).rendered, true, 'ctrl-enter; cell is rendered');
this.validate_notebook_state('enter', 'command', 1);
this.trigger_keydown('enter');
this.test.assertEquals(this.get_cell(1).rendered, false, 'enter; cell is unrendered');
this.select_cell(0);
this.test.assertEquals(this.get_cell(1).rendered, false, 'select 0; cell 1 is still unrendered');
this.validate_notebook_state('select 0', 'command', 0);
this.select_cell(1);
this.validate_notebook_state('select 1', 'command', 1);
this.trigger_keydown('ctrl-enter');
this.test.assertEquals(this.get_cell(1).rendered, true, 'ctrl-enter; cell is rendered');
this.select_cell(0);
this.validate_notebook_state('select 0', 'command', 0);
this.trigger_keydown('shift-enter');
this.validate_notebook_state('shift-enter', 'command', 1);
this.test.assertEquals(this.get_cell(1).rendered, true, 'shift-enter; cell is rendered');
this.trigger_keydown('shift-enter'); // Creates one cell
this.validate_notebook_state('shift-enter', 'edit', 2);
this.test.assertEquals(this.get_cell(1).rendered, true, 'shift-enter; cell is rendered');
});
});

@ -0,0 +1,21 @@
// Test
casper.notebook_test(function () {
this.then(function () {
// Split and merge cells
this.select_cell(0);
this.trigger_keydown('a', 'enter'); // Create cell above and enter edit mode.
this.validate_notebook_state('a, enter', 'edit', 0);
this.set_cell_text(0, 'abcd');
this.set_cell_editor_cursor(0, 0, 2);
this.test.assertEquals(this.get_cell_text(0), 'abcd', 'Verify that cell 0 has the new contents.');
this.trigger_keydown('ctrl-shift-subtract'); // Split
this.test.assertEquals(this.get_cell_text(0), 'ab', 'split; Verify that cell 0 has the first half.');
this.test.assertEquals(this.get_cell_text(1), 'cd', 'split; Verify that cell 1 has the second half.');
this.validate_notebook_state('split', 'edit', 1);
this.select_cell(0); // Move up to cell 0
this.trigger_keydown('shift-m'); // Merge
this.validate_notebook_state('merge', 'command', 0);
this.test.assertEquals(this.get_cell_text(0), 'ab\ncd', 'merge; Verify that cell 0 has the merged contents.');
});
});

@ -10,12 +10,12 @@ casper.notebook_test(function () {
for (i = 0; i < ncells; i++) {
IPython.notebook.delete_cell();
}
// Simulate the "up arrow" and "down arrow" keys.
//
IPython.keyboard.trigger_keydown('up');
IPython.keyboard.trigger_keydown('down');
return true;
});
// Simulate the "up arrow" and "down arrow" keys.
this.trigger_keydown('up');
this.trigger_keydown('down');
this.test.assertTrue(result, 'Up/down arrow okay in empty notebook.');
});

@ -22,7 +22,11 @@ casper.notebook_test(function () {
var cell = IPython.notebook.get_cell(0);
cell.set_text('a=11; print(a)');
cell.clear_output();
IPython.keyboard.trigger_keydown('shift-enter');
});
this.then(function(){
this.trigger_keydown('shift-enter');
});
this.wait_for_output(0);
@ -41,7 +45,10 @@ casper.notebook_test(function () {
var cell = IPython.notebook.get_cell(0);
cell.set_text('a=12; print(a)');
cell.clear_output();
IPython.keyboard.trigger_keydown('ctrl-enter');
});
this.then(function(){
this.trigger_keydown('ctrl-enter');
});
this.wait_for_output(0);

@ -31,8 +31,8 @@ casper.notebook_test(function () {
});
// interrupt using Ctrl-M I keyboard shortcut
this.thenEvaluate( function() {
IPython.keyboard.trigger_keydown('i');
this.then(function(){
this.trigger_keydown('i');
});
this.wait_for_output(0);

@ -1,38 +0,0 @@
//
// Test merging two notebook cells.
//
casper.notebook_test(function() {
var output = this.evaluate(function () {
// Fill in test data.
IPython.notebook.command_mode();
var set_cell_text = function () {
var cell_one = IPython.notebook.get_selected_cell();
cell_one.set_text('a = 5');
IPython.keyboard.trigger_keydown('b');
var cell_two = IPython.notebook.get_selected_cell();
cell_two.set_text('print(a)');
};
// merge_cell_above()
set_cell_text();
IPython.notebook.merge_cell_above();
var merged_above = IPython.notebook.get_selected_cell();
// merge_cell_below()
set_cell_text();
IPython.notebook.select(0);
IPython.notebook.merge_cell_below();
var merged_below = IPython.notebook.get_selected_cell();
return {
above: merged_above.get_text(),
below: merged_below.get_text()
};
});
this.test.assertEquals(output.above, 'a = 5\nprint(a)',
'Successful merge_cell_above().');
this.test.assertEquals(output.below, 'a = 5\nprint(a)',
'Successful merge_cell_below().');
});

@ -0,0 +1,43 @@
//
// Test merging two notebook cells.
//
casper.notebook_test(function() {
var that = this;
var set_cells_text = function () {
that.evaluate(function() {
var cell_one = IPython.notebook.get_selected_cell();
cell_one.set_text('a = 5');
});
that.trigger_keydown('b');
that.evaluate(function() {
var cell_two = IPython.notebook.get_selected_cell();
cell_two.set_text('print(a)');
});
};
this.evaluate(function () {
IPython.notebook.command_mode();
});
// merge_cell_above()
set_cells_text();
var output_above = this.evaluate(function () {
IPython.notebook.merge_cell_above();
return IPython.notebook.get_selected_cell().get_text();
});
// merge_cell_below()
set_cells_text();
var output_below = this.evaluate(function() {
IPython.notebook.select(0);
IPython.notebook.merge_cell_below();
return IPython.notebook.get_selected_cell().get_text();
});
this.test.assertEquals(output_above, 'a = 5\nprint(a)',
'Successful merge_cell_above().');
this.test.assertEquals(output_below, 'a = 5\nprint(a)',
'Successful merge_cell_below().');
});

@ -2,15 +2,15 @@
// Utility functions for the HTML notebook's CasperJS tests.
//
// Get the URL of a notebook server on which to run tests.
casper.get_notebook_server = function () {
port = casper.cli.get("port")
// Get the URL of a notebook server on which to run tests.
port = casper.cli.get("port");
port = (typeof port === 'undefined') ? '8888' : port;
return 'http://127.0.0.1:' + port
return 'http://127.0.0.1:' + port;
};
// Create and open a new notebook.
casper.open_new_notebook = function () {
// Create and open a new notebook.
var baseUrl = this.get_notebook_server();
this.start(baseUrl);
this.thenClick('button#new_notebook');
@ -34,15 +34,15 @@ casper.open_new_notebook = function () {
});
};
// Return whether or not the kernel is running.
casper.kernel_running = function kernel_running() {
// Return whether or not the kernel is running.
return this.evaluate(function kernel_running() {
return IPython.notebook.kernel.running;
});
};
// Shut down the current notebook's kernel.
casper.shutdown_current_kernel = function () {
// Shut down the current notebook's kernel.
this.thenEvaluate(function() {
IPython.notebook.kernel.kill();
});
@ -50,8 +50,9 @@ casper.shutdown_current_kernel = function () {
this.wait(1000);
};
// Delete created notebook.
casper.delete_current_notebook = function () {
// Delete created notebook.
// For some unknown reason, this doesn't work?!?
this.thenEvaluate(function() {
IPython.notebook.delete();
@ -59,6 +60,7 @@ casper.delete_current_notebook = function () {
};
casper.wait_for_busy = function () {
// Waits for the notebook to enter a busy state.
this.waitFor(function () {
return this.evaluate(function () {
return IPython._status == 'busy';
@ -67,6 +69,7 @@ casper.wait_for_busy = function () {
};
casper.wait_for_idle = function () {
// Waits for the notebook to idle.
this.waitFor(function () {
return this.evaluate(function () {
return IPython._status == 'idle';
@ -74,8 +77,8 @@ casper.wait_for_idle = function () {
});
};
// wait for the nth output in a given cell
casper.wait_for_output = function (cell_num, out_num) {
// wait for the nth output in a given cell
this.wait_for_idle();
out_num = out_num || 0;
this.then(function() {
@ -94,29 +97,29 @@ casper.wait_for_output = function (cell_num, out_num) {
});
};
// wait for a widget msg que to reach 0
//
// Parameters
// ----------
// widget_info : object
// Object which contains info related to the widget. The model_id property
// is used to identify the widget.
casper.wait_for_widget = function (widget_info) {
// wait for a widget msg que to reach 0
//
// Parameters
// ----------
// widget_info : object
// Object which contains info related to the widget. The model_id property
// is used to identify the widget.
this.waitFor(function () {
var pending = this.evaluate(function (m) {
return IPython.notebook.kernel.widget_manager.get_model(m).pending_msgs;
}, {m: widget_info.model_id});
if (pending == 0) {
if (pending === 0) {
return true;
} else {
return false;
}
});
}
};
// return an output of a given cell
casper.get_output_cell = function (cell_num, out_num) {
// return an output of a given cell
out_num = out_num || 0;
var result = casper.evaluate(function (c, o) {
var cell = IPython.notebook.get_cell(c);
@ -137,25 +140,33 @@ casper.get_output_cell = function (cell_num, out_num) {
}
};
// return the number of cells in the notebook
casper.get_cells_length = function () {
// return the number of cells in the notebook
var result = casper.evaluate(function () {
return IPython.notebook.get_cells().length;
})
});
return result;
};
// Set the text content of a cell.
casper.set_cell_text = function(index, text){
// Set the text content of a cell.
this.evaluate(function (index, text) {
var cell = IPython.notebook.get_cell(index);
cell.set_text(text);
}, index, text);
};
// Inserts a cell at the bottom of the notebook
// Returns the new cell's index.
casper.get_cell_text = function(index){
// Get the text content of a cell.
return this.evaluate(function (index) {
var cell = IPython.notebook.get_cell(index);
return cell.get_text();
}, index);
};
casper.insert_cell_at_bottom = function(cell_type){
// Inserts a cell at the bottom of the notebook
// Returns the new cell's index.
cell_type = cell_type || 'code';
return this.evaluate(function (cell_type) {
@ -164,9 +175,9 @@ casper.insert_cell_at_bottom = function(cell_type){
}, cell_type);
};
// Insert a cell at the bottom of the notebook and set the cells text.
// Returns the new cell's index.
casper.append_cell = function(text, cell_type) {
// Insert a cell at the bottom of the notebook and set the cells text.
// Returns the new cell's index.
var index = this.insert_cell_at_bottom(cell_type);
if (text !== undefined) {
this.set_cell_text(index, text);
@ -174,9 +185,9 @@ casper.append_cell = function(text, cell_type) {
return index;
};
// Asynchronously executes a cell by index.
// Returns the cell's index.
casper.execute_cell = function(index){
// Asynchronously executes a cell by index.
// Returns the cell's index.
var that = this;
this.then(function(){
that.evaluate(function (index) {
@ -187,11 +198,11 @@ casper.execute_cell = function(index){
return index;
};
// Synchronously executes a cell by index.
// Optionally accepts a then_callback parameter. then_callback will get called
// when the cell has finished executing.
// Returns the cell's index.
casper.execute_cell_then = function(index, then_callback) {
// Synchronously executes a cell by index.
// Optionally accepts a then_callback parameter. then_callback will get called
// when the cell has finished executing.
// Returns the cell's index.
var return_val = this.execute_cell(index);
this.wait_for_idle();
@ -206,18 +217,18 @@ casper.execute_cell_then = function(index, then_callback) {
return return_val;
};
// Utility function that allows us to easily check if an element exists
// within a cell. Uses JQuery selector to look for the element.
casper.cell_element_exists = function(index, selector){
// Utility function that allows us to easily check if an element exists
// within a cell. Uses JQuery selector to look for the element.
return casper.evaluate(function (index, selector) {
var $cell = IPython.notebook.get_cell(index).element;
return $cell.find(selector).length > 0;
}, index, selector);
};
// Utility function that allows us to execute a jQuery function on an
// element within a cell.
casper.cell_element_function = function(index, selector, function_name, function_args){
// Utility function that allows us to execute a jQuery function on an
// element within a cell.
return casper.evaluate(function (index, selector, function_name, function_args) {
var $cell = IPython.notebook.get_cell(index).element;
var $el = $cell.find(selector);
@ -225,8 +236,183 @@ casper.cell_element_function = function(index, selector, function_name, function
}, index, selector, function_name, function_args);
};
// Wrap a notebook test to reduce boilerplate.
casper.validate_notebook_state = function(message, mode, cell_index) {
// Validate the entire dual mode state of the notebook. Make sure no more than
// one cell is selected, focused, in edit mode, etc...
// General tests.
this.test.assertEquals(this.get_keyboard_mode(), this.get_notebook_mode(),
message + '; keyboard and notebook modes match');
// Is the selected cell the only cell that is selected?
if (cell_index!==undefined) {
this.test.assert(this.is_only_cell_selected(cell_index),
message + '; cell ' + cell_index + ' is the only cell selected');
}
// Mode specific tests.
if (mode==='command') {
// Are the notebook and keyboard manager in command mode?
this.test.assertEquals(this.get_keyboard_mode(), 'command',
message + '; in command mode');
// Make sure there isn't a single cell in edit mode.
this.test.assert(this.is_only_cell_edit(null),
message + '; all cells in command mode');
this.test.assert(this.is_cell_editor_focused(null),
message + '; no cell editors are focused while in command mode');
} else if (mode==='edit') {
// Are the notebook and keyboard manager in edit mode?
this.test.assertEquals(this.get_keyboard_mode(), 'edit',
message + '; in edit mode');
if (cell_index!==undefined) {
// Is the specified cell the only cell in edit mode?
this.test.assert(this.is_only_cell_edit(cell_index),
message + '; cell ' + cell_index + ' is the only cell in edit mode');
// Is the specified cell the only cell with a focused code mirror?
this.test.assert(this.is_cell_editor_focused(cell_index),
message + '; cell ' + cell_index + '\'s editor is appropriately focused');
}
} else {
this.test.assert(false, message + '; ' + mode + ' is an unknown mode');
}
};
casper.select_cell = function(index) {
// Select a cell in the notebook.
this.evaluate(function (i) {
IPython.notebook.select(i);
}, {i: index});
};
casper.click_cell_editor = function(index) {
// Emulate a click on a cell's editor.
// Code Mirror does not play nicely with emulated brower events.
// Instead of trying to emulate a click, here we run code similar to
// the code used in Code Mirror that handles the mousedown event on a
// region of codemirror that the user can focus.
this.evaluate(function (i) {
var cm = IPython.notebook.get_cell(i).code_mirror;
if (cm.options.readOnly != "nocursor" && (document.activeElement != cm.display.input))
cm.display.input.focus();
}, {i: index});
};
casper.set_cell_editor_cursor = function(index, line_index, char_index) {
// Set the Code Mirror instance cursor's location.
this.evaluate(function (i, l, c) {
IPython.notebook.get_cell(i).code_mirror.setCursor(l, c);
}, {i: index, l: line_index, c: char_index});
};
casper.focus_notebook = function() {
// Focus the notebook div.
this.evaluate(function (){
$('#notebook').focus();
}, {});
};
casper.trigger_keydown = function() {
// Emulate a keydown in the notebook.
for (var i = 0; i < arguments.length; i++) {
this.evaluate(function (k) {
var element = $(document);
var event = IPython.keyboard.shortcut_to_event(k, 'keydown');
element.trigger(event);
}, {k: arguments[i]});
}
};
casper.get_keyboard_mode = function() {
// Get the mode of the keyboard manager.
return this.evaluate(function() {
return IPython.keyboard_manager.mode;
}, {});
};
casper.get_notebook_mode = function() {
// Get the mode of the notebook.
return this.evaluate(function() {
return IPython.notebook.mode;
}, {});
};
casper.get_cell = function(index) {
// Get a single cell.
//
// Note: Handles to DOM elements stored in the cell will be useless once in
// CasperJS context.
return this.evaluate(function(i) {
var cell = IPython.notebook.get_cell(i);
if (cell) {
return cell;
}
return null;
}, {i : index});
};
casper.is_cell_editor_focused = function(index) {
// Make sure a cell's editor is the only editor focused on the page.
return this.evaluate(function(i) {
var focused_textarea = $('#notebook .CodeMirror-focused textarea');
if (focused_textarea.length > 1) { throw 'More than one Code Mirror editor is focused at once!'; }
if (i === null) {
return focused_textarea.length === 0;
} else {
var cell = IPython.notebook.get_cell(i);
if (cell) {
return cell.code_mirror.getInputField() == focused_textarea[0];
}
}
return false;
}, {i : index});
};
casper.is_only_cell_selected = function(index) {
// Check if a cell is the only cell selected.
// Pass null as the index to check if no cells are selected.
return this.is_only_cell_on(index, 'selected', 'unselected');
};
casper.is_only_cell_edit = function(index) {
// Check if a cell is the only cell in edit mode.
// Pass null as the index to check if all of the cells are in command mode.
return this.is_only_cell_on(index, 'edit_mode', 'command_mode');
};
casper.is_only_cell_on = function(i, on_class, off_class) {
// Check if a cell is the only cell with the `on_class` DOM class applied to it.
// All of the other cells are checked for the `off_class` DOM class.
// Pass null as the index to check if all of the cells have the `off_class`.
var cells_length = this.get_cells_length();
for (var j = 0; j < cells_length; j++) {
if (j === i) {
if (this.cell_has_class(j, off_class) || !this.cell_has_class(j, on_class)) {
return false;
}
} else {
if (!this.cell_has_class(j, off_class) || this.cell_has_class(j, on_class)) {
return false;
}
}
}
return true;
};
casper.cell_has_class = function(index, classes) {
// Check if a cell has a class.
return this.evaluate(function(i, c) {
var cell = IPython.notebook.get_cell(i);
if (cell) {
return cell.element.hasClass(c);
}
return false;
}, {i : index, c: classes});
};
casper.notebook_test = function(test) {
// Wrap a notebook test to reduce boilerplate.
this.open_new_notebook();
this.then(test);
@ -253,14 +439,14 @@ casper.notebook_test = function(test) {
casper.wait_for_dashboard = function () {
// Wait for the dashboard list to load.
casper.waitForSelector('.list_item');
}
};
casper.open_dashboard = function () {
// Start casper by opening the dashboard page.
var baseUrl = this.get_notebook_server();
this.start(baseUrl);
this.wait_for_dashboard();
}
};
casper.dashboard_test = function (test) {
// Open the dashboard page and run a test.
@ -276,16 +462,16 @@ casper.dashboard_test = function (test) {
this.run(function() {
this.test.done();
});
}
};
casper.options.waitTimeout=10000
casper.options.waitTimeout=10000;
casper.on('waitFor.timeout', function onWaitForTimeout(timeout) {
this.echo("Timeout for " + casper.get_notebook_server());
this.echo("Is the notebook server running?");
});
// Pass `console.log` calls from page JS to casper.
casper.printLog = function () {
casper.print_log = function () {
// Pass `console.log` calls from page JS to casper.
this.on('remote.message', function(msg) {
this.echo('Remote message caught: ' + msg);
});

Loading…
Cancel
Save