Skip to content

Commit

Permalink
Add integration tests for views
Browse files Browse the repository at this point in the history
  • Loading branch information
jacebrowning committed Oct 13, 2019
1 parent e388f83 commit 7c16d4e
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 39 deletions.
7 changes: 4 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ docs/requirements.txt: poetry.lock
.PHONY: uml
uml: install docs/*.png
docs/*.png: $(MODULES)
poetry run pyreverse $(PACKAGE) -p $(PACKAGE) -a 1 -f ALL -o png --ignore tests
- mv -f classes_$(PACKAGE).png docs/classes.png
- mv -f packages_$(PACKAGE).png docs/packages.png
# TODO: AttributeError: 'Unknown' object has no attribute 'attrname'
# poetry run pyreverse $(PACKAGE) -p $(PACKAGE) -a 1 -f ALL -o png --ignore tests
# - mv -f classes_$(PACKAGE).png docs/classes.png
# - mv -f packages_$(PACKAGE).png docs/packages.png

.PHONY: mkdocs-serve
mkdocs-serve: mkdocs
Expand Down
69 changes: 39 additions & 30 deletions poetry.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pytest-describe = "*"
pytest-expecter = "*"
pytest-random = "*"
freezegun = "*"
flaky = "*"

# Reports
coveragespace = "*"
Expand Down
2 changes: 2 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ addopts =
--cov-report=term-missing:skip-covered
--no-cov-on-fail

--no-success-flaky-report

cache_dir = .cache

markers =
74 changes: 74 additions & 0 deletions tests/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# pylint: disable=redefined-outer-name,unused-variable,expression-not-assigned

import pytest

from twerk import utils
from twerk.views import private, public


@pytest.fixture(scope="module")
def browser():
with utils.get_browser(headless=True) as browser:
yield browser


@pytest.fixture
def credentials():
try:
return utils.get_credentials(prompt=False)
except EnvironmentError as e:
pytest.skip(str(e))


def describe_public_views():
def describe_profile():
@pytest.fixture(scope="module")
def profile(browser):
return public.Profile(browser, username="jack")

@pytest.mark.flaky
def it_contains_properties(expect, profile):
expect(profile.tweets) > 0
expect(profile.following) > 0
expect(profile.followers) > 0
expect(profile.likes) > 0
expect(profile.joined) != None


def describe_private_views():
def describe_profile():
@pytest.fixture
def profile(browser, credentials):
return private.Profile(browser, username="jack", credentials=credentials)

@pytest.mark.flaky
def it_contains_properties(expect, profile):
expect(profile.tweets) > 0
expect(profile.following) > 0
expect(profile.followers) > 0
expect(profile.likes) == 0 # not yet supported
expect(profile.joined) != None

def describe_profile_block():
@pytest.fixture
def profile_block(browser, credentials):
return private.ProfileBlock(
browser, username="jack", credentials=credentials
)

@pytest.mark.flaky
def it_can_cancel(expect, profile_block):
view = profile_block.cancel()
expect(view).isinstance(private.Profile)

def describe_profile_report():
@pytest.fixture
def profile_report(browser, credentials):
return private.ProfileReport(
browser, username="jack", credentials=credentials
)

@pytest.mark.flaky
def it_can_cancel(expect, profile_report):
view = profile_report.cancel()
expect(view).isinstance(private.Profile)
18 changes: 12 additions & 6 deletions twerk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,26 @@
from .models import Credentials


def get_browser() -> Browser:
def get_browser(headless: bool = False) -> Browser:
log.silence("selenium", "urllib3")
options = dict(headless=headless, wait_time=1.0)
try:
return Browser("firefox", wait_time=1.0)
return Browser("firefox", **options)
except Exception as e: # pylint: disable=broad-except
log.debug(str(e))
if "geckodriver" in str(e):
path = GeckoDriverManager().install()
return Browser("firefox", wait_time=1.0, executable_path=path)
return Browser("firefox", executable_path=path, **options)
raise e from None


def get_credentials() -> Credentials:
username = os.getenv("TWITTER_USERNAME") or input("Twitter username: ")
password = os.getenv("TWITTER_PASSWORD") or getpass("Twitter password: ")
def get_credentials(prompt: bool = True) -> Credentials:
username = os.getenv("TWITTER_USERNAME")
password = os.getenv("TWITTER_PASSWORD")
if not all((username, password)) and not prompt:
raise EnvironmentError("Twitter credentials not available")
username = username or input("Twitter username: ")
password = password or getpass("Twitter password: ")
return Credentials(username, password)


Expand Down
7 changes: 7 additions & 0 deletions twerk/views/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ def _url(self) -> str:
return f"https://twitter.com/{self.username}"

def _goto(self) -> Profile:
if self._browser.is_element_visible_by_css('aria-label="Profile"'):
log.info("Logging out")
self._browser.visit("https://twitter.com/logout")
self._browser.find_by_text("Log out").click()

log.info(f"Visiting {self._url}")
self._browser.visit(self._url)

return self

@property
Expand Down

0 comments on commit 7c16d4e

Please sign in to comment.