mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Continue push toward smarter component based Selenium testing.
This continues a thread started in 0650978a91 and #4732 of switching to smarter selectors from a more structured YAML description of the Galaxy DOM. This continues that by:
- Eliminating any use of the old navigation YAML file (navigation-data.yml).
- Replace href selectors with other things since they break when testing Galaxy with a proxy-prefix.
- Extending the raw selectors to allow concept of nesting selectors.
- Building even smarter "components" that wrap these raw selectors generated from the YAML directly in a way that allows them to utilize the actual Selenium session and helper class.
So the old ``self.navigation_data`` is gone, ``self.navigation`` still yields the raw selectors, and ``self.components`` yields the smarter variant. Hopefully all will agree the code that uses ``self.components`` is more compact and readable.
The following a very basic example of this:
```diff
def click_masthead_user(self):
- self.wait_for_and_click(self.navigation.masthead.selectors.user)
+ self.components.masthead.user.wait_for_and_click()
```
Here is an example of combining it with the new child selector syntax:
```diff
def assert_item_dbkey_displayed_as(self, hid, dbkey):
- item_body_selector = self.history_panel_item_body_selector(hid=hid, wait=True)
- dbkey_selector = item_body_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["dbkey"]
- dbkey_element = self.wait_for_selector_visible(dbkey_selector)
- assert dbkey in dbkey_element.text
+ item_body = self.history_panel_item_component(hid=hid)
+ dbkey_text = item_body.dbkey.wait_for_text()
+ assert dbkey in dbkey_text
```
This commit is contained in:
@@ -272,31 +272,20 @@ class SeleniumTestCase(FunctionalTestCase, NavigatesGalaxy, UsesApiTestCaseMixin
|
||||
base = self.url
|
||||
return urljoin(base, url)
|
||||
|
||||
@property
|
||||
def test_data(self):
|
||||
return self.navigation_data
|
||||
|
||||
def assert_initial_history_panel_state_correct(self):
|
||||
# Move into a TestsHistoryPanel mixin
|
||||
unnamed_name = self.test_data["historyPanel"]["text"]["history"]["newName"]
|
||||
unnamed_name = self.components.history_panel.new_name.text
|
||||
|
||||
name_element = self.history_panel_name_element()
|
||||
assert name_element.is_displayed()
|
||||
assert unnamed_name in name_element.text
|
||||
|
||||
size_selector = self.test_data["historyPanel"]["selectors"]["history"]["size"]
|
||||
initial_size_str = self.test_data["historyPanel"]["text"]["history"]["newSize"]
|
||||
initial_size_str = self.components.history_panel.new_size.text
|
||||
size_selector = self.components.history_panel.size
|
||||
size_text = size_selector.wait_for_text()
|
||||
assert initial_size_str in size_text, "%s not in %s" % (initial_size_str, size_text)
|
||||
|
||||
size_element = self.wait_for_selector(size_selector)
|
||||
assert size_element.is_displayed()
|
||||
assert initial_size_str in size_element.text, "%s not in %s" % (initial_size_str, size_element.text)
|
||||
|
||||
empty_msg_selector = self.test_data["historyPanel"]["selectors"]["history"]["emptyMsg"]
|
||||
empty_msg_str = self.test_data["historyPanel"]["text"]["history"]["emptyMsg"]
|
||||
|
||||
empty_msg_element = self.wait_for_selector(empty_msg_selector)
|
||||
assert empty_msg_element.is_displayed()
|
||||
assert empty_msg_str in empty_msg_element.text
|
||||
self.components.history_panel.empty_message.wait_for_visible()
|
||||
|
||||
def admin_login(self):
|
||||
self.home()
|
||||
@@ -355,50 +344,35 @@ class SharedStateSeleniumTestCase(SeleniumTestCase):
|
||||
class UsesHistoryItemAssertions:
|
||||
|
||||
def assert_item_peek_includes(self, hid, expected):
|
||||
item_body_selector = self.history_panel_item_body_selector(hid=hid, wait=True)
|
||||
peek_selector = item_body_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["peek"]
|
||||
peek_selector = self.wait_for_selector_visible(peek_selector)
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
peek_text = item_body.peek.wait_for_text()
|
||||
assert expected in peek_text
|
||||
|
||||
def assert_item_info_includes(self, hid, expected):
|
||||
item_body_selector = self.history_panel_item_body_selector(hid=hid, wait=True)
|
||||
info_selector = item_body_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["info"]
|
||||
info_element = self.wait_for_selector_visible(info_selector)
|
||||
text = info_element.text
|
||||
assert expected in text, "Failed to find expected info text [%s] in info [%s]" % (expected, text)
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
info_text = item_body.info.wait_for_text()
|
||||
assert expected in info_text, "Failed to find expected info text [%s] in info [%s]" % (expected, info_text)
|
||||
|
||||
def assert_item_dbkey_displayed_as(self, hid, dbkey):
|
||||
item_body_selector = self.history_panel_item_body_selector(hid=hid, wait=True)
|
||||
dbkey_selector = item_body_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["dbkey"]
|
||||
dbkey_element = self.wait_for_selector_visible(dbkey_selector)
|
||||
assert dbkey in dbkey_element.text
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
dbkey_text = item_body.dbkey.wait_for_text()
|
||||
assert dbkey in dbkey_text
|
||||
|
||||
def assert_item_summary_includes(self, hid, expected_text):
|
||||
item_body_selector = self.history_panel_item_body_selector(hid=hid, wait=True)
|
||||
summary_selector = "%s %s" % (item_body_selector, self.test_data["historyPanel"]["selectors"]["hda"]["summary"])
|
||||
summary_element = self.wait_for_selector_visible(summary_selector)
|
||||
text = summary_element.text
|
||||
assert expected_text in text, "Expected summary [%s] not found in [%s]." % (expected_text, text)
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
summary_text = item_body.summary.wait_for_text()
|
||||
assert expected_text in summary_text, "Expected summary [%s] not found in [%s]." % (expected_text, summary_text)
|
||||
|
||||
def assert_item_name(self, hid, name):
|
||||
item_selector = self.history_panel_item_selector(hid, wait=True)
|
||||
title_selector = item_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["name"]
|
||||
title_element = self.wait_for_selector_visible(title_selector)
|
||||
assert title_element.text == name, title_element.text
|
||||
def assert_item_name(self, hid, expected_name):
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
name = item_body.name.wait_for_text()
|
||||
assert name == expected_name, name
|
||||
|
||||
def assert_item_hid_text(self, hid):
|
||||
# Check the text HID matches HID returned from API.
|
||||
item_selector = self.history_panel_item_selector(hid, wait=True)
|
||||
hid_selector = item_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["hid"]
|
||||
hid_element = self.wait_for_selector_visible(hid_selector)
|
||||
assert hid_element.text == str(hid), hid_element.text
|
||||
|
||||
def _assert_item_button(self, buttons_area, expected_button, button_def):
|
||||
selector = button_def["selector"]
|
||||
# Let old tooltip expire, etc...
|
||||
self.sleep_for(self.wait_types.UX_TRANSITION)
|
||||
button_item = self.wait_for_selector_visible("%s %s" % (buttons_area, selector))
|
||||
expected_tooltip = button_def.get("tooltip")
|
||||
self.assert_tooltip_text(button_item, expected_tooltip)
|
||||
item_body = self.history_panel_item_component(hid=hid)
|
||||
hid_text = item_body.hid.wait_for_text()
|
||||
assert hid_text == str(hid), hid_text
|
||||
|
||||
|
||||
def default_web_host_for_selenium_tests():
|
||||
|
||||
@@ -11,14 +11,12 @@ class AnonymousHistoriesTestCase(SeleniumTestCase):
|
||||
self.home()
|
||||
self.assert_initial_history_panel_state_correct()
|
||||
|
||||
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)
|
||||
# Anonymous users can annotate or tag, these components should be absent.
|
||||
self.components.history_panel.tag_icon.assert_absent_or_hidden()
|
||||
self.components.history_panel.annotation_icon.assert_absent_or_hidden()
|
||||
|
||||
# History has a name but...
|
||||
name_element = self.wait_for_present(self.navigation.history_panel.selectors.name)
|
||||
name_element.click()
|
||||
name_element = self.components.history_panel.name.wait_for_and_click()
|
||||
|
||||
# ... name should NOT be editable when clicked by anon-user
|
||||
editable_text_class = self.navigation._.selectors.editable_text
|
||||
@@ -29,21 +27,18 @@ class AnonymousHistoriesTestCase(SeleniumTestCase):
|
||||
self.home()
|
||||
self.perform_upload(self.get_filename("1.txt"))
|
||||
self.wait_for_history()
|
||||
hda = self.latest_history_item()
|
||||
# Reload the history and make sure the state is preserved.
|
||||
self.home()
|
||||
element = self.wait_for_selector(self.hda_div_selector(hda["id"]))
|
||||
assert 'state-ok' in element.get_attribute("class")
|
||||
self.history_panel_wait_for_hid_state(1, "ok")
|
||||
|
||||
# empty should be NO LONGER be displayed
|
||||
self.assert_absent_or_hidden(self.navigation.history_panel.selectors.empty_message)
|
||||
self.components.history_panel.empty_message.assert_absent_or_hidden()
|
||||
|
||||
@selenium_test
|
||||
def test_anon_history_after_registration(self):
|
||||
self._upload_file_anonymous_then_register_user()
|
||||
hda = self.latest_history_item()
|
||||
self.home()
|
||||
element = self.wait_for_selector(self.hda_div_selector(hda["id"]))
|
||||
assert 'state-ok' in element.get_attribute("class")
|
||||
self.history_panel_wait_for_hid_state(1, "ok")
|
||||
|
||||
@selenium_test
|
||||
def test_clean_anon_history_after_logout(self):
|
||||
|
||||
@@ -90,7 +90,7 @@ class CustomBuildsTestcase(SharedStateSeleniumTestCase):
|
||||
def navigate_to_custom_builds_page(self):
|
||||
self.home()
|
||||
self.click_masthead_user() # Open masthead menu
|
||||
self.wait_for_and_click_selector('a[href="/custom_builds"]')
|
||||
self.components.masthead.custom_builds.wait_for_and_click()
|
||||
|
||||
def setup_shared_state(self):
|
||||
CustomBuildsTestcase.user_email = self._get_random_email()
|
||||
|
||||
@@ -4,6 +4,15 @@ from .framework import (
|
||||
UsesHistoryItemAssertions,
|
||||
)
|
||||
|
||||
BUTTON_TOOLTIPS = {
|
||||
"display": 'View data',
|
||||
"edit": 'Edit attributes',
|
||||
"delete": 'Delete',
|
||||
"download": 'Download',
|
||||
"info": 'View details',
|
||||
"rerun": 'Run this job again',
|
||||
}
|
||||
|
||||
|
||||
class HistoryDatasetStateTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
|
||||
|
||||
@@ -16,8 +25,9 @@ class HistoryDatasetStateTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
|
||||
self.assert_item_hid_text(1)
|
||||
self._assert_title_buttons(1)
|
||||
|
||||
# Expand HDA
|
||||
# Expand HDA and wait for details to show up.
|
||||
self.history_panel_click_item_title(hid=1, wait=True)
|
||||
self.history_panel_item_body_component(1, wait=True)
|
||||
|
||||
self.assert_item_summary_includes(1, "1 sequence")
|
||||
self.assert_item_dbkey_displayed_as(1, "?")
|
||||
@@ -27,20 +37,15 @@ class HistoryDatasetStateTestCase(SeleniumTestCase, UsesHistoryItemAssertions):
|
||||
self._assert_action_buttons(1)
|
||||
|
||||
def _assert_title_buttons(self, hid, expected_buttons=['display', 'edit', 'delete']):
|
||||
item_selector = self.history_panel_item_selector(hid, wait=True)
|
||||
buttons_area = item_selector + ' ' + self.test_data["historyPanel"]["selectors"]["hda"]["titleButtonArea"]
|
||||
buttons = self.test_data["historyPanel"]["hdaTitleButtons"]
|
||||
|
||||
for expected_button in expected_buttons:
|
||||
button = buttons[expected_button]
|
||||
self._assert_item_button(buttons_area, expected_button, button)
|
||||
self._assert_buttons(hid, expected_buttons)
|
||||
|
||||
def _assert_action_buttons(self, hid, expected_buttons=["info", "download"]):
|
||||
item_body_selector = self.history_panel_item_body_selector(hid=hid)
|
||||
self.wait_for_selector_visible(item_body_selector)
|
||||
|
||||
buttons_selector = item_body_selector + " " + self.test_data["historyPanel"]["selectors"]["hda"]["primaryActionButtons"]
|
||||
self.wait_for_selector_visible(buttons_selector)
|
||||
self._assert_buttons(hid, expected_buttons)
|
||||
|
||||
def _assert_buttons(self, hid, expected_buttons):
|
||||
item_button = self.history_panel_item_component(hid=hid)
|
||||
# Let old tooltip expire, etc...
|
||||
for expected_button in expected_buttons:
|
||||
self._assert_item_button(buttons_selector, expected_button, self.test_data["historyPanel"]["hdaPrimaryActionButtons"][expected_button])
|
||||
self.sleep_for(self.wait_types.UX_TRANSITION)
|
||||
button = item_button["%s_button" % expected_button]
|
||||
self.assert_tooltip_text(button.wait_for_visible(), BUTTON_TOOLTIPS[expected_button])
|
||||
|
||||
@@ -21,13 +21,9 @@ class HistoryOptionsTestCase(SeleniumTestCase):
|
||||
|
||||
self.wait_for_absent_or_hidden(menu_selector)
|
||||
|
||||
hda = self.latest_history_item()
|
||||
hid = hda["hid"]
|
||||
hid = 1
|
||||
self.history_panel_click_item_title(hid=hid, wait=True)
|
||||
|
||||
hda_body_selector = self.hda_body_selector(hda["id"])
|
||||
self.wait_for_selector_visible(hda_body_selector)
|
||||
|
||||
item_component = self.history_panel_item_body_component(hid=hid)
|
||||
item_component.wait_for_visible()
|
||||
self.history_panel_click_item_title(hid=hid, wait=True)
|
||||
|
||||
self.assert_selector_absent_or_hidden_after_transitions(hda_body_selector)
|
||||
item_component.assert_absent_or_hidden_after_transitions()
|
||||
|
||||
@@ -90,7 +90,7 @@ class HistoryPanelTestCase(SeleniumTestCase):
|
||||
|
||||
# Open the details, verify they are open and do a refresh.
|
||||
self.history_panel_ensure_showing_item_details(hid=1)
|
||||
self.history_panel_item_body_selector(1, wait=True)
|
||||
self.history_panel_item_body_component(1, wait=True)
|
||||
self.history_panel_refresh_click()
|
||||
|
||||
# After the refresh, verify the details are still open.
|
||||
|
||||
@@ -29,16 +29,14 @@ class HistorySharingTestCase(SeleniumTestCase):
|
||||
self.submit_login(user1_email, retries=VALID_LOGIN_RETRIES)
|
||||
self.navigate_to_history_share_page()
|
||||
|
||||
user_sharing_menu = self.components.histories.sharing.user_n_menu(n="0")
|
||||
with self.main_panel():
|
||||
first_user_element = self.wait_for_selector("#user-0-popup")
|
||||
first_user_element.click()
|
||||
|
||||
unshare_link = self.wait_for_selector('a[href^="/history/sharing?unshare_user"]')
|
||||
unshare_link.click()
|
||||
user_sharing_menu.wait_for_and_click()
|
||||
self.components.histories.sharing.unshare.wait_for_and_click()
|
||||
|
||||
self.navigate_to_history_share_page()
|
||||
with self.main_panel():
|
||||
self.assert_selector_absent("#user-0-popup")
|
||||
user_sharing_menu.assert_absent()
|
||||
|
||||
self.logout_if_needed()
|
||||
self.submit_login(user2_email, retries=VALID_LOGIN_RETRIES)
|
||||
@@ -106,8 +104,7 @@ class HistorySharingTestCase(SeleniumTestCase):
|
||||
def navigate_to_history_user_share_page(self):
|
||||
self.navigate_to_history_share_page()
|
||||
with self.main_panel():
|
||||
user_share_link_selector = 'a[href^="/history/share?"]'
|
||||
self.wait_for_and_click_selector(user_share_link_selector)
|
||||
self.components.histories.sharing.share_with_a_user_button.wait_for_and_click()
|
||||
|
||||
def share_history_with_user(self, user_id=None, user_email=None, assert_valid=False):
|
||||
"""Share the current history with a target user by ID or email.
|
||||
|
||||
@@ -209,6 +209,5 @@ class HistoryGridTestCase(SharedStateSeleniumTestCase):
|
||||
|
||||
def navigate_to_published_histories_page(self):
|
||||
self.home()
|
||||
self.click_masthead_libraries()
|
||||
selector = 'a[href="/histories/list_published"]'
|
||||
self.wait_for_and_click_selector(selector)
|
||||
self.click_masthead_shared_data()
|
||||
self.components.masthead.published_histories.wait_for_and_click()
|
||||
|
||||
@@ -26,7 +26,7 @@ class RegistrationTestCase(SeleniumTestCase):
|
||||
self.logout_if_needed()
|
||||
assert not self.is_logged_in()
|
||||
self.home()
|
||||
assert len(self.driver.find_elements_by_xpath(self.test_data["selectors"]["masthead"]["userMenu"]["userEmail_xpath"])) == 0
|
||||
self.components.masthead.user_email.assert_absent_or_hidden()
|
||||
|
||||
@selenium_test
|
||||
def test_reregister_email_fails(self):
|
||||
|
||||
@@ -275,7 +275,7 @@ class SavedHistoriesTestCase(SharedStateSeleniumTestCase):
|
||||
def navigate_to_saved_histories_page(self):
|
||||
self.home()
|
||||
self.click_masthead_user() # Open masthead menu
|
||||
self.wait_for_and_click_selector('a[href="/histories/list"]')
|
||||
self.components.masthead.saved_histories.wait_for_and_click()
|
||||
|
||||
def setup_shared_state(self):
|
||||
SavedHistoriesTestCase.user_email = self._get_random_email()
|
||||
|
||||
Reference in New Issue
Block a user