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
ea3797c3
Commit
ea3797c3
authored
Feb 22, 2017
by
raeeschachar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moving upgraded e2e page objects to platform
parent
f62b6602
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
146 additions
and
34 deletions
+146
-34
common/test/acceptance/pages/common/utils.py
+46
-24
common/test/acceptance/pages/studio/library.py
+3
-3
common/test/acceptance/pages/studio/settings.py
+2
-0
common/test/acceptance/pages/studio/settings_graders.py
+90
-2
common/test/acceptance/pages/studio/utils.py
+3
-3
common/test/acceptance/pages/studio/video/video.py
+2
-2
No files found.
common/test/acceptance/pages/common/utils.py
View file @
ea3797c3
"""
"""
Utility methods common to Studio and the LMS.
Utility methods common to Studio and the LMS.
"""
"""
from
bok_choy.promise
import
Empty
Promise
from
bok_choy.promise
import
Broken
Promise
from
common.test.acceptance.tests.helpers
import
disable_animations
from
common.test.acceptance.tests.helpers
import
disable_animations
from
selenium.webdriver.common.action_chains
import
ActionChains
from
selenium.webdriver.common.action_chains
import
ActionChains
def
wait_for_notification
(
pag
e
):
def
sync_on_notification
(
page
,
style
=
'default'
,
wait_for_hide
=
Fals
e
):
"""
"""
Waits for the "mini-notification" to appear and disappear on the given page (subclass of PageObject).
Sync on notifications but do not raise errors.
A BrokenPromise in the wait_for probably means that we missed it.
We should just swallow this error and not raise it for reasons including:
* We are not specifically testing this functionality
* This functionality is covered by unit tests
* This verification method is prone to flakiness
and browser version dependencies
See classes in edx-platform:
lms/static/sass/elements/_system-feedback.scss
"""
"""
def
_is_saving
():
hiding_class
=
'is-hiding'
"""Whether or not the notification is currently showing."""
shown_class
=
'is-shown'
return
page
.
q
(
css
=
'.wrapper-notification-mini.is-shown'
)
.
present
def
notification_has_class
(
style
,
el_class
):
def
_is_saving_done
():
"""
"""Whether or not the notification is finished showing."""
Return a boolean representing whether
return
page
.
q
(
css
=
'.wrapper-notification-mini.is-hiding'
)
.
present
the notification has the class applied.
"""
EmptyPromise
(
if
style
==
'mini'
:
_is_saving
,
css_string
=
'.wrapper-notification-mini.{}'
'Notification should have been shown.'
,
else
:
try_interval
=
0.1
,
css_string
=
'.wrapper-notification-confirmation.{}'
timeout
=
60
,
return
page
.
q
(
css
=
css_string
.
format
(
el_class
))
.
present
)
.
fulfill
()
EmptyPromise
(
# Wait for the notification to show.
_is_saving_done
,
# This notification appears very quickly and maybe missed. Don't raise an error.
'Notification should have been hidden.'
,
try
:
try_interval
=
0.1
,
page
.
wait_for
(
timeout
=
60
,
lambda
:
notification_has_class
(
style
,
shown_class
),
)
.
fulfill
()
'Notification should have been shown.'
,
timeout
=
5
)
except
BrokenPromise
as
_err
:
pass
# Now wait for it to hide.
# This is not required for web page interaction, so not really needed.
if
wait_for_hide
:
page
.
wait_for
(
lambda
:
notification_has_class
(
style
,
hiding_class
),
'Notification should have hidden.'
)
def
click_css
(
page
,
css
,
source_index
=
0
,
require_notification
=
True
):
def
click_css
(
page
,
css
,
source_index
=
0
,
require_notification
=
True
):
...
@@ -53,7 +75,7 @@ def click_css(page, css, source_index=0, require_notification=True):
...
@@ -53,7 +75,7 @@ def click_css(page, css, source_index=0, require_notification=True):
page
.
q
(
css
=
css
)
.
filter
(
_is_visible
)
.
nth
(
source_index
)
.
click
()
page
.
q
(
css
=
css
)
.
filter
(
_is_visible
)
.
nth
(
source_index
)
.
click
()
if
require_notification
:
if
require_notification
:
wait_for
_notification
(
page
)
sync_on
_notification
(
page
)
# Some buttons trigger ajax posts
# Some buttons trigger ajax posts
# (e.g. .add-missing-groups-button as configured in split_test_author_view.js)
# (e.g. .add-missing-groups-button as configured in split_test_author_view.js)
...
...
common/test/acceptance/pages/studio/library.py
View file @
ea3797c3
...
@@ -11,7 +11,7 @@ from common.test.acceptance.pages.studio.users import UsersPageMixin
...
@@ -11,7 +11,7 @@ from common.test.acceptance.pages.studio.users import UsersPageMixin
from
common.test.acceptance.pages.studio.pagination
import
PaginatedMixin
from
common.test.acceptance.pages.studio.pagination
import
PaginatedMixin
from
selenium.webdriver.common.keys
import
Keys
from
selenium.webdriver.common.keys
import
Keys
from
common.test.acceptance.pages.studio.utils
import
HelpMixin
from
common.test.acceptance.pages.studio.utils
import
HelpMixin
from
common.test.acceptance.pages.common.utils
import
confirm_prompt
,
wait_for
_notification
from
common.test.acceptance.pages.common.utils
import
confirm_prompt
,
sync_on
_notification
from
common.test.acceptance.pages.studio
import
BASE_URL
from
common.test.acceptance.pages.studio
import
BASE_URL
...
@@ -92,7 +92,7 @@ class LibraryEditPage(LibraryPage, PaginatedMixin, UsersPageMixin):
...
@@ -92,7 +92,7 @@ class LibraryEditPage(LibraryPage, PaginatedMixin, UsersPageMixin):
Click on the duplicate button for the given XBlock
Click on the duplicate button for the given XBlock
"""
"""
self
.
_action_btn_for_xblock_id
(
xblock_id
,
"duplicate"
)
.
click
()
self
.
_action_btn_for_xblock_id
(
xblock_id
,
"duplicate"
)
.
click
()
wait_for
_notification
(
self
)
sync_on
_notification
(
self
)
self
.
wait_for_ajax
()
self
.
wait_for_ajax
()
def
click_delete_button
(
self
,
xblock_id
,
confirm
=
True
):
def
click_delete_button
(
self
,
xblock_id
,
confirm
=
True
):
...
@@ -101,7 +101,7 @@ class LibraryEditPage(LibraryPage, PaginatedMixin, UsersPageMixin):
...
@@ -101,7 +101,7 @@ class LibraryEditPage(LibraryPage, PaginatedMixin, UsersPageMixin):
"""
"""
self
.
_action_btn_for_xblock_id
(
xblock_id
,
"delete"
)
.
click
()
self
.
_action_btn_for_xblock_id
(
xblock_id
,
"delete"
)
.
click
()
if
confirm
:
if
confirm
:
confirm_prompt
(
self
)
# this will also
wait_for
_notification()
confirm_prompt
(
self
)
# this will also
sync_on
_notification()
self
.
wait_for_ajax
()
self
.
wait_for_ajax
()
def
_get_xblocks
(
self
):
def
_get_xblocks
(
self
):
...
...
common/test/acceptance/pages/studio/settings.py
View file @
ea3797c3
...
@@ -285,6 +285,8 @@ class SettingsPage(CoursePage):
...
@@ -285,6 +285,8 @@ class SettingsPage(CoursePage):
'#alert-confirmation-title'
,
'#alert-confirmation-title'
,
'Save confirmation message is visible'
'Save confirmation message is visible'
)
)
# After visibility an ajax call is in process, waiting for that to complete
self
.
wait_for_ajax
()
def
refresh_page
(
self
,
wait_for_confirmation
=
True
):
def
refresh_page
(
self
,
wait_for_confirmation
=
True
):
"""
"""
...
...
common/test/acceptance/pages/studio/settings_graders.py
View file @
ea3797c3
...
@@ -2,10 +2,10 @@
...
@@ -2,10 +2,10 @@
Course Grading Settings page.
Course Grading Settings page.
"""
"""
from
common.test.acceptance.pages.studio.
course_page
import
Course
Page
from
common.test.acceptance.pages.studio.
settings
import
Settings
Page
class
GradingPage
(
Course
Page
):
class
GradingPage
(
Settings
Page
):
"""
"""
Course Grading Settings page.
Course Grading Settings page.
"""
"""
...
@@ -14,3 +14,91 @@ class GradingPage(CoursePage):
...
@@ -14,3 +14,91 @@ class GradingPage(CoursePage):
def
is_browser_on_page
(
self
):
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'body.grading'
)
.
present
return
self
.
q
(
css
=
'body.grading'
)
.
present
def
letter_grade
(
self
,
selector
):
"""
Returns: first letter of grade range on grading page
Example: if there are no manually added grades it would
return Pass, if a grade is added it will return 'A'
"""
return
self
.
q
(
css
=
selector
)[
0
]
.
text
def
add_new_grade
(
self
):
"""
Add new grade
"""
self
.
q
(
css
=
'.new-grade-button'
)
.
click
()
self
.
save_changes
()
def
remove_grade
(
self
):
"""
Remove an added grade
"""
# Button displays after hovering on it
btn_css
=
'.remove-button'
self
.
browser
.
execute_script
(
"$('{}').focus().click()"
.
format
(
btn_css
))
self
.
wait_for_ajax
()
self
.
save_changes
()
def
remove_all_grades
(
self
):
"""
Removes all grades
"""
while
len
(
self
.
q
(
css
=
'.remove-button'
))
>
0
:
self
.
remove_grade
()
def
add_new_assignment_type
(
self
):
"""
Add New Assignment type
"""
self
.
q
(
css
=
'.add-grading-data'
)
.
click
()
self
.
save_changes
()
def
fill_assignment_type_fields
(
self
,
name
,
abbreviation
,
total_grade
,
total_number
,
drop
):
"""
Fills text to Assignment Type fields according to assignment box
number and text provided
Arguments:
name: Assignment Type Name
abbreviation: Abbreviation
total_grade: Weight of Total Grade
total_number: Total Number
drop: Number of Droppable
"""
self
.
q
(
css
=
'#course-grading-assignment-name'
)
.
fill
(
name
)
self
.
q
(
css
=
'#course-grading-assignment-shortname'
)
.
fill
(
abbreviation
)
self
.
q
(
css
=
'#course-grading-assignment-gradeweight'
)
.
fill
(
total_grade
)
self
.
q
(
css
=
'#course-grading-assignment-totalassignments'
)
.
fill
(
total_number
)
self
.
q
(
css
=
'#course-grading-assignment-droppable'
)
.
fill
(
drop
)
self
.
save_changes
()
def
assignment_name_field_value
(
self
):
"""
Returns: Assignment type field value
"""
return
self
.
q
(
css
=
'#course-grading-assignment-name'
)
.
attrs
(
'value'
)
def
delete_assignment_type
(
self
):
"""
Deletes Assignment type
"""
self
.
q
(
css
=
'.remove-grading-data'
)
.
first
.
click
()
self
.
save_changes
()
def
delete_all_assignment_types
(
self
):
"""
Deletes all assignment types
"""
while
len
(
self
.
q
(
css
=
'.remove-grading-data'
))
>
0
:
self
.
delete_assignment_type
()
common/test/acceptance/pages/studio/utils.py
View file @
ea3797c3
...
@@ -6,7 +6,7 @@ from selenium.webdriver.common.keys import Keys
...
@@ -6,7 +6,7 @@ from selenium.webdriver.common.keys import Keys
from
bok_choy.javascript
import
js_defined
from
bok_choy.javascript
import
js_defined
from
bok_choy.promise
import
EmptyPromise
from
bok_choy.promise
import
EmptyPromise
from
common.test.acceptance.pages.common.utils
import
click_css
,
wait_for
_notification
from
common.test.acceptance.pages.common.utils
import
click_css
,
sync_on
_notification
NAV_HELP_NOT_SIGNED_IN_CSS
=
'.nav-item.nav-not-signedin-help a'
NAV_HELP_NOT_SIGNED_IN_CSS
=
'.nav-item.nav-not-signedin-help a'
...
@@ -103,7 +103,7 @@ def add_component(page, item_type, specific_type, is_advanced_problem=False):
...
@@ -103,7 +103,7 @@ def add_component(page, item_type, specific_type, is_advanced_problem=False):
all_options
=
page
.
q
(
css
=
'.new-component-{} ul.new-component-template li button span'
.
format
(
item_type
))
all_options
=
page
.
q
(
css
=
'.new-component-{} ul.new-component-template li button span'
.
format
(
item_type
))
chosen_option
=
all_options
.
filter
(
text
=
specific_type
)
.
first
chosen_option
=
all_options
.
filter
(
text
=
specific_type
)
.
first
chosen_option
.
click
()
chosen_option
.
click
()
wait_for
_notification
(
page
)
sync_on
_notification
(
page
)
page
.
wait_for_ajax
()
page
.
wait_for_ajax
()
...
@@ -219,7 +219,7 @@ def drag(page, source_index, target_index, placeholder_height=0):
...
@@ -219,7 +219,7 @@ def drag(page, source_index, target_index, placeholder_height=0):
action
.
release
(
target
)
.
perform
()
action
.
release
(
target
)
.
perform
()
else
:
else
:
action
.
release
()
.
perform
()
action
.
release
()
.
perform
()
wait_for
_notification
(
page
)
sync_on
_notification
(
page
)
def
verify_ordering
(
test_class
,
page
,
expected_orderings
):
def
verify_ordering
(
test_class
,
page
,
expected_orderings
):
...
...
common/test/acceptance/pages/studio/video/video.py
View file @
ea3797c3
...
@@ -8,7 +8,7 @@ from bok_choy.promise import EmptyPromise, Promise
...
@@ -8,7 +8,7 @@ from bok_choy.promise import EmptyPromise, Promise
from
bok_choy.javascript
import
wait_for_js
,
js_defined
from
bok_choy.javascript
import
wait_for_js
,
js_defined
from
common.test.acceptance.tests.helpers
import
YouTubeStubConfig
from
common.test.acceptance.tests.helpers
import
YouTubeStubConfig
from
common.test.acceptance.pages.lms.video.video
import
VideoPage
from
common.test.acceptance.pages.lms.video.video
import
VideoPage
from
common.test.acceptance.pages.common.utils
import
wait_for
_notification
from
common.test.acceptance.pages.common.utils
import
sync_on
_notification
from
selenium.webdriver.common.keys
import
Keys
from
selenium.webdriver.common.keys
import
Keys
from
selenium.webdriver.common.action_chains
import
ActionChains
from
selenium.webdriver.common.action_chains
import
ActionChains
...
@@ -160,7 +160,7 @@ class VideoComponentPage(VideoPage):
...
@@ -160,7 +160,7 @@ class VideoComponentPage(VideoPage):
"""
"""
self
.
q
(
css
=
BUTTON_SELECTORS
[
button_name
])
.
nth
(
index
)
.
click
()
self
.
q
(
css
=
BUTTON_SELECTORS
[
button_name
])
.
nth
(
index
)
.
click
()
if
require_notification
:
if
require_notification
:
wait_for
_notification
(
self
)
sync_on
_notification
(
self
)
self
.
wait_for_ajax
()
self
.
wait_for_ajax
()
@staticmethod
@staticmethod
...
...
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