-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add liveserver and liveclient fixtures (closes #24)
- Loading branch information
Showing
8 changed files
with
176 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,3 +18,4 @@ Fixtures | |
fixtures_messages | ||
fixtures_migrations | ||
fixtures_utils | ||
fixtures_live |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Live server | ||
=========== | ||
|
||
These instruments allows you to lunch a live servers and live clients, e.g. for UI testing purposes. | ||
|
||
.. automodule:: pytest_djangoapp.fixtures.live | ||
:members: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
from typing import Type, TypeVar, Dict | ||
|
||
import pytest | ||
from django.contrib.staticfiles.testing import StaticLiveServerTestCase | ||
|
||
TypeLiveClient = TypeVar('TypeLiveClient', bound='LiveClient') | ||
|
||
|
||
@pytest.fixture() | ||
def liveserver() -> Type['LiveServer']: | ||
"""Runs a live server. Available as a context manager. | ||
Example:: | ||
def test_live(liveserver): | ||
with liveserver() as server: | ||
print(f'Live server is available at: {server.url}') | ||
""" | ||
return LiveServer | ||
|
||
|
||
@pytest.fixture() | ||
def liveclient(): | ||
"""Runs a live client. Available as a context manager. | ||
Example:: | ||
def test_live(liveserver, liveclient): | ||
with liveserver() as server: | ||
# Let's run Firefox using Selenium. | ||
with liveclient('selenium', browser='firefox') as client: | ||
selenium = client.handle # Selenium driver is available in .handle | ||
# Let's open server's root URL and check heading 1 on that page | ||
selenium.get(server.url) | ||
assert selenium.find_element('tag name', 'h1').text == 'Not Found' | ||
""" | ||
|
||
def get_client(typename: str, *, browser: str) -> TypeLiveClient: | ||
return LiveClient.spawn(alias=typename, browser=browser) | ||
|
||
return get_client | ||
|
||
|
||
class LiveServer: | ||
|
||
_cls = StaticLiveServerTestCase | ||
|
||
def __init__(self, *, host: str = None, port: int = None): | ||
|
||
cls = self._cls | ||
|
||
if host: | ||
cls.host = host | ||
|
||
if port is not None: | ||
cls.port = port | ||
|
||
@property | ||
def url(self) -> str: | ||
"""URL to access this live server.""" | ||
return self._cls.live_server_url | ||
|
||
def __enter__(self): | ||
self._cls._start_server_thread() | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
self._cls._terminate_thread() | ||
|
||
|
||
class LiveClient: | ||
"""Base class for live clients.""" | ||
|
||
alias: str = '' | ||
|
||
_registry: Dict[str, TypeLiveClient] = {} | ||
|
||
def __init_subclass__(cls, **kwargs): | ||
super().__init_subclass__() | ||
|
||
alias = cls.alias | ||
|
||
if alias: | ||
cls._registry[alias] = cls | ||
|
||
def __init__(self, *, browser: str): | ||
self._browser = browser | ||
self.handle = None | ||
|
||
def __enter__(self) -> TypeLiveClient: | ||
self.handle = self._handle_init() | ||
return self | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
self._handle_destroy() | ||
|
||
@classmethod | ||
def spawn(cls, alias: str, **kwargs) -> TypeLiveClient: | ||
client_cls = LiveClient._registry[alias] | ||
return client_cls(**kwargs) | ||
|
||
def _handle_init(self): # pragma: nocover | ||
raise NotImplementedError | ||
|
||
def _handle_destroy(self): | ||
pass | ||
|
||
|
||
class SeleniumLiveClient(LiveClient): | ||
"""This live client wraps Selenium. | ||
https://selenium-python.readthedocs.io/ | ||
""" | ||
alias: str = 'selenium' | ||
|
||
def _handle_init(self): | ||
from django.test.selenium import SeleniumTestCaseBase | ||
|
||
cls = SeleniumTestCaseBase | ||
browser = self._browser | ||
driver_cls = cls.import_webdriver(browser) | ||
|
||
return driver_cls(options=cls.import_options(browser)()) | ||
|
||
def _handle_destroy(self): | ||
|
||
handle = self.handle | ||
|
||
if handle: | ||
handle.quit() | ||
|
||
super()._handle_destroy() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from unittest.mock import MagicMock | ||
|
||
|
||
def test_liveserver(liveserver, liveclient): | ||
|
||
with liveserver(host='localhost', port=33445) as server: | ||
assert server.url == 'http://localhost:33445' | ||
|
||
|
||
def test_selenium(liveserver, liveclient, monkeypatch): | ||
|
||
monkeypatch.setattr('django.test.selenium.SeleniumTestCaseBase', MagicMock()) | ||
|
||
with liveserver() as server: | ||
|
||
with liveclient('selenium', browser='firefox') as client: | ||
selenium = client.handle | ||
|
||
selenium.get(server.url) | ||
assert 'MagicMock' in f"{selenium.find_element('tag name', 'h1').text}" |