Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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
edx
edx-platform
Commits
2cdd005f
Commit
2cdd005f
authored
Sep 18, 2013
by
chrisndodge
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1037 from edx/rc/2013-09-18
Rc/2013 09 18
parents
d3dc9d27
71a5df72
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
64 additions
and
41 deletions
+64
-41
CHANGELOG.rst
+4
-0
cms/djangoapps/contentstore/features/static-pages.py
+1
-1
common/djangoapps/terrain/ui_helpers.py
+48
-25
common/lib/xmodule/xmodule/lti_module.py
+5
-9
lms/static/sass/views/_verification.scss
+4
-4
lms/templates/discussion/_thread_list_template.html
+2
-2
No files found.
CHANGELOG.rst
View file @
2cdd005f
...
@@ -5,6 +5,10 @@ These are notable changes in edx-platform. This is a rolling list of changes,
...
@@ -5,6 +5,10 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near
in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected.
the top. Include a label indicating the component affected.
Studio/LMS: Added ability to set due date formatting through Studio's Advanced Settings.
The key is due_date_display_format, and the value should be a format supported by Python's
strftime function.
Common: Added configurable backends for tracking events. Tracking events using
Common: Added configurable backends for tracking events. Tracking events using
the python logging module is the default backend. Support for MongoDB and a
the python logging module is the default backend. Support for MongoDB and a
Django database is also available.
Django database is also available.
...
...
cms/djangoapps/contentstore/features/static-pages.py
View file @
2cdd005f
...
@@ -67,7 +67,7 @@ def get_index(name):
...
@@ -67,7 +67,7 @@ def get_index(name):
page_name_css
=
'section[data-type="HTMLModule"]'
page_name_css
=
'section[data-type="HTMLModule"]'
all_pages
=
world
.
css_find
(
page_name_css
)
all_pages
=
world
.
css_find
(
page_name_css
)
for
i
in
range
(
len
(
all_pages
)):
for
i
in
range
(
len
(
all_pages
)):
if
all_pages
[
i
]
.
html
==
'
\n
{name}
\n
'
.
format
(
name
=
name
):
if
world
.
retry_on_exception
(
lambda
:
all_pages
[
i
]
.
html
)
==
'
\n
{name}
\n
'
.
format
(
name
=
name
):
return
i
return
i
return
None
return
None
...
...
common/djangoapps/terrain/ui_helpers.py
View file @
2cdd005f
...
@@ -6,6 +6,7 @@ import time
...
@@ -6,6 +6,7 @@ import time
import
platform
import
platform
from
urllib
import
quote_plus
from
urllib
import
quote_plus
from
selenium.common.exceptions
import
WebDriverException
,
TimeoutException
from
selenium.common.exceptions
import
WebDriverException
,
TimeoutException
from
selenium.common.exceptions
import
StaleElementReferenceException
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.common.by
import
By
from
selenium.webdriver.common.by
import
By
from
selenium.webdriver.support.ui
import
WebDriverWait
from
selenium.webdriver.support.ui
import
WebDriverWait
...
@@ -45,18 +46,25 @@ def css_has_text(css_selector, text, index=0):
...
@@ -45,18 +46,25 @@ def css_has_text(css_selector, text, index=0):
@world.absorb
@world.absorb
def
wait_for
(
func
,
timeout
=
5
):
def
wait_for
(
func
,
timeout
=
5
):
WebDriverWait
(
world
.
browser
.
driver
,
timeout
)
.
until
(
func
)
WebDriverWait
(
driver
=
world
.
browser
.
driver
,
timeout
=
timeout
,
ignored_exceptions
=
(
StaleElementReferenceException
)
)
.
until
(
func
)
def
wait_for_present
(
css_selector
,
timeout
=
30
):
def
wait_for_present
(
css_selector
,
timeout
=
30
):
"""
"""
Waiting for the element to be present in the DOM.
Waiting for the element to be present in the DOM.
Throws an error if the
wait_for time
expires.
Throws an error if the
WebDriverWait timeout clock
expires.
Otherwise this method will return None
Otherwise this method will return None
"""
"""
try
:
try
:
WebDriverWait
(
driver
=
world
.
browser
.
driver
,
WebDriverWait
(
timeout
=
60
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
driver
=
world
.
browser
.
driver
,
timeout
=
timeout
,
ignored_exceptions
=
(
StaleElementReferenceException
)
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
except
TimeoutException
:
except
TimeoutException
:
raise
TimeoutException
(
"Timed out waiting for {} to be present."
.
format
(
css_selector
))
raise
TimeoutException
(
"Timed out waiting for {} to be present."
.
format
(
css_selector
))
...
@@ -65,12 +73,15 @@ def wait_for_present(css_selector, timeout=30):
...
@@ -65,12 +73,15 @@ def wait_for_present(css_selector, timeout=30):
def
wait_for_visible
(
css_selector
,
timeout
=
30
):
def
wait_for_visible
(
css_selector
,
timeout
=
30
):
"""
"""
Waiting for the element to be visible in the DOM.
Waiting for the element to be visible in the DOM.
Throws an error if the
wait_for time
expires.
Throws an error if the
WebDriverWait timeout clock
expires.
Otherwise this method will return None
Otherwise this method will return None
"""
"""
try
:
try
:
WebDriverWait
(
driver
=
world
.
browser
.
driver
,
WebDriverWait
(
timeout
=
timeout
)
.
until
(
EC
.
visibility_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
driver
=
world
.
browser
.
driver
,
timeout
=
timeout
,
ignored_exceptions
=
(
StaleElementReferenceException
)
)
.
until
(
EC
.
visibility_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
except
TimeoutException
:
except
TimeoutException
:
raise
TimeoutException
(
"Timed out waiting for {} to be visible."
.
format
(
css_selector
))
raise
TimeoutException
(
"Timed out waiting for {} to be visible."
.
format
(
css_selector
))
...
@@ -79,12 +90,15 @@ def wait_for_visible(css_selector, timeout=30):
...
@@ -79,12 +90,15 @@ def wait_for_visible(css_selector, timeout=30):
def
wait_for_invisible
(
css_selector
,
timeout
=
30
):
def
wait_for_invisible
(
css_selector
,
timeout
=
30
):
"""
"""
Waiting for the element to be either invisible or not present on the DOM.
Waiting for the element to be either invisible or not present on the DOM.
Throws an error if the
wait_for time
expires.
Throws an error if the
WebDriverWait timeout clock
expires.
Otherwise this method will return None
Otherwise this method will return None
"""
"""
try
:
try
:
WebDriverWait
(
driver
=
world
.
browser
.
driver
,
WebDriverWait
(
timeout
=
timeout
)
.
until
(
EC
.
invisibility_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
driver
=
world
.
browser
.
driver
,
timeout
=
timeout
,
ignored_exceptions
=
(
StaleElementReferenceException
)
)
.
until
(
EC
.
invisibility_of_element_located
((
By
.
CSS_SELECTOR
,
css_selector
,)))
except
TimeoutException
:
except
TimeoutException
:
raise
TimeoutException
(
"Timed out waiting for {} to be invisible."
.
format
(
css_selector
))
raise
TimeoutException
(
"Timed out waiting for {} to be invisible."
.
format
(
css_selector
))
...
@@ -93,14 +107,17 @@ def wait_for_invisible(css_selector, timeout=30):
...
@@ -93,14 +107,17 @@ def wait_for_invisible(css_selector, timeout=30):
def
wait_for_clickable
(
css_selector
,
timeout
=
30
):
def
wait_for_clickable
(
css_selector
,
timeout
=
30
):
"""
"""
Waiting for the element to be present and clickable.
Waiting for the element to be present and clickable.
Throws an error if the
wait_for time
expires.
Throws an error if the
WebDriverWait timeout clock
expires.
Otherwise this method will return None.
Otherwise this method will return None.
"""
"""
# Sometimes the element is clickable then gets obscured.
# Sometimes the element is clickable then gets obscured.
# In this case, pause so that it is not reported clickable too early
# In this case, pause so that it is not reported clickable too early
try
:
try
:
WebDriverWait
(
world
.
browser
.
driver
,
WebDriverWait
(
timeout
=
timeout
)
.
until
(
EC
.
element_to_be_clickable
((
By
.
CSS_SELECTOR
,
css_selector
,)))
driver
=
world
.
browser
.
driver
,
timeout
=
timeout
,
ignored_exceptions
=
(
StaleElementReferenceException
)
)
.
until
(
EC
.
element_to_be_clickable
((
By
.
CSS_SELECTOR
,
css_selector
,)))
except
TimeoutException
:
except
TimeoutException
:
raise
TimeoutException
(
"Timed out waiting for {} to be clickable."
.
format
(
css_selector
))
raise
TimeoutException
(
"Timed out waiting for {} to be clickable."
.
format
(
css_selector
))
...
@@ -133,7 +150,7 @@ def css_click(css_selector, index=0, wait_time=30):
...
@@ -133,7 +150,7 @@ def css_click(css_selector, index=0, wait_time=30):
# another element might be on top of it. In this case, try
# another element might be on top of it. In this case, try
# clicking in the upper left corner.
# clicking in the upper left corner.
try
:
try
:
return
world
.
css_find
(
css_selector
)[
index
]
.
click
(
)
return
retry_on_exception
(
lambda
:
world
.
css_find
(
css_selector
)[
index
]
.
click
()
)
except
WebDriverException
:
except
WebDriverException
:
return
css_click_at
(
css_selector
,
index
=
index
)
return
css_click_at
(
css_selector
,
index
=
index
)
...
@@ -177,19 +194,19 @@ def id_click(elem_id):
...
@@ -177,19 +194,19 @@ def id_click(elem_id):
@world.absorb
@world.absorb
def
css_fill
(
css_selector
,
text
,
index
=
0
):
def
css_fill
(
css_selector
,
text
,
index
=
0
):
css_find
(
css_selector
)[
index
]
.
fill
(
text
)
retry_on_exception
(
lambda
:
css_find
(
css_selector
)[
index
]
.
fill
(
text
)
)
@world.absorb
@world.absorb
def
click_link
(
partial_text
,
index
=
0
):
def
click_link
(
partial_text
,
index
=
0
):
world
.
browser
.
find_link_by_partial_text
(
partial_text
)[
index
]
.
click
(
)
retry_on_exception
(
lambda
:
world
.
browser
.
find_link_by_partial_text
(
partial_text
)[
index
]
.
click
()
)
@world.absorb
@world.absorb
def
css_text
(
css_selector
,
index
=
0
,
timeout
=
30
):
def
css_text
(
css_selector
,
index
=
0
,
timeout
=
30
):
# Wait for the css selector to appear
# Wait for the css selector to appear
if
is_css_present
(
css_selector
):
if
is_css_present
(
css_selector
):
return
css_find
(
css_selector
,
wait_time
=
timeout
)[
index
]
.
text
return
retry_on_exception
(
lambda
:
css_find
(
css_selector
,
wait_time
=
timeout
)[
index
]
.
text
)
else
:
else
:
return
""
return
""
...
@@ -198,7 +215,7 @@ def css_text(css_selector, index=0, timeout=30):
...
@@ -198,7 +215,7 @@ def css_text(css_selector, index=0, timeout=30):
def
css_value
(
css_selector
,
index
=
0
):
def
css_value
(
css_selector
,
index
=
0
):
# Wait for the css selector to appear
# Wait for the css selector to appear
if
is_css_present
(
css_selector
):
if
is_css_present
(
css_selector
):
return
css_find
(
css_selector
)[
index
]
.
value
return
retry_on_exception
(
lambda
:
css_find
(
css_selector
)[
index
]
.
value
)
else
:
else
:
return
""
return
""
...
@@ -209,18 +226,18 @@ def css_html(css_selector, index=0):
...
@@ -209,18 +226,18 @@ def css_html(css_selector, index=0):
Returns the HTML of a css_selector
Returns the HTML of a css_selector
"""
"""
assert
is_css_present
(
css_selector
)
assert
is_css_present
(
css_selector
)
return
css_find
(
css_selector
)[
index
]
.
html
return
retry_on_exception
(
lambda
:
css_find
(
css_selector
)[
index
]
.
html
)
@world.absorb
@world.absorb
def
css_has_class
(
css_selector
,
class_name
,
index
=
0
):
def
css_has_class
(
css_selector
,
class_name
,
index
=
0
):
return
css_find
(
css_selector
)[
index
]
.
has_class
(
class_name
)
return
retry_on_exception
(
lambda
:
css_find
(
css_selector
)[
index
]
.
has_class
(
class_name
)
)
@world.absorb
@world.absorb
def
css_visible
(
css_selector
,
index
=
0
):
def
css_visible
(
css_selector
,
index
=
0
):
assert
is_css_present
(
css_selector
)
assert
is_css_present
(
css_selector
)
return
css_find
(
css_selector
)[
index
]
.
visible
return
retry_on_exception
(
lambda
:
css_find
(
css_selector
)[
index
]
.
visible
)
@world.absorb
@world.absorb
...
@@ -277,15 +294,21 @@ def trigger_event(css_selector, event='change', index=0):
...
@@ -277,15 +294,21 @@ def trigger_event(css_selector, event='change', index=0):
@world.absorb
@world.absorb
def
retry_on_exception
(
func
,
max_attempts
=
5
):
def
retry_on_exception
(
func
,
max_attempts
=
5
,
ignored_exceptions
=
StaleElementReferenceException
):
"""
Retry the interaction, ignoring the passed exceptions.
By default ignore StaleElementReferenceException, which happens often in our application
when the DOM is being manipulated by client side JS.
Note that ignored_exceptions is passed directly to the except block, and as such can be
either a single exception or multiple exceptions as a parenthesized tuple.
"""
attempt
=
0
attempt
=
0
while
attempt
<
max_attempts
:
while
attempt
<
max_attempts
:
try
:
try
:
return
func
()
return
func
()
break
break
except
WebDriverException
:
except
ignored_exceptions
:
world
.
wait
(
1
)
world
.
wait
(
1
)
attempt
+=
1
attempt
+=
1
except
:
attempt
+=
1
assert_true
(
attempt
<
max_attempts
,
'Ran out of attempts to execute {}'
.
format
(
func
))
assert_true
(
attempt
<
max_attempts
,
'Ran out of attempts to execute {}'
.
format
(
func
))
common/lib/xmodule/xmodule/lti_module.py
View file @
2cdd005f
...
@@ -227,17 +227,13 @@ class LTIModule(LTIFields, XModule):
...
@@ -227,17 +227,13 @@ class LTIModule(LTIFields, XModule):
body
=
body
,
body
=
body
,
headers
=
headers
)
headers
=
headers
)
except
ValueError
:
# scheme not in url
except
ValueError
:
# scheme not in url
# Stubbing headers for now:
#https://github.com/idan/oauthlib/blob/master/oauthlib/oauth1/rfc5849/signature.py#L136
#Stubbing headers for now:
headers
=
{
headers
=
{
u'Content-Type'
:
u'application/x-www-form-urlencoded'
,
u'Content-Type'
:
u'application/x-www-form-urlencoded'
,
u'Authorization'
:
u'oAuth '
# cont..
u'Authorization'
:
u'OAuth oauth_nonce="80966668944732164491378916897",
\
u'oauth_nonce="80966668944732164491378916897", '
# cont..
oauth_timestamp="1378916897", oauth_version="1.0", oauth_signature_method="HMAC-SHA1",
\
u'oauth_timestamp="1378916897", '
# cont..
oauth_consumer_key="", oauth_signature="frVp4JuvT1mVXlxktiAUjQ7
%2
F1cw
%3
D"'
}
u'oauth_version="1.0", '
# cont..
u'oauth_signature_method="HMAC-SHA1", '
# cont..
u'oauth_consumer_key="", '
# cont..
u'oauth_signature="frVp4JuvT1mVXlxktiAUjQ7
%2
F1cw
%3
D"'
,
}
params
=
headers
[
'Authorization'
]
params
=
headers
[
'Authorization'
]
# parse headers to pass to template as part of context:
# parse headers to pass to template as part of context:
...
...
lms/static/sass/views/_verification.scss
View file @
2cdd005f
...
@@ -1661,13 +1661,13 @@
...
@@ -1661,13 +1661,13 @@
margin
:
0
flex-gutter
()
0
0
;
margin
:
0
flex-gutter
()
0
0
;
.title
{
.title
{
@extend
.
hd-lv4
;
@extend
%
hd-lv4
;
margin-bottom
:
(
$baseline
/
4
);
margin-bottom
:
(
$baseline
/
4
);
}
}
.copy
{
.copy
{
@extend
.
t-copy-sub1
;
@extend
%
t-copy-sub1
;
@extend
.
t-weight3
;
@extend
%
t-weight3
;
}
}
.list-actions
{
.list-actions
{
...
@@ -1675,7 +1675,7 @@
...
@@ -1675,7 +1675,7 @@
}
}
.action-verify
label
{
.action-verify
label
{
@extend
.
t-copy-sub1
;
@extend
%
t-copy-sub1
;
}
}
}
}
...
...
lms/templates/discussion/_thread_list_template.html
View file @
2cdd005f
...
@@ -4,13 +4,13 @@
...
@@ -4,13 +4,13 @@
<
div
class
=
"home"
>
<
div
class
=
"home"
>
<
a
href
=
"#"
class
=
"home-icon"
>
<
a
href
=
"#"
class
=
"home-icon"
>
<
i
class
=
"icon icon-home"
><
/i
>
<
i
class
=
"icon icon-home"
><
/i
>
<
span
class
=
"
text-
sr"
>
$
{
_
(
"Discussion Home"
)}
<
/span
>
<
span
class
=
"sr"
>
$
{
_
(
"Discussion Home"
)}
<
/span
>
<
/a
>
<
/a
>
<
/div
>
<
/div
>
<
div
class
=
"browse is-open"
>
<
div
class
=
"browse is-open"
>
<
a
href
=
"#"
class
=
"browse-topic-drop-icon"
>
<
a
href
=
"#"
class
=
"browse-topic-drop-icon"
>
<
i
class
=
"icon icon-reorder"
><
/i
>
<
i
class
=
"icon icon-reorder"
><
/i
>
<
span
class
=
"
text-
sr"
>
$
{
_
(
"Discussion Topics"
)}
<
/span
>
<
span
class
=
"sr"
>
$
{
_
(
"Discussion Topics"
)}
<
/span
>
<
/a
>
<
/a
>
<
a
href
=
"#"
class
=
"browse-topic-drop-btn"
><
span
class
=
"current-board"
>
$
{
_
(
"Show All Discussions"
)}
<
/span> <span class="drop-arrow">▾</
span
><
/a
>
<
a
href
=
"#"
class
=
"browse-topic-drop-btn"
><
span
class
=
"current-board"
>
$
{
_
(
"Show All Discussions"
)}
<
/span> <span class="drop-arrow">▾</
span
><
/a
>
<
/div
>
<
/div
>
...
...
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