Skip to content

Commit

Permalink
Fix flaky tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bradenmacdonald committed Aug 18, 2016
1 parent 7b5bc7d commit 4bceaac
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
2 changes: 1 addition & 1 deletion run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
sys.path.append(xblock_sdk_dir)

# Use the workbench settings file:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "workbench.settings")
# Configure a range of ports in case the default port of 8081 is in use
os.environ.setdefault("DJANGO_LIVE_TEST_SERVER_ADDRESS", "localhost:8081-8099")

Expand Down
12 changes: 12 additions & 0 deletions tests/integration/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from xml.sax.saxutils import escape
from selenium.webdriver.support.ui import WebDriverWait

from bok_choy.promise import EmptyPromise
from workbench import scenarios
from xblockutils.resources import ResourceLoader

Expand Down Expand Up @@ -122,3 +123,14 @@ def wait_until_has_class(class_name, elem):
wait = WebDriverWait(elem, 2)
wait.until(lambda e: class_name in e.get_attribute('class').split(),
u"Class name {} not in {}".format(class_name, elem.get_attribute('class')))

def wait_for_ajax(self, timeout=15):
"""
Wait for jQuery to be loaded and for all ajax requests to finish.
Same as bok-choy's PageObject.wait_for_ajax()
"""
def is_ajax_finished():
""" Check if all the ajax calls on the current page have completed. """
return self.browser.execute_script("return typeof(jQuery)!='undefined' && jQuery.active==0")

EmptyPromise(is_ajax_finished, "Finished waiting for ajax requests.", timeout=timeout).fulfill()
32 changes: 20 additions & 12 deletions tests/integration/test_interaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from ddt import ddt, data, unpack
from mock import Mock, patch

