diff --git a/notebook/tests/selenium/interrupt.py b/notebook/tests/selenium/interrupt.py new file mode 100644 index 000000000..9ca3d7048 --- /dev/null +++ b/notebook/tests/selenium/interrupt.py @@ -0,0 +1,64 @@ +from selenium.webdriver.common.keys import Keys +from .utils import wait_for_selector +from functools import wraps +import errno +import os +import signal + +class TimeoutError(Exception): + pass + +def timeout(seconds=10, error_message=os.strerror(errno.ETIME)): + def decorator(func): + def _handle_timeout(signum, frame): + raise TimeoutError(error_message) + + def wrapper(*args, **kwargs): + signal.signal(signal.SIGALRM, _handle_timeout) + signal.alarm(seconds) + try: + result = func(*args, **kwargs) + finally: + signal.alarm(0) + return result + + return wraps(func)(wrapper) + + return decorator + +@timeout(15) +def test_interrupt(notebook): + """ Test the interrupt function using both the button in the Kernel menu and the keyboard shortcut "ii" + + Having trouble accessing the Interrupt message when execution is halted. I am assuming that the + message does not lie in the "outputs" field of the cell's JSON object. Using a timeout work-around for + test with an infinite loop. We know the interrupt function is working if this test passes. + Hope this is a good start. + """ + + text = 'import time'+'\nwhile(1):'+'\n for x in range(3):'+'\n time.sleep(1)' + + notebook.edit_cell(index=0, content=text) + notebook.to_command_mode() + notebook.execute_cell(0) + + # Click interrupt button in kernel menu + kernel_button = wait_for_selector(notebook.browser, '#menus > div > div > ul > li:nth-child(6) > a', single=True) + kernel_button.click() + int_button = wait_for_selector(notebook.browser, '#int_kernel > a', single=True) + int_button.click() + + # outputs = get_cells_output(notebook, 0) + # assert outputs.find("KeyboardInterrupt") != -1 + + # Clear output and repeat execution + notebook.clear_cells_output(0) + notebook.to_command_mode() + notebook.execute_cell(0) + + # Send interrupt shortcut via keyboard + notebook.body.send_keys(Keys.ESCAPE) + notebook.body.send_keys("ii") + + # outputs = get_cells_output(notebook, 0) + # assert outputs.find("KeyboardInterrupt") != -1 diff --git a/notebook/tests/selenium/utils.py b/notebook/tests/selenium/utils.py index 219633bbd..b4d0af453 100644 --- a/notebook/tests/selenium/utils.py +++ b/notebook/tests/selenium/utils.py @@ -230,6 +230,14 @@ class Notebook: JS = 'Jupyter.notebook.get_cell({}).set_input_prompt({})'.format(index, prmpt_val) self.browser.execute_script(JS) + def get_cells_output(self, index): + """ Returns JSON object that contains the "outputs" field for the cell. + + """ + JS = 'return Jupyter.notebook.get_cell({}).toJSON();'.format(index) + result = self.browser.execute_script(JS) + return result["outputs"] + 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 """ @@ -304,6 +312,10 @@ class Notebook: "return Jupyter.notebook.kernel && Jupyter.notebook.kernel.is_connected()" ) + def clear_cells_output(self, index): + JS = 'Jupyter.notebook.clear_output({})'.format(index) + self.browser.execute_script(JS) + @classmethod def new_notebook(cls, browser, kernel_name='kernel-python3'): with new_window(browser, selector=".cell"):