From cd5578bf57fd168e1e64ceb03b9276e869482c05 Mon Sep 17 00:00:00 2001 From: Ambuj Date: Sun, 23 Nov 2025 17:51:31 +0530 Subject: [PATCH] Feat: Added a copy to clipboard features for copying the test id. --- src/layout/css/style.scss | 40 +++++++++++++++++++++++++++++++++ src/pytest_html/basereport.py | 18 ++++++++++++++- src/pytest_html/scripts/main.js | 19 ++++++++++++++++ 3 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/layout/css/style.scss b/src/layout/css/style.scss index b4bf0eee..934c9104 100644 --- a/src/layout/css/style.scss +++ b/src/layout/css/style.scss @@ -116,6 +116,46 @@ span.xpassed, } } +.col-testId { + position: relative; + + .copy-btn { + margin-left: 8px; + padding: 3px 5px; + border: 1px solid #ccc; + border-radius: 3px; + background-color: transparent; + cursor: pointer; + font-size: 0; + line-height: 1; + vertical-align: middle; + transition: all 0.15s ease; + color: #999; + + svg { + display: block; + width: 12px; + height: 12px; + } + + &:hover { + background-color: #f6f6f6; + border-color: #999; + color: #666; + } + + &:active { + background-color: #e6e6e6; + } + + &.copied { + background-color: #4caf4faa; + border-color: #4caf4faa; + color: white; + } + } +} + /*------------------ * 2. Extra *------------------*/ diff --git a/src/pytest_html/basereport.py b/src/pytest_html/basereport.py index cfcc74b2..58e32a1c 100644 --- a/src/pytest_html/basereport.py +++ b/src/pytest_html/basereport.py @@ -284,7 +284,23 @@ def _process_report(self, report, duration, processed_extras): ] cells = [ f'{outcome}', - f'{test_id}', + f"""{test_id} + + """, f'{formatted_duration}', f'{_process_links(links)}', ] diff --git a/src/pytest_html/scripts/main.js b/src/pytest_html/scripts/main.js index f01f2eac..61354bd9 100644 --- a/src/pytest_html/scripts/main.js +++ b/src/pytest_html/scripts/main.js @@ -70,6 +70,10 @@ const renderContent = (tests) => { find('.logexpander', row).addEventListener('click', (evt) => evt.target.parentNode.classList.toggle('expanded'), ) + const copyBtn = find('.copy-btn', row) + if (copyBtn) { + copyBtn.addEventListener('click', handleCopyTestId) + } newTable.appendChild(row) } }) @@ -86,6 +90,21 @@ const renderDerived = () => { }) } +const handleCopyTestId = (evt) => { + evt.stopPropagation() + const button = evt.currentTarget + const testId = button.dataset.testId + + navigator.clipboard.writeText(testId).then(() => { + button.classList.add('copied') + setTimeout(() => { + button.classList.remove('copied') + }, 500) + }).catch(() => { + // Silently fail if clipboard API unavailable + }) +} + const bindEvents = () => { const filterColumn = (evt) => { const { target: element } = evt