diff --git a/notebook/tests/notebook/deletecell.js b/notebook/tests/notebook/deletecell.js deleted file mode 100644 index 6c98f28cc0..0000000000 --- a/notebook/tests/notebook/deletecell.js +++ /dev/null @@ -1,107 +0,0 @@ - -// Test -casper.notebook_test(function () { - var that = this; - var cell_is_deletable = function (index) { - // Get the deletable status of a cell. - return that.evaluate(function (index) { - var cell = IPython.notebook.get_cell(index); - return cell.is_deletable(); - }, index); - }; - - var a = 'print("a")'; - var index = this.append_cell(a); - - var b = 'print("b")'; - index = this.append_cell(b); - - var c = 'print("c")'; - index = this.append_cell(c); - - this.thenEvaluate(function() { - IPython.notebook.get_cell(1).metadata.deletable = false; - IPython.notebook.get_cell(2).metadata.deletable = 0; // deletable only when exactly false - IPython.notebook.get_cell(3).metadata.deletable = true; - }); - - this.then(function () { - // Check deletable status of the cells - this.test.assert(cell_is_deletable(0), 'Cell 0 is deletable'); - this.test.assert(!cell_is_deletable(1), 'Cell 1 is not deletable'); - this.test.assert(cell_is_deletable(2), 'Cell 2 is deletable'); - this.test.assert(cell_is_deletable(3), 'Cell 3 is deletable'); - }); - - // Try to delete cell 0 (should succeed) - this.then(function () { - this.select_cell(0); - this.trigger_keydown('esc'); - this.trigger_keydown('d', 'd'); - this.test.assertEquals(this.get_cells_length(), 3, 'Delete cell 0: There are now 3 cells'); - this.test.assertEquals(this.get_cell_text(0), a, 'Delete cell 0: Cell 1 is now cell 0'); - this.test.assertEquals(this.get_cell_text(1), b, 'Delete cell 0: Cell 2 is now cell 1'); - this.test.assertEquals(this.get_cell_text(2), c, 'Delete cell 0: Cell 3 is now cell 2'); - this.validate_notebook_state('dd', 'command', 0); - }); - - // Try to delete cell 0 (should fail) - this.then(function () { - this.select_cell(0); - this.trigger_keydown('d', 'd'); - this.test.assertEquals(this.get_cells_length(), 3, 'Delete cell 0: There are still 3 cells'); - this.test.assertEquals(this.get_cell_text(0), a, 'Delete cell 0: Cell 0 was not deleted'); - this.test.assertEquals(this.get_cell_text(1), b, 'Delete cell 0: Cell 1 was not affected'); - this.test.assertEquals(this.get_cell_text(2), c, 'Delete cell 0: Cell 2 was not affected'); - this.validate_notebook_state('dd', 'command', 0); - }); - - // Try to delete cell 1 (should succeed) - this.then(function () { - this.select_cell(1); - this.trigger_keydown('d', 'd'); - this.test.assertEquals(this.get_cells_length(), 2, 'Delete cell 1: There are now 2 cells'); - this.test.assertEquals(this.get_cell_text(0), a, 'Delete cell 1: Cell 0 was not affected'); - this.test.assertEquals(this.get_cell_text(1), c, 'Delete cell 1: Cell 1 was not affected'); - this.validate_notebook_state('dd', 'command', 1); - }); - - // Try to delete cell 1 (should succeed) - this.then(function () { - this.select_cell(1); - this.trigger_keydown('d', 'd'); - this.test.assertEquals(this.get_cells_length(), 1, 'Delete cell 1: There is now 1 cell'); - this.test.assertEquals(this.get_cell_text(0), a, 'Delete cell 2: Cell 0 was not affected'); - this.validate_notebook_state('dd', 'command', 0); - }); - - // Change the deletable status of the last cells - this.thenEvaluate(function() { - IPython.notebook.get_cell(0).metadata.deletable = true; - }); - - this.then(function () { - // Check deletable status of the cell - this.test.assert(cell_is_deletable(0), 'Cell 0 is deletable'); - - // Try to delete the last cell (should succeed) - this.select_cell(0); - this.trigger_keydown('d', 'd'); - this.test.assertEquals(this.get_cells_length(), 1, 'Delete last cell: There is still 1 cell'); - this.test.assertEquals(this.get_cell_text(0), "", 'Delete last cell: Cell 0 was deleted'); - this.validate_notebook_state('dd', 'command', 0); - }); - - // Make sure copied cells are deletable - this.thenEvaluate(function() { - IPython.notebook.get_cell(0).metadata.deletable = false; - }); - this.then(function () { - this.select_cell(0); - this.trigger_keydown('c', 'v'); - this.test.assertEquals(this.get_cells_length(), 2, 'Copy cell: There are 2 cells'); - this.test.assert(!cell_is_deletable(0), 'Cell 0 is not deletable'); - this.test.assert(cell_is_deletable(1), 'Cell 1 is deletable'); - this.validate_notebook_state('cv', 'command', 1); - }); -}); diff --git a/notebook/tests/selenium/test_deletecell.py b/notebook/tests/selenium/test_deletecell.py new file mode 100644 index 0000000000..388dd2ad83 --- /dev/null +++ b/notebook/tests/selenium/test_deletecell.py @@ -0,0 +1,60 @@ +import os +import pytest + +def cell_is_deletable(nb, index): + JS = 'return Jupyter.notebook.get_cell({}).is_deletable();'.format(index) + return nb.browser.execute_script(JS) + +def delete_cell(notebook, index): + notebook.focus_cell(index) + notebook.to_command_mode + notebook.current_cell.send_keys('dd') + +def test_delete_cells(notebook): + a = 'print("a")' + b = 'print("b")' + c = 'print("c")' + + notebook.edit_cell(index=0, content=a) + notebook.append(b, c) + notebook.to_command_mode() + + # Validate initial state + assert notebook.get_cells_contents() == [a, b, c] + for cell in range(0, 3): + assert cell_is_deletable(notebook, cell) + + notebook.set_cell_metadata(0, 'deletable', 'false') + notebook.set_cell_metadata(1, 'deletable', 0 + ) + assert not cell_is_deletable(notebook, 0) + assert cell_is_deletable(notebook, 1) + assert cell_is_deletable(notebook, 2) + + # Try to delete cell a (should not be deleted) + delete_cell(notebook, 0) + assert notebook.get_cells_contents() == [a, b, c] + + # Try to delete cell b (should succeed) + delete_cell(notebook, 1) + assert notebook.get_cells_contents() == [a, c] + + # Try to delete cell c (should succeed) + delete_cell(notebook, 1) + assert notebook.get_cells_contents() == [a] + + # Change the deletable state of cell a + notebook.set_cell_metadata(0, 'deletable', 'true') + + # Try to delete cell a (should succeed) + delete_cell(notebook, 0) + assert len(notebook.cells) == 1 # it contains an empty cell + + # Make sure copied cells are deletable + notebook.edit_cell(index=0, content=a) + notebook.set_cell_metadata(0, 'deletable', 'false') + assert not cell_is_deletable(notebook, 0) + notebook.to_command_mode() + notebook.current_cell.send_keys('cv') + assert len(notebook.cells) == 2 + assert cell_is_deletable(notebook, 1) diff --git a/notebook/tests/selenium/utils.py b/notebook/tests/selenium/utils.py index efe49fb4c4..ef40927721 100644 --- a/notebook/tests/selenium/utils.py +++ b/notebook/tests/selenium/utils.py @@ -127,6 +127,14 @@ def wait_for_stale_cell(self, cell): wait = WebDriverWait(self.browser, 10) element = wait.until(EC.staleness_of(cell)) + def get_cells_contents(self): + JS = 'return Jupyter.notebook.get_cells().map(function(c) {return c.get_text();})' + return self.browser.execute_script(JS) + + def set_cell_metadata(self, index, key, value): + JS = 'Jupyter.notebook.get_cell({}).metadata.{} = {}'.format(index, key, value) + return self.browser.execute_script(JS) + def edit_cell(self, cell=None, index=0, content="", render=False): """Set the contents of a cell to *content*, by cell object or by index """