Skip to content

Commit

Permalink
CI Test Fixes Round 4 (#226)
Browse files Browse the repository at this point in the history
* Refactors to _dashboard_nav for added reliability.

* Added docs/comments, code cleanup.

* Remove timeout option for get_inner_text.
  • Loading branch information
ericsnekbytes authored Feb 24, 2023
1 parent 92bb8c5 commit c0ced4f
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 24 deletions.
6 changes: 6 additions & 0 deletions nbclassic/tests/end_to_end/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ def playwright_browser(playwright):
break
except Exception:
time.sleep(.2)
else:
# You need to make sure the host machine has run `playwright install`
# to actually obtain the browser here/for this to work (you should be
# able to run the playwright binary after pip installing nbclassic
# with optional test extras)
raise Exception('Could not open browser! Did you `playwright install` on this machine?')

yield browser

Expand Down
30 changes: 25 additions & 5 deletions nbclassic/tests/end_to_end/test_dashboard_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


import os

from .utils import TREE_PAGE
from jupyter_server.utils import url_path_join
pjoin = os.path.join
Expand All @@ -20,6 +21,7 @@ def get_list_items(nb):
Gets list items from a directory listing page
"""

nb.wait_for_selector('#notebook_list .item_link', page=TREE_PAGE)
notebook_list = nb.locate('#notebook_list', page=TREE_PAGE)
link_items = notebook_list.locate_all('.item_link')

Expand All @@ -31,25 +33,43 @@ def get_list_items(nb):


def test_navigation(notebook_frontend):

print('[Test] [test_dashboard_nav] Start!')

print('[Test] Obtain list of elements')
link_elements = get_list_items(notebook_frontend)

# Recursively traverse and check folder in the Jupyter root dir
def check_links(nb, list_of_link_elements):
print('[Test] Check links')
if len(list_of_link_elements) < 1:
return False
return

for item in list_of_link_elements:
print(f'[Test] Check "{item["label"]}"')
if 'Untitled.ipynb' in item["label"]:
# Skip notebook files in the temp dir
continue

item["element"].click()

assert url_in_tree(notebook_frontend) == True
assert item["link"] in nb.get_page_url(page=TREE_PAGE)
notebook_frontend.wait_for_condition(
lambda: url_in_tree(notebook_frontend),
timeout=600,
period=5
)
notebook_frontend.wait_for_condition(
lambda: item["link"] in nb.get_page_url(page=TREE_PAGE),
timeout=600,
period=5
)

new_links = get_list_items(nb)
if len(new_links) > 0:
check_links(nb, new_links)

nb.go_back(page=TREE_PAGE)

return
return

check_links(notebook_frontend, link_elements)
print('[Test] [test_dashboard_nav] Finished!')
74 changes: 55 additions & 19 deletions nbclassic/tests/end_to_end/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
BROWSER_OBJ = 'BROWSER_OBJ'
# Other constants
CELL_OUTPUT_SELECTOR = '.output_subarea'

SECONDS_TO_MILLISECONDS = 1000

class EndToEndTimeout(Exception):

Expand Down Expand Up @@ -100,8 +100,8 @@ def __bool__(self):
# (Quick/dirty )We can debug on failures by deferring bad inits and testing for them here
return self._bool

def click(self):
return self._element.click()
def click(self, timeout=30):
return self._element.click(timeout=timeout * SECONDS_TO_MILLISECONDS)

def get_inner_text(self):
return self._element.inner_text()
Expand Down Expand Up @@ -174,9 +174,8 @@ def get_user_data(self):
return self._user_data

def expect_not_to_be_visible(self, timeout=30):
seconds_to_milliseconds = 1000
try:
expect(self._element).not_to_be_visible(timeout=timeout * seconds_to_milliseconds)
expect(self._element).not_to_be_visible(timeout=timeout * SECONDS_TO_MILLISECONDS)
except ValueError as err:
raise Exception('Cannot expect not_to_be_visible on this type!') from err
except AssertionError as err:
Expand Down Expand Up @@ -797,27 +796,64 @@ def is_kernel_running(self):
def wait_for_kernel_ready(self):
self._editor_page.wait_for_selector(".kernel_idle_icon")

def _open_notebook_editor_page(self, existing_file_name=None):
def get_editor_page_from_existing_notebook(self, existing_file_name):
tree_page = self._tree_page

if existing_file_name is not None:
existing_notebook = tree_page.locator(f"text={existing_file_name}")
existing_notebook.click()
self._tree_page.reload() # TODO: FIX this, page count does not update to 2
else:
# Simulate a user opening a new notebook/kernel
new_dropdown_element = tree_page.locator('#new-dropdown-button')
new_dropdown_element.click()
kernel_name = 'kernel-python3'
kernel_selector = f'#{kernel_name} a'
new_notebook_element = tree_page.locator(kernel_selector)
new_notebook_element.click()
# Find the link to the notebook file on the tree page
notebook_name_selector = f"text={existing_file_name}"
tree_page.wait_for_selector(notebook_name_selector)
# Click the existing notebook link on the tree page to open the editor
existing_notebook = tree_page.locator(notebook_name_selector)
existing_notebook.click()
self._tree_page.reload() # TODO: FIX this, page count does not update to 2

def wait_for_new_page():
return [pg for pg in self._browser_data[BROWSER_CONTEXT].pages if 'tree' not in pg.url]

new_pages = self.wait_for_condition(
wait_for_new_page,
timeout=125,
period=1
)
editor_page = new_pages[0]

return editor_page

def get_new_editor_page(self):
tree_page = self._tree_page

# Simulate a user opening a new notebook/kernel
new_dropdown_element = tree_page.locator('#new-dropdown-button')
new_dropdown_element.click()
kernel_name = 'kernel-python3'
kernel_selector = f'#{kernel_name} a'
new_notebook_element = tree_page.locator(kernel_selector)
new_notebook_element.click()

def wait_for_new_page():
return [pg for pg in self._browser_data[BROWSER_CONTEXT].pages if 'tree' not in pg.url]

new_pages = self.wait_for_condition(wait_for_new_page)
editor_page = new_pages[0]

return editor_page

def _open_notebook_editor_page(self, existing_file_name=None):
tree_page = self._tree_page

if existing_file_name is not None:
editor_page = self.wait_for_condition(
lambda: self.get_editor_page_from_existing_notebook(existing_file_name),
timeout=500,
period=1
)
else:
editor_page = self.wait_for_condition(
lambda: self.get_new_editor_page(),
timeout=500,
period=1
)

return editor_page

def get_page_url(self, page):
Expand All @@ -829,7 +865,7 @@ def get_page_url(self, page):
raise Exception('Error, provide a valid page to evaluate from!')

return specified_page.url

def go_back(self, page):
if page == TREE_PAGE:
specified_page = self._tree_page
Expand Down

0 comments on commit c0ced4f

Please sign in to comment.