|
@@ -2,19 +2,18 @@
|
|
|
# -*- coding: utf-8 -*-
|
|
|
from __future__ import print_function, absolute_import
|
|
|
|
|
|
+import json
|
|
|
import os
|
|
|
import sys
|
|
|
import time
|
|
|
import threading
|
|
|
|
|
|
from tornado import ioloop
|
|
|
-from notebook.notebookapp import NotebookApp, flags, aliases
|
|
|
+from notebook.notebookapp import flags, aliases
|
|
|
from traitlets import Bool, Unicode
|
|
|
-from jupyterlab_launcher import LabConfig, add_handlers
|
|
|
|
|
|
from selenium import webdriver
|
|
|
-
|
|
|
-from .commands import get_app_dir
|
|
|
+from .labapp import LabApp
|
|
|
|
|
|
|
|
|
here = os.path.dirname(__file__)
|
|
@@ -31,9 +30,8 @@ test_aliases = dict(aliases)
|
|
|
test_aliases['app-dir'] = 'TestApp.app_dir'
|
|
|
|
|
|
|
|
|
-class TestApp(NotebookApp):
|
|
|
+class TestApp(LabApp):
|
|
|
|
|
|
- default_url = Unicode('/lab')
|
|
|
open_browser = Bool(False)
|
|
|
base_url = '/foo'
|
|
|
flags = test_flags
|
|
@@ -46,64 +44,67 @@ class TestApp(NotebookApp):
|
|
|
help="The app directory to build in")
|
|
|
|
|
|
def start(self):
|
|
|
- self.io_loop = ioloop.IOLoop.current()
|
|
|
- config = LabConfig()
|
|
|
- if self.core_mode:
|
|
|
- config.assets_dir = os.path.join(here, 'build')
|
|
|
- elif self.app_dir:
|
|
|
- config.assets_dir = os.path.join(self.app_dir, 'static')
|
|
|
- else:
|
|
|
- config.assets_dir = os.path.join(get_app_dir(), 'static')
|
|
|
-
|
|
|
- print('****Testing assets dir %s' % config.assets_dir)
|
|
|
+ web_app = self.web_app
|
|
|
+ web_app.settings.setdefault('page_config_data', dict())
|
|
|
+ web_app.settings['page_config_data']['seleniumTest'] = True
|
|
|
|
|
|
- config.settings_dir = ''
|
|
|
-
|
|
|
- add_handlers(self.web_app, config)
|
|
|
+ self.io_loop = ioloop.IOLoop.current()
|
|
|
self.io_loop.call_later(1, self._run_selenium)
|
|
|
super(TestApp, self).start()
|
|
|
|
|
|
def _run_selenium(self):
|
|
|
+ # This must be done in a thread to allow the selenium driver
|
|
|
+ # to connect to the server.
|
|
|
thread = threading.Thread(target=run_selenium,
|
|
|
- args=(self.display_url, self._selenium_finished))
|
|
|
+ args=(self.display_url, self.log, self._selenium_finished))
|
|
|
thread.start()
|
|
|
|
|
|
def _selenium_finished(self, result):
|
|
|
self.io_loop.add_callback(lambda: sys.exit(result))
|
|
|
|
|
|
|
|
|
-def run_selenium(url, callback):
|
|
|
+def run_selenium(url, log, callback):
|
|
|
"""Run the selenium test and call the callback with the exit code.exit
|
|
|
"""
|
|
|
|
|
|
- print('Starting Firefox Driver')
|
|
|
+ log.info('Starting Firefox Driver')
|
|
|
driver = webdriver.Firefox()
|
|
|
|
|
|
- print('Navigating to page:', url)
|
|
|
+ log.info('Navigating to page:', url)
|
|
|
driver.get(url)
|
|
|
|
|
|
- completed = False
|
|
|
-
|
|
|
# Start a poll loop.
|
|
|
t0 = time.time()
|
|
|
- while time.time() - t0 < 10:
|
|
|
- el = driver.find_element_by_id('main')
|
|
|
- if el:
|
|
|
- completed = True
|
|
|
- break
|
|
|
+ while time.time() - t0 < 20:
|
|
|
+ try:
|
|
|
+ el = driver.find_element_by_id('seleniumResult')
|
|
|
+ if el:
|
|
|
+ break
|
|
|
+ except Exception as e:
|
|
|
+ pass
|
|
|
|
|
|
# Avoid hogging the main thread.
|
|
|
time.sleep(0.5)
|
|
|
|
|
|
+ if not el:
|
|
|
+ driver.quit()
|
|
|
+ log.error('Application did not restore properly')
|
|
|
+ callback(1)
|
|
|
+ return
|
|
|
+
|
|
|
+ errors = json.loads(el.get_attribute('textContent'))
|
|
|
driver.quit()
|
|
|
|
|
|
- # Return the exit code.
|
|
|
- if not completed:
|
|
|
- callback(1)
|
|
|
- else:
|
|
|
- if os.path.exists('./geckodriver.log'):
|
|
|
+ if os.path.exists('./geckodriver.log'):
|
|
|
os.remove('./geckodriver.log')
|
|
|
- callback(0)
|
|
|
+
|
|
|
+ if errors:
|
|
|
+ for error in errors:
|
|
|
+ log.error(error)
|
|
|
+ callback(1)
|
|
|
+ return
|
|
|
+
|
|
|
+ callback(0)
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|