Package: django-selenium-test
django-selenium-testWrite Selenium tests on Django 3.2, Django 4.0, Django 3.1 and Python 3.8+.
Based ondjango-selenium-clean.This documentation is currently a work-in-progress.TutorialInstallationIn your virtualenv:pipinstalldjango-selenium-testSetting upCreate a new django project and app:django-adminstartprojectfoocdfoo
pythonmanage.pystartappbarInfoo/settings.py, add'bar'toINSTALLED_APPSInfoo/urls.py, addfrom bar.views import SimpleViewto the
top, and addurl(r'^$', SimpleView.as_view())tourlpatterns.Add the SimpleView tobar/views.py:importtextwrapfromdjango.httpimportHttpResponsefromdjango.views.generic.baseimportViewclassSimpleView(View):defdispatch(request,*args,**kwargs):response_text=textwrap.dedent('''\<html><head><title>Greetings to the world</title></head><body><h1 id="earth">Greetings to earth</h1><h1 id="world" style="display: none;">Hello, world!</h1><p>We have some javascript here so that when you click the buttonthe heading above toggles between "Greetings to earth" and"Hello, world!".</p><button onclick="toggle()">Toggle</button><script type="text/javascript">toggle = function () {var heading_earth = document.getElementById("earth");var heading_world = document.getElementById("world");if (heading_earth.style.display == 'none') {heading_world.style.display = 'none';heading_earth.style.display = 'block';} else {heading_earth.style.display = 'none';heading_world.style.display = 'block';}}</script></body></html>''')returnHttpResponse(response_text)We're done setting up. If you now runpython manage.py runserverin your browser and visithttp://localhost:8000/in your browser, you
should see the simple page. Let's now proceed to write a test for it.Writing the testModifybar/tests.pyso that it has the following contents:fromunittestimportskipUnlessfromdjango.confimportsettingsfromdjango_selenium_testimportselenium,SeleniumTestCase,PageElementfromselenium.webdriver.common.byimportBy@skipUnless(getattr(settings,'SELENIUM_WEBDRIVERS',False),"Selenium is unconfigured")classHelloTestCase(SeleniumTestCase):heading_earth=PageElement(By.ID,'earth')heading_world=PageElement(By.ID,'world')button=PageElement(By.CSS_SELECTOR,'button')deftest_toggle(self):# Visit the pageself.selenium.get(self.live_server_url)# Check that the earth heading is visibleself.assertTrue(self.heading_earth.is_displayed())self.assertFalse(self.heading_world.is_displayed())# Toggle and check the new conditionself.button.click()self.heading_world.wait_until_is_displayed()self.assertFalse(self.heading_earth.is_displayed())self.assertTrue(self.heading_world.is_displayed())# Toggle again and re-checkself.button.click()self.heading_earth.wait_until_is_displayed()self.assertTrue(self.heading_earth.is_displayed())self.assertFalse(self.heading_world.is_displayed())Executing the testTrypython manage.py testand it will skip the test because
selenium is unconfigured. You need to configure it by specifyingSELENIUM_WEBDRIVERSinfoo/settings.py:fromdjango_selenium_test.settingsimportmake_chrome_driverSELENIUM_WEBDRIVERS={'default':make_chrome_driver([],{}),}Now try again, and it should execute the test.Advanced test running tricksExecuting a test in many widthsAdd this to yourfoo/settings.py:SELENIUM_WIDTHS=[1024,800,350]This will result in executing allSeleniumTestCase's three times,
one for each specified browser width. Useful for responsive designs.
The default is to run them on only one width, 1024.Using many selenium driversYou can have manySELENIUM_WEBDRIVERS:fromdjango_selenium_test.settingsimportmake_chrome_driver,make_firefox_driverSELENIUM_WEBDRIVERS={'default':make_chrome_driver([],{})'firefox':make_firefox_driver([],{})}By default, thedefaultone is used. You can specify another using
theSELENIUM_WEBDRIVERenvironment variable:SELENIUM_WEBDRIVER=firefoxpythonmanage.pytestRunning a headless browserIt can be very useful to run the selenium tests with a headless
browser, that is, in an invisible browser window. For one thing, it
is much faster.To achieve this, pass headless=True to the make_BRAND_driver() function:fromdjango_selenium_test.settingsimportmake_chrome_driver,make_firefox_driverSELENIUM_WEBDRIVERS={'default':make_chrome_driver([],{},headless=True)'firefox':make_firefox_driver([],{},headless=True)}Using advanced integration tests(Currently undocumented)ReferenceSeleniumTestCase objects.. code:: pythonfrom django_selenium_test import SeleniumTestCaseSeleniumTestCaseis the same as Django'sStaticLiveServerTestCasebut it adds a little bit of Selenium
functionality. Derive your Selenium tests from this class instead ofStaticLiveServerTestCase.The most important feature ofSeleniumTestCaseis theseleniumattribute.  Technically it is a wrapper around the selenium driver. In
practice, you can think about it as the browser, or as the equivalent
of Django's test client. It has allselenium driver attributes and methods_, but you will mostly useget(). It also has the
following additional methods:self.selenium.login(**credentials),self.selenium.force_login(user, base_url),self.selenium.logout()Similar to the Django test clientlogin(),force_login()andlogout()methods.login()returnsTrueif login is
possible;Falseif the provided credentials are incorrect, or the
user is inactive, or if the sessions framework is not available.Theforce_login()code was adapted fromdjango-selenium-login,
which is licensed under the MIT License.self.selenium.wait_until_n_windows(n, timeout=2)Useful when a Javascript action has caused the browser to open
another window. The typical usage is this:button_that_will_open_a_second_window.click()self.selenium.wait_until_n_windows(n=2,timeout=10)windows=self.selenium.window_handlesself.selenium.switch_to.window(windows[1])# continue testingIf the timeout (in seconds) elapses and the number of browser
windows never becomesn, anAssertionErroris raised.selenium driver attributes and methodsPageElement objectsfromdjango_selenium_testimportPageElementPageElementis a lazy wrapper around WebElement_; it has all its
properties and methods. It is initialized with a locator_, but the
element is not actually located until needed. In addition to
WebElement_ properties and methods, it has these:PageElement.exists(): Returns True if the element can be located.PageElement.wait_until_exists(timeout=10)PageElement.wait_until_not_exists(timeout=10)PageElement.wait_until_is_displayed(timeout=10)PageElement.wait_until_not_displayed(timeout=10)PageElement.wait_until_contains(text, timeout=10)PageElement.wait_until_not_contains(text, timeout=10)What these methods do should be self-explanatory from their name. The
ones ending incontainsrefer to whether the element contains the
specified text.  The methods raise an exception if there is a timeout.WebElementlocatorIntegrationTest objects(Currently undocumented)Running django-selenium-test's own unit testsBy default the unit tests will use Chrome::./setup.pytestUse theSELENIUM_BROWSERenvironment variable to use another browser:SELENIUM_BROWSER=firefox./setup.pytestLicenseLicensed under the BSD 3-clause license; seeLICENSE.txtfor details.