Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix selenium tests #3460

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions esp/INSTALL
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ a) Libraries obtained from the Internet
If you use Ubuntu, a list of required system packages can be found in
`packages_base.txt` in this directory; you can install them all at once with
"./update_deps.sh".
Note that if you use this approach, you still must download
selenium-server-standalone separately.

Packages useful for a production server are listed in a separate file.
To install those, use "apt-get install -y $(< packages_prod.txt)".
Expand All @@ -61,7 +59,6 @@ zlib System zlib1g-dev
python System 2.5 python
setuptools Python python-setuptools
virtualenv Python python-virtualenv
selenium-server-standalone System http://selenium.googlecode.com/files/selenium-server-standalone-2.9.0.jar
Node.js System nodejs
LESS JS node-less

Expand Down
2 changes: 0 additions & 2 deletions esp/esp/django_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,6 @@
USE_MAILMAN = False
MAILMAN_PATH = '/usr/lib/mailman/bin/'

SELENIUM_PATH = os.path.join(os.path.dirname(__file__), '../../../dependencies/selenium-server-standalone-2.9.0/selenium-server-standalone-2.9.0.jar')

AUTHENTICATION_BACKENDS = (
'esp.utils.auth_backend.ESPAuthBackend',
)
Expand Down
8 changes: 0 additions & 8 deletions esp/esp/local_settings.py.travis
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,3 @@ MIDDLEWARE_LOCAL = []
DATABASE_NAME = 'test_django'
DATABASE_USER = 'testuser'
DATABASE_PASSWORD = 'testpassword'

############
# Selenium #
############

SELENIUM_TESTSERVER_HOST = 'localhost'
SELENIUM_TESTSERVER_PORT = 8000
SELENIUM_DRIVER = 'Chrome'
1 change: 1 addition & 0 deletions esp/esp/program/modules/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"""

from esp.program.modules.tests.ajaxschedulingmodule import AJAXSchedulingModuleTest
from esp.program.modules.tests.ajaxstudentreg import AjaxStudentRegTest
from esp.program.modules.tests.availabilitymodule import AvailabilityModuleTest
from esp.program.modules.tests.regprofilemodule import RegProfileModuleTest
from esp.program.modules.tests.studentreg import StudentRegTest
Expand Down
13 changes: 2 additions & 11 deletions esp/esp/program/modules/tests/ajaxstudentreg.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,12 @@
from esp.program.models.class_ import ClassSection
from esp.program.tests import ProgramFrameworkTest

from django_selenium.testcases import SeleniumTestCase
import random
import json
import logging
logger = logging.getLogger(__name__)

# TODO(gkanwar): Remove non-selenium tests from this TestCase
class AjaxStudentRegTest(ProgramFrameworkTest, SeleniumTestCase):
class AjaxStudentRegTest(ProgramFrameworkTest):
def setUp(self, *args, **kwargs):
from esp.program.modules.base import ProgramModule, ProgramModuleObj

Expand All @@ -54,7 +52,6 @@ def setUp(self, *args, **kwargs):
'num_rooms': 6,
} )
ProgramFrameworkTest.setUp(self, *args, **kwargs)
SeleniumTestCase.setUp(self)

self.add_student_profiles()
self.schedule_randomly()
Expand Down Expand Up @@ -100,7 +97,7 @@ def expect_ajaxerror(self, request_url, post_data, error_str):
error_msg = response_dict['error']

self.assertTrue(error_received)
self.assertTrue(error_msg == error_str, 'Unexpected Ajax error: "%s", expected "%s"' % (error_msg, error_str))
self.assertTrue(str(error_msg) == error_str, 'Unexpected Ajax error: "%s", expected "%s"' % (error_msg, error_str))

def test_ajax_schedule(self):
program = self.program
Expand Down Expand Up @@ -186,9 +183,3 @@ def test_ajax_clearslot(self):
response = self.client.get('/learn/%s/ajax_clearslot/%d' % (program.getUrlBase(), sec2.meeting_times.all()[0].id), HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.expect_empty_schedule(response)

def test_lottery(self):
# TODO(gkanwar): Make this test actually do something, or remove it
program = self.program

self.webdriver.get('/learn/%s/lotterystudentreg' % program.getUrlBase())

87 changes: 36 additions & 51 deletions esp/esp/qsd/seltests.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,15 @@
"""
from esp.qsd.models import QuasiStaticData
from esp.seltests.util import try_normal_login, logout, noActiveAjaxJQuery
from esp.tagdict.models import Tag
from esp.users.models import ESPUser
from esp.web.models import NavBarCategory, default_navbarcategory

from django.conf import settings
from django.contrib.sites.models import Site
from django.utils.unittest.case import skipUnless
from django_selenium.testcases import SeleniumTestCase
from selenium import selenium
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.keys import Keys

