Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update selenium tests #3412

Merged
merged 8 commits into from
Mar 23, 2018
4 changes: 3 additions & 1 deletion notebook/static/tree/js/notebooklist.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ define([
this.sessions = {};
this.base_url = options.base_url || utils.get_body_data("baseUrl");
this.notebook_path = options.notebook_path || utils.get_body_data("notebookPath");
this.initial_notebook_path = this.notebook_path;
this.contents = options.contents;
if (this.session_list && this.session_list.events) {
this.session_list.events.on('sessions_loaded.Dashboard',
Expand Down Expand Up @@ -358,7 +359,8 @@ define([
var that = this;
// Add an event handler browser back and forward events
window.onpopstate = function(e) {
var path = window.history.state ? window.history.state.path : '';
var path = (window.history.state && window.history.state.path) ?
window.history.state.path : that.initial_notebook_path;
that.update_location(path);
};
var breadcrumb = $('.breadcrumb');
Expand Down
23 changes: 13 additions & 10 deletions notebook/tests/selenium/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ def notebook_server():
requests.post(urljoin(info['url'], 'api/shutdown'),
headers={'Authorization': 'token '+info['token']})


def _get_selenium_driver():
@pytest.fixture(scope='session')
def selenium_driver():
if os.environ.get('SAUCE_USERNAME'):
username = os.environ["SAUCE_USERNAME"]
access_key = os.environ["SAUCE_ACCESS_KEY"]
Expand All @@ -81,16 +81,19 @@ def _get_selenium_driver():
capabilities['version'] = '57.0'
hub_url = "%s:%s@localhost:4445" % (username, access_key)
print("Connecting remote driver on Sauce Labs")
return Remote(desired_capabilities=capabilities,
driver = Remote(desired_capabilities=capabilities,
command_executor="http://%s/wd/hub" % hub_url)
elif os.environ.get('JUPYTER_TEST_BROWSER') == 'chrome':
return Chrome()
driver = Chrome()
else:
return Firefox()
driver = Firefox()

yield driver

# Teardown
driver.quit()

@pytest.fixture
def browser(notebook_server):
b = _get_selenium_driver()
b.get("{url}?token={token}".format(**notebook_server))
yield b
b.quit()
def authenticated_browser(selenium_driver, notebook_server):
selenium_driver.get("{url}?token={token}".format(**notebook_server))
return selenium_driver
77 changes: 52 additions & 25 deletions notebook/tests/selenium/test_dashboard_nav.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,70 @@
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

pjoin = os.path.join


class PageError(Exception):
"""Error for an action being incompatible with the current jupyter web page.

"""
def __init__(self, message):
self.message = message



def get_list_items(browser):
"""Gets list items from a directory listing page

Raises PageError if not in directory listing page (url has tree in it)
"""
try:
assert 'tree' in browser.current_url
except PageError:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a convoluted way of writing if 'tree' not in browser.current_url: , even if it was catching the right error. Let's stick to the simple if statement rather than using assert to achieve the same thing.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair enough — changed.

raise PageError("You are not in the notebook's file tree view."
"This function can only be used the file tree context.")
# we need to make sure that at least one item link loads
wait_for_selector(browser, '.item_link')

return [{
'link': a.get_attribute('href'),
'label': a.find_element_by_class_name('item_name').text,
'element': a,
} for a in browser.find_elements_by_class_name('item_link')]


def only_dir_links(browser):
"""Return only links that point at other directories in the tree

"""
items = get_list_items(browser)
return [i for i in items if 'tree' in i['link'] and i['label'] != '..']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will go wrong for any file that has tree in the name. Maybe that's unlikely, but I think it's worth doing it a bit more thoroughly.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok addressed by using an explicit check for whether urls point to something in the tree (with url_in_tree)



def wait_for_selector(browser, selector, timeout=10):
wait = WebDriverWait(browser, timeout)
return wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, selector)))


def test_items(authenticated_browser):
visited_dict = {}
# Going down the tree to collect links
while True:
wait_for_selector(authenticated_browser, '.item_link')
current_url = authenticated_browser.current_url
items = visited_dict[current_url] = only_dir_links(authenticated_browser)
try:
item = items[0]
item["element"].click()
assert authenticated_browser.current_url == item['link']
except IndexError:
break
# Going back up the tree while we still have unvisited links
while visited_dict:
current_items = only_dir_links(authenticated_browser)
current_items_links = [item["link"] for item in current_items]
stored_items = visited_dict.pop(authenticated_browser.current_url)
stored_items_links = [item["link"] for item in stored_items]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neat, I like the comparison of what's here now vs what was here before.

assert stored_items_links == current_items_links
authenticated_browser.back()

def test_items(browser, visited=None):
tree_root_url = browser.current_url
if visited is None:
visited = set()

wait_for_selector(browser, '.item_link')
items = get_list_items(browser)
print(browser.current_url, len(items))
for item in items:
print(item)
url = item['link']
if url.startswith(tree_root_url):
print("Going to", url)
if url in visited:
continue
visited.add(url)
browser.get(url)
wait_for_selector(browser, '.item_link')
assert browser.current_url == url

test_items(browser, visited)
#browser.back()

print()