Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
ecommerce
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
ecommerce
Commits
2261bfdc
Commit
2261bfdc
authored
May 02, 2016
by
Renzo Lucioni
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #703 from edx/renzo/fix-acceptance-tests
Fix acceptance/end-to-end tests
parents
ca9f1c93
74dc1917
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
128 additions
and
91 deletions
+128
-91
acceptance_tests/api.py
+2
-2
acceptance_tests/config.py
+19
-41
acceptance_tests/mixins.py
+40
-11
acceptance_tests/pages/coupons.py
+31
-9
acceptance_tests/pages/marketing.py
+13
-13
acceptance_tests/test_coupon_admin.py
+3
-0
acceptance_tests/test_payment.py
+6
-8
acceptance_tests/test_profed_enrollment.py
+7
-6
acceptance_tests/utils.py
+6
-0
ecommerce/extensions/api/v2/views/coupons.py
+1
-1
No files found.
acceptance_tests/api.py
View file @
2261bfdc
import
requests
from
requests.auth
import
AuthBase
from
acceptance_tests.config
import
ENROLLMENT_API_URL
,
ENROLLMENT_API_TOKEN
from
acceptance_tests.config
import
ACCESS_TOKEN
,
ENROLLMENT_API_URL
class
BearerAuth
(
AuthBase
):
...
...
@@ -20,7 +20,7 @@ class BearerAuth(AuthBase):
class
EnrollmentApiClient
(
object
):
def
__init__
(
self
,
host
=
None
,
key
=
None
):
self
.
host
=
host
or
ENROLLMENT_API_URL
self
.
key
=
key
or
ENROLLMENT_API
_TOKEN
self
.
key
=
key
or
ACCESS
_TOKEN
def
get_enrollment_status
(
self
,
username
,
course_id
):
"""
...
...
acceptance_tests/config.py
View file @
2261bfdc
import
os
from
acceptance_tests.utils
import
str2bool
def
str2bool
(
s
):
s
=
unicode
(
s
)
return
s
.
lower
()
in
(
u'yes'
,
u'true'
,
u't'
,
u'1'
)
# GENERAL CONFIGURATION
ACCESS_TOKEN
=
os
.
environ
.
get
(
'ACCESS_TOKEN'
)
ENABLE_OAUTH2_TESTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_OAUTH2_TESTS'
,
True
))
HONOR_COURSE_ID
=
os
.
environ
.
get
(
'HONOR_COURSE_ID'
,
'course-v1:edX+DemoX+Demo_Course'
)
VERIFIED_COURSE_ID
=
os
.
environ
.
get
(
'VERIFIED_COURSE_ID'
,
'course-v1:BerkeleyX+ColWri.3.6x+3T2015'
)
PROFESSIONAL_COURSE_ID
=
os
.
environ
.
get
(
'PROFESSIONAL_COURSE_ID'
,
'course-v1:UBCx+Marketing5501x+2T2015'
)
if
ACCESS_TOKEN
is
None
:
raise
RuntimeError
(
'A valid OAuth2 access token is required to run acceptance tests.'
)
# END GENERAL CONFIGURATION
raise
RuntimeError
(
'A valid OAuth2 access token is required.'
)
HONOR_COURSE_ID
=
os
.
environ
.
get
(
'HONOR_COURSE_ID'
)
VERIFIED_COURSE_ID
=
os
.
environ
.
get
(
'VERIFIED_COURSE_ID'
)
if
not
all
([
HONOR_COURSE_ID
,
VERIFIED_COURSE_ID
]):
raise
RuntimeError
(
'IDs for courses with honor and verified modes are required.'
)
PROFESSIONAL_COURSE_ID
=
os
.
environ
.
get
(
'PROFESSIONAL_COURSE_ID'
)
# OTTO CONFIGURATION
try
:
ECOMMERCE_URL_ROOT
=
os
.
environ
.
get
(
'ECOMMERCE_URL_ROOT'
)
.
strip
(
'/'
)
except
AttributeError
:
raise
RuntimeError
(
'
You must provide a valid URL root for the E-Commerce Service to run acceptance tests
.'
)
raise
RuntimeError
(
'
A valid URL root for the E-Commerce Service is required
.'
)
ECOMMERCE_API_URL
=
os
.
environ
.
get
(
'ECOMMERCE_API_URL'
,
ECOMMERCE_URL_ROOT
+
'/api/v2'
)
ECOMMERCE_API_TOKEN
=
os
.
environ
.
get
(
'ECOMMERCE_API_TOKEN'
,
ACCESS_TOKEN
)
MAX_COMPLETION_RETRIES
=
int
(
os
.
environ
.
get
(
'MAX_COMPLETION_RETRIES'
,
3
))
PAYPAL_EMAIL
=
os
.
environ
.
get
(
'PAYPAL_EMAIL'
)
PAYPAL_PASSWORD
=
os
.
environ
.
get
(
'PAYPAL_PASSWORD'
)
# It can be a pain to set up CyberSource for local testing. This flag allows CyberSource
# tests to be disabled.
ENABLE_CYBERSOURCE_TESTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_CYBERSOURCE_TESTS'
,
True
))
# END OTTO CONFIGURATION
# MARKETING CONFIGURATION
ENABLE_MARKETING_SITE
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_MARKETING_SITE'
,
False
))
MARKETING_URL_ROOT
=
os
.
environ
.
get
(
'MARKETING_URL_ROOT'
)
.
strip
(
'/'
)
if
ENABLE_MARKETING_SITE
else
None
# These must correspond to the course IDs provided for each enrollment mode.
VERIFIED_COURSE_SLUG
=
os
.
environ
.
get
(
'VERIFIED_COURSE_SLUG'
,
'dracula-stoker-berkeleyx-book-club-uc-berkeleyx-colwri3-6x'
)
PROFESSIONAL_COURSE_SLUG
=
os
.
environ
.
get
(
'PROFESSIONAL_COURSE_SLUG'
,
'marketing-non-marketers-ubcx-marketing5501x'
)
# END MARKETING CONFIGURATION
try
:
MARKETING_URL_ROOT
=
os
.
environ
.
get
(
'MARKETING_URL_ROOT'
)
.
strip
(
'/'
)
except
AttributeError
:
MARKETING_URL_ROOT
=
None
# LMS CONFIGURATION
try
:
LMS_URL_ROOT
=
os
.
environ
.
get
(
'LMS_URL_ROOT'
)
.
strip
(
'/'
)
except
AttributeError
:
raise
RuntimeError
(
'
You must provide a valid URL root for the LMS to run acceptance tests
.'
)
raise
RuntimeError
(
'
A valid LMS URL root is required
.'
)
ENABLE_OAUTH2_TESTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_OAUTH2_TESTS'
,
True
))
LMS_USERNAME
=
os
.
environ
.
get
(
'LMS_USERNAME'
)
LMS_EMAIL
=
os
.
environ
.
get
(
'LMS_EMAIL'
)
LMS_PASSWORD
=
os
.
environ
.
get
(
'LMS_PASSWORD'
)
LMS_AUTO_AUTH
=
str2bool
(
os
.
environ
.
get
(
'LMS_AUTO_AUTH'
,
False
))
LMS_HTTPS
=
str2bool
(
os
.
environ
.
get
(
'LMS_HTTPS'
,
True
))
ENROLLMENT_API_URL
=
os
.
environ
.
get
(
'ENROLLMENT_API_URL'
,
LMS_URL_ROOT
+
'/api/enrollment/v1'
)
ENROLLMENT_API_TOKEN
=
os
.
environ
.
get
(
'ENROLLMENT_API_TOKEN'
,
ACCESS_TOKEN
)
BASIC_AUTH_USERNAME
=
os
.
environ
.
get
(
'BASIC_AUTH_USERNAME'
)
BASIC_AUTH_PASSWORD
=
os
.
environ
.
get
(
'BASIC_AUTH_PASSWORD'
)
if
ENABLE_OAUTH2_TESTS
and
not
(
LMS_URL_ROOT
and
LMS_USERNAME
and
LMS_PASSWORD
):
raise
RuntimeError
(
'Configuring LMS settings is required to run OAuth2 tests.'
)
# END LMS CONFIGURATION
if
ENABLE_OAUTH2_TESTS
and
not
all
([
LMS_URL_ROOT
,
LMS_USERNAME
,
LMS_PASSWORD
]):
raise
RuntimeError
(
'LMS settings are required to run OAuth2 tests.'
)
ENABLE_COUPON_ADMIN_TESTS
=
str2bool
(
os
.
environ
.
get
(
'ENABLE_COUPON_ADMIN_TESTS'
,
False
))
acceptance_tests/mixins.py
View file @
2261bfdc
...
...
@@ -20,7 +20,7 @@ from acceptance_tests.config import (
BASIC_AUTH_PASSWORD
,
ECOMMERCE_API_URL
,
LMS_USERNAME
,
ECOMMERCE_API
_TOKEN
,
ACCESS
_TOKEN
,
MAX_COMPLETION_RETRIES
,
PAYPAL_PASSWORD
,
PAYPAL_EMAIL
,
...
...
@@ -126,7 +126,7 @@ class EnrollmentApiMixin(object):
class
EcommerceApiMixin
(
object
):
@property
def
ecommerce_api_client
(
self
):
return
EdxRestApiClient
(
ECOMMERCE_API_URL
,
oauth_access_token
=
ECOMMERCE_API
_TOKEN
)
return
EdxRestApiClient
(
ECOMMERCE_API_URL
,
oauth_access_token
=
ACCESS
_TOKEN
)
def
assert_order_created_and_completed
(
self
):
orders
=
self
.
ecommerce_api_client
.
orders
.
get
()[
'results'
]
...
...
@@ -192,17 +192,29 @@ class PaymentMixin(object):
# Click the payment button
self
.
browser
.
find_element_by_css_selector
(
'#paypal'
)
.
click
()
# Wait for form to load
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
ID
,
'loginFields'
)))
# Wait for login form to load. PayPal's test environment is slow.
wait
=
WebDriverWait
(
self
.
browser
,
30
)
iframe_present
=
EC
.
presence_of_element_located
((
By
.
CSS_SELECTOR
,
'#injectedUnifiedLogin > iframe'
))
iframe
=
wait
.
until
(
iframe_present
)
# Log into PayPal
self
.
browser
.
switch_to
.
frame
(
iframe
)
self
.
browser
.
find_element_by_css_selector
(
'input#email'
)
.
send_keys
(
PAYPAL_EMAIL
)
self
.
browser
.
find_element_by_css_selector
(
'input#password'
)
.
send_keys
(
PAYPAL_PASSWORD
)
self
.
browser
.
find_element_by_css_selector
(
'input[type="submit"]'
)
.
click
()
self
.
browser
.
find_element_by_css_selector
(
'button[type="submit"]'
)
.
click
()
self
.
browser
.
switch_to
.
default_content
()
# Wait for the checkout form to load. PayPal's test environment is slow.
wait
=
WebDriverWait
(
self
.
browser
,
30
)
confirmation_button_present
=
EC
.
presence_of_element_located
((
By
.
ID
,
'confirmButtonTop'
))
confirmation_button
=
wait
.
until
(
confirmation_button_present
)
# Wait for the checkout form to load, then submit it.
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
ID
,
'confirmButtonTop'
)))
self
.
browser
.
find_element_by_css_selector
(
'input#confirmButtonTop'
)
.
click
()
# PayPal's loading spinner sticks around for longer than it should.
wait
=
WebDriverWait
(
self
.
browser
,
2
)
spinner_invisibility
=
EC
.
invisibility_of_element_located
((
By
.
ID
,
'spinner'
))
wait
.
until
(
spinner_invisibility
)
confirmation_button
.
click
()
def
checkout_with_cybersource
(
self
,
address
):
""" Completes the checkout process via CyberSource. """
...
...
@@ -213,7 +225,9 @@ class PaymentMixin(object):
self
.
dismiss_alert
()
# Wait for form to load
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
ID
,
'billing_details'
)))
wait
=
WebDriverWait
(
self
.
browser
,
10
)
billing_details_present
=
EC
.
presence_of_element_located
((
By
.
ID
,
'billing_details'
))
wait
.
until
(
billing_details_present
)
# Select the credit card type (Visa) first since it triggers the display of additional fields
self
.
browser
.
find_element_by_css_selector
(
'#card_type_001'
)
.
click
()
# Visa
...
...
@@ -253,9 +267,24 @@ class PaymentMixin(object):
def
assert_receipt_page_loads
(
self
):
""" Verifies the receipt page loaded in the browser. """
refresh
=
False
# Wait for the payment processor response to be processed, and the receipt page updated.
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'content-main'
)))
# In a test environment, it can take a while for the payment processor to respond.
for
_
in
range
(
MAX_COMPLETION_RETRIES
):
try
:
if
refresh
:
self
.
browser
.
refresh
()
WebDriverWait
(
self
.
browser
,
2
)
.
until
(
EC
.
alert_is_present
())
self
.
browser
.
switch_to
.
alert
.
accept
()
# Wait for the payment processor response to be processed, and the receipt page updated.
wait
=
WebDriverWait
(
self
.
browser
,
10
)
receipt_loaded
=
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'content-main'
))
wait
.
until
(
receipt_loaded
)
break
except
TimeoutException
:
refresh
=
True
# Verify we reach the receipt page.
self
.
assertIn
(
'receipt'
,
self
.
browser
.
title
.
lower
())
...
...
acceptance_tests/pages/coupons.py
View file @
2261bfdc
...
...
@@ -5,6 +5,7 @@ import string # pylint: disable=deprecated-module
from
bok_choy.javascript
import
wait_for_js
from
selenium.webdriver.common.by
import
By
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.support.select
import
Select
from
selenium.webdriver.support.ui
import
WebDriverWait
from
acceptance_tests.config
import
VERIFIED_COURSE_ID
...
...
@@ -15,9 +16,18 @@ from acceptance_tests.pages.ecommerce import EcommerceAppPage
def
_get_coupon_name
(
is_discount
):
""" Returns an appropriate coupon name. """
prefix
=
'test-discount-code-'
if
is_discount
else
'test-enrollment-code-'
postfix
=
''
.
join
(
random
.
choice
(
string
.
ascii_letters
)
for
_
in
range
(
3
))
suffix
=
''
.
join
(
random
.
choice
(
string
.
ascii_letters
)
for
_
in
range
(
10
))
return
prefix
+
postfix
return
prefix
+
suffix
class
verified_option_selected
(
object
):
"""An expectation for checking that the verified option has been selected."""
def
__init__
(
self
,
select
):
self
.
select
=
select
def
__call__
(
self
,
_
):
return
self
.
select
.
first_selected_option
.
text
==
'Verified'
class
BasketPage
(
EcommerceAppPage
):
...
...
@@ -50,19 +60,32 @@ class CouponsCreatePage(EcommerceAppPage):
self
.
q
(
css
=
'input[name="title"]'
)
.
fill
(
coupon_name
)
self
.
q
(
css
=
course_id_input
)
.
fill
(
VERIFIED_COURSE_ID
)
self
.
wait_for_ajax
()
self
.
wait_for_element_presence
(
'select[name="seat_type"] option[value="Verified"]'
,
'Seat Type Drop-Down List is Present'
wait
=
WebDriverWait
(
self
.
browser
,
5
)
verified_option_present
=
EC
.
presence_of_element_located
(
(
By
.
CSS_SELECTOR
,
'select[name="seat_type"] option[value="Verified"]'
)
)
wait
.
until
(
verified_option_present
)
self
.
q
(
css
=
"input[name='start_date']"
)
.
fill
(
str
(
DEFAULT_START_DATE
))
self
.
q
(
css
=
"input[name='end_date']"
)
.
fill
(
str
(
DEFAULT_END_DATE
))
self
.
q
(
css
=
"input[name='client']"
)
.
fill
(
'Test Client'
)
self
.
q
(
css
=
'select[name="seat_type"] option[value="Verified"]'
)
.
first
.
click
()
select
=
Select
(
self
.
browser
.
find_element_by_css_selector
(
'select[name="seat_type"]'
))
select
.
select_by_visible_text
(
'Verified'
)
# This prevents the test from advancing before the seat type is selected.
wait
=
WebDriverWait
(
self
.
browser
,
5
)
wait
.
until
(
verified_option_selected
)
if
is_discount
:
self
.
q
(
css
=
'select[name="code_type"] option[value="Discount code"]'
)
.
first
.
click
()
self
.
wait_for_element_presence
(
'input[name="benefit_value"]'
,
'Benefit Value Input is Present'
)
select
=
Select
(
self
.
browser
.
find_element_by_css_selector
(
'select[name="code_type"]'
))
select
.
select_by_visible_text
(
'Discount Code'
)
wait
=
WebDriverWait
(
self
.
browser
,
5
)
benefit_input_present
=
EC
.
presence_of_element_located
((
By
.
CSS_SELECTOR
,
'input[name="benefit_value"]'
))
wait
.
until
(
benefit_input_present
)
self
.
q
(
css
=
"input[name='benefit_value']"
)
.
fill
(
'50'
)
self
.
q
(
css
=
"div.form-actions > button.btn"
)
.
click
()
...
...
@@ -90,7 +113,6 @@ class CouponsDetailsPage(EcommerceAppPage):
@wait_for_js
def
go_to_edit_coupon_form_page
(
self
):
self
.
browser
.
find_element_by_id
(
'CouponEdit'
)
.
click
()
# self.q(css='div.coupon-detail-view div.pull-right a.btn.btn-primary.btn-small').first.click()
self
.
wait_for_ajax
()
...
...
acceptance_tests/pages/marketing.py
View file @
2261bfdc
import
urllib
from
bok_choy.page_object
import
PageObject
import
requests
from
acceptance_tests.config
import
MARKETING_URL_ROOT
,
BASIC_AUTH_USERNAME
,
BASIC_AUTH_PASSWORD
class
MarketingCourseAboutPage
(
PageObject
):
def
__init__
(
self
,
browser
,
course_id
):
super
(
MarketingCourseAboutPage
,
self
)
.
__init__
(
browser
)
drupal_catalog_url
=
'{}/api/catalog/v2/courses/{}'
.
format
(
MARKETING_URL_ROOT
,
course_id
)
response
=
requests
.
get
(
drupal_catalog_url
)
data
=
response
.
json
()
self
.
about_page_path
=
data
[
'course_about_uri'
]
def
is_browser_on_page
(
self
):
return
self
.
q
(
css
=
'.js-enroll-btn'
)
.
visible
def
_build_url
(
self
,
path
):
url
=
'{}/{}'
.
format
(
MARKETING_URL_ROOT
,
path
)
@property
def
url
(
self
):
url
=
'{}/{}'
.
format
(
MARKETING_URL_ROOT
,
self
.
about_page_path
)
if
BASIC_AUTH_USERNAME
and
BASIC_AUTH_PASSWORD
:
url
=
url
.
replace
(
'://'
,
'://{}:{}@'
.
format
(
BASIC_AUTH_USERNAME
,
BASIC_AUTH_PASSWORD
))
return
url
@property
def
url
(
self
):
path
=
'course/{}'
.
format
(
urllib
.
quote_plus
(
self
.
slug
))
return
self
.
_build_url
(
path
)
def
__init__
(
self
,
browser
,
slug
):
super
(
MarketingCourseAboutPage
,
self
)
.
__init__
(
browser
)
self
.
slug
=
slug
acceptance_tests/test_coupon_admin.py
View file @
2261bfdc
from
datetime
import
date
from
unittest
import
skipUnless
from
bok_choy.web_app_test
import
WebAppTest
from
acceptance_tests.config
import
ENABLE_COUPON_ADMIN_TESTS
from
acceptance_tests.constants
import
DEFAULT_END_DATE
,
DEFAULT_START_DATE
from
acceptance_tests.mixins
import
CouponMixin
,
LogistrationMixin
from
acceptance_tests.pages
import
CouponsCreatePage
,
CouponsDetailsPage
,
CouponsListPage
@skipUnless
(
ENABLE_COUPON_ADMIN_TESTS
,
'Coupon admin tests are disabled.'
)
class
CouponAdministrationTests
(
CouponMixin
,
LogistrationMixin
,
WebAppTest
):
def
setUp
(
self
):
""" Instantiate the page objects. """
...
...
acceptance_tests/test_payment.py
View file @
2261bfdc
...
...
@@ -6,7 +6,7 @@ from selenium.webdriver.common.by import By
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.support.ui
import
WebDriverWait
from
acceptance_tests.config
import
(
VERIFIED_COURSE_ID
,
ENABLE_MARKETING_SITE
,
VERIFIED_COURSE_SLUG
,
from
acceptance_tests.config
import
(
VERIFIED_COURSE_ID
,
MARKETING_URL_ROOT
,
PAYPAL_PASSWORD
,
PAYPAL_EMAIL
,
ENABLE_CYBERSOURCE_TESTS
)
from
acceptance_tests.constants
import
CYBERSOURCE_DATA1
,
CYBERSOURCE_DATA2
from
acceptance_tests.mixins
import
(
LogistrationMixin
,
EnrollmentApiMixin
,
EcommerceApiMixin
,
...
...
@@ -26,18 +26,17 @@ class VerifiedCertificatePaymentTests(UnenrollmentMixin, EcommerceApiMixin, Enro
""" Begin the checkout process for a verified certificate. """
self
.
login_with_lms
(
self
.
email
,
self
.
password
)
# If a slug is provided, use the marketing site.
if
ENABLE_MARKETING_SITE
:
course_about_page
=
MarketingCourseAboutPage
(
self
.
browser
,
VERIFIED_COURSE_SLUG
)
if
MARKETING_URL_ROOT
:
course_about_page
=
MarketingCourseAboutPage
(
self
.
browser
,
self
.
course_id
)
course_about_page
.
visit
()
# Click the first enroll button on the page to take the browser to the track selection page.
course_about_page
.
q
(
css
=
'.js-enroll-btn'
)
.
first
.
click
()
# Wait for the track selection page to load.
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'form-register-choose'
))
)
wait
=
WebDriverWait
(
self
.
browser
,
10
)
track_selection_present
=
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'form-register-choose'
))
wait
.
until
(
track_selection_present
)
else
:
course_modes_page
=
LMSCourseModePage
(
self
.
browser
,
self
.
course_id
)
course_modes_page
.
visit
()
...
...
@@ -59,7 +58,6 @@ class VerifiedCertificatePaymentTests(UnenrollmentMixin, EcommerceApiMixin, Enro
def
test_paypal
(
self
):
""" Test checkout with PayPal. """
if
not
(
PAYPAL_EMAIL
and
PAYPAL_PASSWORD
):
self
.
fail
(
'No PayPal credentials supplied!'
)
...
...
acceptance_tests/test_profed_enrollment.py
View file @
2261bfdc
from
unittest
import
skipUnless
from
bok_choy.web_app_test
import
WebAppTest
from
selenium.webdriver.common.by
import
By
from
selenium.webdriver.support
import
expected_conditions
as
EC
from
selenium.webdriver.support.ui
import
WebDriverWait
from
acceptance_tests.config
import
PROFESSIONAL_COURSE_ID
,
ENABLE_MARKETING_SITE
,
PROFESSIONAL_COURSE_SLUG
from
acceptance_tests.config
import
PROFESSIONAL_COURSE_ID
,
MARKETING_URL_ROOT
from
acceptance_tests.mixins
import
LogistrationMixin
,
EnrollmentApiMixin
from
acceptance_tests.pages
import
LMSCourseModePage
,
MarketingCourseAboutPage
@skipUnless
(
PROFESSIONAL_COURSE_ID
,
'Professional education tests are not enabled.'
)
class
ProfessionalEducationEnrollmentTests
(
EnrollmentApiMixin
,
LogistrationMixin
,
WebAppTest
):
def
test_payment_required
(
self
):
"""Verify payment is required before enrolling in a professional education course."""
# Sign into LMS
username
,
password
,
email
=
self
.
get_lms_user
()
self
.
login_with_lms
(
email
,
password
)
if
ENABLE_MARKETING_SITE
:
course_about_page
=
MarketingCourseAboutPage
(
self
.
browser
,
PROFESSIONAL_COURSE_
SLUG
)
if
MARKETING_URL_ROOT
:
course_about_page
=
MarketingCourseAboutPage
(
self
.
browser
,
PROFESSIONAL_COURSE_
ID
)
course_about_page
.
visit
()
# Click the first enroll button on the page to take the browser to the track selection page,
# and allow it to load.
course_about_page
.
q
(
css
=
'.js-enroll-btn'
)
.
first
.
click
()
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'
make-payment-step
'
)))
WebDriverWait
(
self
.
browser
,
10
)
.
until
(
EC
.
presence_of_element_located
((
By
.
CLASS_NAME
,
'
basket
'
)))
else
:
# Visit the course mode page (where auto-enrollment normally occurs)
LMSCourseModePage
(
self
.
browser
,
PROFESSIONAL_COURSE_ID
)
.
visit
()
...
...
acceptance_tests/utils.py
0 → 100644
View file @
2261bfdc
"""Utilities for end-to-end tests."""
def
str2bool
(
s
):
s
=
unicode
(
s
)
return
s
.
lower
()
in
(
u'yes'
,
u'true'
,
u't'
,
u'1'
)
ecommerce/extensions/api/v2/views/coupons.py
View file @
2261bfdc
...
...
@@ -101,7 +101,7 @@ class CouponViewSet(EdxOrderPlacementMixin, viewsets.ModelViewSet):
raise
NotImplementedError
(
'Multi-use voucher types are not supported'
)
# When a black-listed course mode is received raise an exception.
# Audit modes do not have a certificate type and therefor will raise
# Audit modes do not have a certificate type and therefor
e
will raise
# an AttributeError exception.
seats
=
Product
.
objects
.
filter
(
stockrecords__id__in
=
stock_record_ids
)
for
seat
in
seats
:
...
...
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