Commit c21dbe4c by Jay Zoldak

Improvements to clicking and synchronization in Studio bok-choy tests.

parent 4bd3093e
......@@ -103,10 +103,21 @@ class ContainerPage(PageObject):
def delete(self, source_index):
"""
Delete the item with index source_index (based on vertical placement in page).
Only visible items are counted in the source_index.
The index of the first item is 0.
"""
# Click the delete button
click_css(self, 'a.delete-button', source_index, require_notification=False)
# Wait for the warning prompt to appear
self.wait_for_element_visibility('#prompt-warning', 'Deletion warning prompt is visible')
# Make sure the delete button is there
confirmation_button_css = '#prompt-warning a.button.action-primary'
self.wait_for_element_visibility(confirmation_button_css, 'Confirmation dialog button is visible')
# Click the confirmation dialog button
click_css(self, 'a.button.action-primary', 0)
click_css(self, confirmation_button_css, 0)
def edit(self):
"""
......@@ -125,6 +136,7 @@ class ContainerPage(PageObject):
def add_missing_groups(self):
"""
Click the "add missing groups" link.
Note that this does an ajax call.
"""
self.q(css='.add-missing-groups-button').first.click()
......
"""
Utility methods useful for Studio page tests.
"""
from bok_choy.promise import Promise
from selenium.webdriver.common.action_chains import ActionChains
from bok_choy.promise import EmptyPromise
def click_css(page, css, source_index=0, require_notification=True):
"""
Click the button/link with the given css and index on the specified page (subclass of PageObject).
Will only consider buttons with a non-zero size.
Will only consider elements that are displayed and have a height and width greater than zero.
If require_notification is False (default value is True), the method will return immediately.
Otherwise, it will wait for the "mini-notification" to appear and disappear.
"""
buttons = page.q(css=css).filter(lambda el: el.size['width'] > 0)
target = buttons[source_index]
ActionChains(page.browser).click(target).release().perform()
def _is_visible(el):
# Only make the call to size once (instead of once for the height and once for the width)
# because otherwise you will trigger a extra query on a remote element.
return el.is_displayed() and all(size > 0 for size in el.size.itervalues())
# Disable jQuery animations for faster testing with more reliable synchronization
page.browser.execute_script("jQuery.fx.off = true;")
# Click on the element in the browser
page.q(css=css).filter(lambda el: _is_visible(el)).nth(source_index).click()
# Some buttons trigger ajax posts
# (e.g. .add-missing-groups-button as configured in split_test_author_view.js)
# so after you click anything wait for the ajax call to finish
page.wait_for_ajax()
if require_notification:
wait_for_notification(page)
......@@ -26,15 +38,13 @@ def wait_for_notification(page):
Waits for the "mini-notification" to appear and disappear on the given page (subclass of PageObject).
"""
def _is_saving():
num_notifications = page.q(css='.wrapper-notification-mini.is-shown').present
return (num_notifications == 1, num_notifications)
return page.q(css='.wrapper-notification-mini.is-shown').present
def _is_saving_done():
num_notifications = page.q(css='.wrapper-notification-mini.is-hiding').present
return (num_notifications == 1, num_notifications)
return page.q(css='.wrapper-notification-mini.is-hiding').present
Promise(_is_saving, 'Notification should have been shown.', timeout=60).fulfill()
Promise(_is_saving_done, 'Notification should have been hidden.', timeout=60).fulfill()
EmptyPromise(_is_saving, 'Notification should have been shown.', timeout=60).fulfill()
EmptyPromise(_is_saving_done, 'Notification should have been hidden.', timeout=60).fulfill()
def press_the_notification_button(page, name):
......@@ -66,18 +76,24 @@ def add_advanced_component(page, menu_index, name):
menu_index specifies which instance of the menus should be used (based on vertical
placement within the page).
"""
# Click on the Advanced icon.
click_css(page, 'a>span.large-advanced-icon', menu_index, require_notification=False)
# Sporadically, the advanced component was not getting created after the click_css call on the category (below).
# Try making sure that the menu of advanced components is visible before clicking (the HTML is always on the
# This does an animation to hide the first level of buttons
# and instead show the Advanced buttons that are available.
# We should be OK though because click_css turns off jQuery animations
# Make sure that the menu of advanced components is visible before clicking (the HTML is always on the
# page, but will have display none until the large-advanced-icon is clicked).
def is_advanced_components_showing():
advanced_buttons = page.q(css=".new-component-advanced").filter(lambda el: el.size['width'] > 0)
return (len(advanced_buttons) == 1, len(advanced_buttons))
page.wait_for_element_visibility('.new-component-advanced', 'Advanced component menu is visible')
Promise(is_advanced_components_showing, "Advanced component menu not showing").fulfill()
# Now click on the component to add it.
component_css = 'a[data-category={}]'.format(name)
page.wait_for_element_visibility(component_css, 'Advanced component {} is visible'.format(name))
click_css(page, 'a[data-category={}]'.format(name))
# Adding some components, e.g. the Discussion component, will make an ajax call
# but we should be OK because the click_css method is written to handle that.
click_css(page, component_css, 0)
def type_in_codemirror(page, index, text, find_prefix="$"):
......
......@@ -169,6 +169,9 @@ class SplitTest(ContainerBase, SplitTestMixin):
Test deleting an inactive group.
"""
container = self.create_poorly_configured_split_instance()
# The inactive group is the 2nd group, but it is the first one
# with a visible delete button, so use index 0
container.delete(0)
self.verify_groups(container, ['alpha'], [], verify_missing_groups_not_present=False)
......
......@@ -24,7 +24,7 @@
-e git+https://github.com/edx/django-waffle.git@823a102e48#egg=django-waffle
-e git+https://github.com/edx/event-tracking.git@0.1.0#egg=event-tracking
-e git+https://github.com/edx/edx-analytics-api-client.git@0.1.0#egg=analytics-client
-e git+https://github.com/edx/bok-choy.git@82b4e82d79b9d4c6d087ebbfa26ea23235728e62#egg=bok_choy
-e git+https://github.com/edx/bok-choy.git@821d3b0ac742c204a93d802a8732be024a0bce22#egg=bok_choy
-e git+https://github.com/edx-solutions/django-splash.git@9965a53c269666a30bb4e2b3f6037c138aef2a55#egg=django-splash
-e git+https://github.com/edx/acid-block.git@459aff7b63db8f2c5decd1755706c1a64fb4ebb1#egg=acid-xblock
-e git+https://github.com/edx/edx-ora2.git@release-2014-07-21T12.20#egg=edx-ora2
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment