"""Test the HTML builder and check output against XPath.""" import re from pathlib import Path import pytest import sphinx.builders.html from sphinx.builders.html._assets import _file_checksum from sphinx.errors import ThemeError @pytest.mark.sphinx('html', testroot='html_assets') def test_html_assets(app): app.build(force_all=True) # exclude_path and its family assert not (app.outdir / 'static' / 'index.html').exists() assert not (app.outdir / 'extra' / 'index.html').exists() # html_static_path assert not (app.outdir / '_static' / '.htaccess').exists() assert not (app.outdir / '_static' / '.htpasswd').exists() assert (app.outdir / '_static' / 'API.html').exists() assert (app.outdir / '_static' / 'API.html').read_text(encoding='utf8') == 'Sphinx-1.4.4' assert (app.outdir / '_static' / 'css' / 'style.css').exists() assert (app.outdir / '_static' / 'js' / 'custom.js').exists() assert (app.outdir / '_static' / 'rimg.png').exists() assert not (app.outdir / '_static' / '_build' / 'index.html').exists() assert (app.outdir / '_static' / 'background.png').exists() assert not (app.outdir / '_static' / 'subdir' / '.htaccess').exists() assert not (app.outdir / '_static' / 'subdir' / '.htpasswd').exists() # html_extra_path assert (app.outdir / '.htaccess').exists() assert not (app.outdir / '.htpasswd').exists() assert (app.outdir / 'API.html_t').exists() assert (app.outdir / 'css/style.css').exists() assert (app.outdir / 'rimg.png').exists() assert not (app.outdir / '_build' / 'index.html').exists() assert (app.outdir / 'background.png').exists() assert (app.outdir / 'subdir' / '.htaccess').exists() assert not (app.outdir / 'subdir' / '.htpasswd').exists() # html_css_files content = (app.outdir / 'index.html').read_text(encoding='utf8') assert '' in content assert ('' in content) # html_js_files assert '' in content assert ('' in content) @pytest.mark.sphinx('html', testroot='html_assets') def test_assets_order(app, monkeypatch): monkeypatch.setattr(sphinx.builders.html, '_file_checksum', lambda o, f: '') app.add_css_file('normal.css') app.add_css_file('early.css', priority=100) app.add_css_file('late.css', priority=750) app.add_css_file('lazy.css', priority=900) app.add_js_file('normal.js') app.add_js_file('early.js', priority=100) app.add_js_file('late.js', priority=750) app.add_js_file('lazy.js', priority=900) app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') # css_files expected = [ '_static/early.css', '_static/pygments.css', '_static/alabaster.css', 'https://example.com/custom.css', '_static/normal.css', '_static/late.css', '_static/css/style.css', '_static/lazy.css', ] pattern = '.*'.join(f'href="{re.escape(f)}"' for f in expected) assert re.search(pattern, content, re.DOTALL), content # js_files expected = [ '_static/early.js', '_static/doctools.js', '_static/sphinx_highlight.js', 'https://example.com/script.js', '_static/normal.js', '_static/late.js', '_static/js/custom.js', '_static/lazy.js', ] pattern = '.*'.join(f'src="{re.escape(f)}"' for f in expected) assert re.search(pattern, content, re.DOTALL), content @pytest.mark.sphinx('html', testroot='html_file_checksum') def test_file_checksum(app): app.add_css_file('stylesheet-a.css') app.add_css_file('stylesheet-b.css') app.add_css_file('https://example.com/custom.css') app.add_js_file('script.js') app.add_js_file('empty.js') app.add_js_file('https://example.com/script.js') app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') # checksum for local files assert '' in content assert '' in content assert '' in content # empty files have no checksum assert '' in content # no checksum for hyperlinks assert '' in content assert '' in content def test_file_checksum_query_string(): with pytest.raises(ThemeError, match='Local asset file paths must not contain query strings'): _file_checksum(Path(), 'with_query_string.css?dead_parrots=1') with pytest.raises(ThemeError, match='Local asset file paths must not contain query strings'): _file_checksum(Path(), 'with_query_string.js?dead_parrots=1') with pytest.raises(ThemeError, match='Local asset file paths must not contain query strings'): _file_checksum(Path.cwd(), '_static/with_query_string.css?dead_parrots=1') with pytest.raises(ThemeError, match='Local asset file paths must not contain query strings'): _file_checksum(Path.cwd(), '_static/with_query_string.js?dead_parrots=1') @pytest.mark.sphinx('html', testroot='html_assets') def test_javscript_loading_method(app): app.add_js_file('normal.js') app.add_js_file('early.js', loading_method='async') app.add_js_file('late.js', loading_method='defer') app.build(force_all=True) content = (app.outdir / 'index.html').read_text(encoding='utf8') assert '' in content assert '' in content assert '' in content