Switch to a new more structured YAML format for navigation data.

Break everything into components.
This commit is contained in:
John Chilton
2017-10-02 11:54:59 -04:00
parent e709000206
commit 0650978a91
13 changed files with 458 additions and 127 deletions
+155 -2
View File
@@ -1,5 +1,158 @@
import re
import string
import yaml
from pkg_resources import resource_string
data_yaml = resource_string(__name__, 'navigation-data.yml').decode("UTF-8")
NAVIGATION_DATA = yaml.safe_load(data_yaml)
from selenium.webdriver.common.by import By
from galaxy.util.bunch import Bunch
old_data_yaml = resource_string(__name__, 'navigation-data.yml').decode("UTF-8")
NAVIGATION_DATA = yaml.safe_load(old_data_yaml)
new_data_yaml = resource_string(__name__, 'navigation.yml').decode("UTF-8")
NAVIGATION_RAW = yaml.safe_load(new_data_yaml)
class SelectorTemplate(object):
def __init__(self, selector, selector_type, kwds=None, with_classes=None):
self._selector = selector
self.selector_type = selector_type
self.__kwds = kwds or {}
self.with_classes = with_classes or []
@staticmethod
def from_dict(raw_value):
if isinstance(raw_value, dict):
return SelectorTemplate(raw_value["selector"], raw_value.get("type", "css"))
else:
return SelectorTemplate(raw_value, "css")
def with_class(self, class_):
assert self.selector_type == "css"
return SelectorTemplate(self._selector, self.selector_type, kwds=self.__kwds, with_classes=self.with_classes + [class_])
def __call__(self, **kwds):
new_kwds = self.__kwds
new_kwds.update(**kwds)
return SelectorTemplate(self._selector, self.selector_type, kwds=new_kwds, with_classes=self.with_classes)
@property
def description(self):
if self.selector_type == "css":
template = "CSS selector [%s]"
elif self.selector_type == "xpath":
template = "XPATH selector [%s]"
elif self.selector_type == "id":
template = "DOM element with id [%s]"
return template % self.selector
@property
def selector(self):
selector = self._selector
if self.__kwds is not None:
selector = string.Template(selector).substitute(self.__kwds)
selector = selector + "".join([".%s" % c for c in self.with_classes])
return selector
@property
def element_locator(self):
if self.selector_type == "css":
by = By.CSS_SELECTOR
elif self.selector_type == "xpath":
by = By.XPATH
elif self.selector_type == "id":
by = By.ID
else:
raise Exception("Unknown selector type")
return (by, self.selector)
@property
def as_css_class(self):
assert self.selector_type == "css"
assert re.compile(r"\.\w+").match(self._selector)
return self._selector[1:]
class Label(object):
def __init__(self, text):
self.text = text
@property
def description(self):
return "Link text [%s]" % self.text
@property
def element_locator(self):
return (By.LINK_TEXT, self.text)
class Text(object):
def __init__(self, text):
self.text = text
@property
def description(self):
return "Text containing [%s]" % self.text
@property
def element_locator(self):
return (By.PARTIAL_LINK_TEXT, self.text)
class Component(object):
def __init__(self, name, sub_components, selectors, labels, text):
self.name = name
self._sub_components = sub_components
self._selectors = selectors
self._labels = labels
self._text = text
self.selectors = Bunch(**self._selectors)
self.labels = Bunch(**self._labels)
self.text = Bunch(**self._text)
@property
def selector(self):
if "_" in self._selectors:
return self._selectors["_"]
else:
raise Exception("No _ selector for [%s]" % self)
@staticmethod
def from_dict(name, raw_value):
selectors = {}
labels = {}
text = {}
sub_components = {}
for key, value in raw_value.items():
if key == "selectors":
for selector_key, selector_value in value.items():
selectors[selector_key] = SelectorTemplate.from_dict(selector_value)
elif key == "labels":
for label_key, label_value in value.items():
labels[label_key] = Label(label_value)
elif key == "text":
for text_key, text_value in value.items():
text[text_key] = Text(text_value)
else:
component = Component.from_dict(key, value)
sub_components[key] = component
return Component(name, sub_components, selectors, labels, text)
def __getattr__(self, attr):
return self._sub_components[attr]
def __str__(self):
return "Component[%s]" % self.name
NAVIGATION = Component.from_dict("root", NAVIGATION_RAW)
+47
View File
@@ -28,13 +28,28 @@ class HasDriver:
for element in elements:
assert not element.is_displayed()
def assert_absent_or_hidden(self, selector_template):
elements = self.find_elements(selector_template)
for element in elements:
assert not element.is_displayed()
def selector_is_displayed(self, selector):
element = self.driver.find_element_by_css_selector(selector)
return element.is_displayed()
def is_displayed(self, selector_template):
element = self.driver.find_element(*selector_template.element_locator)
return element.is_displayed()
def assert_selector_absent(self, selector):
assert len(self.driver.find_elements_by_css_selector(selector)) == 0
def find_elements(self, selector_template):
return self.driver.find_elements(*selector_template.element_locator)
def assert_absent(self, selector_template):
assert len(self.find_elements(selector_template)) == 0
def wait_for_xpath(self, xpath, **kwds):
element = self._wait_on(
ec.presence_of_element_located((By.XPATH, xpath)),
@@ -59,6 +74,22 @@ class HasDriver:
)
return element
def wait_for_present(self, selector_template, **kwds):
element = self._wait_on(
ec.presence_of_element_located(selector_template.element_locator),
"%s to become present" % selector_template.description,
**kwds
)
return element
def wait_for_visible(self, selector_template, **kwds):
element = self._wait_on(
ec.visibility_of_element_located(selector_template.element_locator),
"%s to become visible" % selector_template.description,
**kwds
)
return element
def wait_for_selector_visible(self, selector, **kwds):
element = self._wait_on(
ec.visibility_of_element_located((By.CSS_SELECTOR, selector)),
@@ -75,6 +106,14 @@ class HasDriver:
)
return element
def wait_for_clickable(self, selector_template, **kwds):
element = self._wait_on(
ec.element_to_be_clickable(selector_template.element_locator),
"%s to become clickable" % selector_template.description,
**kwds
)
return element
def wait_for_selector_absent_or_hidden(self, selector, **kwds):
element = self._wait_on(
ec.invisibility_of_element_located((By.CSS_SELECTOR, selector)),
@@ -91,6 +130,14 @@ class HasDriver:
)
return element
def wait_for_absent_or_hidden(self, selector_template, **kwds):
element = self._wait_on(
ec.invisibility_of_element_located(selector_template.element_locator),
"%s to become absent or hidden" % selector_template.description,
**kwds
)
return element
def wait_for_id(self, id, **kwds):
return self._wait_on(
ec.presence_of_element_located((By.ID, id)),
+67 -59
View File
@@ -17,7 +17,10 @@ import yaml
from galaxy.util.bunch import Bunch
from . import sizzle
from .data import NAVIGATION_DATA
from .data import (
NAVIGATION, # newer variant of NAVIGATION_DATA
NAVIGATION_DATA,
)
from .has_driver import (
exception_indicates_not_clickable,
exception_indicates_stale_element,
@@ -130,6 +133,10 @@ class NavigatesGalaxy(HasDriver):
def navigation_data(self):
return NAVIGATION_DATA
@property
def navigation(self):
return NAVIGATION
def wait_length(self, wait_type):
return wait_type.default_length * self.timeout_multiplier
@@ -142,11 +149,11 @@ class NavigatesGalaxy(HasDriver):
def home(self):
self.get()
self.wait_for_selector_visible("#masthead")
self.wait_for_selector_visible("#current-history-panel")
self.wait_for_visible(self.navigation.masthead.selector)
self.wait_for_visible(self.navigation.history_panel.selector)
def switch_to_main_panel(self):
self.driver.switch_to.frame(self.navigation_data["selectors"]["frames"]["main"])
self.driver.switch_to.frame("galaxy_main")
@contextlib.contextmanager
def main_panel(self):
@@ -182,12 +189,8 @@ class NavigatesGalaxy(HasDriver):
'galaxysession': self.get_galaxy_session()
}
def history_panel_name_selector(self):
name_selector = self.test_data["historyPanel"]["selectors"]["history"]["name"]
return name_selector
def history_panel_name_element(self):
return self.wait_for_selector(self.history_panel_name_selector())
return self.wait_for_present(self.navigation.history_panel.selectors.name)
@retry_during_transitions
def history_panel_name(self):
@@ -248,23 +251,25 @@ class NavigatesGalaxy(HasDriver):
self.wait(timeout).until(history_has_hid)
contents = self.api_get("histories/%s/contents" % current_history_id)
history_item = [d for d in contents if d["hid"] == hid][0]
history_item_selector = "#%s-%s" % (history_item["history_content_type"], history_item["id"])
history_item_selector = self.navigation.history_panel.item.selector(
history_content_type=history_item["history_content_type"],
id=history_item["id"]
)
try:
self.history_item_wait_for_selector(history_item_selector, allowed_force_refreshes)
self.history_item_wait_for(history_item_selector, allowed_force_refreshes)
except self.TimeoutException as e:
dataset_elements = self.driver.find_elements_by_css_selector("#current-history-panel .list-items div")
div_ids = [d.get_attribute('id') for d in dataset_elements]
contents_elements = self.find_elements(self.navigation.history_panel.selectors.contents)
div_ids = [("#" + d.get_attribute('id')) for d in contents_elements]
template = "Failed waiting on history item %d to become visible, visible datasets include [%s]."
message = template % (hid, ",".join(div_ids))
raise self.prepend_timeout_message(e, message)
return history_item_selector
def history_item_wait_for_selector(self, history_item_selector, allowed_force_refreshes):
def history_item_wait_for(self, history_item_selector, allowed_force_refreshes):
attempt = 0
while True:
try:
rval = self.wait_for_selector_visible(history_item_selector, wait_type=WAIT_TYPES.JOB_COMPLETION)
rval = self.wait_for_visible(history_item_selector, wait_type=WAIT_TYPES.JOB_COMPLETION)
break
except self.TimeoutException:
if attempt >= allowed_force_refreshes:
@@ -278,23 +283,26 @@ class NavigatesGalaxy(HasDriver):
# Use the search box showing up as a proxy that the history display
# has left the "loading" state and is showing a valid set of history contents
# (even if empty).
self.wait_for_selector_visible("#current-history-panel input.search-query", wait_type=WAIT_TYPES.DATABASE_OPERATION)
self.wait_for_visible(self.navigation.history_panel.selectors.search, wait_type=WAIT_TYPES.DATABASE_OPERATION)
def history_panel_wait_for_hid_hidden(self, hid):
current_history_id = self.current_history_id()
contents = self.api_get("histories/%s/contents" % current_history_id)
history_item = [d for d in contents if d["hid"] == hid][0]
history_item_selector = "#%s-%s" % (history_item["history_content_type"], history_item["id"])
self.wait_for_selector_absent(history_item_selector, wait_type=WAIT_TYPES.JOB_COMPLETION)
history_item_selector = self.navigation.history_panel.item.selector(
history_content_type=history_item["history_content_type"],
id=history_item["id"]
)
self.wait_for_absent_or_hidden(history_item_selector, wait_type=WAIT_TYPES.JOB_COMPLETION)
return history_item_selector
def history_panel_wait_for_hid_state(self, hid, state, allowed_force_refreshes=0):
history_item_selector = self.history_panel_wait_for_hid_visible(hid, allowed_force_refreshes=allowed_force_refreshes)
history_item_selector_state = "%s.state-%s" % (history_item_selector, state)
history_item_selector_state = history_item_selector.with_class("state-%s" % state)
try:
self.history_item_wait_for_selector(history_item_selector_state, allowed_force_refreshes)
self.history_item_wait_for(history_item_selector_state, allowed_force_refreshes)
except self.TimeoutException as e:
history_item = self.driver.find_element_by_css_selector(history_item_selector)
history_item = self.wait_for_visible(history_item_selector)
current_state = "UNKNOWN"
classes = history_item.get_attribute("class").split(" ")
for clazz in classes:
@@ -348,10 +356,10 @@ class NavigatesGalaxy(HasDriver):
}
self.click_masthead_user()
self.click_label(self.navigation_data["labels"]["masthead"]["userMenu"]["login"])
self.wait_for_and_click(self.navigation.masthead.labels.login)
with self.main_panel():
form = self.wait_for_selector(self.navigation_data["selectors"]["loginPage"]["form"])
form = self.wait_for_visible(self.navigation.login.selectors.form)
self.fill(form, login_info)
self.snapshot("logging-in")
self.click_submit(form)
@@ -380,17 +388,16 @@ class NavigatesGalaxy(HasDriver):
self.home()
self.click_masthead_user()
self.click_label(self.navigation_data["labels"]["masthead"]["userMenu"]["register"])
self.wait_for_and_click(self.navigation.masthead.labels.register)
with self.main_panel():
register_form_id = self.navigation_data["selectors"]["registrationPage"]["form"]
form = self.wait_for_id(register_form_id)
form = self.wait_for_visible(self.navigation.registration.selectors.form)
self.fill(form, dict(
email=email,
password=password,
username=username,
confirm=confirm
))
self.click_xpath(self.navigation_data["selectors"]["registrationPage"]["submit_xpath"])
self.wait_for_and_click(self.navigation.registration.selectors.submit)
# Give the browser a bit of time to submit the request.
# It would be good to eliminate this sleep, but it can't be because Galaxy
# doesn't swap the "User" menu automatically after it registers a user and
@@ -409,7 +416,7 @@ class NavigatesGalaxy(HasDriver):
# Make sure the user menu was dropped down
user_menu = self.wait_for_selector_visible("ul.nav#user .dropdown-menu")
try:
user_email_element = self.wait_for_xpath_visible(self.navigation_data["selectors"]["masthead"]["userMenu"]["userEmail_xpath"])
user_email_element = self.wait_for_visible(self.navigation.masthead.selectors.user_email)
except self.TimeoutException as e:
menu_items = user_menu.find_elements_by_css_selector("li a")
menu_text = [mi.text for mi in menu_items]
@@ -425,7 +432,7 @@ class NavigatesGalaxy(HasDriver):
def wait_for_logged_in(self):
try:
self.wait_for_selector_visible("a.loggedin-only")
self.wait_for_visible(self.navigation.masthead.selectors.logged_in_only)
except self.TimeoutException as e:
user_info = self.api_get("users/current")
if "username" in user_info:
@@ -709,13 +716,16 @@ class NavigatesGalaxy(HasDriver):
self.wait_for_and_click_selector("button#execute")
def click_masthead_user(self):
self.click_xpath(self.navigation_data["selectors"]["masthead"]["user"])
self.wait_for_and_click(self.navigation.masthead.selectors.user)
def click_masthead_libraries(self):
self.wait_for_and_click(self.navigation.masthead.labels.libraries)
def click_masthead_workflow(self):
self.click_xpath(self.navigation_data["selectors"]["masthead"]["workflow"])
self.wait_for_and_click(self.navigation.masthead.labels.workflow)
def click_button_new_workflow(self):
self.wait_for_and_click_selector(self.navigation_data["selectors"]["workflows"]["new_button"])
self.wait_for_and_click(self.navigation.workflows.selectors.new_button)
def wait_for_sizzle_selector_clickable(self, selector):
element = self._wait_on(
@@ -741,16 +751,11 @@ class NavigatesGalaxy(HasDriver):
self.click_history_options()
# Click labelled option
menu_selector = self.history_options_menu_selector()
self.wait_for_selector_visible(menu_selector)
self.wait_for_visible(self.navigation.history_panel.selectors.options_menu)
menu_item_sizzle_selector = '#history-options-button-menu > li > a:contains("%s")' % option_label
menu_selection_element = self.wait_for_sizzle_selector_clickable(menu_item_sizzle_selector)
menu_selection_element.click()
def history_options_menu_selector(self):
menu_selector = self.test_data["historyOptions"]["selectors"]["menu"]
return menu_selector
@retry_during_transitions
def histories_click_advanced_search(self):
search_selector = '#standard-search .advanced-search-toggle'
@@ -777,36 +782,31 @@ class NavigatesGalaxy(HasDriver):
self.send_enter(editable_text_input_element)
def history_panel_click_to_rename(self):
self.wait_for_and_click_selector(self.history_panel_name_selector())
return self.wait_for_selector(self.history_panel_edit_title_input_selector())
def history_panel_edit_title_input_selector(self):
return self.test_data["historyPanel"]["selectors"]["history"]["nameEditableTextInput"]
self.wait_for_and_click(self.navigation.history_panel.selectors.name)
return self.wait_for_visible(self.navigation.history_panel.selectors.name_edit_input)
def history_panel_refresh_click(self):
self.wait_for_and_click_selector("#history-refresh-button")
def history_panel_multi_operations_selector(self):
return self.test_data["historyPanel"]["selectors"]["history"]["multiOperationsIcon"]
self.wait_for_and_click(self.navigation.history_panel.selectors.refresh_button)
def history_panel_multi_operations_show(self):
operations_selector = self.history_panel_multi_operations_selector()
self.wait_for_and_click_selector(operations_selector)
return self.wait_for_and_click(self.navigation.history_panel.multi_operations.selectors.show_button)
def history_panel_muli_operation_select_hid(self, hid):
item_selector = self.history_panel_item_selector(hid, wait=True)
operation_radio_selector = "%s .selector" % item_selector
self.wait_for_and_click_selector(operation_radio_selector)
def history_panel_multi_operation_action_selector(self):
return self.test_data["historyPanel"]["selectors"]["history"]["multiOperationsActionBtn"]
def history_panel_multi_operation_action_click(self, action):
time.sleep(5)
self.wait_for_and_click_selector(self.history_panel_multi_operation_action_selector())
menu_element = self.wait_for_selector_visible(".list-action-menu.open")
action_element = menu_element.find_element_by_link_text(action)
action_element.click()
# Maybe isn't needed?
# self.sleep_for(WAIT_TYPES.UX_RENDER)
self.wait_for_and_click(self.navigation.history_panel.multi_operations.selectors.action_button)
@retry_during_transitions
def _click_action_in_menu():
menu_element = self.wait_for_visible(self.navigation.history_panel.multi_operations.selectors.action_menu)
menu_element.find_element_by_link_text(action.text).click()
_click_action_in_menu()
def history_panel_item_click_visualization_menu(self, hid):
viz_button_selector = "%s %s" % (self.history_panel_item_selector(hid), ".visualizations-dropdown")
@@ -917,7 +917,7 @@ class NavigatesGalaxy(HasDriver):
if self.is_logged_in():
self.home()
self.click_masthead_user()
self.click_label(self.navigation_data["labels"]["masthead"]["userMenu"]["logout"])
self.wait_for_and_click(self.navigation.masthead.labels.logout)
self.click_label('go to the home page')
assert not self.is_logged_in()
@@ -986,6 +986,8 @@ class NavigatesGalaxy(HasDriver):
return self.assert_selector_absent_or_hidden(selector)
def assert_tooltip_text(self, element, expected, sleep=0, click_away=True):
if hasattr(expected, "text"):
expected = expected.text
text = self.get_tooltip_text(element, sleep=sleep, click_away=click_away)
assert text == expected, "Tooltip text [%s] was not expected text [%s]." % (text, expected)
@@ -1038,6 +1040,12 @@ class NavigatesGalaxy(HasDriver):
element.click()
return element
@retry_during_transitions
def wait_for_and_click(self, selector_template):
element = self.wait_for_clickable(selector_template)
element.click()
return element
def select2_set_value(self, container_selector, value, with_click=True):
# There are two hacky was to select things from the select2 widget -
# with_click=True: This simulates the mouse click after the suggestion contains
+1
View File
@@ -1,3 +1,4 @@
# Deprecated navigation constants - prefer navigation.yml.
selectors:
tooltipBalloon: '.tooltip'
editableText: '.editable-text'
+129
View File
@@ -0,0 +1,129 @@
# top_level: {global: <components>, workflows: <components>, histories: <components>}
# components := {<subcomponent_name>: <components>} | <component>
# component := {selectors: <selectors_map>, labels: <labels_map>, ids: <id_map>}
# selectors_map := {<selector_name>: <selector>}
# selector := <str> | {type: <selector_type>, selector: <str>}
# selector_type := css|xpath|sizzle|id
# labels_map := {<label_name>: <label>}
_: # global stuff
selectors:
editable_text: '.editable-text'
masthead:
selectors:
_: '#masthead'
user:
type: xpath
selector: '//ul[@id="user"]'
workflow:
type: xpath
selector: '//ul[@id="workflow"]'
user_email:
type: xpath
selector: '//a[contains(text(), "Logged in as")]'
logged_in_only: 'a.loggedin-only'
labels:
# top-level menus
analyze: 'Analyze Data'
workflow: 'Workflow'
libraries: 'Shared Data'
visualization: 'Visualization'
help: 'Help'
user: 'User'
# user menu
register: 'Register'
login: 'Login'
logout: 'Logout'
history_panel:
menu:
labels:
new: 'Create New'
item:
selectors:
_: '#${history_content_type}-${id}'
title: '${item_selector} .title'
hid: '${item_selector} .hid'
name: '${item_selector} .name'
titleButtonArea: '${item_selector} .primary-actions'
summary: '${item_selector} .summary'
blurb: '${item_selector} .blurb .value'
dbkey: '${item_selector} .dbkey .value'
info: '${item_selector} .info .value'
body: '${item_selector} .details'
multi_operations:
selectors:
show_button: '#current-history-panel .actions .show-selectors-btn'
action_button: '#current-history-panel .list-action-menu .list-action-menu-btn'
action_menu: '.list-action-menu.open'
labels:
build_pair: "Build Dataset Pair"
build_list: "Build Dataset List"
build_list_pairs: "Build List of Dataset Pairs"
selectors:
_: '#current-history-panel'
search: '#current-history-panel input.search-query'
refresh_button: '#history-refresh-button'
name: '.title .name'
name_edit_input: '.name input'
contents: '#current-history-panel .list-items div.history-content'
empty_message: '.empty-message'
tag_icon: '.actions .history-tag-btn'
tag_area: '.controls .tags-display'
annotation_icon: '.actions .history-annotate-btn'
annotation_area: '.controls .annotation-display'
annotation_editable_text: '.controls .annotation-display .annotation.editable-text'
annotation_edit: '.controls .annotation-display .annotation textarea'
annotation_done: '.controls .annotation-display .annotation button'
options_button: '#history-options-button'
options_button_icon: '#history-options-button span.fa-cog'
options_menu: '#history-options-button-menu'
text:
tooltip_name: 'Click to rename history'
collection_builders:
selectors:
clear_filters: "a.clear-filters-link"
forward_datasets: ".forward-column .column-datasets"
reverse_datasets: ".reverse-column .column-datasets"
login:
selectors:
form: 'form#login'
registration:
selectors:
form: '#registration'
submit:
type: xpath
selector: "//input[@value='Submit']"
workflows:
selectors:
new_button: '#new-workflow'
import_button: '#import-workflow'
published_grids:
selectors:
search: '#input-free-text-search-filter'
+11 -12
View File
@@ -11,19 +11,19 @@ class AnonymousHistoriesTestCase(SeleniumTestCase):
self.home()
self.assert_initial_history_panel_state_correct()
tag_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["tagIcon"]
anno_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["annoIcon"]
self.assert_selector_absent(tag_icon_selector)
self.assert_selector_absent(anno_icon_selector)
tag_icon_selector = self.navigation.history_panel.selectors.tag_icon
annotation_icon_selector = self.navigation.history_panel.selectors.annotation_icon
self.assert_absent_or_hidden(tag_icon_selector)
self.assert_absent_or_hidden(annotation_icon_selector)
name_selector = self.test_data["historyPanel"]["selectors"]["history"]["name"]
name_element = self.wait_for_selector(name_selector)
# name should NOT be editable when clicked by anon-user
editable_text_class = self.test_data["selectors"]["editableText"]
assert editable_text_class not in name_element.get_attribute("class")
# History has a name but...
name_element = self.wait_for_present(self.navigation.history_panel.selectors.name)
name_element.click()
# ... name should NOT be editable when clicked by anon-user
editable_text_class = self.navigation._.selectors.editable_text
assert editable_text_class.as_css_class not in name_element.get_attribute("class")
@selenium_test
def test_anon_history_upload(self):
self.home()
@@ -35,8 +35,7 @@ class AnonymousHistoriesTestCase(SeleniumTestCase):
assert 'state-ok' in element.get_attribute("class")
# empty should be NO LONGER be displayed
empty_msg_selector = self.test_data["historyPanel"]["selectors"]["history"]["emptyMsg"]
self.assert_selector_absent_or_hidden(empty_msg_selector)
self.assert_absent_or_hidden(self.navigation.history_panel.selectors.empty_message)
@selenium_test
def test_anon_history_after_registration(self):
@@ -14,7 +14,7 @@ class CollectionBuildersTestCase(SeleniumTestCase):
self.history_panel_wait_for_hid_ok(1)
self.history_panel_multi_operations_show()
self.history_panel_muli_operation_select_hid(1)
self.history_panel_multi_operation_action_click("Build Dataset List")
self.history_panel_multi_operation_action_click(self.navigation.history_panel.multi_operations.labels.build_list)
self.collection_builder_set_name("my cool list")
@@ -27,7 +27,7 @@ class CollectionBuildersTestCase(SeleniumTestCase):
self.history_panel_wait_for_hid_ok(1)
self.history_panel_multi_operations_show()
self.history_panel_muli_operation_select_hid(1)
self.history_panel_multi_operation_action_click("Build Dataset List")
self.history_panel_multi_operation_action_click(self.navigation.history_panel.multi_operations.labels.build_list)
self.collection_builder_hide_originals()
self.collection_builder_set_name("my cool list")
@@ -46,7 +46,7 @@ class CollectionBuildersTestCase(SeleniumTestCase):
self.history_panel_multi_operations_show()
self.history_panel_muli_operation_select_hid(1)
self.history_panel_muli_operation_select_hid(2)
self.history_panel_multi_operation_action_click("Build Dataset Pair")
self.history_panel_multi_operation_action_click(self.navigation.history_panel.multi_operations.labels.build_pair)
self.collection_builder_set_name("my awesome pair")
self.collection_builder_create()
@@ -61,7 +61,7 @@ class CollectionBuildersTestCase(SeleniumTestCase):
self.history_panel_multi_operations_show()
self.history_panel_muli_operation_select_hid(1)
self.history_panel_muli_operation_select_hid(2)
self.history_panel_multi_operation_action_click("Build List of Dataset Pairs")
self.history_panel_multi_operation_action_click(self.navigation.history_panel.multi_operations.labels.build_list_pairs)
self.collection_builder_clear_filters()
self.collection_builder_click_paired_item("forward", 0)
@@ -80,16 +80,15 @@ class CollectionBuildersTestCase(SeleniumTestCase):
self.history_panel_multi_operations_show()
self.history_panel_muli_operation_select_hid(1)
self.history_panel_muli_operation_select_hid(2)
self.history_panel_multi_operation_action_click("Build List of Dataset Pairs")
self.history_panel_multi_operation_action_click(self.navigation.history_panel.multi_operations.labels.build_list_pairs)
clear_filter_link = self.wait_for_selector_visible("a.clear-filters-link")
clear_filter_link.click()
self.wait_for_and_click(self.navigation.collection_builders.selectors.clear_filters)
forward_column = self.wait_for_selector_visible(".forward-column .column-datasets")
forward_column = self.wait_for_visible(self.navigation.collection_builders.selectors.forward_datasets)
first_datset_forward = forward_column.find_elements_by_css_selector("li")[0]
first_datset_forward.click()
reverse_column = self.wait_for_selector_visible(".reverse-column .column-datasets")
reverse_column = self.wait_for_visible(self.navigation.collection_builders.selectors.reverse_datasets)
second_dataset_reverse = reverse_column.find_elements_by_css_selector("li")[1]
second_dataset_reverse.click()
@@ -90,8 +90,6 @@ class CustomBuildsTestcase(SharedStateSeleniumTestCase):
def navigate_to_custom_builds_page(self):
self.home()
self.click_masthead_user() # Open masthead menu
label = self.navigation_data['labels']['masthead']['menus']['user']
self.click_label(label)
self.wait_for_and_click_selector('a[href="/custom_builds"]')
def setup_shared_state(self):
+3 -3
View File
@@ -13,13 +13,13 @@ class HistoryOptionsTestCase(SeleniumTestCase):
self.wait_for_history()
self.click_history_options()
menu_selector = self.history_options_menu_selector()
self.wait_for_selector_visible(menu_selector)
menu_selector = self.navigation.history_panel.selectors.options_menu
self.wait_for_visible(menu_selector)
# Click away closes history options
self.click_center()
self.assert_selector_absent_or_hidden(menu_selector)
self.wait_for_absent_or_hidden(menu_selector)
hda = self.latest_history_item()
hid = hda["hid"]
+23 -21
View File
@@ -11,13 +11,14 @@ class HistoryPanelTestCase(SeleniumTestCase):
self.register()
self.assert_initial_history_panel_state_correct()
tag_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["tagIcon"]
anno_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["annoIcon"]
self.assert_selector(tag_icon_selector)
self.assert_selector(anno_icon_selector)
tag_icon_selector = self.navigation.history_panel.selectors.tag_icon
annotation_icon_selector = self.navigation.history_panel.selectors.annotation_icon
self.wait_for_visible(tag_icon_selector)
self.wait_for_visible(annotation_icon_selector)
name_element = self.history_panel_name_element()
self.assert_tooltip_text(name_element, self.test_data["historyPanel"]["text"]["history"]["tooltips"]["name"])
self.assert_tooltip_text(name_element, self.navigation.history_panel.text.tooltip_name)
@selenium_test
def test_history_panel_rename(self):
@@ -34,7 +35,7 @@ class HistoryPanelTestCase(SeleniumTestCase):
editable_text_input_element = self.history_panel_click_to_rename()
editable_text_input_element.send_keys("New History Name")
self.click_center()
self.assert_selector_absent(self.history_panel_edit_title_input_selector())
self.assert_absent(self.navigation.history_panel.selectors.name_edit_input)
assert "New History Name" not in self.history_panel_name()
@selenium_test
@@ -43,7 +44,7 @@ class HistoryPanelTestCase(SeleniumTestCase):
editable_text_input_element = self.history_panel_click_to_rename()
editable_text_input_element.send_keys("New History Name")
self.send_escape(editable_text_input_element)
self.assert_selector_absent(self.history_panel_edit_title_input_selector())
self.assert_absent(self.navigation.history_panel.selectors.name_edit_input)
assert "New History Name" not in self.history_panel_name()
@selenium_test
@@ -51,34 +52,35 @@ class HistoryPanelTestCase(SeleniumTestCase):
# TODO: Test actually editing these values.
self.register()
tag_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["tagIcon"]
anno_icon_selector = self.test_data["historyPanel"]["selectors"]["history"]["annoIcon"]
tag_area_selector = self.test_data["historyPanel"]["selectors"]["history"]["tagArea"]
anno_area_selector = self.test_data["historyPanel"]["selectors"]["history"]["annoArea"]
tag_icon_selector = self.navigation.history_panel.selectors.tag_icon
annotation_icon_selector = self.navigation.history_panel.selectors.annotation_icon
tag_icon = self.wait_for_selector_clickable(tag_icon_selector)
annon_icon = self.wait_for_selector_clickable(anno_icon_selector)
tag_area_selector = self.navigation.history_panel.selectors.tag_area
annotation_area_selector = self.navigation.history_panel.selectors.annotation_area
self.assert_selector_absent_or_hidden(tag_area_selector)
self.assert_selector_absent_or_hidden(anno_area_selector)
tag_icon = self.wait_for_clickable(tag_icon_selector)
annon_icon = self.wait_for_clickable(annotation_icon_selector)
self.assert_absent_or_hidden(tag_area_selector)
self.assert_absent_or_hidden(annotation_area_selector)
tag_icon.click()
self.wait_for_selector(tag_area_selector)
self.assert_selector_absent_or_hidden(anno_area_selector)
self.wait_for_visible(tag_area_selector)
self.assert_absent_or_hidden(annotation_area_selector)
tag_icon.click()
self.sleep_for(self.wait_types.UX_TRANSITION)
annon_icon.click()
self.wait_for_selector(anno_area_selector)
self.assert_selector_absent_or_hidden(tag_area_selector)
self.wait_for_visible(annotation_area_selector)
self.assert_absent_or_hidden(tag_area_selector)
annon_icon.click()
self.sleep_for(self.wait_types.UX_TRANSITION)
self.assert_selector_absent_or_hidden(tag_area_selector)
self.assert_selector_absent_or_hidden(anno_area_selector)
self.assert_absent_or_hidden(tag_area_selector)
self.assert_absent_or_hidden(annotation_area_selector)
@selenium_test
def test_refresh_preserves_state(self):
@@ -147,24 +147,23 @@ class HistoryGridTestCase(SharedStateSeleniumTestCase):
self.sleep_for(self.wait_types.UX_RENDER)
def set_annotation(self, annotation):
anno_icon_selector = self.test_data['historyPanel']['selectors']['history']['annoIcon']
anno_area_selector = self.test_data['historyPanel']['selectors']['history']['annoArea']
self.ensure_annotation_area_displayed()
if not self.selector_is_displayed(anno_area_selector):
self.wait_for_and_click_selector(anno_icon_selector)
self.wait_for_and_click(self.navigation.history_panel.selectors.annotation_editable_text)
anno_area_selector += ' .annotation'
self.wait_for_and_click_selector(anno_area_selector)
annon_area_editable = self.wait_for_and_click(self.navigation.history_panel.selectors.annotation_edit)
anno_done_button = self.wait_for_clickable(self.navigation.history_panel.selectors.annotation_done)
area_editable_selector = anno_area_selector + ' textarea'
done_button_selector = anno_area_selector + ' button'
annon_area_editable = self.wait_for_selector_clickable(area_editable_selector)
anno_done_button = self.wait_for_selector_clickable(done_button_selector)
annon_area_editable.click()
annon_area_editable.send_keys(annotation)
anno_done_button.click()
def ensure_annotation_area_displayed(self):
annotation_area_selector = self.navigation.history_panel.selectors.annotation_area
annotation_icon_selector = self.navigation.history_panel.selectors.annotation_icon
if not self.is_displayed(annotation_area_selector):
self.wait_for_and_click(annotation_icon_selector)
def setup_shared_state(self):
tag1 = self._get_random_name(len=5)
tag2 = self._get_random_name(len=5)
@@ -210,8 +209,6 @@ class HistoryGridTestCase(SharedStateSeleniumTestCase):
def navigate_to_published_histories_page(self):
self.home()
self.click_masthead_user() # Open masthead menu
self.click_label(
self.navigation_data['labels']['masthead']['menus']['libraries'])
self.click_masthead_libraries()
selector = 'a[href="/histories/list_published"]'
self.wait_for_and_click_selector(selector)
@@ -275,8 +275,6 @@ class SavedHistoriesTestCase(SharedStateSeleniumTestCase):
def navigate_to_saved_histories_page(self):
self.home()
self.click_masthead_user() # Open masthead menu
label = self.navigation_data['labels']['masthead']['menus']['user']
self.click_label(label)
self.wait_for_and_click_selector('a[href="/histories/list"]')
def setup_shared_state(self):
+2 -2
View File
@@ -17,8 +17,8 @@ class UploadsTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
assert history_count == 1, "Incorrect number of items in history - expected 1, found %d" % history_count
hda = history_contents[0]
assert hda["name"] == '1.sam'
assert hda["extension"] == "sam"
assert hda["name"] == '1.sam', hda
assert hda["extension"] == "sam", hda
self.history_panel_click_item_title(hid=1, wait=True)
self.assert_item_dbkey_displayed_as(1, "?")