Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
*~
build

# Testing
.pytest_cache/
.coverage
htmlcov/
coverage.xml
*.py[cod]
__pycache__/

# Claude
.claude/*

# Virtual environments
venv/
.venv/
env/
.env/
ENV/

# IDE
.vscode/
.idea/
*.swp
*.swo
.DS_Store

# Poetry
dist/
*.egg-info/

# Sphinx build artifacts
_build/
_static/
_templates/
1,082 changes: 1,082 additions & 0 deletions poetry.lock

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
[tool.poetry]
name = "selenium-python-docs"
version = "1.0.0"
description = "Selenium Python Bindings Documentation"
authors = ["Your Name <[email protected]>"]
readme = "README.rst"
package-mode = false

[tool.poetry.dependencies]
python = "^3.8"
selenium = "*"
Sphinx = "*"
alabaster = "*"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0.0"
pytest-cov = "^4.1.0"
pytest-mock = "^3.12.0"

[tool.poetry.scripts]
test = "pytest:main"
tests = "pytest:main"

[tool.pytest.ini_options]
minversion = "6.0"
addopts = [
"-ra",
"--strict-markers",
"--strict-config",
"--cov-branch",
"--cov-report=term-missing:skip-covered",
"--cov-report=html",
"--cov-report=xml",
]
testpaths = ["tests"]
python_files = "test_*.py"
python_classes = "Test*"
python_functions = "test_*"
markers = [
"unit: marks tests as unit tests",
"integration: marks tests as integration tests",
"slow: marks tests as slow",
]

[tool.coverage.run]
source = ["tests"]
omit = [
"*/tests/*",
"*/test_*",
"*/__pycache__/*",
"*/site-packages/*",
"*/distutils/*",
"*/venv/*",
"*/.venv/*",
]

[tool.coverage.report]
precision = 2
show_missing = true
skip_covered = false
exclude_lines = [
"pragma: no cover",
"def __repr__",
"if self.debug:",
"if __name__ == .__main__.:",
"raise AssertionError",
"raise NotImplementedError",
"if 0:",
"if False:",
"pass",
]

[tool.coverage.html]
directory = "htmlcov"

[tool.coverage.xml]
output = "coverage.xml"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
Empty file added tests/__init__.py
Empty file.
145 changes: 145 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import os
import shutil
import tempfile
from pathlib import Path
from typing import Generator

import pytest


@pytest.fixture
def temp_dir() -> Generator[Path, None, None]:
"""Create a temporary directory for test files."""
temp_path = Path(tempfile.mkdtemp())
yield temp_path
shutil.rmtree(temp_path, ignore_errors=True)


@pytest.fixture
def mock_config() -> dict:
"""Provide a mock configuration dictionary."""
return {
"project_name": "test_project",
"version": "1.0.0",
"author": "Test Author",
"language": "en",
"theme": "alabaster",
"extensions": ["sphinx.ext.autodoc", "sphinx.ext.viewcode"],
}


@pytest.fixture
def sample_rst_content() -> str:
"""Provide sample reStructuredText content for testing."""
return """
Sample Documentation
====================

This is a sample RST document for testing.

Section 1
---------

Some content here.

.. code-block:: python

def hello_world():
print("Hello, World!")

Section 2
---------

More content here.
"""


@pytest.fixture
def sphinx_build_dir(temp_dir: Path) -> Path:
"""Create a mock Sphinx build directory structure."""
build_path = temp_dir / "build"
build_path.mkdir()
(build_path / "html").mkdir()
(build_path / "doctrees").mkdir()
return build_path


@pytest.fixture
def source_dir(temp_dir: Path) -> Path:
"""Create a mock source directory with basic structure."""
source_path = temp_dir / "source"
source_path.mkdir()

# Create conf.py
conf_content = '''
project = 'Test Project'
copyright = '2024, Test Author'
author = 'Test Author'
extensions = []
templates_path = ['_templates']
exclude_patterns = []
html_theme = 'alabaster'
'''
(source_path / "conf.py").write_text(conf_content)

# Create index.rst
index_content = '''
Welcome to Test Project's documentation!
========================================

.. toctree::
:maxdepth: 2
:caption: Contents:

Indices and tables
==================

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
'''
(source_path / "index.rst").write_text(index_content)