from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoSuchElementException, WebDriverException
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
Expand Down Expand Up @@ -154,11 +154,11 @@ def move_item_to_zone(self, item_value, zone_id, action_key):
Place item to descired zone using keybard interaction.
zone_id=None means place item back into the item bank.
"""
# Focus on the item:
# Focus on the item, then press the action key:
item = self._get_item_by_value(item_value)
ActionChains(self.browser).move_to_element(item).perform()
# Press the action key:
item.send_keys(action_key) # Focus is on first *zone* now
item.send_keys("")
item.send_keys(action_key)
# Focus is on first *zone* now
self.assert_grabbed_item(item)
# Get desired zone and figure out how many times we have to press Tab to focus the zone.
if zone_id is None: # moving back to the bank
Expand All @@ -173,8 +173,9 @@ def move_item_to_zone(self, item_value, zone_id, action_key):
# position of the zone (zero presses for first zone, one press for second zone, etc).
tab_press_count = self._get_zone_position(zone_id)
for _ in range(tab_press_count):
self._page.send_keys(Keys.TAB)
ActionChains(self.browser).send_keys(Keys.TAB).perform()
zone.send_keys(action_key)
self.wait_for_ajax()

def assert_grabbed_item(self, item):
self.assertEqual(item.get_attribute('aria-grabbed'), 'true')
Expand Down Expand Up @@ -324,10 +325,8 @@ def parameterized_cannot_move_items_between_zones(self, items_map, all_zones, sc
# When using the keyboard, ensure that dropped items cannot get "grabbed".
# Assert item has no tabindex.
self.assertIsNone(item.get_attribute('tabindex'))
# Focus on the item:
ActionChains(self.browser).move_to_element(item).perform()
# Press the action key:
item.send_keys(action_key)
# Focus on the item, then press the action key:
ActionChains(self.browser).move_to_element(item).send_keys(action_key).perform()
# Assert item is not grabbed.
self.assertEqual(item.get_attribute('aria-grabbed'), 'false')
else:
Expand Down Expand Up @@ -417,7 +416,7 @@ def interact_with_keyboard_help(self, scroll_down=250, use_keyboard=False):
self.assertTrue(dialog_modal_overlay.is_displayed())
self.assertTrue(dialog_modal.is_displayed())

self._page.send_keys(Keys.ESCAPE)
ActionChains(self.browser).send_keys(Keys.ESCAPE).perform()

self.assertFalse(dialog_modal_overlay.is_displayed())
self.assertFalse(dialog_modal.is_displayed())
Expand Down Expand Up @@ -497,6 +496,7 @@ def click_submit(self):
self._wait_until_enabled(submit_button)

submit_button.click()
self.wait_for_ajax()


@ddt
Expand Down Expand Up @@ -693,6 +693,7 @@ def test_multiple_positive_feedback(self):
self.assertEqual(popup.get_attribute('class'), 'popup')
self.assert_placed_item(item.item_id, item.zone_title[i])
reset.click()
self.wait_until_disabled(reset)

def _get_scenario_xml(self):
return self._get_custom_scenario_xml("data/test_multiple_options_data.json")
Expand Down Expand Up @@ -773,11 +774,18 @@ class PreventSpaceBarScrollTest(DefaultDataTestMixin, InteractionTestBase, BaseI
def get_scroll(self):
return self.browser.execute_script('return $(window).scrollTop()')

def hit_spacebar(self):
""" Send a spacebar event to the page/browser """
try:
self._page.send_keys(Keys.SPACE) # Firefox (chrome doesn't allow sending keys to non-focusable elements)
except WebDriverException:
ActionChains(self.browser).send_keys(Keys.SPACE).perform() # Chrome (Firefox types this into the URL bar)

def test_space_bar_scroll(self):
# Window should not be scrolled at first.
self.assertEqual(self.get_scroll(), 0)
# Pressing space bar while no zone is focused should scroll the window down (default browser action).
self._page.send_keys(Keys.SPACE)
self.hit_spacebar()
# Window should be scrolled down a bit.
wait = WebDriverWait(self, 2)
# While the XHR is in progress, a spinner icon is shown inside the item.
Expand Down
21 changes: 13 additions & 8 deletions tests/integration/test_sizing.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,10 @@ def test_square_image_desktop(self):
self._check_sizes(1, self.EXPECTATIONS, expected_img_width=500)

def _size_for_mobile(self):
self.browser.set_window_size(375, 627) # iPhone 6 viewport size
width, height = 400, 627 # iPhone 6 viewport size is 375x627; this is the closest Chrome can get
self.browser.set_window_size(width, height)
wait = WebDriverWait(self.browser, 2)
wait.until(lambda browser: browser.get_window_size()["width"] == 375)
wait.until(lambda browser: browser.get_window_size()["width"] == width)
# Fix platform inconsistencies caused by scrollbar size:
self.browser.execute_script('$("body").css("margin-right", "40px")')
scrollbar_width = self.browser.execute_script(
Expand Down Expand Up @@ -188,16 +189,20 @@ def _check_sizes(self, block_index, expectations, expected_img_width=None, is_de
item_bank = self._page.find_element_by_css_selector('.item-bank')
item_bank_width = item_bank.size["width"]
item_bank_height = item_bank.size["height"]
page_width = self._page.size["width"] # self._page is the .xblock--drag-and-drop div

if is_desktop:
# If using a desktop-sized window, we can know the exact dimensions of various containers:
self.assertEqual(self._page.size["width"], 770) # self._page is the .xblock--drag-and-drop div
self.assertEqual(target_img_width, expected_img_width or 755)
self.assertEqual(item_bank_width, 755)
self.assertEqual(page_width, 770) # div has max-width: 770px
else:
self.assertEqual(self._page.size["width"], 335) # self._page is the .xblock--drag-and-drop div
self.assertEqual(target_img_width, expected_img_width or 328)
self.assertEqual(item_bank_width, 328)
window_width = self.browser.get_window_size()["width"]
self.assertLessEqual(window_width, 400)
self.assertEqual(page_width, window_width - 40)

# The item bank and other elements are inside a wrapper with 'padding: 1%', so we expect
# their width to be 98% of item_bank_width in general
self.assertAlmostEqual(target_img_width, expected_img_width or (page_width * 0.98), delta=1)
self.assertAlmostEqual(item_bank_width, page_width * 0.98, delta=1)

# Test each element, before it is placed (while it is in the item bank).
for expect in expectations:
Expand Down

0 comments on commit 4bceaac

Please sign in to comment.