Skip to content

Commit

Permalink
(test): added settings for browser tests, added a sample test
Browse files Browse the repository at this point in the history
(test): added settings for browser tests, added a sample test
  • Loading branch information
nekhvoya authored and supakeen committed Jul 31, 2023
1 parent 3563f94 commit 5e38f9d
Show file tree
Hide file tree
Showing 12 changed files with 1,185 additions and 997 deletions.
34 changes: 33 additions & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ jobs:
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Test with pytest
- name: Run unit tests
run: |
pytest --cov=pinnwand
e2e-test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ "3.11" ]
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Install playwright
run: playwright install

- name: Install pinnwand
run: pip install pinnwand -e.

- name: Run e2e tests
run: |
pytest --e2e --log-cli-level=INFO
1,420 changes: 744 additions & 676 deletions pdm.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 @@ -36,6 +36,7 @@ dev = [
"isort>=5.12.0",
"bandit>=1.7.5",
"pip-audit>=2.5.6",
"pytest-playwright>=0.3.3",
]
[build-system]
requires = ["pdm-pep517>=1.0"]
Expand Down
578 changes: 258 additions & 320 deletions requirements.txt

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import pytest


def pytest_addoption(parser):
parser.addoption(
"--e2e",
action="store_true",
help="run browser tests only if the option is passed",
)


def pytest_runtest_setup(item):
if "e2e" in item.keywords and not item.config.getoption("--e2e"):
pytest.skip(
"browser tests are skipped because no --e2e option was given"
)
elif item.config.getoption("--e2e") and "e2e" not in item.keywords:
pytest.skip("only browser tests are run when --e2e option is given")


def pytest_configure(config):
config.addinivalue_line("markers", "e2e: mark browser tests")
Empty file added test/e2e/__init__.py
Empty file.
32 changes: 32 additions & 0 deletions test/e2e/env_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from typing import Generator
import pytest
import subprocess
import sys
import logging
import socket

log = logging.getLogger(__name__)


def select_port():
sock = socket.socket()
sock.bind(("", 0))
return sock.getsockname()[1]


PORT = str(select_port())
BASE_URL = f"http://localhost:{PORT}/"


@pytest.mark.e2e
@pytest.fixture(scope="session", autouse=True)
def application() -> Generator[None, None, None]:
# Before All
log.info(f"Starting Pinnwand application on port {PORT}")
proc = subprocess.Popen(
[sys.executable, "-m", "pinnwand", "http", "--port", PORT]
)
yield
# After All
log.info("Terminating Pinnwand application")
proc.terminate()
Empty file.
13 changes: 13 additions & 0 deletions test/e2e/pageobjects/base_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from playwright.sync_api import Locator, expect


class BasePage:
def __init__(self, locator: Locator, name) -> None:
self.page_locator = locator
self.page_name = name

# Expectations
def should_be_opened(self):
expect(
self.page_locator, f"{self.page_name} was not opened"
).to_be_visible()
41 changes: 41 additions & 0 deletions test/e2e/pageobjects/create_paste_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
from playwright.sync_api import Page, expect
from test.e2e.env_config import BASE_URL
from test.e2e.pageobjects.base_page import BasePage
import logging

log = logging.getLogger(__name__)


class CreatePastePage(BasePage):
def __init__(self, page: Page) -> None:
super().__init__(
page.locator(".file-part textarea"), "Create Paste Page"
)
self.page = page
self.url = BASE_URL
self.paste_input = page.locator(".file-part textarea")
self.submit_button = page.locator(".paste-submit button[type=submit]")

def open(self):
log.info(f"Opening Pinnwand at {self.url}")
self.page.goto(self.url)

def type_paste(self, text):
log.info(f"Typing {text} in Paste Input")
self.paste_input.type(text)

def click_submit(self):
log.info("Clicking Submit Button")
self.submit_button.click()

# Expectations
def should_have_title(self, title):
expect(
self.page, f"{self.page_name} had incorrect title"
).to_have_title(title)

def should_have_value_in_paste_input(self, value):
expect(
self.paste_input,
f"Paste Input had incorrect value on {self.page_name}",
).to_have_value(value)
18 changes: 18 additions & 0 deletions test/e2e/pageobjects/view_paste_page.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from playwright.sync_api import Page, expect
from test.e2e.pageobjects.base_page import BasePage
import logging

log = logging.getLogger(__name__)


class ViewPastePage(BasePage):
def __init__(self, page: Page) -> None:
super().__init__(page.locator(".files"), "View Paste Page")
self.page = page
self.source = page.locator(".source")

# Expectations
def should_have_pasted_text(self, text):
expect(
self.source, f"Pasted text was incorrect on {self.page_name}"
).to_have_text(text)
23 changes: 23 additions & 0 deletions test/e2e/testscenarios/test_create_paste.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from playwright.sync_api import Page
import string
from test.e2e.pageobjects.create_paste_page import CreatePastePage
from test.e2e.pageobjects.view_paste_page import ViewPastePage
import pytest
from test.e2e.env_config import application


@pytest.mark.e2e
def test_create_paste(page: Page):
create_paste_page = CreatePastePage(page)
create_paste_page.open()
create_paste_page.should_be_opened()
create_paste_page.should_have_title("Create new paste")

paste_text = string.ascii_letters + string.digits
create_paste_page.type_paste(paste_text)
create_paste_page.should_have_value_in_paste_input(paste_text)
create_paste_page.click_submit()

view_paste_page = ViewPastePage(page)
view_paste_page.should_be_opened()
view_paste_page.should_have_pasted_text(paste_text)

0 comments on commit 5e38f9d

Please sign in to comment.