##// END OF EJS Templates
Backport PR #5459: Fix interact animation page jump FF...
Backport PR #5459: Fix interact animation page jump FF Firefox doesn't render images immediately as the data is available. When animating the way that we animate, this causes the output area to collapse quickly before returning to its original size. When the output area collapses, FireFox scrolls upwards in attempt to compensate for the lost vertical content (so it looks like you are on the same spot in the page, with respect to the contents below the image's prior location). The solution is to resize the image output after the `img onload` event has fired. This PR: - Releases the `clear_output` height lock after the image has been loaded (instead of immediately or using a timeout). - Removes a `setTimeout` call in the `append_output` method. - `clear_output` in zmqshell no longer sends `\r` to the stream outputs. closes #5128

File last commit:

r15624:850d4671
r16229:ff1462d3
Show More
launchnotebook.py
101 lines | 3.1 KiB | text/x-python | PythonLexer
"""Base class for notebook tests."""
from __future__ import print_function
import sys
import time
import requests
from contextlib import contextmanager
from subprocess import Popen, STDOUT
from unittest import TestCase
import nose
from IPython.utils.tempdir import TemporaryDirectory
MAX_WAITTIME = 30 # seconds to wait for notebook server to start
POLL_INTERVAL = 0.1 # time between attempts
# TimeoutError is a builtin on Python 3. This can be removed when we stop
# supporting Python 2.
class TimeoutError(Exception):
pass
class NotebookTestBase(TestCase):
"""A base class for tests that need a running notebook.
This creates an empty profile in a temp ipython_dir
and then starts the notebook server with a separate temp notebook_dir.
"""
port = 12341
@classmethod
def wait_until_alive(cls):
"""Wait for the server to be alive"""
url = 'http://localhost:%i/api/notebooks' % cls.port
for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
try:
requests.get(url)
except requests.exceptions.ConnectionError:
if cls.notebook.poll() is not None:
raise RuntimeError("The notebook server exited with status %s" \
% cls.notebook.poll())
time.sleep(POLL_INTERVAL)
else:
return
raise TimeoutError("The notebook server didn't start up correctly.")
@classmethod
def wait_until_dead(cls):
"""Wait for the server process to terminate after shutdown"""
for _ in range(int(MAX_WAITTIME/POLL_INTERVAL)):
if cls.notebook.poll() is not None:
return
time.sleep(POLL_INTERVAL)
raise TimeoutError("Undead notebook server")
@classmethod
def setup_class(cls):
cls.ipython_dir = TemporaryDirectory()
cls.notebook_dir = TemporaryDirectory()
notebook_args = [
sys.executable, '-c',
'from IPython.html.notebookapp import launch_new_instance; launch_new_instance()',
'--port=%d' % cls.port,
'--port-retries=0', # Don't try any other ports
'--no-browser',
'--ipython-dir=%s' % cls.ipython_dir.name,
'--notebook-dir=%s' % cls.notebook_dir.name,
]
cls.notebook = Popen(notebook_args,
stdout=nose.iptest_stdstreams_fileno(),
stderr=STDOUT,
)
cls.wait_until_alive()
@classmethod
def teardown_class(cls):
cls.notebook.terminate()
cls.ipython_dir.cleanup()
cls.notebook_dir.cleanup()
cls.wait_until_dead()
@classmethod
def base_url(cls):
return 'http://localhost:%i/' % cls.port
@contextmanager
def assert_http_error(status, msg=None):
try:
yield
except requests.HTTPError as e:
real_status = e.response.status_code
assert real_status == status, \
"Expected status %d, got %d" % (real_status, status)
if msg:
assert msg in str(e), e
else:
assert False, "Expected HTTP error status"