diff --git a/.gitignore b/.gitignore index a94067b..0a48c23 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ __pycache__/ *.json *.zip TestResults/ -.vscode/ \ No newline at end of file +.vscode/ +*.pyc \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..67103e7 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.12-slim + +WORKDIR /code + +COPY ./requirements.txt ./ +RUN pip install --no-cache-dir -r requirements.txt + +RUN playwright install + +RUN playwright install-deps diff --git a/README.md b/README.md new file mode 100644 index 0000000..7094ef1 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Readme + +```bash +docker compose run --rm app pytest +# docker-compose up +``` + +Force rebuild with cache + +```bash +docker-compose up --build +``` + +Force rebuild wtihtout cache + +```bash +docker-compose build --no-cache +``` diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..5da046e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,6 @@ +services: + app: + build: . + container_name: python-env + volumes: + - .:/code diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..c10699b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +pytest +pytest-playwright +python-dotenv \ No newline at end of file diff --git a/src/blog.dev.local-it.cloud.env b/src/blog.dev.local-it.cloud.env new file mode 100644 index 0000000..600aaf6 --- /dev/null +++ b/src/blog.dev.local-it.cloud.env @@ -0,0 +1,71 @@ +################################################################################ +# DO NOT EDIT THIS FILE, IT IS AUTOMATICALLY GENERATED AND WILL BE OVERWRITTEN # +################################################################################ + +TYPE=wordpress +TIMEOUT=300 +ENABLE_AUTO_UPDATE=true +COMPOSE_FILE="compose.yml" + +# Setup Wordpress settings on each deploy: +#POST_DEPLOY_CMDS="app core_install" + +DOMAIN=blog.dev.local-it.cloud +## Domain aliases +#EXTRA_DOMAINS=', `www.blog.dev.local-it.cloud`' +LETS_ENCRYPT_ENV=production + +TITLE="My Example Blog" +LOCALE=de_DE +ADMIN_EMAIL=admin@example.com + +# Every new user is per default subscriber, uncomment to change it +DEFAULT_USER_ROLE=administrator + +#WORDPRESS_DEBUG=true + +## Additional extensions +#PHP_EXTENSIONS="calendar" + +SECRET_DB_ROOT_PASSWORD_VERSION=v1 +SECRET_DB_PASSWORD_VERSION=v1 + +# Mostly for compatibility with existing database dumps... +#WORDPRESS_TABLE_PREFIX=wp_ + +# Multisite +#WORDPRESS_CONFIG_EXTRA="\ +#define('WP_CACHE', false);\ +#define('WP_ALLOW_MULTISITE', true );" + +# Multisite phase 2 (see README) +#WORDPRESS_CONFIG_EXTRA="define('MULTISITE', true); define('SUBDOMAIN_INSTALL', true); define('DOMAIN_CURRENT_SITE', '${DOMAIN}'); define('PATH_CURRENT_SITE', '/'); define('SITE_ID_CURRENT_SITE', 1); define('BLOG_ID_CURRENT_SITE', 1); define('FORCE_SSL_ADMIN', true ); define('COOKIE_DOMAIN', \$_SERVER['HTTP_HOST']);" + +# Local SMTP relay +#COMPOSE_FILE="$COMPOSE_FILE:compose.mailrelay.yml" +SMTP_HOST=mail.local-it.org +MAIL_FROM=noreply@local-it.org + +# Remote SMTP relay +COMPOSE_FILE="$COMPOSE_FILE:compose.smtp.yml" +SMTP_HOST=mail.local-it.org +MAIL_FROM=noreply@local-it.org +SMTP_PORT=587 +SMTP_AUTH=on +SMTP_TLS=on +SECRET_SMTP_PASSWORD_VERSION=v1 + +# Authentik SSO +COMPOSE_FILE="$COMPOSE_FILE:compose.authentik.yml" +AUTHENTIK_DOMAIN=dev.local-it.cloud +SECRET_AUTHENTIK_SECRET_VERSION=v1 +SECRET_AUTHENTIK_ID_VERSION=v1 +LOGIN_TYPE='auto' + +# 🚩🚩 dangerous, use only for development sites! + +# Allow remote connections to db +#COMPOSE_FILE="$COMPOSE_FILE:compose.public-db.yml + +# Wide-open CORS +#CORS_ALLOW_ALL=1 diff --git a/src/test_wrapper.py b/src/test_wrapper.py new file mode 100644 index 0000000..74afda3 --- /dev/null +++ b/src/test_wrapper.py @@ -0,0 +1,42 @@ +from pathlib import Path +from typing import Protocol + +from dotenv import dotenv_values +from icecream import ic +from tests_wordpress.testrunner_wordpress import TestRunnerWordpress + + +class TestRunner(Protocol): + def run_tests(): + pass + + +WRAPPER_DICT: dict[str, type[TestRunner]] = {"wordpress": TestRunnerWordpress} + + +class TestWrapper: + def __init__(self, dotenv_path: Path): + self.dotenv_path = dotenv_path + self.root_dir = self.dotenv_path.parent + self.show_files() + self.load_dotenv() + self.load_test_wrapper() + + def show_files(self): + ic(list(self.root_dir.glob("*"))) + + def load_dotenv(self): + assert self.dotenv_path.is_file() + self.config = dotenv_values(self.dotenv_path) + + def load_test_wrapper(self): + config_type = self.config["TYPE"] + ic(config_type) + WrapperClass = WRAPPER_DICT[config_type] + wrapper = WrapperClass(self.dotenv_path) + wrapper.run_tests() + + +if __name__ == "__main__": + dotenv_path = Path(__file__).parent / "./blog.dev.local-it.cloud.env" + t = TestWrapper(dotenv_path) diff --git a/src/tests_wordpress/conftest.py b/src/tests_wordpress/conftest.py new file mode 100644 index 0000000..9d0a65a --- /dev/null +++ b/src/tests_wordpress/conftest.py @@ -0,0 +1,20 @@ +from pathlib import Path + +import pytest +from dotenv import dotenv_values + + +def pytest_addoption(parser): + parser.addoption( + "--env_file_path", + action="store", + ) + + +@pytest.fixture +def config(request): + dotenv_path = request.config.getoption("--env_file_path") + dotenv_path = Path(dotenv_path) + assert dotenv_path.is_file() + config = dotenv_values(dotenv_path) + return config diff --git a/src/tests_wordpress/test_wordpress.py b/src/tests_wordpress/test_wordpress.py new file mode 100644 index 0000000..5d5b407 --- /dev/null +++ b/src/tests_wordpress/test_wordpress.py @@ -0,0 +1,29 @@ +import re + +import pytest +from playwright.sync_api import Page, expect + + +def test_one(): + assert 1 + 1 == 2 + + +def test_two(): + assert 2 + 1 == 3 + + +def test_has_title(page: Page): + page.goto("https://playwright.dev/") + + # Expect a title "to contain" a substring. + expect(page).to_have_title(re.compile("Playwright")) + + +def test_get_started_link(page: Page): + page.goto("https://playwright.dev/") + + # Click the get started link. + page.get_by_role("link", name="Get started").click() + + # Expects page to have a heading with the name of Installation. + expect(page.get_by_role("heading", name="Installation")).to_be_visible() diff --git a/src/tests_wordpress/test_wordpress_feature1.py b/src/tests_wordpress/test_wordpress_feature1.py new file mode 100644 index 0000000..865fd93 --- /dev/null +++ b/src/tests_wordpress/test_wordpress_feature1.py @@ -0,0 +1,26 @@ +import re + +from icecream import ic +from playwright.sync_api import Page, expect + + +def test_one(config): + ic(config) + assert 1 + 1 == 2 + + +def test_has_title(page: Page): + page.goto("https://playwright.dev/") + + # Expect a title "to contain" a substring. + expect(page).to_have_title(re.compile("Playwright")) + + +def test_get_started_link(page: Page): + page.goto("https://playwright.dev/") + + # Click the get started link. + page.get_by_role("link", name="Get started").click() + + # Expects page to have a heading with the name of Installation. + expect(page.get_by_role("heading", name="Installation")).to_be_visible() diff --git a/src/tests_wordpress/testrunner_wordpress.py b/src/tests_wordpress/testrunner_wordpress.py new file mode 100644 index 0000000..d375588 --- /dev/null +++ b/src/tests_wordpress/testrunner_wordpress.py @@ -0,0 +1,45 @@ +from pathlib import Path + +import pytest +from dotenv import dotenv_values +from icecream import ic + + +class TestRunnerWordpress: + def __init__(self, dotenv_path: Path): + self.dotenv_path = dotenv_path + self.show_files() + self.load_dotenv() + # self.run_pytest_dir_wp() + # self.run_pytest_single_wp() + self.run_pytest_single_wp_feature1() + + def show_files(self): + ic(list(self.root_dir.glob("*"))) + + def load_dotenv(self): + dotenv_path = self.root_dir / "./blog.dev.local-it.cloud.env" + assert dotenv_path.is_file() + config = dotenv_values(dotenv_path) + ic(config) + + def run_pytest_dir_wp(self): + pytest.main([self.root_dir / "tests_wordpress"]) + + def run_pytest_single_wp(self): + pytest.main( + [ + self.root_dir / "tests_wordpress" / "test_wordpress.py", + "--env_file_path", + self.dotenv_path, + ] + ) + + def run_pytest_single_wp_feature1(self): + pytest.main( + [ + self.root_dir / "tests_wordpress" / "test_wordpress_feature1.py", + "--env_file_path", + self.dotenv_path, + ] + )