initial change set. add org autocomplete
added unit tests and fixed JS tests added bok choy tests fixed broken botchoy tests fixed course discovery broken test removed monkey patch at class level changes after feedback from matte
This commit is contained in:
@@ -85,6 +85,85 @@ class DashboardPage(PageObject):
|
||||
"""
|
||||
self.q(css='.wrapper-create-library .new-library-save').click()
|
||||
|
||||
@property
|
||||
def new_course_button(self):
|
||||
"""
|
||||
Returns "New Course" button.
|
||||
"""
|
||||
return self.q(css='.new-course-button')
|
||||
|
||||
def is_new_course_form_visible(self):
|
||||
"""
|
||||
Is the new course form visible?
|
||||
"""
|
||||
return self.q(css='.wrapper-create-course').visible
|
||||
|
||||
def click_new_course_button(self):
|
||||
"""
|
||||
Click "New Course" button
|
||||
"""
|
||||
self.q(css='.new-course-button').first.click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def fill_new_course_form(self, display_name, org, number, run):
|
||||
"""
|
||||
Fill out the form to create a new course.
|
||||
"""
|
||||
field = lambda fn: self.q(css='.wrapper-create-course #new-course-{}'.format(fn))
|
||||
field('name').fill(display_name)
|
||||
field('org').fill(org)
|
||||
field('number').fill(number)
|
||||
field('run').fill(run)
|
||||
|
||||
def is_new_course_form_valid(self):
|
||||
"""
|
||||
Returns `True` if new course form is valid otherwise `False`.
|
||||
"""
|
||||
return (
|
||||
self.q(css='.wrapper-create-course .new-course-save:not(.is-disabled)').present and
|
||||
not self.q(css='.wrapper-create-course .wrap-error.is-shown').present
|
||||
)
|
||||
|
||||
def submit_new_course_form(self):
|
||||
"""
|
||||
Submit the new course form.
|
||||
"""
|
||||
self.q(css='.wrapper-create-course .new-course-save').first.click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
@property
|
||||
def error_notification(self):
|
||||
"""
|
||||
Returns error notification element.
|
||||
"""
|
||||
return self.q(css='.wrapper-notification-error.is-shown')
|
||||
|
||||
@property
|
||||
def error_notification_message(self):
|
||||
"""
|
||||
Returns text of error message.
|
||||
"""
|
||||
self.wait_for_element_visibility(
|
||||
".wrapper-notification-error.is-shown .message", "Error message is visible"
|
||||
)
|
||||
return self.error_notification.results[0].find_element_by_css_selector('.message').text
|
||||
|
||||
@property
|
||||
def course_org_field(self):
|
||||
"""
|
||||
Returns course organization input.
|
||||
"""
|
||||
return self.q(css='.wrapper-create-course #new-course-org')
|
||||
|
||||
def select_item_in_autocomplete_widget(self, item_text):
|
||||
"""
|
||||
Selects item in autocomplete where text of item matches item_text.
|
||||
"""
|
||||
self.wait_for_element_visibility(
|
||||
".ui-autocomplete .ui-menu-item", "Autocomplete widget is visible"
|
||||
)
|
||||
self.q(css='.ui-autocomplete .ui-menu-item a').filter(lambda el: el.text == item_text)[0].click()
|
||||
|
||||
def list_courses(self):
|
||||
"""
|
||||
List all the courses found on the page's list of libraries.
|
||||
@@ -102,6 +181,15 @@ class DashboardPage(PageObject):
|
||||
}
|
||||
return self.q(css='.courses li.course-item').map(div2info).results
|
||||
|
||||
def has_course(self, org, number, run):
|
||||
"""
|
||||
Returns `True` if course for given org, number and run exists on the page otherwise `False`
|
||||
"""
|
||||
for course in self.list_courses():
|
||||
if course['org'] == org and course['number'] == number and course['run'] == run:
|
||||
return True
|
||||
return False
|
||||
|
||||
def list_libraries(self):
|
||||
"""
|
||||
Click the tab to display the available libraries, and return detail of them.
|
||||
|
||||
@@ -3,6 +3,7 @@ Test course discovery.
|
||||
"""
|
||||
import datetime
|
||||
import json
|
||||
import uuid
|
||||
|
||||
from bok_choy.web_app_test import WebAppTest
|
||||
from ..helpers import remove_file
|
||||
@@ -34,29 +35,14 @@ class CourseDiscoveryTest(WebAppTest):
|
||||
super(CourseDiscoveryTest, self).setUp()
|
||||
self.page = CourseDiscoveryPage(self.browser)
|
||||
|
||||
for i in range(10):
|
||||
org = self.unique_id
|
||||
number = unicode(i)
|
||||
for i in range(12):
|
||||
org = 'test_org'
|
||||
number = "{}{}".format(str(i), str(uuid.uuid4().get_hex().upper()[0:6]))
|
||||
run = "test_run"
|
||||
name = "test course"
|
||||
name = "test course" if i < 10 else "grass is always greener"
|
||||
settings = {'enrollment_start': datetime.datetime(1970, 1, 1).isoformat()}
|
||||
CourseFixture(org, number, run, name, settings=settings).install()
|
||||
|
||||
for i in range(2):
|
||||
org = self.unique_id
|
||||
number = unicode(i)
|
||||
run = "test_run"
|
||||
name = "grass is always greener"
|
||||
CourseFixture(
|
||||
org,
|
||||
number,
|
||||
run,
|
||||
name,
|
||||
settings={
|
||||
'enrollment_start': datetime.datetime(1970, 1, 1).isoformat()
|
||||
}
|
||||
).install()
|
||||
|
||||
def _auto_auth(self, username, email, staff):
|
||||
"""
|
||||
Logout and login with given credentials.
|
||||
|
||||
140
common/test/acceptance/tests/studio/test_studio_course_create.py
Normal file
140
common/test/acceptance/tests/studio/test_studio_course_create.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""
|
||||
Acceptance tests for course creation.
|
||||
"""
|
||||
import uuid
|
||||
from bok_choy.web_app_test import WebAppTest
|
||||
|
||||
from ...pages.studio.auto_auth import AutoAuthPage
|
||||
from ...pages.studio.index import DashboardPage
|
||||
from ...pages.studio.overview import CourseOutlinePage
|
||||
|
||||
|
||||
class CreateCourseTest(WebAppTest):
|
||||
"""
|
||||
Test that we can create a new course the studio home page.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Load the helper for the home page (dashboard page)
|
||||
"""
|
||||
super(CreateCourseTest, self).setUp()
|
||||
|
||||
self.auth_page = AutoAuthPage(self.browser, staff=True)
|
||||
self.dashboard_page = DashboardPage(self.browser)
|
||||
self.course_name = "New Course Name"
|
||||
self.course_org = "orgX"
|
||||
self.course_number = str(uuid.uuid4().get_hex().upper()[0:6])
|
||||
self.course_run = "2015_T2"
|
||||
|
||||
def test_create_course_with_non_existing_org(self):
|
||||
"""
|
||||
Scenario: Ensure that the course creation with non existing org display proper error message.
|
||||
Given I have filled course creation form with a non existing and all required fields
|
||||
When I click 'Create' button
|
||||
Form validation should pass
|
||||
Then I see the error message explaining reason for failure to create course
|
||||
"""
|
||||
|
||||
self.auth_page.visit()
|
||||
self.dashboard_page.visit()
|
||||
self.assertFalse(self.dashboard_page.has_course(
|
||||
org='testOrg', number=self.course_number, run=self.course_run
|
||||
))
|
||||
self.assertTrue(self.dashboard_page.new_course_button.present)
|
||||
|
||||
self.dashboard_page.click_new_course_button()
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_visible())
|
||||
self.dashboard_page.fill_new_course_form(
|
||||
self.course_name, 'testOrg', self.course_number, self.course_run
|
||||
)
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_valid())
|
||||
self.dashboard_page.submit_new_course_form()
|
||||
self.assertTrue(self.dashboard_page.error_notification.present)
|
||||
self.assertIn(
|
||||
u'Organization you selected does not exist in the system', self.dashboard_page.error_notification_message
|
||||
)
|
||||
|
||||
def test_create_course_with_existing_org(self):
|
||||
"""
|
||||
Scenario: Ensure that the course creation with an existing org should be successful.
|
||||
Given I have filled course creation form with an existing org and all required fields
|
||||
When I click 'Create' button
|
||||
Form validation should pass
|
||||
Then I see the course listing page with newly created course
|
||||
"""
|
||||
|
||||
self.auth_page.visit()
|
||||
self.dashboard_page.visit()
|
||||
self.assertFalse(self.dashboard_page.has_course(
|
||||
org=self.course_org, number=self.course_number, run=self.course_run
|
||||
))
|
||||
self.assertTrue(self.dashboard_page.new_course_button.present)
|
||||
|
||||
self.dashboard_page.click_new_course_button()
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_visible())
|
||||
self.dashboard_page.fill_new_course_form(
|
||||
self.course_name, self.course_org, self.course_number, self.course_run
|
||||
)
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_valid())
|
||||
self.dashboard_page.submit_new_course_form()
|
||||
|
||||
# Successful creation of course takes user to course outline page
|
||||
course_outline_page = CourseOutlinePage(
|
||||
self.browser,
|
||||
self.course_org,
|
||||
self.course_number,
|
||||
self.course_run
|
||||
)
|
||||
course_outline_page.visit()
|
||||
course_outline_page.wait_for_page()
|
||||
|
||||
# Go back to dashboard and verify newly created course exists there
|
||||
self.dashboard_page.visit()
|
||||
self.assertTrue(self.dashboard_page.has_course(
|
||||
org=self.course_org, number=self.course_number, run=self.course_run
|
||||
))
|
||||
|
||||
def test_create_course_with_existing_org_via_autocomplete(self):
|
||||
"""
|
||||
Scenario: Ensure that the course creation with an existing org should be successful.
|
||||
Given I have filled course creation form with an existing org and all required fields
|
||||
And I selected `Course Organization` input via autocomplete
|
||||
When I click 'Create' button
|
||||
Form validation should pass
|
||||
Then I see the course listing page with newly created course
|
||||
"""
|
||||
|
||||
self.auth_page.visit()
|
||||
self.dashboard_page.visit()
|
||||
new_org = 'orgX2'
|
||||
self.assertFalse(self.dashboard_page.has_course(
|
||||
org=new_org, number=self.course_number, run=self.course_run
|
||||
))
|
||||
self.assertTrue(self.dashboard_page.new_course_button.present)
|
||||
|
||||
self.dashboard_page.click_new_course_button()
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_visible())
|
||||
self.dashboard_page.fill_new_course_form(
|
||||
self.course_name, '', self.course_number, self.course_run
|
||||
)
|
||||
self.dashboard_page.course_org_field.fill('org')
|
||||
self.dashboard_page.select_item_in_autocomplete_widget(new_org)
|
||||
self.assertTrue(self.dashboard_page.is_new_course_form_valid())
|
||||
self.dashboard_page.submit_new_course_form()
|
||||
|
||||
# Successful creation of course takes user to course outline page
|
||||
course_outline_page = CourseOutlinePage(
|
||||
self.browser,
|
||||
new_org,
|
||||
self.course_number,
|
||||
self.course_run
|
||||
)
|
||||
course_outline_page.visit()
|
||||
course_outline_page.wait_for_page()
|
||||
|
||||
# Go back to dashboard and verify newly created course exists there
|
||||
self.dashboard_page.visit()
|
||||
self.assertTrue(self.dashboard_page.has_course(
|
||||
org=new_org, number=self.course_number, run=self.course_run
|
||||
))
|
||||
46
common/test/db_fixtures/edx-organizations.json
Normal file
46
common/test/db_fixtures/edx-organizations.json
Normal file
@@ -0,0 +1,46 @@
|
||||
[
|
||||
{
|
||||
"pk": 99,
|
||||
"model": "organizations.organization",
|
||||
"fields": {
|
||||
"name": "Demo org 1",
|
||||
"short_name": "orgX",
|
||||
"description": "Description of organization 1",
|
||||
"logo": "org1_logo.png",
|
||||
"active": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 100,
|
||||
"model": "organizations.organization",
|
||||
"fields": {
|
||||
"name": "Demo org 2",
|
||||
"short_name": "orgX2",
|
||||
"description": "Description of organization 2",
|
||||
"logo": "org2_logo.png",
|
||||
"active": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 101,
|
||||
"model": "organizations.organization",
|
||||
"fields": {
|
||||
"name": "Demo org 3",
|
||||
"short_name": "orgX3",
|
||||
"description": "Description of organization 3",
|
||||
"logo": "org3_logo.png",
|
||||
"active": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 102,
|
||||
"model": "organizations.organization",
|
||||
"fields": {
|
||||
"name": "Demo org 4",
|
||||
"short_name": "test_org",
|
||||
"description": "Description of organization 4",
|
||||
"logo": "org4_logo.png",
|
||||
"active": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user