return source_path


@pytest.fixture
def mock_sphinx_app(mocker):
"""Mock Sphinx application object."""
app = mocker.Mock()
app.config = mocker.Mock()
app.config.project = "Test Project"
app.config.version = "1.0.0"
app.config.release = "1.0.0"
app.config.author = "Test Author"
app.config.language = "en"
app.builder = mocker.Mock()
app.builder.name = "html"
return app


@pytest.fixture(autouse=True)
def reset_environment():
"""Reset environment variables before each test."""
original_env = dict(os.environ)
yield
os.environ.clear()
os.environ.update(original_env)


@pytest.fixture
def sample_makefile_content() -> str:
"""Provide sample Makefile content."""
return """# Minimal makefile for Sphinx documentation
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = source
BUILDDIR = build

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
"""
Empty file added tests/integration/__init__.py
Empty file.
112 changes: 112 additions & 0 deletions tests/test_setup_validation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import subprocess
import sys
from pathlib import Path

import pytest


class TestSetupValidation:
"""Validation tests to ensure the testing infrastructure is properly configured."""

def test_pytest_installed(self):
"""Verify pytest is installed and importable."""
import pytest
assert pytest.__version__

def test_pytest_cov_installed(self):
"""Verify pytest-cov is installed and importable."""
import pytest_cov
assert pytest_cov.__version__

def test_pytest_mock_installed(self):
"""Verify pytest-mock is installed and importable."""
try:
import pytest_mock
# pytest-mock doesn't have __version__, just verify it imports
assert pytest_mock
except ImportError:
pytest.fail("pytest-mock is not installed")

def test_project_structure_exists(self):
"""Verify the expected project structure exists."""
project_root = Path(__file__).parent.parent

# Check main directories
assert project_root.exists()
assert (project_root / "tests").exists()
assert (project_root / "tests" / "unit").exists()
assert (project_root / "tests" / "integration").exists()

# Check configuration files
assert (project_root / "pyproject.toml").exists()
assert (project_root / "tests" / "conftest.py").exists()

def test_pyproject_toml_valid(self):
"""Verify pyproject.toml is valid and contains expected sections."""
project_root = Path(__file__).parent.parent
pyproject_path = project_root / "pyproject.toml"

assert pyproject_path.exists()

content = pyproject_path.read_text()
assert "[tool.poetry]" in content
assert "[tool.pytest.ini_options]" in content
assert "[tool.coverage.run]" in content
assert "[tool.coverage.report]" in content

@pytest.mark.unit
def test_unit_marker(self):
"""Test that the unit marker works correctly."""
assert True

@pytest.mark.integration
def test_integration_marker(self):
"""Test that the integration marker works correctly."""
assert True

@pytest.mark.slow
def test_slow_marker(self):
"""Test that the slow marker works correctly."""
assert True

def test_conftest_fixtures_available(self, temp_dir, mock_config):
"""Verify that fixtures from conftest.py are available."""
assert temp_dir.exists()
assert temp_dir.is_dir()

assert isinstance(mock_config, dict)
assert "project_name" in mock_config
assert mock_config["project_name"] == "test_project"

def test_sphinx_fixtures_available(self, source_dir, sphinx_build_dir):
"""Verify Sphinx-specific fixtures are available."""
assert source_dir.exists()
assert (source_dir / "conf.py").exists()
assert (source_dir / "index.rst").exists()

assert sphinx_build_dir.exists()
assert (sphinx_build_dir / "html").exists()
assert (sphinx_build_dir / "doctrees").exists()

def test_coverage_configuration(self):
"""Verify coverage is properly configured."""
project_root = Path(__file__).parent.parent
pyproject_path = project_root / "pyproject.toml"

content = pyproject_path.read_text()

# Check coverage settings
assert "--cov-branch" in content
assert "--cov-report=html" in content
assert "--cov-report=xml" in content

def test_poetry_run_commands(self):
"""Verify Poetry run commands work correctly."""
# Test that we can run pytest through poetry
result = subprocess.run(
["poetry", "run", "pytest", "--version"],
capture_output=True,
text=True
)
assert result.returncode == 0
assert "pytest" in result.stdout
Empty file added tests/unit/__init__.py
Empty file.