Skip to content

Commit c0ced4f

Browse files
CI Test Fixes Round 4 (#226)
* Refactors to _dashboard_nav for added reliability. * Added docs/comments, code cleanup. * Remove timeout option for get_inner_text.
1 parent 92bb8c5 commit c0ced4f

File tree

3 files changed

+86
-24
lines changed

3 files changed

+86
-24
lines changed

nbclassic/tests/end_to_end/conftest.py

+6
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ def playwright_browser(playwright):
8686
break
8787
except Exception:
8888
time.sleep(.2)
89+
else:
90+
# You need to make sure the host machine has run `playwright install`
91+
# to actually obtain the browser here/for this to work (you should be
92+
# able to run the playwright binary after pip installing nbclassic
93+
# with optional test extras)
94+
raise Exception('Could not open browser! Did you `playwright install` on this machine?')
8995

9096
yield browser
9197

nbclassic/tests/end_to_end/test_dashboard_nav.py

+25-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33

44
import os
5+
56
from .utils import TREE_PAGE
67
from jupyter_server.utils import url_path_join
78
pjoin = os.path.join
@@ -20,6 +21,7 @@ def get_list_items(nb):
2021
Gets list items from a directory listing page
2122
"""
2223

24+
nb.wait_for_selector('#notebook_list .item_link', page=TREE_PAGE)
2325
notebook_list = nb.locate('#notebook_list', page=TREE_PAGE)
2426
link_items = notebook_list.locate_all('.item_link')
2527

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

3234

3335
def test_navigation(notebook_frontend):
34-
36+
print('[Test] [test_dashboard_nav] Start!')
37+
38+
print('[Test] Obtain list of elements')
3539
link_elements = get_list_items(notebook_frontend)
3640

41+
# Recursively traverse and check folder in the Jupyter root dir
3742
def check_links(nb, list_of_link_elements):
43+
print('[Test] Check links')
3844
if len(list_of_link_elements) < 1:
39-
return False
45+
return
4046

4147
for item in list_of_link_elements:
48+
print(f'[Test] Check "{item["label"]}"')
49+
if 'Untitled.ipynb' in item["label"]:
50+
# Skip notebook files in the temp dir
51+
continue
52+
4253
item["element"].click()
4354

44-
assert url_in_tree(notebook_frontend) == True
45-
assert item["link"] in nb.get_page_url(page=TREE_PAGE)
55+
notebook_frontend.wait_for_condition(
56+
lambda: url_in_tree(notebook_frontend),
57+
timeout=600,
58+
period=5
59+
)
60+
notebook_frontend.wait_for_condition(
61+
lambda: item["link"] in nb.get_page_url(page=TREE_PAGE),
62+
timeout=600,
63+
period=5
64+
)
4665

4766
new_links = get_list_items(nb)
4867
if len(new_links) > 0:
4968
check_links(nb, new_links)
5069

5170
nb.go_back(page=TREE_PAGE)
5271

53-
return
72+
return
5473

5574
check_links(notebook_frontend, link_elements)
75+
print('[Test] [test_dashboard_nav] Finished!')

nbclassic/tests/end_to_end/utils.py

+55-19
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
BROWSER_OBJ = 'BROWSER_OBJ'
3232
# Other constants
3333
CELL_OUTPUT_SELECTOR = '.output_subarea'
34-
34+
SECONDS_TO_MILLISECONDS = 1000
3535

3636
class EndToEndTimeout(Exception):
3737

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

103-
def click(self):
104-
return self._element.click()
103+
def click(self, timeout=30):
104+
return self._element.click(timeout=timeout * SECONDS_TO_MILLISECONDS)
105105

106106
def get_inner_text(self):
107107
return self._element.inner_text()
@@ -174,9 +174,8 @@ def get_user_data(self):
174174
return self._user_data
175175

176176
def expect_not_to_be_visible(self, timeout=30):
177-
seconds_to_milliseconds = 1000
178177
try:
179-
expect(self._element).not_to_be_visible(timeout=timeout * seconds_to_milliseconds)
178+
expect(self._element).not_to_be_visible(timeout=timeout * SECONDS_TO_MILLISECONDS)
180179
except ValueError as err:
181180
raise Exception('Cannot expect not_to_be_visible on this type!') from err
182181
except AssertionError as err:
@@ -797,27 +796,64 @@ def is_kernel_running(self):
797796
def wait_for_kernel_ready(self):
798797
self._editor_page.wait_for_selector(".kernel_idle_icon")
799798

800-
def _open_notebook_editor_page(self, existing_file_name=None):
799+
def get_editor_page_from_existing_notebook(self, existing_file_name):
801800
tree_page = self._tree_page
802801

803-
if existing_file_name is not None:
804-
existing_notebook = tree_page.locator(f"text={existing_file_name}")
805-
existing_notebook.click()
806-
self._tree_page.reload() # TODO: FIX this, page count does not update to 2
807-
else:
808-
# Simulate a user opening a new notebook/kernel
809-
new_dropdown_element = tree_page.locator('#new-dropdown-button')
810-
new_dropdown_element.click()
811-
kernel_name = 'kernel-python3'
812-
kernel_selector = f'#{kernel_name} a'
813-
new_notebook_element = tree_page.locator(kernel_selector)
814-
new_notebook_element.click()
802+
# Find the link to the notebook file on the tree page
803+
notebook_name_selector = f"text={existing_file_name}"
804+
tree_page.wait_for_selector(notebook_name_selector)
805+
# Click the existing notebook link on the tree page to open the editor
806+
existing_notebook = tree_page.locator(notebook_name_selector)
807+
existing_notebook.click()
808+
self._tree_page.reload() # TODO: FIX this, page count does not update to 2
809+
810+
def wait_for_new_page():
811+
return [pg for pg in self._browser_data[BROWSER_CONTEXT].pages if 'tree' not in pg.url]
812+
813+
new_pages = self.wait_for_condition(
814+
wait_for_new_page,
815+
timeout=125,
816+
period=1
817+
)
818+
editor_page = new_pages[0]
819+
820+
return editor_page
821+
822+
def get_new_editor_page(self):
823+
tree_page = self._tree_page
824+
825+
# Simulate a user opening a new notebook/kernel
826+
new_dropdown_element = tree_page.locator('#new-dropdown-button')
827+
new_dropdown_element.click()
828+
kernel_name = 'kernel-python3'
829+
kernel_selector = f'#{kernel_name} a'
830+
new_notebook_element = tree_page.locator(kernel_selector)
831+
new_notebook_element.click()
815832

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

819836
new_pages = self.wait_for_condition(wait_for_new_page)
820837
editor_page = new_pages[0]
838+
839+
return editor_page
840+
841+
def _open_notebook_editor_page(self, existing_file_name=None):
842+
tree_page = self._tree_page
843+
844+
if existing_file_name is not None:
845+
editor_page = self.wait_for_condition(
846+
lambda: self.get_editor_page_from_existing_notebook(existing_file_name),
847+
timeout=500,
848+
period=1
849+
)
850+
else:
851+
editor_page = self.wait_for_condition(
852+
lambda: self.get_new_editor_page(),
853+
timeout=500,
854+
period=1
855+
)
856+
821857
return editor_page
822858

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

831867
return specified_page.url
832-
868+
833869
def go_back(self, page):
834870
if page == TREE_PAGE:
835871
specified_page = self._tree_page

0 commit comments

Comments
 (0)