Hello community, here is the log from the commit of package python-pytest-html for openSUSE:Factory checked in at 2020-03-19 19:48:15 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-pytest-html (Old) and /work/SRC/openSUSE:Factory/.python-pytest-html.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pytest-html" Thu Mar 19 19:48:15 2020 rev:9 rq:785474 version:2.1.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-pytest-html/python-pytest-html.changes 2020-03-04 09:41:25.489964443 +0100 +++ /work/SRC/openSUSE:Factory/.python-pytest-html.new.3160/python-pytest-html.changes 2020-03-19 19:51:20.932220461 +0100 @@ -1,0 +2,10 @@ +Mon Mar 16 08:28:48 UTC 2020 - Tomáš Chvátal <[email protected]> + +- Update to 2.1.0: + * Added support for MP4 video format. (#260) + * Added support for sorting metadata by key. (#245) + * Added support for rendering reports collapsed (#239) + * Added extra fixture (#269) + * Added ability to change report title using hook (#270) + +------------------------------------------------------------------- Old: ---- pytest-html-2.0.1.tar.gz New: ---- pytest-html-2.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pytest-html.spec ++++++ --- /var/tmp/diff_new_pack.AY1ZeH/_old 2020-03-19 19:51:23.808222122 +0100 +++ /var/tmp/diff_new_pack.AY1ZeH/_new 2020-03-19 19:51:23.812222124 +0100 @@ -19,7 +19,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} %define skip_python2 1 Name: python-pytest-html -Version: 2.0.1 +Version: 2.1.0 Release: 0 Summary: Pytest plugin for generating HTML reports License: MPL-2.0 ++++++ pytest-html-2.0.1.tar.gz -> pytest-html-2.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/CHANGES.rst new/pytest-html-2.1.0/CHANGES.rst --- old/pytest-html-2.0.1/CHANGES.rst 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/CHANGES.rst 2020-03-11 13:38:36.000000000 +0100 @@ -1,19 +1,41 @@ Release Notes ------------- +**2.1.0 (2020-03-09)** + +* Added support for MP4 video format. (`#260 <https://github.com/pytest-dev/pytest-html/pull/260>`_) + + * Thanks to `@ExaltedBagel <https://github.com/ExaltedBagel>`_ for the PR + +* Added support for sorting metadata by key. (`#245 <https://github.com/pytest-dev/pytest-html/issues/245>`_) + + * Thanks to `@ssbarnea <https://github.com/ssbarnea>`_ for reporting and `@ExaltedBagel <https://github.com/ExaltedBagel>`_ for the fix + +* Added support for rendering reports collapsed (`#239 <https://github.com/pytest-dev/pytest-html/issues/239>`_) + + * Thanks to `@Wramberg <https://github.com/Wramberg>`_ for suggesting this enhancement + +* Added `extra` fixture (`#269 <https://github.com/pytest-dev/pytest-html/pull/269>`_) + + * Thanks to `@christiansandberg <https://github.com/christiansandberg>`_ for the PR + +* Added ability to change report title using hook (`#270 <https://github.com/pytest-dev/pytest-html/pull/270>`_) + + * Thanks to `@werdeil <https://github.com/werdeil>`_ for the PR + **2.0.1 (2019-10-05)** * Properly check for presence of CSS file. (`#246 <https://github.com/pytest-dev/pytest-html/issues/246>`_) - * Thanks to `@wanam <https://github.com/wanam>`_ for reporting, and `@krzysztof-pawlik-gat <https://github.com/krzysztof-pawlik-gat>`_ for the fix + * Thanks to `@wanam <https://github.com/wanam>`_ for reporting, and `@krzysztof-pawlik-gat <https://github.com/krzysztof-pawlik-gat>`_ for the fix * Added support for UTF-8 display. (`#244 <https://github.com/pytest-dev/pytest-html/pull/244>`_) - * Thanks to `@Izhu666 <https://github.com/lzhu666>`_ for the PR + * Thanks to `@Izhu666 <https://github.com/lzhu666>`_ for the PR * Fix initial sort on column. (`#247 <https://github.com/pytest-dev/pytest-html/issues/247>`_) - * Thanks to `@wanam <https://github.com/wanam>`_ for reporting and fixing + * Thanks to `@wanam <https://github.com/wanam>`_ for reporting and fixing **2.0.0 (2019-09-09)** diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/PKG-INFO new/pytest-html-2.1.0/PKG-INFO --- old/pytest-html-2.0.1/PKG-INFO 2019-11-18 22:26:15.000000000 +0100 +++ new/pytest-html-2.1.0/PKG-INFO 2020-03-11 13:38:57.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: pytest-html -Version: 2.0.1 +Version: 2.1.0 Summary: pytest plugin for generating HTML reports Home-page: https://github.com/pytest-dev/pytest-html Author: Dave Hunt @@ -95,6 +95,19 @@ $ pytest --html=report.html --css=highcontrast.css --css=accessible.css + Report Title + ~~~~~~~~~~~~ + + By default report title will be the filename of the report, you can edit it by using the :code: `pytest_html_report_title` hook: + + .. code-block:: python + + import pytest + from py.xml import html + + def pytest_html_report_title(report) + report.title = "My very own title!" + Environment ~~~~~~~~~~~ @@ -187,6 +200,17 @@ extra.append(pytest_html.extras.text('some string', name='Different title')) + It is also possible to use the fixture :code:`extra` to add content directly + in a test function without implementing hooks. These will generally end up + before any extras added by plugins. + + .. code-block:: python + + from pytest_html import extras + + def test_extra(extra): + extra.append(extras.text('some string')) + Modifying the results table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -248,8 +272,15 @@ By default, all rows in the **Results** table will be expanded except those that have :code:`Passed`. - This behavior can be customized with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`. + This behavior can be customized either with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped` + or by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc). + + .. code-block:: ini + + [pytest] + render_collapsed = True + **NOTE:** Setting :code:`render_collapsed` will, unlike the query parameter, affect all statuses. Screenshots ----------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/README.rst new/pytest-html-2.1.0/README.rst --- old/pytest-html-2.0.1/README.rst 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/README.rst 2020-03-11 13:38:36.000000000 +0100 @@ -87,6 +87,19 @@ $ pytest --html=report.html --css=highcontrast.css --css=accessible.css +Report Title +~~~~~~~~~~~~ + +By default report title will be the filename of the report, you can edit it by using the :code: `pytest_html_report_title` hook: + +.. code-block:: python + + import pytest + from py.xml import html + + def pytest_html_report_title(report) + report.title = "My very own title!" + Environment ~~~~~~~~~~~ @@ -179,6 +192,17 @@ extra.append(pytest_html.extras.text('some string', name='Different title')) +It is also possible to use the fixture :code:`extra` to add content directly +in a test function without implementing hooks. These will generally end up +before any extras added by plugins. + +.. code-block:: python + + from pytest_html import extras + + def test_extra(extra): + extra.append(extras.text('some string')) + Modifying the results table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -240,8 +264,15 @@ By default, all rows in the **Results** table will be expanded except those that have :code:`Passed`. -This behavior can be customized with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`. +This behavior can be customized either with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped` +or by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc). + +.. code-block:: ini + + [pytest] + render_collapsed = True +**NOTE:** Setting :code:`render_collapsed` will, unlike the query parameter, affect all statuses. Screenshots ----------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html/extras.py new/pytest-html-2.1.0/pytest_html/extras.py --- old/pytest-html-2.0.1/pytest_html/extras.py 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html/extras.py 2020-03-11 13:38:36.000000000 +0100 @@ -7,6 +7,7 @@ FORMAT_JSON = "json" FORMAT_TEXT = "text" FORMAT_URL = "url" +FORMAT_VIDEO = "video" def extra(content, format, name=None, mime_type=None, extension=None): @@ -49,3 +50,11 @@ def url(content, name="URL"): return extra(content, FORMAT_URL, name) + + +def video(content, name="Video", mime_type="video/mp4", extension="mp4"): + return extra(content, FORMAT_VIDEO, name, mime_type, extension) + + +def mp4(content, name="Video"): + return video(content, name) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html/hooks.py new/pytest-html-2.1.0/pytest_html/hooks.py --- old/pytest-html-2.0.1/pytest_html/hooks.py 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html/hooks.py 2020-03-11 13:38:36.000000000 +0100 @@ -3,6 +3,10 @@ # file, You can obtain one at http://mozilla.org/MPL/2.0/. +def pytest_html_report_title(report): + """ Called before adding the title to the report """ + + def pytest_html_results_summary(prefix, summary, postfix): """ Called before adding the summary section to the report """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html/plugin.py new/pytest-html-2.1.0/pytest_html/plugin.py --- old/pytest-html-2.0.1/pytest_html/plugin.py 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html/plugin.py 2020-03-11 13:38:36.000000000 +0100 @@ -15,6 +15,7 @@ import re from html import escape +import pytest try: from ansi2html import Ansi2HTMLConverter, style @@ -62,6 +63,12 @@ default=[], help="append given css file content to report style file.", ) + parser.addini( + "render_collapsed", + type="bool", + default=False, + help="Open the report with all rows collapsed. Useful for very large reports", + ) def pytest_configure(config): @@ -83,6 +90,29 @@ config.pluginmanager.unregister(html) [email protected](tryfirst=True, hookwrapper=True) +def pytest_runtest_makereport(item, call): + outcome = yield + report = outcome.get_result() + if report.when == "call": + fixture_extras = item.funcargs.get("extra", []) + plugin_extras = getattr(report, "extra", []) + report.extra = fixture_extras + plugin_extras + + [email protected] +def extra(): + """Add details to the HTML reports. + + .. code-block:: python + + import pytest_html + def test_foo(extra): + extra.append(pytest_html.extras.url('http://www.example.com/')) + """ + return [] + + def data_uri(content, mime_type="text/plain", charset="utf-8"): data = b64encode(content.encode(charset)).decode("ascii") return f"data:{mime_type};charset={charset};base64,{data}" @@ -93,6 +123,7 @@ logfile = os.path.expanduser(os.path.expandvars(logfile)) self.logfile = os.path.abspath(logfile) self.test_logs = [] + self.title = os.path.basename(self.logfile) self.results = [] self.errors = self.failed = 0 self.passed = self.skipped = 0 @@ -137,9 +168,13 @@ ) if len(cells) > 0: + tr_class = None + if self.config.getini("render_collapsed"): + tr_class = "collapsed" self.row_table = html.tr(cells) self.row_extra = html.tr( - html.td(self.additional_html, class_="extra", colspan=len(cells)) + html.td(self.additional_html, class_="extra", colspan=len(cells)), + class_=tr_class, ) def __lt__(self, other): @@ -181,33 +216,7 @@ def append_extra_html(self, extra, extra_index, test_index): href = None if extra.get("format") == extras.FORMAT_IMAGE: - content = extra.get("content") - try: - is_uri_or_path = content.startswith(("file", "http")) or isfile( - content - ) - except ValueError: - # On Windows, os.path.isfile throws this exception when - # passed a b64 encoded image. - is_uri_or_path = False - if is_uri_or_path: - if self.self_contained: - warnings.warn( - "Self-contained HTML report " - "includes link to external " - "resource: {}".format(content) - ) - html_div = html.a(html.img(src=content), href=content) - elif self.self_contained: - src = "data:{};base64,{}".format(extra.get("mime_type"), content) - html_div = html.img(src=src) - else: - content = b64decode(content.encode("utf-8")) - href = src = self.create_asset( - content, extra_index, test_index, extra.get("extension"), "wb" - ) - html_div = html.a(html.img(src=src), href=href) - self.additional_html.append(html.div(html_div, class_="image")) + self._append_image(extra, extra_index, test_index) elif extra.get("format") == extras.FORMAT_HTML: self.additional_html.append(html.div(raw(extra.get("content")))) @@ -235,6 +244,9 @@ elif extra.get("format") == extras.FORMAT_URL: href = extra.get("content") + elif extra.get("format") == extras.FORMAT_VIDEO: + self._append_video(extra, extra_index, test_index) + if href is not None: self.links_html.append( html.a( @@ -276,6 +288,52 @@ log.append("No log output captured.") additional_html.append(log) + def _make_media_html_div( + self, extra, extra_index, test_index, base_extra_string, base_extra_class + ): + content = extra.get("content") + try: + is_uri_or_path = content.startswith(("file", "http")) or isfile(content) + except ValueError: + # On Windows, os.path.isfile throws this exception when + # passed a b64 encoded image. + is_uri_or_path = False + if is_uri_or_path: + if self.self_contained: + warnings.warn( + "Self-contained HTML report " + "includes link to external " + f"resource: {content}" + ) + + html_div = html.a( + raw(base_extra_string.format(extra.get("content"))), href=content + ) + elif self.self_contained: + src = f"data:{extra.get('mime_type')};base64,{content}" + html_div = raw(base_extra_string.format(src)) + else: + content = b64decode(content.encode("utf-8")) + href = src = self.create_asset( + content, extra_index, test_index, extra.get("extension"), "wb" + ) + html_div = html.a(class_=base_extra_class, target="_blank", href=href) + return html_div + + def _append_image(self, extra, extra_index, test_index): + image_base = '<img src="{}"/>' + html_div = self._make_media_html_div( + extra, extra_index, test_index, image_base, "image" + ) + self.additional_html.append(html.div(html_div, class_="image")) + + def _append_video(self, extra, extra_index, test_index): + video_base = '<video controls><source src="{}" type="video/mp4"></video>' + html_div = self._make_media_html_div( + extra, extra_index, test_index, video_base, "video" + ) + self.additional_html.append(html.div(html_div, class_="video")) + def _appendrow(self, outcome, report): result = self.TestResult(outcome, report, self.logfile, self.config) if result.row_table is not None: @@ -457,9 +515,11 @@ __name__, os.path.join("resources", "main.js") ).decode("utf-8") + session.config.hook.pytest_html_report_title(report=self) + body = html.body( html.script(raw(main_js)), - html.h1(os.path.basename(self.logfile)), + html.h1(self.title), html.p( "Report generated on {} at {} by ".format( generated.strftime("%d-%b-%Y"), generated.strftime("%H:%M:%S") @@ -505,8 +565,12 @@ if isinstance(value, str) and value.startswith("http"): value = html.a(value, href=value, target="_blank") elif isinstance(value, (list, tuple, set)): - value = ", ".join(str(i) for i in value) - rows.append(html.tr(html.td(key), html.td(value))) + value = ", ".join(str(i) for i in sorted(map(str, value))) + elif isinstance(value, dict): + sorted_dict = {k: value[k] for k in sorted(value)} + value = json.dumps(sorted_dict) + raw_value_string = raw(str(value)) + rows.append(html.tr(html.td(key), html.td(raw_value_string))) environment.append(html.table(rows, id="environment")) return environment diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html/resources/main.js new/pytest-html-2.1.0/pytest_html/resources/main.js --- old/pytest-html-2.0.1/pytest_html/resources/main.js 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html/resources/main.js 2020-03-11 13:38:36.000000000 +0100 @@ -81,7 +81,9 @@ var collapsed = get_query_parameter('collapsed') || 'Passed'; var extras = elem.parentNode.nextElementSibling; var expandcollapse = document.createElement("span"); - if (collapsed.includes(elem.innerHTML)) { + if (extras.classList.contains("collapsed")) { + expandcollapse.classList.add("expander") + } else if (collapsed.includes(elem.innerHTML)) { extras.classList.add("collapsed"); expandcollapse.classList.add("expander"); } else { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html/resources/style.css new/pytest-html-2.1.0/pytest_html/resources/style.css --- old/pytest-html-2.0.1/pytest_html/resources/style.css 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html/resources/style.css 2020-03-11 13:38:36.000000000 +0100 @@ -113,6 +113,19 @@ div.image img { width: 320px } +div.video { + border: 1px solid #e6e6e6; + float: right; + height: 240px; + margin-left: 5px; + overflow: hidden; + width: 320px +} +div.video video { + overflow: hidden; + width: 320px; + height: 240px; +} .collapsed { display: none; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/pytest_html.egg-info/PKG-INFO new/pytest-html-2.1.0/pytest_html.egg-info/PKG-INFO --- old/pytest-html-2.0.1/pytest_html.egg-info/PKG-INFO 2019-11-18 22:26:14.000000000 +0100 +++ new/pytest-html-2.1.0/pytest_html.egg-info/PKG-INFO 2020-03-11 13:38:57.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.2 Name: pytest-html -Version: 2.0.1 +Version: 2.1.0 Summary: pytest plugin for generating HTML reports Home-page: https://github.com/pytest-dev/pytest-html Author: Dave Hunt @@ -95,6 +95,19 @@ $ pytest --html=report.html --css=highcontrast.css --css=accessible.css + Report Title + ~~~~~~~~~~~~ + + By default report title will be the filename of the report, you can edit it by using the :code: `pytest_html_report_title` hook: + + .. code-block:: python + + import pytest + from py.xml import html + + def pytest_html_report_title(report) + report.title = "My very own title!" + Environment ~~~~~~~~~~~ @@ -187,6 +200,17 @@ extra.append(pytest_html.extras.text('some string', name='Different title')) + It is also possible to use the fixture :code:`extra` to add content directly + in a test function without implementing hooks. These will generally end up + before any extras added by plugins. + + .. code-block:: python + + from pytest_html import extras + + def test_extra(extra): + extra.append(extras.text('some string')) + Modifying the results table ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -248,8 +272,15 @@ By default, all rows in the **Results** table will be expanded except those that have :code:`Passed`. - This behavior can be customized with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped`. + This behavior can be customized either with a query parameter: :code:`?collapsed=Passed,XFailed,Skipped` + or by setting the :code:`render_collapsed` in a configuration file (pytest.ini, setup.cfg, etc). + + .. code-block:: ini + + [pytest] + render_collapsed = True + **NOTE:** Setting :code:`render_collapsed` will, unlike the query parameter, affect all statuses. Screenshots ----------- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pytest-html-2.0.1/testing/test_pytest_html.py new/pytest-html-2.1.0/testing/test_pytest_html.py --- old/pytest-html-2.0.1/testing/test_pytest_html.py 2019-11-18 22:25:48.000000000 +0100 +++ new/pytest-html-2.1.0/testing/test_pytest_html.py 2020-03-11 13:38:36.000000000 +0100 @@ -418,6 +418,35 @@ self.test_extra_image(testdir, "image/png", "png") assert mock_isfile.call_count == 1 + @pytest.mark.parametrize("mime_type, extension", [("video/mp4", "mp4")]) + def test_extra_video(self, testdir, mime_type, extension): + content = str(random.random()) + testdir.makeconftest( + f""" + import pytest + @pytest.hookimpl(hookwrapper=True) + def pytest_runtest_makereport(item, call): + outcome = yield + report = outcome.get_result() + if report.when == 'call': + from pytest_html import extras + report.extra = [extras.{extension}('{content}')] + """ + ) + testdir.makepyfile("def test_pass(): pass") + result, html = run(testdir, "report.html", "--self-contained-html") + assert result.ret == 0 + src = f"data:{mime_type};base64,{content}" + assert ( + f'<video controls><source src="{src}" type="{mime_type}"></video>' in html + ) + + def test_extra_video_windows(self, mocker, testdir): + mock_isfile = mocker.patch("pytest_html.plugin.isfile") + mock_isfile.side_effect = ValueError("stat: path too long for Windows") + self.test_extra_video(testdir, "video/mp4", "mp4") + assert mock_isfile.call_count == 1 + @pytest.mark.parametrize( "content", [("u'\u0081'"), ("'foo'"), ("b'\\xe2\\x80\\x93'")] ) @@ -554,6 +583,20 @@ assert link in html assert os.path.exists(src) + def test_extra_fixture(self, testdir): + content = b64encode(b"foo").decode("ascii") + testdir.makepyfile( + f""" + def test_pass(extra): + from pytest_html import extras + extra.append(extras.png('{content}')) + """ + ) + result, html = run(testdir, "report.html", "--self-contained-html") + assert result.ret == 0 + src = f"data:image/png;base64,{content}" + assert f'<img src="{src}"/>' in html + def test_no_invalid_characters_in_filename(self, testdir): testdir.makeconftest( """ @@ -633,10 +676,22 @@ assert "Environment" in html assert len(re.findall(content, html)) == 1 - def test_environment_list_value(self, testdir): - content = tuple(str(random.random()) for i in range(10)) - content += tuple(random.random() for i in range(10)) - expected_content = ", ".join(str(i) for i in content) + _unsorted_tuples = [ + ("Hello", "fzWZP6vKRv", "hello", "garAge", "123Go"), + (2, 4, 2, 1, 54), + ("Yes", 400, "5.4"), + ] + _sorted_tuples = [ + "123Go, Hello, fzWZP6vKRv, garAge, hello", + "1, 2, 2, 4, 54", + "400, 5.4, Yes", + ] + _test_environment_list_value_data_set = zip(_unsorted_tuples, _sorted_tuples) + + @pytest.mark.parametrize( + "content,expected_content", _test_environment_list_value_data_set + ) + def test_environment_list_value(self, testdir, content, expected_content): expected_html_re = fr"<td>content</td>\n\s+<td>{expected_content}</td>" testdir.makeconftest( f""" @@ -651,6 +706,46 @@ assert "Environment" in html assert len(re.findall(expected_html_re, html)) == 1 + _unordered_dict = {k: len(k) for k in _unsorted_tuples[0]} + _unordered_dict_expected = ( + r'<td>content</td>\n\s+<td>{"123Go": 5, "Hello": 5, ' + r'"fzWZP6vKRv": 10, "garAge": 6, "hello": 5}</td>' + ) + _unordered_dict_with_html = { + "First Link": r'<a href="https://www.w3schools.com">W3Schools</a>', + "Second Link": r'<a href="https://www.w3schools.com">W2Schools</a>', + "Third Link": r'<a href="https://www.w3schools.com">W4Schools</a>', + } + _unordered_dict_with_html_expected = ( + r"<td>content</td>\n\s+<td>{" + r'"First Link": "<a href=\\"https://www.w3schools.com\\">W3Schools</a>", ' + r'"Second Link": "<a href=\\"https://www.w3schools.com\\">W2Schools</a>", ' + r'"Third Link": "<a href=\\"https://www.w3schools.com\\">W4Schools</a>"}</td>' + ) + + @pytest.mark.parametrize( + "unordered_dict,expected_output", + [ + (_unordered_dict, _unordered_dict_expected), + (_unordered_dict_with_html, _unordered_dict_with_html_expected), + ], + ) + def test_environment_unordered_dict_value( + self, testdir, unordered_dict, expected_output + ): + testdir.makeconftest( + f""" + def pytest_configure(config): + values = dict({json.dumps(unordered_dict)}) + config._metadata['content'] = values + """ + ) + testdir.makepyfile("def test_pass(): pass") + result, html = run(testdir) + assert result.ret == 0 + assert "Environment" in html + assert len(re.findall(expected_output, html)) == 1 + def test_environment_ordered(self, testdir): testdir.makeconftest( """ @@ -799,3 +894,43 @@ result, html = run(testdir) assert result.ret == 0 assert r"\u6d4b\u8bd5\u7528\u4f8b\u540d\u79f0" not in html + + @pytest.mark.parametrize("is_collapsed", [True, False]) + def test_collapsed(self, testdir, is_collapsed): + collapsed_html = '<tr class="collapsed">' + expected_count = 2 if is_collapsed else 0 + testdir.makeini( + f""" + [pytest] + render_collapsed = {is_collapsed} + """ + ) + testdir.makepyfile( + """ + def test_fail(): + assert False + + def test_pass(): + assert True + """ + ) + result, html = run(testdir) + assert result.ret == 1 + assert len(re.findall(collapsed_html, html)) == expected_count + assert_results(html, tests=2, passed=1, failed=1) + + def test_custom_content_report_title(self, testdir): + content_report_title = str(random.random()) + testdir.makeconftest( + f""" + import pytest + from py.xml import html + + def pytest_html_report_title(report): + report.title = "title is {content_report_title}" + """ + ) + testdir.makepyfile("def test_pass(): pass") + result, html = run(testdir) + assert result.ret == 0 + assert len(re.findall(content_report_title, html)) == 1