class TestQsdCachePurging(SeleniumTestCase):
class TestQsdCachePurging(StaticLiveServerTestCase):
"""
This test requires Varnish (or some proxy caching server that accepts
PURGE requests) to be set up on the port and host specified in
Expand All @@ -56,17 +52,18 @@ class TestQsdCachePurging(SeleniumTestCase):
TEST_STRING = 'Hello there from a django test!'

def editQSD(self):
elem = self.find_element_by_class_name("qsd_header")
elem = self.selenium.find_element_by_class_name("qsd_header")
elem.click()
elem = self.find_element_by_name("qsd_content")
elem = self.selenium.find_element_by_class_name("jodit_wysiwyg")
for x in range(0, len(elem.text)):
elem.send_keys(Keys.DELETE)
elem.send_keys(self.TEST_STRING)
elem.send_keys(Keys.TAB)
WebDriverWait(self, 10).until(noActiveAjaxJQuery)
elem = self.selenium.find_element_by_class_name("btn-success")
elem.click()
WebDriverWait(self.selenium, 10).until(noActiveAjaxJQuery)

def setUp(self):
SeleniumTestCase.setUp(self)
super(TestQsdCachePurging, self).setUp()

# Make our users
self.admin_user, created = ESPUser.objects.get_or_create(username='admin', first_name='Harry', last_name='Alborez')
Expand Down Expand Up @@ -94,45 +91,33 @@ def setUp(self):
qsd_rec_new.keywords = ''
qsd_rec_new.save()

# Set the port that the webdriver will try to access
self._old_port = self.driver.testserver_port
self.driver.testserver_port = settings.VARNISH_PORT

# Add the varnish_purge tag
Tag.objects.get_or_create(key='varnish_purge', value='true')

# Set up the correct site
site = Site.objects.get_current()
site.domain = settings.VARNISH_HOST+":"+str(settings.VARNISH_PORT)
site.save()

def check_page(self, page):
self.open_url("/")
try_normal_login(self, self.admin_user.username, self.PASSWORD_STRING)
self.open_url(page)
self.editQSD()

self.delete_all_cookies()
self.open_url(page)
self.assertTrue(self.is_text_present(self.TEST_STRING))
logout(self)

try_normal_login(self, self.qsd_user.username, self.PASSWORD_STRING)
self.open_url(page)
self.editQSD()

self.delete_all_cookies()
self.open_url(page)
self.assertTrue(self.is_text_present(self.TEST_STRING))

@skipUnless(hasattr(settings, 'VARNISH_HOST') and hasattr(settings, 'VARNISH_PORT'), "Varnish settings weren't set")
def test_inline(self):
self.check_page("/")

@skipUnless(hasattr(settings, 'VARNISH_HOST') and hasattr(settings, 'VARNISH_PORT'), "Varnish settings weren't set")
def test_regular(self):
self.check_page("/test.html")
options = webdriver.FirefoxOptions()
options.add_argument("--headless")
self.selenium = webdriver.Firefox(firefox_options=options)
self.selenium.implicitly_wait(10)

def test_qsd_editing(self):
for page in ["/", "/test.html"]:
self.selenium.get('%s%s' % (self.live_server_url, "/"))
try_normal_login(self.selenium, self.live_server_url, self.admin_user.username, self.PASSWORD_STRING)
self.selenium.get('%s%s' % (self.live_server_url, page))
self.assertTrue(self.selenium.find_element_by_class_name("qsd_header").is_displayed(), "Admin should be able to see the QSD header on " + page)
self.editQSD()

self.selenium.delete_all_cookies()
self.selenium.get('%s%s' % (self.live_server_url, page))
self.assertTrue(self.TEST_STRING in self.selenium.page_source)
logout(self.selenium, self.live_server_url)

self.selenium.get('%s%s' % (self.live_server_url, "/"))
try_normal_login(self.selenium, self.live_server_url, self.qsd_user.username, self.PASSWORD_STRING)
self.selenium.get('%s%s' % (self.live_server_url, page))
self.assertFalse(self.selenium.find_element_by_class_name("qsd_header").is_displayed(), "Non-admin shouldn't be able to see the QSD header on " + page)

self.selenium.delete_all_cookies()
self.selenium.get('%s%s' % (self.live_server_url, page))
self.assertTrue(self.TEST_STRING in self.selenium.page_source)

def tearDown(self):
self.selenium.quit()
super(TestQsdCachePurging, self).tearDown()
self.driver.testserver_port = self._old_port
2 changes: 2 additions & 0 deletions esp/esp/qsd/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@

from django.template import Template, Context

from esp.qsd.seltests import TestQsdCachePurging # Run Selenium tests with regular tests

class QSDCorrectnessTest(TestCase):
""" Tests to ensure that QSD-related caches are cleared appropriately. """

Expand Down
Empty file.
Empty file.
48 changes: 0 additions & 48 deletions esp/esp/seltests/management/commands/seltest.py

This file was deleted.

32 changes: 20 additions & 12 deletions esp/esp/seltests/seltests.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from django_selenium.testcases import SeleniumTestCase
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from selenium import webdriver
from esp.seltests.util import try_normal_login, logout
from esp.users.models import ESPUser
from esp.utils.models import TemplateOverride

class CsrfTestCase(SeleniumTestCase):
class CsrfTestCase(StaticLiveServerTestCase):
def setUp(self):
super(CsrfTestCase, self).setUp()
user, created = ESPUser.objects.get_or_create(username='student', first_name='Student', last_name='Student')
Expand All @@ -16,8 +17,13 @@ def setUp(self):
else:
to = TemplateOverride.objects.filter(name='index.html')[0]
self.good_version = to.next_version() - 1
options = webdriver.FirefoxOptions()
options.add_argument("--headless")
self.selenium = webdriver.Firefox(firefox_options=options)
self.selenium.implicitly_wait(10)

def tearDown(self):
self.selenium.quit()
super(CsrfTestCase, self).tearDown()
if (self.good_version > 1):
# Tear down the template override for consistent behavior
Expand All @@ -44,16 +50,18 @@ def setUpNormalLogin(self):
def test_csrf_delete(self):
# Now set up and test normal login
self.setUpNormalLogin()
self.open_url("/") # Load index
self.selenium.get('%s%s' % (self.live_server_url, '/')) # Load index

try_normal_login(self, "student", "student")
self.assertTrue(self.is_text_present('Student Student'))
logout(self)
try_normal_login(self.selenium, self.live_server_url, "student", "student")
self.assertTrue(self.selenium.find_element_by_class_name('logged_in').is_displayed())
self.assertTrue(self.selenium.find_element_by_id('user_first_name').text == "Student")
self.assertTrue(self.selenium.find_element_by_id('user_last_name').text == "Student")
logout(self.selenium, self.live_server_url)

self.delete_cookie("esp_csrftoken")
self.selenium.delete_cookie("esp_csrftoken")

try_normal_login(self, "student", "student")
self.assertTrue(self.is_text_present('Student Student'))
logout(self)

self.close()
try_normal_login(self.selenium, self.live_server_url, "student", "student")
self.assertTrue(self.selenium.find_element_by_class_name('logged_in').is_displayed())
self.assertTrue(self.selenium.find_element_by_id('user_first_name').text == "Student")
self.assertTrue(self.selenium.find_element_by_id('user_last_name').text == "Student")
logout(self.selenium, self.live_server_url)
1 change: 1 addition & 0 deletions esp/esp/seltests/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from esp.seltests.seltests import CsrfTestCase # Run Selenium tests with regular tests
33 changes: 14 additions & 19 deletions esp/esp/seltests/util.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
from selenium.webdriver.support.ui import WebDriverWait
import time
def noActiveAjaxJQuery(selenium):
return selenium.execute_script("return $j.active == 0")

def noActiveAjaxJQuery(driver):
return driver.execute_script("return $j.active == 0")
def try_login(selenium, username, password):
username_input = selenium.find_element_by_name("username")
username_input.send_keys(username)
password_input = selenium.find_element_by_name("password")
password_input.send_keys(password)
selenium.find_element_by_id('gologin').click()

def try_login(driver, username, password):
elem = WebDriverWait(driver, 10).until(
lambda driver: driver.find_element_by_name("username"))
elem.send_keys(username)
elem = WebDriverWait(driver, 10).until(
lambda driver: driver.find_element_by_name("password"))
elem.send_keys(password)
elem.submit()
def try_normal_login(selenium, live_server_url, username, password):
try_login(selenium, username, password)
selenium.get('%s%s' % (live_server_url, "/"))

def try_normal_login(driver, username, password):
try_login(driver, username, password)
driver.open_url("/")

def logout(driver):
driver.open_url("/myesp/signout/")
driver.open_url("/")
def logout(selenium, live_server_url):
selenium.get('%s%s' % (live_server_url, "/myesp/signout/"))
selenium.get('%s%s' % (live_server_url, "/"))
1 change: 1 addition & 0 deletions esp/packages_base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ libc-ares2
libev4
git-core
libfreetype6-dev
firefox-geckodriver
3 changes: 1 addition & 2 deletions esp/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ django-form-utils==1.0.3 # Provides BetterForm (used in customforms) and BetterM
django-formtools==2.1 # Used once in customforms
django-localflavor==1.1 # Provides address and phone number fields
django-reversion==1.10.0 # Handles versioning, currently for QSD and TemplateOverrides
django-selenium==0.9.8 # Runs selenium tests which probably don't work anymore
django-sendgrid-v5==0.9.0 # Provides support for using SendGrid as the EmailBackend
django-vanilla-views==1.0.4 # Provides simpler generic views, currently used only for grade change requests
git+https://github.com/learning-unlimited/django-admin-tools.git@esp # Extends Django Admin
Expand All @@ -31,7 +30,7 @@ pyinotify # Makes dev servers auto-reload
pylibmc==1.5.0 # Talks to memcached
pytz==2015.4 # Required for timezone support
raven # Required for Sentry error reporting
selenium==2.44.0 # Runs selenium tests which probably don't work anymore
selenium<4 # Runs selenium tests (version 4 dropped Python 2.7 support)
shortuuid==0.4.2 # django-extensions dependency
stripe==1.19.1 # Required for credit card processing
twilio==3.6.5 # Required for text messaging support
Expand Down