From bceb11cb8700dd2918b42ba79052aea82c954dc2 Mon Sep 17 00:00:00 2001 From: knowlen Date: Tue, 15 Jul 2025 23:58:44 -0700 Subject: [PATCH 1/3] Fix ReadTheDocs build: Remove incorrect sitemap plugin - Removed non-existent mkdocs-sitemap-plugin from requirements - Removed sitemap plugin configuration from mkdocs.yml - MkDocs has built-in sitemap generation (no plugin needed) - Moved minify options to the correct minify plugin section - Updated test to check for site_url instead of sitemap plugin The sitemap.xml is automatically generated by MkDocs when site_url is set. --- mkdocs.yml | 5 ----- tests/docs/test_seo_links.py | 8 ++++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index 6bf7505..2f1e513 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -150,11 +150,6 @@ plugins: - minify: minify_html: true minify_js: true - - # SEO Enhancements - - sitemap: - changefreq: weekly - priority: 0.5 minify_css: true htmlmin_opts: remove_comments: true diff --git a/tests/docs/test_seo_links.py b/tests/docs/test_seo_links.py index 35e8424..8ef9f51 100644 --- a/tests/docs/test_seo_links.py +++ b/tests/docs/test_seo_links.py @@ -66,13 +66,13 @@ def test_search_terms_format(self): assert "Python" in search_terms_line def test_mkdocs_sitemap_config(self): - """Test that sitemap is configured in mkdocs.yml.""" + """Test that site_url is configured for sitemap generation.""" mkdocs_path = Path(__file__).parent.parent.parent / "mkdocs.yml" content = mkdocs_path.read_text() - # Check for sitemap plugin - assert "- sitemap:" in content, "Sitemap plugin not configured" - assert "changefreq:" in content, "Sitemap changefreq not configured" + # Check for site_url which is required for sitemap generation + assert "site_url:" in content, "site_url not configured (required for sitemap)" + assert "esologs-python.readthedocs.io" in content, "Site URL should be set" def test_mkdocs_social_meta(self): """Test that OpenGraph meta tags are configured.""" From 779497d2c912b87741ca149eb1bcf3b5c0cd934b Mon Sep 17 00:00:00 2001 From: knowlen Date: Wed, 16 Jul 2025 00:15:53 -0700 Subject: [PATCH 2/3] Remove non-existent mkdocs-sitemap-plugin from dependencies - Removed mkdocs-sitemap-plugin from docs/requirements.txt - Removed mkdocs-sitemap-plugin from pyproject.toml - This package doesn't exist on PyPI and was causing build failures The previous commit only fixed mkdocs.yml but missed these critical files. --- docs/requirements.txt | 1 - pyproject.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/docs/requirements.txt b/docs/requirements.txt index fa285cf..a1b4147 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -6,7 +6,6 @@ mkdocs-material>=9.4.0 mkdocs-minify-plugin>=0.7.0 mkdocs-git-revision-date-localized-plugin>=1.2.0 pymdown-extensions>=10.0.0 -mkdocs-sitemap-plugin>=1.0.0 # Required for the ESO Logs Python package itself requests>=2.25.0 diff --git a/pyproject.toml b/pyproject.toml index b2cb6b3..dc9b254 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -62,7 +62,6 @@ docs = [ "mkdocs-minify-plugin>=0.7.0", "mkdocs-git-revision-date-localized-plugin>=1.2.0", "pymdown-extensions>=10.0.0", - "mkdocs-sitemap-plugin>=1.0.0", ] all = [ "esologs-python[dev,websockets,pandas,docs]", From aef1b784539763750c9996d51f4c263b43c67342 Mon Sep 17 00:00:00 2001 From: knowlen Date: Wed, 16 Jul 2025 00:18:35 -0700 Subject: [PATCH 3/3] Add integration tests for sitemap.xml generation - Added test_sitemap_generation.py with comprehensive sitemap tests - Verifies MkDocs generates valid sitemap.xml - Validates XML structure and sitemap protocol - Checks all URLs start with correct domain - Ensures site_url is properly configured - Enhanced test_seo_links.py with sitemap requirements test - Verifies MkDocs version supports sitemap (>= 0.13.0) - Confirms site_url is set in mkdocs.yml - Ensures no sitemap plugin is configured (uses built-in) - Updated documentation tests README with new test files These tests will help prevent future sitemap-related issues. --- tests/docs/README.md | 4 +- tests/docs/test_seo_links.py | 23 +++++ tests/docs/test_sitemap_generation.py | 126 ++++++++++++++++++++++++++ 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 tests/docs/test_sitemap_generation.py diff --git a/tests/docs/README.md b/tests/docs/README.md index c512b46..935bda1 100644 --- a/tests/docs/README.md +++ b/tests/docs/README.md @@ -28,9 +28,11 @@ This directory contains tests that validate code examples from: - `test_report_analysis_examples.py` - Tests all examples from report analysis API reference - `test_report_search_examples.py` - Tests all examples from report search API reference - `test_system_examples.py` - Tests all examples from system API reference +- `test_seo_links.py` - Tests SEO metadata, links, and documentation requirements +- `test_sitemap_generation.py` - Tests sitemap.xml generation and validation - `conftest.py` - Shared test fixtures and configuration -**Total: 98 tests** across all documentation files +**Total: 108 tests** across all documentation files ## Running Tests diff --git a/tests/docs/test_seo_links.py b/tests/docs/test_seo_links.py index 8ef9f51..b5dc8c4 100644 --- a/tests/docs/test_seo_links.py +++ b/tests/docs/test_seo_links.py @@ -94,3 +94,26 @@ def test_robots_txt_exists(self): assert "User-agent:" in content, "User-agent directive missing" assert "Sitemap:" in content, "Sitemap directive missing" assert "esologs-python.readthedocs.io" in content, "Site URL missing" + + def test_sitemap_requirements(self): + """Test that all requirements for sitemap generation are met.""" + # Check MkDocs version supports sitemap (>= 0.13.0) + import mkdocs + + version_parts = mkdocs.__version__.split(".") + major = int(version_parts[0]) + minor = int(version_parts[1]) if len(version_parts) > 1 else 0 + + assert major > 0 or ( + major == 0 and minor >= 13 + ), "MkDocs version too old for sitemap generation" + + # Check site_url is set + mkdocs_path = Path(__file__).parent.parent.parent / "mkdocs.yml" + content = mkdocs_path.read_text() + assert "site_url:" in content, "site_url must be set for sitemap generation" + + # Ensure no sitemap plugin is configured (uses built-in) + assert ( + "- sitemap:" not in content or "# SEO Enhancements" not in content + ), "Sitemap plugin should not be configured (use built-in)" diff --git a/tests/docs/test_sitemap_generation.py b/tests/docs/test_sitemap_generation.py new file mode 100644 index 0000000..ec7efb2 --- /dev/null +++ b/tests/docs/test_sitemap_generation.py @@ -0,0 +1,126 @@ +"""Test sitemap.xml generation in MkDocs builds.""" + +import subprocess +import tempfile +import xml.etree.ElementTree as ET +from pathlib import Path + +import pytest + + +class TestSitemapGeneration: + """Test that MkDocs generates sitemap.xml correctly.""" + + @pytest.mark.integration + def test_mkdocs_generates_sitemap(self): + """Test that MkDocs build generates a valid sitemap.xml file.""" + # Get the project root directory + project_root = Path(__file__).parent.parent.parent + + # Use a temporary directory for the build + with tempfile.TemporaryDirectory() as temp_dir: + # Run mkdocs build + result = subprocess.run( + ["mkdocs", "build", "--site-dir", temp_dir, "--clean"], + cwd=project_root, + capture_output=True, + text=True, + ) + + # Check build succeeded + assert result.returncode == 0, f"MkDocs build failed: {result.stderr}" + + # Check sitemap.xml exists + sitemap_path = Path(temp_dir) / "sitemap.xml" + assert sitemap_path.exists(), "sitemap.xml was not generated" + + # Validate sitemap content + tree = ET.parse(sitemap_path) + root = tree.getroot() + + # Check root element + assert root.tag.endswith("urlset"), "Invalid sitemap root element" + + # Check namespace + expected_ns = "http://www.sitemaps.org/schemas/sitemap/0.9" + assert expected_ns in root.tag, f"Missing sitemap namespace in {root.tag}" + + # Check for URL entries + urls = root.findall(".//{http://www.sitemaps.org/schemas/sitemap/0.9}url") + assert len(urls) > 0, "No URLs found in sitemap" + + # Check each URL has required elements + for url in urls: + loc = url.find("{http://www.sitemaps.org/schemas/sitemap/0.9}loc") + assert loc is not None, "URL entry missing element" + assert loc.text, "URL entry has empty element" + assert loc.text.startswith( + "https://esologs-python.readthedocs.io" + ), f"Invalid URL: {loc.text}" + + # Check specific pages are included + url_texts = [ + url.find("{http://www.sitemaps.org/schemas/sitemap/0.9}loc").text + for url in urls + ] + assert any( + "https://esologs-python.readthedocs.io/" == url for url in url_texts + ), "Home page not in sitemap" + + def test_mkdocs_site_url_configured(self): + """Test that site_url is properly configured in mkdocs.yml.""" + mkdocs_path = Path(__file__).parent.parent.parent / "mkdocs.yml" + content = mkdocs_path.read_text() + + # Parse for site_url + site_url_line = None + for line in content.split("\n"): + if line.strip().startswith("site_url:"): + site_url_line = line + break + + assert site_url_line is not None, "site_url not found in mkdocs.yml" + + # Extract URL + site_url = site_url_line.split(":", 1)[1].strip() + assert site_url == "https://esologs-python.readthedocs.io/" + + @pytest.mark.integration + def test_sitemap_xml_validation(self): + """Test that generated sitemap.xml is valid XML and follows sitemap protocol.""" + project_root = Path(__file__).parent.parent.parent + + with tempfile.TemporaryDirectory() as temp_dir: + # Build docs + subprocess.run( + ["mkdocs", "build", "--site-dir", temp_dir, "--clean"], + cwd=project_root, + capture_output=True, + ) + + sitemap_path = Path(temp_dir) / "sitemap.xml" + if not sitemap_path.exists(): + pytest.skip("Sitemap not generated") + + # Read and validate XML structure + with open(sitemap_path) as f: + content = f.read() + + # Basic XML validation + assert content.startswith("" in content, "Unclosed urlset element" + + # Check for sitemap namespace + assert "xmlns" in content, "Missing namespace declaration" + assert "sitemaps.org/schemas/sitemap" in content, "Missing sitemap schema" + + # Check structure + assert "" in content, "No URL entries found" + assert "" in content, "No location elements found" + + # Count URLs + url_count = content.count("") + loc_count = content.count("") + assert url_count == loc_count, "Mismatch between url and loc elements" + assert url_count > 5, f"Too few URLs in sitemap: {url_count}"