Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xblock-drag-and-drop-v2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
xblock-drag-and-drop-v2
Commits
ecca8bf3
Commit
ecca8bf3
authored
Aug 18, 2016
by
Braden MacDonald
Committed by
GitHub
Aug 18, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #95 from open-craft/test-fixes
Fix some flaky Selenium tests
parents
c958bc54
ef636fe9
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
47 additions
and
21 deletions
+47
-21
run_tests.py
+1
-1
tests/integration/test_base.py
+12
-0
tests/integration/test_interaction.py
+21
-12
tests/integration/test_sizing.py
+13
-8
No files found.
run_tests.py
View file @
ecca8bf3
...
@@ -18,7 +18,7 @@ if __name__ == "__main__":
...
@@ -18,7 +18,7 @@ if __name__ == "__main__":
sys
.
path
.
append
(
xblock_sdk_dir
)
sys
.
path
.
append
(
xblock_sdk_dir
)
# Use the workbench settings file:
# 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
# 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"
)
os
.
environ
.
setdefault
(
"DJANGO_LIVE_TEST_SERVER_ADDRESS"
,
"localhost:8081-8099"
)
...
...
tests/integration/test_base.py
View file @
ecca8bf3
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
from
xml.sax.saxutils
import
escape
from
xml.sax.saxutils
import
escape
from
selenium.webdriver.support.ui
import
WebDriverWait
from
selenium.webdriver.support.ui
import
WebDriverWait
from
bok_choy.promise
import
EmptyPromise
from
workbench
import
scenarios
from
workbench
import
scenarios
from
xblockutils.resources
import
ResourceLoader
from
xblockutils.resources
import
ResourceLoader
...
@@ -122,3 +123,14 @@ class BaseIntegrationTest(SeleniumBaseTest):
...
@@ -122,3 +123,14 @@ class BaseIntegrationTest(SeleniumBaseTest):
wait
=
WebDriverWait
(
elem
,
2
)
wait
=
WebDriverWait
(
elem
,
2
)
wait
.
until
(
lambda
e
:
class_name
in
e
.
get_attribute
(
'class'
)
.
split
(),
wait
.
until
(
lambda
e
:
class_name
in
e
.
get_attribute
(
'class'
)
.
split
(),
u"Class name {} not in {}"
.
format
(
class_name
,
elem
.
get_attribute
(
'class'
)))
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
()
tests/integration/test_interaction.py
View file @
ecca8bf3
...
@@ -3,7 +3,7 @@
...
@@ -3,7 +3,7 @@
from
ddt
import
ddt
,
data
,
unpack
from
ddt
import
ddt
,
data
,
unpack
from
mock
import
Mock
,
patch
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
import
ActionChains
from
selenium.webdriver.common.keys
import
Keys
from
selenium.webdriver.common.keys
import
Keys
from
selenium.webdriver.support.ui
import
WebDriverWait
from
selenium.webdriver.support.ui
import
WebDriverWait
...
@@ -135,6 +135,7 @@ class InteractionTestBase(object):
...
@@ -135,6 +135,7 @@ class InteractionTestBase(object):
self
.
drag_item_to_zone
(
item_value
,
zone_id
)
self
.
drag_item_to_zone
(
item_value
,
zone_id
)
else
:
else
:
self
.
move_item_to_zone
(
item_value
,
zone_id
,
action_key
)
self
.
move_item_to_zone
(
item_value
,
zone_id
,
action_key
)
self
.
wait_for_ajax
()
def
drag_item_to_zone
(
self
,
item_value
,
zone_id
):
def
drag_item_to_zone
(
self
,
item_value
,
zone_id
):
"""
"""
...
@@ -154,11 +155,11 @@ class InteractionTestBase(object):
...
@@ -154,11 +155,11 @@ class InteractionTestBase(object):
Place item to descired zone using keybard interaction.
Place item to descired zone using keybard interaction.
zone_id=None means place item back into the item bank.
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
)
item
=
self
.
_get_item_by_value
(
item_value
)
ActionChains
(
self
.
browser
)
.
move_to_element
(
item
)
.
perform
(
)
item
.
send_keys
(
""
)
# Press the action key:
item
.
send_keys
(
action_key
)
item
.
send_keys
(
action_key
)
# Focus is on first *zone* now
# Focus is on first *zone* now
self
.
assert_grabbed_item
(
item
)
self
.
assert_grabbed_item
(
item
)
# Get desired zone and figure out how many times we have to press Tab to focus the zone.
# 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
if
zone_id
is
None
:
# moving back to the bank
...
@@ -173,7 +174,7 @@ class InteractionTestBase(object):
...
@@ -173,7 +174,7 @@ class InteractionTestBase(object):
# position of the zone (zero presses for first zone, one press for second zone, etc).
# position of the zone (zero presses for first zone, one press for second zone, etc).
tab_press_count
=
self
.
_get_zone_position
(
zone_id
)
tab_press_count
=
self
.
_get_zone_position
(
zone_id
)
for
_
in
range
(
tab_press_count
):
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
)
zone
.
send_keys
(
action_key
)
def
assert_grabbed_item
(
self
,
item
):
def
assert_grabbed_item
(
self
,
item
):
...
@@ -324,10 +325,8 @@ class InteractionTestBase(object):
...
@@ -324,10 +325,8 @@ class InteractionTestBase(object):
# When using the keyboard, ensure that dropped items cannot get "grabbed".
# When using the keyboard, ensure that dropped items cannot get "grabbed".
# Assert item has no tabindex.
# Assert item has no tabindex.
self
.
assertIsNone
(
item
.
get_attribute
(
'tabindex'
))
self
.
assertIsNone
(
item
.
get_attribute
(
'tabindex'
))
# Focus on the item:
# Focus on the item, then press the action key:
ActionChains
(
self
.
browser
)
.
move_to_element
(
item
)
.
perform
()
ActionChains
(
self
.
browser
)
.
move_to_element
(
item
)
.
send_keys
(
action_key
)
.
perform
()
# Press the action key:
item
.
send_keys
(
action_key
)
# Assert item is not grabbed.
# Assert item is not grabbed.
self
.
assertEqual
(
item
.
get_attribute
(
'aria-grabbed'
),
'false'
)
self
.
assertEqual
(
item
.
get_attribute
(
'aria-grabbed'
),
'false'
)
else
:
else
:
...
@@ -417,7 +416,7 @@ class InteractionTestBase(object):
...
@@ -417,7 +416,7 @@ class InteractionTestBase(object):
self
.
assertTrue
(
dialog_modal_overlay
.
is_displayed
())
self
.
assertTrue
(
dialog_modal_overlay
.
is_displayed
())
self
.
assertTrue
(
dialog_modal
.
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_overlay
.
is_displayed
())
self
.
assertFalse
(
dialog_modal
.
is_displayed
())
self
.
assertFalse
(
dialog_modal
.
is_displayed
())
...
@@ -497,6 +496,7 @@ class AssessmentTestMixin(object):
...
@@ -497,6 +496,7 @@ class AssessmentTestMixin(object):
self
.
_wait_until_enabled
(
submit_button
)
self
.
_wait_until_enabled
(
submit_button
)
submit_button
.
click
()
submit_button
.
click
()
self
.
wait_for_ajax
()
@ddt
@ddt
...
@@ -693,6 +693,7 @@ class MultipleValidOptionsInteractionTest(DefaultDataTestMixin, InteractionTestB
...
@@ -693,6 +693,7 @@ class MultipleValidOptionsInteractionTest(DefaultDataTestMixin, InteractionTestB
self
.
assertEqual
(
popup
.
get_attribute
(
'class'
),
'popup'
)
self
.
assertEqual
(
popup
.
get_attribute
(
'class'
),
'popup'
)
self
.
assert_placed_item
(
item
.
item_id
,
item
.
zone_title
[
i
])
self
.
assert_placed_item
(
item
.
item_id
,
item
.
zone_title
[
i
])
reset
.
click
()
reset
.
click
()
self
.
wait_until_disabled
(
reset
)
def
_get_scenario_xml
(
self
):
def
_get_scenario_xml
(
self
):
return
self
.
_get_custom_scenario_xml
(
"data/test_multiple_options_data.json"
)
return
self
.
_get_custom_scenario_xml
(
"data/test_multiple_options_data.json"
)
...
@@ -773,11 +774,18 @@ class PreventSpaceBarScrollTest(DefaultDataTestMixin, InteractionTestBase, BaseI
...
@@ -773,11 +774,18 @@ class PreventSpaceBarScrollTest(DefaultDataTestMixin, InteractionTestBase, BaseI
def
get_scroll
(
self
):
def
get_scroll
(
self
):
return
self
.
browser
.
execute_script
(
'return $(window).scrollTop()'
)
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
):
def
test_space_bar_scroll
(
self
):
# Window should not be scrolled at first.
# Window should not be scrolled at first.
self
.
assertEqual
(
self
.
get_scroll
(),
0
)
self
.
assertEqual
(
self
.
get_scroll
(),
0
)
# Pressing space bar while no zone is focused should scroll the window down (default browser action).
# 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.
# Window should be scrolled down a bit.
wait
=
WebDriverWait
(
self
,
2
)
wait
=
WebDriverWait
(
self
,
2
)
# While the XHR is in progress, a spinner icon is shown inside the item.
# While the XHR is in progress, a spinner icon is shown inside the item.
...
@@ -984,3 +992,4 @@ class ZoneAlignInteractionTest(InteractionTestBase, BaseIntegrationTest):
...
@@ -984,3 +992,4 @@ class ZoneAlignInteractionTest(InteractionTestBase, BaseIntegrationTest):
self
.
scroll_down
(
pixels
=
200
)
self
.
scroll_down
(
pixels
=
200
)
reset
.
click
()
reset
.
click
()
self
.
scroll_down
(
pixels
=
0
)
self
.
scroll_down
(
pixels
=
0
)
self
.
wait_until_disabled
(
reset
)
tests/integration/test_sizing.py
View file @
ecca8bf3
...
@@ -111,9 +111,10 @@ class SizingTests(InteractionTestBase, BaseIntegrationTest):
...
@@ -111,9 +111,10 @@ class SizingTests(InteractionTestBase, BaseIntegrationTest):
self
.
_check_sizes
(
1
,
self
.
EXPECTATIONS
,
expected_img_width
=
500
)
self
.
_check_sizes
(
1
,
self
.
EXPECTATIONS
,
expected_img_width
=
500
)
def
_size_for_mobile
(
self
):
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
=
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:
# Fix platform inconsistencies caused by scrollbar size:
self
.
browser
.
execute_script
(
'$("body").css("margin-right", "40px")'
)
self
.
browser
.
execute_script
(
'$("body").css("margin-right", "40px")'
)
scrollbar_width
=
self
.
browser
.
execute_script
(
scrollbar_width
=
self
.
browser
.
execute_script
(
...
@@ -188,16 +189,20 @@ class SizingTests(InteractionTestBase, BaseIntegrationTest):
...
@@ -188,16 +189,20 @@ class SizingTests(InteractionTestBase, BaseIntegrationTest):
item_bank
=
self
.
_page
.
find_element_by_css_selector
(
'.item-bank'
)
item_bank
=
self
.
_page
.
find_element_by_css_selector
(
'.item-bank'
)
item_bank_width
=
item_bank
.
size
[
"width"
]
item_bank_width
=
item_bank
.
size
[
"width"
]
item_bank_height
=
item_bank
.
size
[
"height"
]
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
is_desktop
:
# If using a desktop-sized window, we can know the exact dimensions of various containers:
# 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
(
page_width
,
770
)
# div has max-width: 770px
self
.
assertEqual
(
target_img_width
,
expected_img_width
or
755
)
self
.
assertEqual
(
item_bank_width
,
755
)
else
:
else
:
self
.
assertEqual
(
self
.
_page
.
size
[
"width"
],
335
)
# self._page is the .xblock--drag-and-drop div
window_width
=
self
.
browser
.
get_window_size
()[
"width"
]
self
.
assertEqual
(
target_img_width
,
expected_img_width
or
328
)
self
.
assertLessEqual
(
window_width
,
400
)
self
.
assertEqual
(
item_bank_width
,
328
)
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).
# Test each element, before it is placed (while it is in the item bank).
for
expect
in
expectations
:
for
expect
in
expectations
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment