Skip to content

How to add HTML Extras that contain a <script> tag (and allow that script to be executed)? #1010

@cc-stjm

Description

@cc-stjm

I'm trying to do similar to #931 but I think I've worked out the general case - is there a way we can add extra HTML code that contains script tags, such that the script can be executed?

Minimum viable demo:

import pytest_html

def test_demo(extras):
    extras.append(pytest_html.extras.html('Before'))
    extras.append(pytest_html.extras.html('<script>alert("Hello, World!");</script>'))
    extras.append(pytest_html.extras.html('After'))

When you load in a web browser, you'll find the <script> tag added between 'Before' and 'After'. However, if you open report.html in a text editor, you find that it isn't inserted into the raw HTML, but rather it's encoded data as part of the data-jsonblob property of <div id="data-container" data-jsonblob="..."> - i.e. the <script> doesn't get executed, because it's inserted dynamically. It appears this is understood behaviour

A bit of experimentation suggested that the createRange method documented here would work, with the disadvantage that the script seems to be executed whenever the row is expanded or collapsed. I achieved this by replacing these lines

            if (format_type === 'html') {
                resultBody.querySelector('.extraHTML').insertAdjacentHTML('beforeend', `<div>${content}</div>`)
            }

with

            if (format_type === 'html') {
                const range = document.createRange()
                const fragment = range.createContextualFragment(content)
                resultBody.querySelector('.extraHTML').appendChild(fragment)
            }

This isn't necessarily the best way to fix this though.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions