File: conftest.py

package info (click to toggle)
streamlink 7.3.0-2~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 5,584 kB
  • sloc: python: 49,172; sh: 184; makefile: 145
file content (75 lines) | stat: -rw-r--r-- 2,753 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
from __future__ import annotations

import sys
from contextlib import asynccontextmanager
from subprocess import PIPE
from unittest.mock import Mock

import pytest
import trio

from streamlink.webbrowser.webbrowser import Webbrowser


@pytest.fixture()
def caplog(caplog: pytest.LogCaptureFixture):
    caplog.set_level(1, "streamlink")
    return caplog


@pytest.fixture(autouse=True)
def resolve_executable(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch):
    return_value = getattr(request, "param", "default")
    monkeypatch.setattr("streamlink.webbrowser.webbrowser.resolve_executable", Mock(return_value=return_value))
    return return_value


@pytest.fixture()
def webbrowser_launch(monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture):
    trio_run_process = trio.run_process

    # use a memory channel, so we can wait until the process has launched
    sender: trio.MemorySendChannel
    receiver: trio.MemoryReceiveChannel
    sender, receiver = trio.open_memory_channel(1)

    async def fake_trio_run_process(*args, task_status, **kwargs):
        task_status_started = task_status.started

        def fake_task_status_started(process: trio.Process):
            task_status_started(process)
            sender.send_nowait(process)

        # intercept the task status report
        task_status.started = fake_task_status_started
        # override the stdin parameter, so we can send data to our dummy process
        kwargs["stdin"] = PIPE

        return await trio_run_process(*args, task_status=task_status, **kwargs)

    monkeypatch.setattr("trio.run_process", fake_trio_run_process)

    @asynccontextmanager
    async def webbrowser_launch(*args, webbrowser: Webbrowser | None = None, **kwargs):
        # dummy web browser process, which idles until stdin receives input with an exit code
        webbrowser = webbrowser or Webbrowser()
        webbrowser.executable = sys.executable
        webbrowser.arguments = ["-c", "import sys; sys.exit(int(sys.stdin.readline()))", *webbrowser.arguments]

        headless = kwargs.get("headless", False)

        async with webbrowser.launch(*args, **kwargs) as nursery:
            assert isinstance(nursery, trio.Nursery)
            assert [(record.name, record.levelname, record.msg) for record in caplog.records] == [
                (
                    "streamlink.webbrowser.webbrowser",
                    "info",
                    f"Launching web browser: {sys.executable} ({headless=})",
                ),
            ]
            caplog.records.clear()
            # wait until the process has launched, so we can test it
            process = await receiver.receive()
            yield nursery, process

    return webbrowser_launch