Files
edx-platform/common/test/acceptance/pages/lms/tab_nav.py
2021-03-09 18:03:34 +05:00

110 lines
3.5 KiB
Python

"""
High-level tab navigation.
"""
from bok_choy.page_object import PageObject
from bok_choy.promise import EmptyPromise, Promise
class TabNavPage(PageObject):
"""
High-level tab navigation.
"""
url = None
# def is_using_v1_style_tabs(self):
# return self.q(css='ol.course-tabs').present
def is_using_boostrap_style_tabs(self):
return self.q(css='ul.navbar-nav').present
def is_browser_on_page(self):
return (self.q(css='ol.course-tabs').present or
self.q(css='ul.navbar-nav').present)
def go_to_tab(self, tab_name):
"""
Navigate to the tab `tab_name`.
"""
if tab_name not in ['Course', 'Home', 'Discussion', 'Wiki', 'Progress']:
self.warning(f"'{tab_name}' is not a valid tab name")
# The only identifier for individual tabs is the link href
# so we find the tab with `tab_name` in its text.
tab_css = self._tab_css(tab_name)
if tab_css is not None:
self.q(css=tab_css).first.click()
else:
self.warning(f"No tabs found for '{tab_name}'")
self.wait_for_page()
self._is_on_tab_promise(tab_name).fulfill()
def _tab_css(self, tab_name):
"""
Return the CSS to click for `tab_name`.
If no tabs exist for that name, return `None`.
"""
all_tabs = self.tab_names
try:
tab_index = all_tabs.index(tab_name)
except ValueError:
return None
else:
if self.is_using_boostrap_style_tabs():
return 'ul.navbar-nav li:nth-of-type({}) a'.format(tab_index + 1)
else:
return 'ol.course-tabs li:nth-of-type({}) a'.format(tab_index + 1)
@property
def tab_names(self):
"""
Return the list of available tab names. If no tab names
are available, wait for them to load. Raises a `BrokenPromiseError`
if the tab names fail to load.
"""
def _standard_check_func():
tab_names = self.q(css='ol.course-tabs li a').text
return (len(tab_names) > 0, tab_names)
def _bootstrap_check_func():
tab_names = self.q(css='ul.navbar-nav li a').text
return (len(tab_names) > 0, tab_names)
if self.is_using_boostrap_style_tabs():
return Promise(_bootstrap_check_func, "Get all tab names").fulfill()
else:
return Promise(_standard_check_func, "Get all tab names").fulfill()
def _is_on_tab(self, tab_name):
"""
Return a boolean indicating whether the current tab is `tab_name`.
This is a private method, so it does NOT enforce the page check,
which is what we want when we're polling the DOM in a promise.
"""
if self.is_using_boostrap_style_tabs():
current_tab_list = self.q(css='ul.navbar-nav > .nav-item.active').text
else:
current_tab_list = self.q(css='ol.course-tabs > li > a.active').text
if len(current_tab_list) == 0:
self.warning("Could not find current tab")
return False
else:
return current_tab_list[0].strip().split('\n')[0] == tab_name
def _is_on_tab_promise(self, tab_name):
"""
Return a `Promise` that the user is on the tab `tab_name`.
"""
# Use the private version of _is_on_tab to skip the page check
return EmptyPromise(
lambda: self._is_on_tab(tab_name),
f"{tab_name} is the current tab"
)