From aa658d3d7929210b81c94afe272e8da1e815568e Mon Sep 17 00:00:00 2001 From: Amy Skerry Date: Fri, 26 Oct 2018 07:36:02 -0700 Subject: [PATCH] Migrate display isolation test to selenium As per issue #3335, we want all js tests migrated to selenium. This change migrates and extends the svg isolation test (extended to include slightly more thorough validation of expected isolation behavior). Test Plan: py.test -v notebook/tests/selenium/test_display_isolation.py --- notebook/tests/notebook/isolated_svg.js | 90 ------------------- .../tests/selenium/test_display_isolation.py | 84 +++++++++++++++++ notebook/tests/selenium/utils.py | 6 +- 3 files changed, 89 insertions(+), 91 deletions(-) delete mode 100644 notebook/tests/notebook/isolated_svg.js create mode 100644 notebook/tests/selenium/test_display_isolation.py diff --git a/notebook/tests/notebook/isolated_svg.js b/notebook/tests/notebook/isolated_svg.js deleted file mode 100644 index ac29d490e..000000000 --- a/notebook/tests/notebook/isolated_svg.js +++ /dev/null @@ -1,90 +0,0 @@ -// -// Test display isolation -// An object whose metadata contains an "isolated" tag must be isolated -// from the rest of the document. In the case of inline SVGs, this means -// that multiple SVGs have different scopes. This test checks that there -// are no CSS leaks between two isolated SVGs. -// - -casper.notebook_test(function () { - this.evaluate(function () { - var cell = IPython.notebook.get_cell(0); - cell.set_text( "from IPython.core.display import SVG, display_svg\n" + - "s1 = '''" + - "" + - "" + - "'''\n" + - "s2 = '''" + - "" + - "'''\n" + - "display_svg(SVG(s1), metadata=dict(isolated=True))\n" + - "display_svg(SVG(s2), metadata=dict(isolated=True))\n" - ); - cell.execute(); - }); - - this.then(function() { - var fname=this.test.currentTestFile.split('/').pop().toLowerCase(); - this.echo(fname); - this.echo(this.currentUrl); - this.evaluate(function (n) { - IPython.notebook.rename(n); - IPython.notebook.save_notebook(); - }, {n : fname}); - this.echo(this.currentUrl); - }); - - this.then(function() { - - url = this.evaluate(function() { - IPython.notebook.rename("foo"); - return document.location.href; - }); - this.echo("renamed" + url); - this.echo(this.currentUrl); - }); - - this.wait_for_output(0); - - this.then(function () { - var colors = this.evaluate(function () { - var colors = []; - var ifr = __utils__.findAll("iframe"); - var svg1 = ifr[0].contentWindow.document.getElementById('r1'); - colors[0] = window.getComputedStyle(svg1).fill; - var svg2 = ifr[1].contentWindow.document.getElementById('r2'); - colors[1] = window.getComputedStyle(svg2).fill; - return colors; - }); - this.assert_colors_equal('#ff0000', colors && colors[0], 'display_svg() First svg should be red'); - this.assert_colors_equal('#000000', colors && colors[1], 'display_svg() Second svg should be black'); - }); - - // now ensure that we can pass the same metadata dict to plain old display() - this.thenEvaluate(function () { - var cell = IPython.notebook.get_cell(0); - cell.clear_output(); - cell.set_text( "from IPython.display import display\n" + - "display(SVG(s1), metadata=dict(isolated=True))\n" + - "display(SVG(s2), metadata=dict(isolated=True))\n" - ); - cell.execute(); - }); - - this.wait_for_output(0); - - // same test as original - this.then(function () { - var colors = this.evaluate(function () { - var colors = []; - var ifr = __utils__.findAll("iframe"); - var svg1 = ifr[0].contentWindow.document.getElementById('r1'); - colors[0] = window.getComputedStyle(svg1).fill; - var svg2 = ifr[1].contentWindow.document.getElementById('r2'); - colors[1] = window.getComputedStyle(svg2).fill; - return colors; - }); - this.assert_colors_equal('#ff0000', colors && colors[0], 'display() First svg should be red'); - this.assert_colors_equal('#000000', colors && colors[1], 'display() Second svg should be black'); - }); -}); diff --git a/notebook/tests/selenium/test_display_isolation.py b/notebook/tests/selenium/test_display_isolation.py new file mode 100644 index 000000000..4b75a5dc9 --- /dev/null +++ b/notebook/tests/selenium/test_display_isolation.py @@ -0,0 +1,84 @@ +"""Test display isolation. + +An object whose metadata contains an "isolated" tag must be isolated +from the rest of the document. +""" + + +def test_display_isolation(notebook): + import_ln = """from IPython.core.display import HTML, SVG, display, display_svg""" + notebook.edit_cell(index=0, content=import_ln) + notebook.execute_cell(notebook.current_cell) + isolated_html(notebook) + isolated_svg(notebook) + + +def isolated_html(notebook): + """Test HTML display isolation. + + HTML styling rendered without isolation will affect the whole + document, whereas styling applied with isolation will affect only + the local display object. + """ + red = 'rgb(255, 0, 0)' + blue = 'rgb(0, 0, 255)' + test_str = """
Should be red from non-isolation
""" + notebook.add_and_execute_cell(content="""display(HTML("%s"))""" % test_str) + non_isolated = ( + "" % red + + "
Should be red
") + display_ni = """display(HTML("%s"), metadata={"isolated":False})""" % ( + non_isolated) + notebook.add_and_execute_cell(content=display_ni) + isolated = ( + "" % blue + + "
Should be blue
") + display_i = """display(HTML("%s"), metadata={"isolated":True})""" % ( + isolated) + notebook.add_and_execute_cell(content=display_i) + + # The non-isolated div will be in the body + non_isolated_div = notebook.body.find_element_by_id("non-isolated") + assert non_isolated_div.value_of_css_property("color") == red + + # The non-isolated styling will have affected the output of other cells + test_div = notebook.body.find_element_by_id("test") + assert test_div.value_of_css_property("color") == red + + # The isolated div will be in an iframe, only that element will be blue + iframe = notebook.body.find_element_by_tag_name("iframe") + notebook.browser.switch_to.frame(iframe) + isolated_div = notebook.browser.find_element_by_id("isolated") + assert isolated_div.value_of_css_property("color") == blue + notebook.browser.switch_to.default_content() + + +def isolated_svg(notebook): + """Test that multiple isolated SVGs have different scopes. + + Asserts that there no CSS leaks between two isolated SVGs. + """ + yellow = "rgb(255, 255, 0)" + black = "rgb(0, 0, 0)" + svg_1_str = """s1 = ''''''""" % yellow + svg_2_str = """s2 = ''''''""" + + notebook.add_and_execute_cell(content=svg_1_str) + notebook.add_and_execute_cell(content=svg_2_str) + notebook.add_and_execute_cell( + content="display_svg(SVG(s1), metadata=dict(isolated=True))") + notebook.add_and_execute_cell( + content="display_svg(SVG(s2), metadata=dict(isolated=True))") + iframes = notebook.body.find_elements_by_tag_name("iframe") + + # The first rectangle will be red + notebook.browser.switch_to.frame(iframes[1]) + isolated_svg_1 = notebook.browser.find_element_by_id('r1') + assert isolated_svg_1.value_of_css_property("fill") == yellow + notebook.browser.switch_to.default_content() + + # The second rectangle will be black + notebook.browser.switch_to.frame(iframes[2]) + isolated_svg_2 = notebook.browser.find_element_by_id('r2') + assert isolated_svg_2.value_of_css_property("fill") == black + diff --git a/notebook/tests/selenium/utils.py b/notebook/tests/selenium/utils.py index c93200dc6..a10b7c2b1 100644 --- a/notebook/tests/selenium/utils.py +++ b/notebook/tests/selenium/utils.py @@ -194,6 +194,10 @@ class Notebook: if cell_type != 'code': self.convert_cell_type(index=new_index, cell_type=cell_type) + def add_and_execute_cell(self, index=-1, cell_type="code", content=""): + self.add_cell(index=index, cell_type=cell_type, content=content) + self.execute_cell(index) + def delete_cell(self, index): self.focus_cell(index) self.to_command_mode() @@ -264,7 +268,7 @@ def new_window(browser, selector=None): yield new_window_handle = next(window for window in browser.window_handles if window not in initial_window_handles) - browser.switch_to_window(new_window_handle) + browser.switch_to.window(new_window_handle) if selector is not None: wait_for_selector(browser, selector)