Update next-gen with recent changes to master (#494)

* remove phantomjs dependency (#424)

* properly classify all npm dependencies (#425)

* Move the changelog to read the docs (#423)

* split plugin.py into smaller files (#427)

* Implement the visible URL query parameter to control visibility of test results on page load. (#433)

* enable control of test result visability via query params

* Allow for redacting of environment table values (#431)

* Disable Codecov (#480)

* Disable Codecov

* Disable pypy3 on mac

* Add Tests.yml reusable workflow (#484)

* Use the tests reusable workflow (#486)

* Migrate to precommit.ci (#487)

* Separate Nightly workflow (#488)

Co-authored-by: Gleb Nikonorov <gleb.i.nikonorov@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Jim Brännlund 2022-01-26 10:12:02 +01:00 committed by GitHub
parent ff0875105e
commit ff7cc3280f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 404 additions and 164 deletions

View File

@ -1,4 +1,4 @@
name: gh
name: Main
on:
create: # is used for publishing to PyPI and TestPyPI
@ -12,13 +12,11 @@ on:
- >-
**
pull_request:
schedule:
- cron: 1 0 * * * # Run daily at 0:01 UTC
jobs:
build_docs:
name: Build Docs
runs-on: ubuntu-18.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
- name: Set up Python
@ -26,149 +24,18 @@ jobs:
with:
python-version: 3.6
- name: Install tox
run: |
python -m pip install --upgrade tox
run: python -m pip install --upgrade tox
- name: Build docs with tox
run: |
python -m tox -e docs
build_python:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-18.04
name: py36-ubuntu
python-version: 3.6
run: python -m tox -e docs
- os: windows-latest
name: py36-windows
python-version: 3.6
tests:
uses: pytest-dev/pytest-html/.github/workflows/tests.yml@master
- os: macOS-latest
name: py36-mac
python-version: 3.6
- os: ubuntu-18.04
name: py37-ubuntu
python-version: 3.7
- os: windows-latest
name: py37-windows
python-version: 3.7
- os: macOS-latest
name: py37-mac
python-version: 3.7
- os: ubuntu-18.04
name: py38-ubuntu
python-version: 3.8
- os: windows-latest
name: py38-windows
python-version: 3.8
- os: macOS-latest
name: py38-mac
python-version: 3.8
- os: ubuntu-18.04
name: py39-ubuntu
python-version: 3.9
- os: windows-latest
name: py39-windows
python-version: 3.9
- os: macOS-latest
name: py39-mac
python-version: 3.9
- os: ubuntu-18.04
name: pypy3-ubuntu
python-version: pypy3
- os: windows-latest
name: pypy3-windows
python-version: pypy3
- os: macOS-latest
name: pypy3-mac
python-version: pypy3
- os: ubuntu-18.04
name: devel-ubuntu
python-version: 3.8
steps:
- name: Set Newline Behavior
run : |
git config --global core.autocrlf false
- uses: actions/checkout@master
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix['python-version'] }}
- name: Install tox
run: |
python -m pip install --upgrade tox
- name: Get Tox Environment Name From Matrix Name
uses: rishabhgupta/split-by@v1
id: split-matrix-name
with:
string: '${{ matrix.name }}'
split-by: '-'
- name: Test with tox
run: |
python -m tox -e ${{ steps.split-matrix-name.outputs._0}}-cov
- name: Upload coverage to codecov
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true
file: ./coverage.xml
flags: tests
name: ${{ matrix.py }} - ${{ matrix.os }}
verbose: true
build_javascript:
name: grunt
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: Install Dependencies
run: |
npm install
- name: QUnit Tests
run: |
npm test
env:
CI: true
linting:
name: linting
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@master
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: 3.6
- name: Install tox
run: |
python -m pip install --upgrade tox
- name: Lint with tox
run: |
python -m tox -e linting
publish:
name: Publish to PyPI registry
needs:
- build_python
- build_javascript
- tests
runs-on: ubuntu-latest
env:
PY_COLORS: 1
TOXENV: packaging

9
.github/workflows/nightly.yml vendored Normal file
View File

@ -0,0 +1,9 @@
name: Nightly tests
on:
schedule:
- cron: '1 0 * * *' # Run daily at 0:01 UTC
jobs:
tests:
uses: pytest-dev/pytest-html/.github/workflows/tests.yml@master

119
.github/workflows/tests.yml vendored Normal file
View File

@ -0,0 +1,119 @@
name: Tests
on:
workflow_call:
jobs:
test_python:
name: ${{ matrix.name }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
include:
- os: ubuntu-latest
name: py36-ubuntu
python-version: 3.6
- os: windows-latest
name: py36-windows
python-version: 3.6
- os: macOS-latest
name: py36-mac
python-version: 3.6
- os: ubuntu-latest
name: py37-ubuntu
python-version: 3.7
- os: windows-latest
name: py37-windows
python-version: 3.7
- os: macOS-latest
name: py37-mac
python-version: 3.7
- os: ubuntu-latest
name: py38-ubuntu
python-version: 3.8
- os: windows-latest
name: py38-windows
python-version: 3.8
- os: macOS-latest
name: py38-mac
python-version: 3.8
- os: ubuntu-latest
name: py39-ubuntu
python-version: 3.9
- os: windows-latest
name: py39-windows
python-version: 3.9
- os: macOS-latest
name: py39-mac
python-version: 3.9
- os: ubuntu-latest
name: pypy3-ubuntu
python-version: pypy3
- os: windows-latest
name: pypy3-windows
python-version: pypy3
# https://github.com/pytest-dev/pytest-html/issues/482
# - os: macOS-latest
# name: pypy3-mac
# python-version: pypy3
- os: ubuntu-latest
name: devel-ubuntu
python-version: 3.9
steps:
- name: Set Newline Behavior
run : git config --global core.autocrlf false
- uses: actions/checkout@master
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix['python-version'] }}
- name: Install tox
run: python -m pip install --upgrade tox
- name: Get Tox Environment Name From Matrix Name
uses: rishabhgupta/split-by@v1
id: split-matrix-name
with:
string: '${{ matrix.name }}'
split-by: '-'
- name: Test with tox
run: python -m tox -e ${{ steps.split-matrix-name.outputs._0}}-cov
# TODO: https://github.com/pytest-dev/pytest-html/issues/481
# - name: Upload coverage to codecov
# if: github.event.schedule == ''
# uses: codecov/codecov-action@v2
# with:
# fail_ci_if_error: true
# file: ./coverage.xml
# flags: tests
# name: ${{ matrix.py }} - ${{ matrix.os }}
# verbose: true
test_javascript:
name: grunt
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: '12.x'
- name: Install Dependencies
run: npm install
- name: QUnit Tests
run: npm test

View File

@ -37,13 +37,13 @@ repos:
hooks:
- id: pyupgrade
args: [--py3-plus]
- repo: https://github.com/pre-commit/mirrors-eslint
rev: v7.13.0
hooks:
- id: eslint
additional_dependencies:
- eslint@7.13.0
args: [src]
# - repo: https://github.com/pre-commit/mirrors-eslint
# rev: v7.13.0
# hooks:
# - id: eslint
# additional_dependencies:
# - eslint@7.13.0
# args: [src]
- repo: local
hooks:
- id: rst

View File

@ -11,4 +11,3 @@ build-backend = "setuptools.build_meta"
[tool.setuptools_scm]
local_scheme = "no-local-version"
write_to = "src/pytest_html/__version.py"

View File

@ -178,7 +178,7 @@ class HTMLReport:
]
with open(
os.path.join(os.path.dirname(__file__), "resources", "main.js")
os.path.join(os.path.dirname(__file__), "resources", "old_main.js")
) as main_js_fp:
main_js = main_js_fp.read()

View File

@ -4,12 +4,12 @@
import os
import pytest
from _pytest.pathlib import Path
from . import extras # noqa: F401
from .html_report import HTMLReport
from .nextgen import NextGenReport
from _pytest.pathlib import Path
def pytest_addhooks(pluginmanager):
from . import hooks

View File

@ -64,17 +64,17 @@
<h2>Summary</h2>
<p class="run-count"></p>
<p class="filter">(Un)check the boxes to filter the results.</p>
<input checked="true" class="filter" data-test-result="error" name="filter_checkbox" type="checkbox"/><span class="error"></span>
<input checked="true" class="filter" data-test-result="error" name="filter_checkbox" type="checkbox"/><span class="error"></span>
<input checked="true" class="filter" data-test-result="failed" name="filter_checkbox" type="checkbox"/><span class="failed"></span>
<input checked="true" class="filter" data-test-result="rerun" name="filter_checkbox" type="checkbox"/><span class="rerun"></span>
<input checked="true" class="filter" data-test-result="xfailed" name="filter_checkbox" type="checkbox"/><span class="xfailed"></span>
<input checked="true" class="filter" data-test-result="xpassed" name="filter_checkbox" type="checkbox"/><span class="xpassed"></span>
<input checked="true" class="filter" data-test-result="xfailed" name="filter_checkbox" type="checkbox"/><span class="xfailed"></span>
<input checked="true" class="filter" data-test-result="xpassed" name="filter_checkbox" type="checkbox"/><span class="xpassed"></span>
<input checked="true" class="filter" data-test-result="passed" name="filter_checkbox" type="checkbox"/><span class="passed"></span>
<input checked="true" class="filter" data-test-result="skipped" name="filter_checkbox" type="checkbox"/><span class="skipped"></span>
</div>
<div class="summary__reload">
<div class="summary__reload__button" onclick="location.reload()">
@ -86,7 +86,7 @@
</div>
<h2>Results</h2>
<table id="results-table">
</table>
</body>
<footer>
@ -97,4 +97,4 @@
<script src="index.js"></script>
<script src="main.js"></script>
</footer>
</html>
</html>

View File

@ -61,8 +61,8 @@ function addCollapse() {
const resulttable = find('table#results-table');
const showhideall = document.createElement('p');
showhideall.innerHTML =
'<a href="javascript:showAllExtras()">Show all details</a> / ' +
'<a href="javascript:hideAllExtras()">Hide all details</a>';
'<a href="javascript:showAllExtras()">Show all details</a> / ' +
'<a href="javascript:hideAllExtras()">Hide all details</a>';
resulttable.parentElement.insertBefore(showhideall, resulttable);
// Add show/hide link to each result
@ -82,9 +82,9 @@ function addCollapse() {
elem.addEventListener('click', function (event) {
if (
event.currentTarget.parentNode.nextElementSibling.classList.contains(
'collapsed'
)
event.currentTarget.parentNode.nextElementSibling.classList.contains(
'collapsed'
)
) {
showExtras(event.currentTarget);
} else {

View File

@ -0,0 +1,246 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
function toArray(iter) {
if (iter === null) {
return null;
}
return Array.prototype.slice.call(iter);
}
function find(selector, elem) { // eslint-disable-line no-redeclare
if (!elem) {
elem = document;
}
return elem.querySelector(selector);
}
function findAll(selector, elem) {
if (!elem) {
elem = document;
}
return toArray(elem.querySelectorAll(selector));
}
function sortColumn(elem) {
toggleSortStates(elem);
const colIndex = toArray(elem.parentNode.childNodes).indexOf(elem);
let key;
if (elem.classList.contains('result')) {
key = keyResult;
} else if (elem.classList.contains('links')) {
key = keyLink;
} else {
key = keyAlpha;
}
sortTable(elem, key(colIndex));
}
function showAllExtras() { // eslint-disable-line no-unused-vars
findAll('.col-result').forEach(showExtras);
}
function hideAllExtras() { // eslint-disable-line no-unused-vars
findAll('.col-result').forEach(hideExtras);
}
function showExtras(colresultElem) {
const extras = colresultElem.parentNode.nextElementSibling;
const expandcollapse = colresultElem.firstElementChild;
extras.classList.remove('collapsed');
expandcollapse.classList.remove('expander');
expandcollapse.classList.add('collapser');
}
function hideExtras(colresultElem) {
const extras = colresultElem.parentNode.nextElementSibling;
const expandcollapse = colresultElem.firstElementChild;
extras.classList.add('collapsed');
expandcollapse.classList.remove('collapser');
expandcollapse.classList.add('expander');
}
function showFilters() {
let visibleString = getQueryParameter('visible') || 'all';
visibleString = visibleString.toLowerCase();
const checkedItems = visibleString.split(',');
const filterItems = document.getElementsByClassName('filter');
for (let i = 0; i < filterItems.length; i++) {
filterItems[i].hidden = false;
if (visibleString != 'all') {
filterItems[i].checked = checkedItems.includes(filterItems[i].getAttribute('data-test-result'));
filterTable(filterItems[i]);
}
}
}
function addCollapse() {
// Add links for show/hide all
const resulttable = find('table#results-table');
const showhideall = document.createElement('p');
showhideall.innerHTML = '<a href="javascript:showAllExtras()">Show all details</a> / ' +
'<a href="javascript:hideAllExtras()">Hide all details</a>';
resulttable.parentElement.insertBefore(showhideall, resulttable);
// Add show/hide link to each result
findAll('.col-result').forEach(function(elem) {
const collapsed = getQueryParameter('collapsed') || 'Passed';
const extras = elem.parentNode.nextElementSibling;
const expandcollapse = document.createElement('span');
if (extras.classList.contains('collapsed')) {
expandcollapse.classList.add('expander');
} else if (collapsed.includes(elem.innerHTML)) {
extras.classList.add('collapsed');
expandcollapse.classList.add('expander');
} else {
expandcollapse.classList.add('collapser');
}
elem.appendChild(expandcollapse);
elem.addEventListener('click', function(event) {
if (event.currentTarget.parentNode.nextElementSibling.classList.contains('collapsed')) {
showExtras(event.currentTarget);
} else {
hideExtras(event.currentTarget);
}
});
});
}
function getQueryParameter(name) {
const match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
function init () { // eslint-disable-line no-unused-vars
resetSortHeaders();
addCollapse();
showFilters();
sortColumn(find('.initial-sort'));
findAll('.sortable').forEach(function(elem) {
elem.addEventListener('click',
function() {
sortColumn(elem);
}, false);
});
}
function sortTable(clicked, keyFunc) {
const rows = findAll('.results-table-row');
const reversed = !clicked.classList.contains('asc');
const sortedRows = sort(rows, keyFunc, reversed);
/* Whole table is removed here because browsers acts much slower
* when appending existing elements.
*/
const thead = document.getElementById('results-table-head');
document.getElementById('results-table').remove();
const parent = document.createElement('table');
parent.id = 'results-table';
parent.appendChild(thead);
sortedRows.forEach(function(elem) {
parent.appendChild(elem);
});
document.getElementsByTagName('BODY')[0].appendChild(parent);
}
function sort(items, keyFunc, reversed) {
const sortArray = items.map(function(item, i) {
return [keyFunc(item), i];
});
sortArray.sort(function(a, b) {
const keyA = a[0];
const keyB = b[0];
if (keyA == keyB) return 0;
if (reversed) {
return keyA < keyB ? 1 : -1;
} else {
return keyA > keyB ? 1 : -1;
}
});
return sortArray.map(function(item) {
const index = item[1];
return items[index];
});
}
function keyAlpha(colIndex) {
return function(elem) {
return elem.childNodes[1].childNodes[colIndex].firstChild.data.toLowerCase();
};
}
function keyLink(colIndex) {
return function(elem) {
const dataCell = elem.childNodes[1].childNodes[colIndex].firstChild;
return dataCell == null ? '' : dataCell.innerText.toLowerCase();
};
}
function keyResult(colIndex) {
return function(elem) {
const strings = ['Error', 'Failed', 'Rerun', 'XFailed', 'XPassed',
'Skipped', 'Passed'];
return strings.indexOf(elem.childNodes[1].childNodes[colIndex].firstChild.data);
};
}
function resetSortHeaders() {
findAll('.sort-icon').forEach(function(elem) {
elem.parentNode.removeChild(elem);
});
findAll('.sortable').forEach(function(elem) {
const icon = document.createElement('div');
icon.className = 'sort-icon';
icon.textContent = 'vvv';
elem.insertBefore(icon, elem.firstChild);
elem.classList.remove('desc', 'active');
elem.classList.add('asc', 'inactive');
});
}
function toggleSortStates(elem) {
//if active, toggle between asc and desc
if (elem.classList.contains('active')) {
elem.classList.toggle('asc');
elem.classList.toggle('desc');
}
//if inactive, reset all other functions and add ascending active
if (elem.classList.contains('inactive')) {
resetSortHeaders();
elem.classList.remove('inactive');
elem.classList.add('active');
}
}
function isAllRowsHidden(value) {
return value.hidden == false;
}
function filterTable(elem) { // eslint-disable-line no-unused-vars
const outcomeAtt = 'data-test-result';
const outcome = elem.getAttribute(outcomeAtt);
const classOutcome = outcome + ' results-table-row';
const outcomeRows = document.getElementsByClassName(classOutcome);
for(let i = 0; i < outcomeRows.length; i++){
outcomeRows[i].hidden = !elem.checked;
}
const rows = findAll('.results-table-row').filter(isAllRowsHidden);
const allRowsHidden = rows.length == 0 ? true : false;
const notFoundMessage = document.getElementById('not-found-message');
notFoundMessage.hidden = !allRowsHidden;
}

View File

@ -12,7 +12,7 @@
<script src="https://code.jquery.com/qunit/qunit-2.0.1.js"></script>
<script src="https://raw.githubusercontent.com/alex-seville/blanket/master/dist/qunit/blanket.min.js"></script>
<script src="test.js"></script>
<script src="../src/pytest_html/resources/main.js" data-cover></script>
<script src="../src/pytest_html/resources/old_main.js" data-cover></script>
<div id="qunit-fixture">
<table id="results-table">
<thead id="results-table-head">

View File

@ -369,7 +369,7 @@ class TestHTML:
assert result.ret == 0
content = pkg_resources.resource_string(
"pytest_html", os.path.join("resources", "main.js")
"pytest_html", os.path.join("resources", "old_main.js")
)
content = content.decode("utf-8")
assert content