diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1b94aee..b5063f4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,31 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9] + grappelli: ["0", "1"] + python-version: ["3.11"] + django-version: ["4.2"] + exclude: + - python-version: "3.11" + grappelli: "1" + include: + - python-version: "3.8" + django-version: "4.2" + grappelli: "1" + - python-version: "3.9" + django-version: "5.0" + grappelli: "0" + - python-version: "3.10" + django-version: "5.0" + grappelli: "1" + - python-version: "3.12" + django-version: "5.1" + grappelli: "0" + + name: Django ${{ matrix.django-version }} (Python ${{ matrix.python-version }})${{ matrix.grappelli == '1' && ' + grappelli' || '' }} + + env: + DJANGO: ${{ matrix.django-version }} + GRAPPELLI: ${{ matrix.grappelli }} steps: - uses: actions/checkout@v3 diff --git a/selenosis/__init__.py b/selenosis/__init__.py index 4563971..a87492b 100644 --- a/selenosis/__init__.py +++ b/selenosis/__init__.py @@ -5,14 +5,10 @@ # # without running afoul of the strict import order required by Django 1.9+. # This implementation is shamelessly stolen from werkzeug's ``__init__.py``. -import pkg_resources import sys from types import ModuleType -try: - __version__ = pkg_resources.get_distribution('django-selenosis').version -except pkg_resources.DistributionNotFound: - __version__ = None +__version__ = "2.0.5" # import mapping to objects in other modules all_by_module = { diff --git a/selenosis/runner.py b/selenosis/runner.py index 969f48e..9b8b840 100644 --- a/selenosis/runner.py +++ b/selenosis/runner.py @@ -35,17 +35,13 @@ class NoFailFastUnexpectedSuccessTestResultMixin: """Overridden test result class that doesn't failfast on unexpected success""" def addUnexpectedSuccess(self, test): - self.unexpectedSuccesses.append((test, 'Success')) + self.unexpectedSuccesses.append(test) if self.showAll: self.stream.writeln("unexpected success") elif self.dots: self.stream.write("u") self.stream.flush() - def printErrors(self): - super(NoFailFastUnexpectedSuccessTestResultMixin, self).printErrors() - self.printErrorList('UNEXPECTED SUCCESS', self.unexpectedSuccesses) - class TextTestResult(NoFailFastUnexpectedSuccessTestResultMixin, unittest.TextTestResult): pass @@ -55,10 +51,7 @@ class DebugSQLTextTestResult( NoFailFastUnexpectedSuccessTestResultMixin, django.test.runner.DebugSQLTextTestResult): - def addUnexpectedSuccess(self, test): - super(DebugSQLTextTestResult, self).addUnexpectedSuccess(test) - self.debug_sql_stream.seek(0) - self.unexpectedSuccesses[-1] += (self.debug_sql_stream.read(),) + pass class _FailedTest(unittest.TestCase): diff --git a/selenosis/selenium.py b/selenosis/selenium.py index f06a5f4..2bc3eaa 100644 --- a/selenosis/selenium.py +++ b/selenosis/selenium.py @@ -160,12 +160,19 @@ def setUpClass(cls): cls.selenium = selenium cls.selenium.implicitly_wait(10) super(SelenosisTestCase, cls).setUpClass() + if hasattr(cls, "addClassCleanup"): + cls.addClassCleanup(cls._quit_selenium) @classmethod - def _tearDownClassInternal(cls): + def _quit_selenium(cls): # quit() the WebDriver before attempting to terminate and join the # single-threaded LiveServerThread to avoid a dead lock if the browser # kept a connection alive. - if hasattr(cls, 'selenium'): + if hasattr(cls, "selenium"): cls.selenium.quit() + + @classmethod + def _tearDownClassInternal(cls): + if not hasattr(cls, "addClassCleanup"): + cls._quit_selenium() super(SelenosisTestCase, cls)._tearDownClassInternal() diff --git a/selenosis/settings.py b/selenosis/settings.py index 6b88cae..d737959 100644 --- a/selenosis/settings.py +++ b/selenosis/settings.py @@ -14,6 +14,7 @@ } } SECRET_KEY = 'z-i*xqqn)r0i7leak^#clq6y5j8&tfslp^a4duaywj2$**s*0_' +USE_TZ = True try: import grappelli # noqa diff --git a/setup.py b/setup.py index 4841b81..99e82e5 100755 --- a/setup.py +++ b/setup.py @@ -1,9 +1,23 @@ #!/usr/bin/env python from os import path +import re from setuptools import setup, find_packages +# Find the package version in __init__.py without importing it +init_file = path.join(path.dirname(__file__), "selenosis", "__init__.py") +with open(init_file) as f: + for line in f: + m = re.search(r"""^__version__ = (['"])(.+?)\1$""", line) + if m is not None: + version = m.group(2) + break + else: + raise LookupError("Unable to find __version__ in " + init_file) + + + def read(*parts): file_path = path.join(path.dirname(__file__), *parts) return open(file_path).read() @@ -11,7 +25,7 @@ def read(*parts): setup( name='django-selenosis', - version='2.0.5', + version=version, license='BSD', description='Helpers for writing selenium tests for Django', long_description=read('README.rst'), diff --git a/tox.ini b/tox.ini index cc3ac8f..b6cc9e7 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,10 @@ [tox] envlist = - py{37,38,39}-dj{22,31,32}{,-grp} + py{36,37,38,39}-dj22-{grp,nogrp} + py{36,37,38,39,310}-dj32-{grp,nogrp} + py{38,39,310,311,312}-dj42-{grp,nogrp} + py{310,311,312}-dj50-{grp,nogrp} + py{310,311,312}-dj51-nogrp [testenv] commands = @@ -11,12 +15,14 @@ deps = pytest-django selenium dj22: Django>=2.2,<3.0 - dj31: Django>=3.1,<3.2 dj32: Django>=3.2,<4.0 - dj22-grp: django-grappelli==2.13.4 - dj31-grp: django-grappelli==2.14.4 - dj32-grp: django-grappelli==2.15.1 - + dj42: Django>=4.2,<4.3 + dj50: Django>=5.0,<5.1 + dj51: Django>=5.1a1,<5.2 + dj22-grp: django-grappelli>=2.13,<2.14 + dj32-grp: django-grappelli>=2.15,<2.16 + dj42-grp: django-grappelli>=3.0,<3.1 + dj50-grp: django-grappelli>=4.0,<4.1 [testenv:clean] description = Clean all build and test artifacts @@ -38,3 +44,17 @@ python = 3.7: py37 3.8: py38 3.9: py39 + 3.10: py310 + 3.11: py311 + 3.12: py312 + +[gh-actions:env] +DJANGO = + 2.2: dj22 + 3.2: dj32 + 4.2: dj42 + 5.0: dj50 + 5.1: dj51 +GRAPPELLI = + 0: nogrp + 1: grp