Add `mock_context_manager`; factor out all `run_before` methods
What changed, and why it matters
This commit is a test-code cleanup only. It replaces manual 'before/after' setup callbacks in the screenshot generator with reusable Python context managers that automatically clean up mock data. There is no change to the actual SeedSigner application or its security behavior.
No security action needed. This is a benign test refactoring.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors tests/screenshot_generator/generator.py and tests/screenshot_generator/utils.py. It introduces @contextmanager helpers (mock_load_psbt, mock_single_sig_psbt_loaded, mock_multisig_psbt_loaded, mock_multisig_wallet_descriptor_loaded, mock_address_verification_data_loaded, etc.) and a default no-op context manager. ScreenshotConfig gains a mock_context_manager field replacing run_before/run_after callbacks. The generator now wraps each screenshot render in the context manager, ensuring patches/mocks are reverted automatically. No production code is modified.
Changed components
tests/screenshot_generator/generator.pytests/screenshot_generator/utils.pyInspect captured patch +110 / −90
diff --git a/tests/screenshot_generator/generator.py b/tests/screenshot_generator/generator.py
index 673086f..a7294fd 100644
--- a/tests/screenshot_generator/generator.py
+++ b/tests/screenshot_generator/generator.py
@@ -1,13 +1,14 @@
-from dataclasses import dataclass
import embit
+import os
import pathlib
import pytest
-import os
import random
import sys
import time
-from unittest.mock import Mock, patch, MagicMock
+from contextlib import contextmanager
+from dataclasses import dataclass
from PIL import ImageFont
+from unittest.mock import Mock, patch, MagicMock
from embit import compact
from embit.psbt import PSBT, OutputScope
@@ -24,7 +25,6 @@ sys.modules['seedsigner.hardware.camera.Camera'] = MagicMock()
sys.modules['seedsigner.hardware.microsd'] = MagicMock()
from seedsigner.controller import Controller
-from seedsigner.gui.components import GUIConstants
from seedsigner.gui.renderer import Renderer
from seedsigner.gui.screens.screen import BaseScreen
from seedsigner.gui.screens.seed_screens import SeedAddPassphraseScreen
@@ -240,32 +240,49 @@ def generate_screenshots(locale):
settingsqr_data_persistent = f"settings::v1 name=English_noob_mode persistent=E xpub_qr=urca,sta denom=thr network=M qr_density=M sigs=ss scripts=nat xpub_details=E passphrase=E camera=0 compact_seedqr=E bip85=D priv_warn=E dire_warn=E partners=E locale={locale}"
settingsqr_data_not_persistent = f"settings::v1 name=Mode_Ephemeral persistent=D xpub_qr=urca,sta denom=thr network=M qr_density=M sigs=ss scripts=nat xpub_details=E passphrase=E camera=0 compact_seedqr=E bip85=D priv_warn=E dire_warn=E partners=E locale={locale}"
- # Set up screenshot-specific callbacks to inject data before the View is run and
- # reset data after the View is run.
- def load_single_sig_psbt_cb():
+ # Set up screenshot-specific mocks to provide temporary data/state
+ @contextmanager
+ def mock_load_psbt(base64_psbt: str, seed: Seed = seed_12b):
+ """
+ Reusable utility for other context managers to mock loading a PSBT into the
+ Controller.
+ """
decoder = DecodeQR()
- decoder.add_data(BASE64_SINGLE_SIG_PSBT)
- controller.psbt = decoder.get_psbt()
- controller.psbt_seed = seed_12b
- controller.psbt_parser = PSBTParser(p=controller.psbt, seed=seed_12b)
- controller.multisig_wallet_descriptor = None
+ decoder.add_data(base64_psbt)
+ with patch.object(controller, 'psbt', decoder.get_psbt()):
+ with patch.object(controller, 'psbt_seed', seed):
+ with patch.object(controller, 'psbt_parser', PSBTParser(p=controller.psbt, seed=seed)):
+ yield
- def load_multisig_psbt_cb():
- decoder = DecodeQR()
- decoder.add_data(BASE64_MULTISIG_PSBT)
- controller.psbt = decoder.get_psbt()
- controller.psbt_seed = seed_12b
- controller.psbt_parser = PSBTParser(p=controller.psbt, seed=seed_12b)
- controller.multisig_wallet_descriptor = None
+ @contextmanager
+ def mock_single_sig_psbt_loaded():
+ with mock_load_psbt(BASE64_SINGLE_SIG_PSBT):
+ yield
- def load_multisig_wallet_descriptor_cb():
- controller.multisig_wallet_descriptor = embit.descriptor.Descriptor.from_string(MULTISIG_WALLET_DESCRIPTOR)
+ @contextmanager
+ def mock_multisig_psbt_loaded():
+ with mock_load_psbt(BASE64_MULTISIG_PSBT):
+ yield
- def load_address_verification_data_cb():
- controller.unverified_address = dict(
+ @contextmanager
+ def mock_multisig_wallet_descriptor_loaded():
+ with patch.object(controller, 'multisig_wallet_descriptor', embit.descriptor.Descriptor.from_string(MULTISIG_WALLET_DESCRIPTOR)):
+ yield
+
+
+ @contextmanager
+ def mock_multisig_psbt_and_descriptor_loaded():
+ with mock_multisig_psbt_loaded():
+ with mock_multisig_wallet_descriptor_loaded():
+ yield
+
+
+ @contextmanager
+ def mock_address_verification_data_loaded():
+ fake_addr_verification_data = dict(
# These are all totally fake data
address="bc1q6p00wazu4nnqac29fvky6vhjnnhku5u2g9njss62rvy7e0yuperq86f5ek",
network=SettingsConstants.MAINNET,
@@ -275,25 +292,27 @@ def generate_screenshots(locale):
verified_index=5,
verified_index_is_change=False
)
+ with patch.object(controller, 'unverified_address', fake_addr_verification_data):
+ yield
- def PSBTSelectSeedView_cb_before():
+ @contextmanager
+ def mock_controller_psbt_seed_empty():
# Have to ensure this is cleared out in order to get the seed selection screen
- controller.psbt_seed = None
+ with patch.object(controller, 'psbt_seed', None):
+ yield
- def PSBTOverviewView_op_return_cb_before():
- controller.psbt_seed = seed_12b
- decoder = DecodeQR()
- decoder.add_data(BASE64_PSBT_WITH_OP_RETURN_TEXT)
- controller.psbt = decoder.get_psbt()
- controller.psbt_parser = PSBTParser(p=controller.psbt, seed=seed_12b)
-
+ @contextmanager
+ def mock_psbt_with_op_return_loaded():
+ with mock_load_psbt(BASE64_PSBT_WITH_OP_RETURN_TEXT):
+ yield
+
- def PSBTOpReturnView_raw_hex_data_cb_before():
- decoder.add_data(BASE64_PSBT_WITH_OP_RETURN_RAW_BYTES)
- controller.psbt = decoder.get_psbt()
- controller.psbt_parser = PSBTParser(p=controller.psbt, seed=seed_12b)
+ @contextmanager
+ def mock_psbt_with_op_return_raw_bytes_loaded():
+ with mock_load_psbt(BASE64_PSBT_WITH_OP_RETURN_RAW_BYTES):
+ yield
screenshot_sections = {
@@ -330,8 +349,8 @@ def generate_screenshots(locale):
ScreenshotConfig(seed_views.SeedReviewPassphraseView),
ScreenshotConfig(seed_views.SeedOptionsView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedBackupView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedExportXpubSigTypeView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedBackupView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedExportXpubSigTypeView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedExportXpubScriptTypeView, dict(seed_num=0, sig_type="msig")),
ScreenshotConfig(seed_views.SeedExportXpubCustomDerivationView, dict(seed_num=0, sig_type="ss", script_type="")),
ScreenshotConfig(seed_views.SeedExportXpubQRFormatView, dict(seed_num=0, sig_type="ss", script_type="nat")),
@@ -342,19 +361,19 @@ def generate_screenshots(locale):
ScreenshotConfig(seed_views.SeedWordsWarningView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedWordsView, dict(seed_num=0, page_index=2), screenshot_name="SeedWordsView_2"),
- ScreenshotConfig(seed_views.SeedBIP85SelectNumWordsView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedBIP85SelectChildIndexView, dict(seed_num=0, num_words=24)),
- ScreenshotConfig(seed_views.SeedBIP85InvalidChildIndexView, dict(seed_num=0, num_words=12)),
- ScreenshotConfig(seed_views.SeedWordsBackupTestPromptView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedWordsBackupTestView, dict(seed_num=0, rand_seed=6102)),
- ScreenshotConfig(seed_views.SeedWordsBackupTestMistakeView, dict(seed_num=0, cur_index=7, wrong_word="satoshi")),
- ScreenshotConfig(seed_views.SeedWordsBackupTestSuccessView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedBIP85SelectNumWordsView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedBIP85SelectChildIndexView, dict(seed_num=0, num_words=24)),
+ ScreenshotConfig(seed_views.SeedBIP85InvalidChildIndexView, dict(seed_num=0, num_words=12)),
+ ScreenshotConfig(seed_views.SeedWordsBackupTestPromptView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedWordsBackupTestView, dict(seed_num=0, rand_seed=6102)),
+ ScreenshotConfig(seed_views.SeedWordsBackupTestMistakeView, dict(seed_num=0, cur_index=7, wrong_word="satoshi")),
+ ScreenshotConfig(seed_views.SeedWordsBackupTestSuccessView, dict(seed_num=0)),
+ ScreenshotConfig(seed_views.SeedTranscribeSeedQRFormatView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRWarningView, dict(seed_num=0)),
- ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Compact"),
- ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Standard"),
- ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Compact"),
- ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Standard"),
+ ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=21), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Compact"),
+ ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_12_Standard"),
+ ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__COMPACTSEEDQR, num_modules=25), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Compact"),
+ ScreenshotConfig(seed_views.SeedTranscribeSeedQRWholeQRView, dict(seed_num=2, seedqr_format=QRType.SEED__SEEDQR, num_modules=29), screenshot_name="SeedTranscribeSeedQRWholeQRView_24_Standard"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__COMPACTSEEDQR, initial_zone_x=1, initial_zone_y=1), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Compact"),
ScreenshotConfig(seed_views.SeedTranscribeSeedQRZoomedInView, dict(seed_num=0, seedqr_format=QRType.SEED__SEEDQR, initial_zone_x=2, initial_zone_y=2), screenshot_name="SeedTranscribeSeedQRZoomedInView_12_Standard"),
@@ -368,11 +387,11 @@ def generate_screenshots(locale):
ScreenshotConfig(seed_views.SeedSelectSeedView, dict(flow=Controller.FLOW__VERIFY_SINGLESIG_ADDR), screenshot_name="SeedSelectSeedView_address_verification"),
ScreenshotConfig(seed_views.AddressVerificationSigTypeView),
- ScreenshotConfig(seed_views.SeedAddressVerificationView, dict(seed_num=0), run_before=load_address_verification_data_cb),
- ScreenshotConfig(seed_views.SeedAddressVerificationSuccessView, dict(seed_num=0)), # Relies on callback above
+ ScreenshotConfig(seed_views.SeedAddressVerificationView, dict(seed_num=0), mock_context_manager=mock_address_verification_data_loaded),
+ ScreenshotConfig(seed_views.SeedAddressVerificationSuccessView, dict(seed_num=0), mock_context_manager=mock_address_verification_data_loaded),
ScreenshotConfig(seed_views.LoadMultisigWalletDescriptorView),
- ScreenshotConfig(seed_views.MultisigWalletDescriptorView, run_before=load_multisig_wallet_descriptor_cb),
+ ScreenshotConfig(seed_views.MultisigWalletDescriptorView, mock_context_manager=mock_multisig_wallet_descriptor_loaded),
ScreenshotConfig(seed_views.SeedDiscardView, dict(seed_num=0)),
ScreenshotConfig(seed_views.SeedSelectSeedView, dict(flow=Controller.FLOW__SIGN_MESSAGE), screenshot_name="SeedSelectSeedView_sign_message"),
@@ -382,27 +401,27 @@ def generate_screenshots(locale):
ScreenshotConfig(seed_views.SeedElectrumMnemonicStartView),
],
"PSBT Views": [
- ScreenshotConfig(psbt_views.PSBTSelectSeedView, run_before=PSBTSelectSeedView_cb_before),
- ScreenshotConfig(psbt_views.PSBTOverviewView, run_before=load_multisig_psbt_cb),
+ ScreenshotConfig(psbt_views.PSBTSelectSeedView, mock_context_manager=mock_controller_psbt_seed_empty),
+ ScreenshotConfig(psbt_views.PSBTOverviewView, mock_context_manager=mock_multisig_psbt_loaded),
ScreenshotConfig(psbt_views.PSBTUnsupportedScriptTypeWarningView),
ScreenshotConfig(psbt_views.PSBTNoChangeWarningView),
- ScreenshotConfig(psbt_views.PSBTMathView),
- ScreenshotConfig(psbt_views.PSBTAddressDetailsView, dict(address_num=0)),
-
- ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_single_sig_change_verified", run_before=load_single_sig_psbt_cb),
- ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=1), screenshot_name="PSBTChangeDetailsView_single_sig_self_transfer_verified", run_before=load_single_sig_psbt_cb),
- ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_multisig_unverified", run_before=load_multisig_psbt_cb),
- ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_multisig_verified", run_before=load_multisig_wallet_descriptor_cb),
- ScreenshotConfig(psbt_views.PSBTOverviewView, screenshot_name="PSBTOverviewView_op_return", run_before=PSBTOverviewView_op_return_cb_before),
- ScreenshotConfig(psbt_views.PSBTOpReturnView, screenshot_name="PSBTOpReturnView_text"), # Relies on callback above
- ScreenshotConfig(psbt_views.PSBTOpReturnView, screenshot_name="PSBTOpReturnView_raw_hex_data", run_before=PSBTOpReturnView_raw_hex_data_cb_before),
+ ScreenshotConfig(psbt_views.PSBTMathView, mock_context_manager=mock_multisig_psbt_loaded),
+ ScreenshotConfig(psbt_views.PSBTAddressDetailsView, dict(address_num=0), mock_context_manager=mock_multisig_psbt_loaded),
+
+ ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_single_sig_change_verified", mock_context_manager=mock_single_sig_psbt_loaded),
+ ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=1), screenshot_name="PSBTChangeDetailsView_single_sig_self_transfer_verified", mock_context_manager=mock_single_sig_psbt_loaded),
+ ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_multisig_unverified", mock_context_manager=mock_multisig_psbt_loaded),
+ ScreenshotConfig(psbt_views.PSBTChangeDetailsView, dict(change_address_num=0), screenshot_name="PSBTChangeDetailsView_multisig_verified", mock_context_manager=mock_multisig_psbt_and_descriptor_loaded),
+ ScreenshotConfig(psbt_views.PSBTOverviewView, screenshot_name="PSBTOverviewView_op_return", mock_context_manager=mock_psbt_with_op_return_loaded),
+ ScreenshotConfig(psbt_views.PSBTOpReturnView, screenshot_name="PSBTOpReturnView_text", mock_context_manager=mock_psbt_with_op_return_loaded),
+ ScreenshotConfig(psbt_views.PSBTOpReturnView, screenshot_name="PSBTOpReturnView_raw_hex_data", mock_context_manager=mock_psbt_with_op_return_raw_bytes_loaded),
ScreenshotConfig(psbt_views.PSBTAddressVerificationFailedView, dict(is_change=True, is_multisig=False), screenshot_name="PSBTAddressVerificationFailedView_singlesig_change"),
ScreenshotConfig(psbt_views.PSBTAddressVerificationFailedView, dict(is_change=False, is_multisig=False), screenshot_name="PSBTAddressVerificationFailedView_singlesig_selftransfer"),
ScreenshotConfig(psbt_views.PSBTAddressVerificationFailedView, dict(is_change=True, is_multisig=True), screenshot_name="PSBTAddressVerificationFailedView_multisig_change"),
ScreenshotConfig(psbt_views.PSBTAddressVerificationFailedView, dict(is_change=False, is_multisig=True), screenshot_name="PSBTAddressVerificationFailedView_multisig_selftransfer"),
- ScreenshotConfig(psbt_views.PSBTFinalizeView),
+ ScreenshotConfig(psbt_views.PSBTFinalizeView, mock_context_manager=mock_multisig_psbt_loaded),
#ScreenshotConfig(PSBTSignedQRDisplayViewScreenshotConfig),
- ScreenshotConfig(psbt_views.PSBTSigningErrorView),
+ ScreenshotConfig(psbt_views.PSBTSigningErrorView, mock_context_manager=mock_multisig_psbt_loaded),
],
"Tools Views": [
ScreenshotConfig(tools_views.ToolsMenuView),
@@ -418,14 +437,14 @@ def generate_screenshots(locale):
ScreenshotConfig(tools_views.ToolsCalcFinalWordShowFinalWordView, dict(coin_flips="0010101"), screenshot_name="ToolsCalcFinalWordShowFinalWordView_coin_flips"),
ScreenshotConfig(tools_views.ToolsCalcFinalWordDoneView),
ScreenshotConfig(tools_views.ToolsAddressExplorerSelectSourceView),
- ScreenshotConfig(tools_views.ToolsAddressExplorerAddressTypeView),
+ ScreenshotConfig(tools_views.ToolsAddressExplorerAddressTypeView, mock_context_manager=mock_multisig_wallet_descriptor_loaded),
ScreenshotConfig(tools_views.ToolsAddressExplorerAddressListView),
# ScreenshotConfig(tools_views.ToolsAddressExplorerAddressView),
],
"Settings Views": settings_views_list + [
ScreenshotConfig(settings_views.IOTestView),
ScreenshotConfig(settings_views.DonateView),
- ScreenshotConfig(settings_views.SettingsIngestSettingsQRView, dict(data=settingsqr_data_persistent), screenshot_name="SettingsIngestSettingsQRView_persistent"),
+ ScreenshotConfig(settings_views.SettingsIngestSettingsQRView, dict(data=settingsqr_data_persistent), screenshot_name="SettingsIngestSettingsQRView_persistent"),
ScreenshotConfig(settings_views.SettingsIngestSettingsQRView, dict(data=settingsqr_data_not_persistent), screenshot_name="SettingsIngestSettingsQRView_not_persistent"),
],
"Misc Error Views": [
@@ -433,7 +452,7 @@ def generate_screenshots(locale):
ScreenshotConfig(UnhandledExceptionView, dict(error=["IndexError", "line 1, in some_buggy_code.py", "list index out of range"])),
ScreenshotConfig(CameraConnectionErrorView),
ScreenshotConfig(NetworkMismatchErrorView, dict(derivation_path="m/84'/1'/0'")),
- ScreenshotConfig(OptionDisabledView, dict(settings_attr=SettingsConstants.SETTING__MESSAGE_SIGNING)),
+ ScreenshotConfig(OptionDisabledView, dict(settings_attr=SettingsConstants.SETTING__MESSAGE_SIGNING)),
ScreenshotConfig(scan_views.ScanInvalidQRTypeView)
]
}
@@ -456,9 +475,11 @@ def generate_screenshots(locale):
try:
cur_count = screenshot_renderer.render_count
- # Set up and run the target View
- screenshot_config.run_callback_before()
- screenshot_config.View_cls(**screenshot_config.view_kwargs).run()
+ # Activate the (optional) context manager for this screenshot to activate
+ # any specialized mocks/patches.
+ with screenshot_config.mock_context_manager():
+ # Set up and run the target View
+ screenshot_config.View_cls(**screenshot_config.view_kwargs).run()
if screenshot_renderer.render_count == cur_count:
# The View didn't actually render anything
@@ -485,8 +506,6 @@ def generate_screenshots(locale):
toast_thread.stop()
toast_thread.join()
- screenshot_config.run_callback_after()
-
# Parse the main `l10n/messages.pot` for overall stats
messages_source_path = os.path.join(pathlib.Path(__file__).parent.resolve().parent.resolve().parent.resolve(), "l10n", "messages.pot")
diff --git a/tests/screenshot_generator/utils.py b/tests/screenshot_generator/utils.py
index 56bfb91..0998936 100644
--- a/tests/screenshot_generator/utils.py
+++ b/tests/screenshot_generator/utils.py
@@ -1,5 +1,5 @@
import os
-
+from contextlib import contextmanager
from dataclasses import dataclass
from PIL import Image, ImageDraw
@@ -40,11 +40,11 @@ class ScreenshotRenderer(Renderer):
renderer.draw = ImageDraw.Draw(renderer.canvas)
renderer.render_count = 0
-
+
def set_screenshot_filename(self, filename:str):
self.screenshot_filename = filename
-
+
def set_screenshot_path(self, path):
if not os.path.exists(path):
@@ -73,14 +73,25 @@ class ScreenshotRenderer(Renderer):
+@contextmanager
+def default_mock_context_manager():
+ # Just a no-op context manager
+ yield
+
+
+
@dataclass
class ScreenshotConfig:
+ """
+ - mock_context_manager: Sets up temporary mock/patch context for the screenshot.
+ Ensures that there are no persistent state changes left over that might affect other
+ screenshots.
+ """
View_cls: View
view_kwargs: dict = None
screenshot_name: str = None
toast_thread: BaseToastOverlayManagerThread = None
- run_before: callable = None
- run_after: callable = None
+ mock_context_manager: callable = default_mock_context_manager
def __post_init__(self):
@@ -88,13 +99,3 @@ class ScreenshotConfig:
self.view_kwargs = {}
if not self.screenshot_name:
self.screenshot_name = self.View_cls.__name__
-
-
- def run_callback_before(self):
- if self.run_before:
- self.run_before()
-
-
- def run_callback_after(self):
- if self.run_after:
- self.run_after()
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.