Files
temp/tests/features/steps/template_loaders_coverage_steps.py.disabled

925 lines
31 KiB
Plaintext

"""Step definitions for template loaders coverage tests."""
import os
import tempfile
from pathlib import Path
from unittest.mock import Mock, MagicMock
from behave import given, when, then
from cleveragents.core.exceptions import TemplateError
from cleveragents.templates.loaders import (
TemplateLoader,
FileTemplateLoader,
DirectoryTemplateLoader,
ConfigTemplateLoader,
load_from_file,
load_from_string,
)
from cleveragents.templates.renderer import TemplateRenderer
@given("I have a clean test environment for template loaders")
def step_clean_environment_loaders(context):
"""Set up clean test environment."""
context.temp_files = []
context.temp_dirs = []
context.mock_renderer = None
context.loader = None
context.result = None
context.error = None
context.file_paths = []
context.directory_path = None
context.template_content = None
@given("I have a template renderer for loaders")
def step_template_renderer_loaders(context):
"""Create a mock template renderer."""
context.mock_renderer = Mock(spec=TemplateRenderer)
context.mock_renderer.register_template = Mock()
@when("I create a base TemplateLoader instance")
def step_create_base_loader(context):
"""Create a base TemplateLoader instance."""
context.loader = TemplateLoader(context.mock_renderer)
@then("the TemplateLoader should be initialized with renderer")
def step_verify_loader_initialized(context):
"""Verify TemplateLoader is initialized with renderer."""
assert context.loader is not None
assert context.loader.renderer == context.mock_renderer
@then("the renderer should be accessible")
def step_verify_renderer_accessible(context):
"""Verify renderer is accessible."""
assert hasattr(context.loader, "renderer")
assert context.loader.renderer is not None
@given("I have a base TemplateLoader instance")
def step_have_base_loader(context):
"""Create a base TemplateLoader instance."""
context.loader = TemplateLoader(context.mock_renderer)
@when("I call the load method on base TemplateLoader")
def step_call_base_loader_load(context):
"""Call load method on base TemplateLoader."""
try:
context.loader.load()
except Exception as e:
context.error = e
@then("a NotImplementedError should be raised")
def step_verify_not_implemented_error(context):
"""Verify NotImplementedError is raised."""
assert context.error is not None
assert isinstance(context.error, NotImplementedError)
@then('the not implemented error message should be correct')
def step_verify_not_implemented_message(context):
"""Verify error message content."""
assert "Method 'load' is not implemented yet" in str(context.error)
@given("I have valid file paths for templates")
def step_valid_file_paths(context):
"""Create valid file paths."""
context.file_paths = [Path("/tmp/template1.j2"), Path("/tmp/template2.j2")]
@when("I create a FileTemplateLoader instance")
def step_create_file_loader(context):
"""Create FileTemplateLoader instance."""
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
@then("the FileTemplateLoader should be initialized correctly")
def step_verify_file_loader_init(context):
"""Verify FileTemplateLoader initialization."""
assert context.loader is not None
assert context.loader.renderer == context.mock_renderer
assert context.loader.file_paths == context.file_paths
@then("the file paths should be stored")
def step_verify_file_paths_stored(context):
"""Verify file paths are stored."""
assert hasattr(context.loader, "file_paths")
assert context.loader.file_paths == context.file_paths
@given("I have temporary template files created")
def step_create_temp_files(context):
"""Create temporary template files."""
context.temp_files = []
context.file_paths = []
# Create first temp file
temp1 = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
temp1.write("Template 1 content: {{ variable1 }}")
temp1.close()
context.temp_files.append(temp1.name)
context.file_paths.append(Path(temp1.name))
# Create second temp file
temp2 = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
temp2.write("Template 2 content: {{ variable2 }}")
temp2.close()
context.temp_files.append(temp2.name)
context.file_paths.append(Path(temp2.name))
@when("I create and use FileTemplateLoader to load templates")
def step_use_file_loader(context):
"""Create and use FileTemplateLoader."""
try:
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
context.loader.load()
except Exception as e:
context.error = e
@then("the templates should be loaded successfully")
def step_verify_templates_loaded(context):
"""Verify templates loaded successfully."""
assert context.error is None
assert context.mock_renderer.register_template.call_count == len(context.file_paths)
@then("the templates should be registered with the renderer")
def step_verify_templates_registered(context):
"""Verify templates are registered."""
assert context.mock_renderer.register_template.called
assert context.mock_renderer.register_template.call_count > 0
@then("the template names should be derived from file stems")
def step_verify_template_names_from_stems(context):
"""Verify template names come from file stems."""
calls = context.mock_renderer.register_template.call_args_list
for i, call in enumerate(calls):
expected_name = Path(context.temp_files[i]).stem
actual_name = call[0][0] # First argument to register_template
assert actual_name == expected_name
@given("I have a non-existent file path")
def step_non_existent_file_path(context):
"""Create non-existent file path."""
context.file_paths = [Path("/non/existent/file.j2")]
@when("I create and use FileTemplateLoader with non-existent file")
def step_use_file_loader_non_existent(context):
"""Use FileTemplateLoader with non-existent file."""
try:
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
context.loader.load()
except Exception as e:
context.error = e
@then("a TemplateError should be raised")
def step_verify_template_error(context):
"""Verify TemplateError is raised."""
assert context.error is not None
assert isinstance(context.error, TemplateError)
@then('the template file not found error should be raised')
def step_verify_file_not_found_error(context):
"""Verify error mentions file not found."""
assert "Template file not found" in str(context.error)
@given("I have an unreadable file path")
def step_unreadable_file_path(context):
"""Create unreadable file path."""
# Create a temp file and make it unreadable
temp = tempfile.NamedTemporaryFile(mode="w", suffix=".j2", delete=False)
temp.write("content")
temp.close()
# Make file unreadable
os.chmod(temp.name, 0o000)
context.temp_files.append(temp.name)
context.file_paths = [Path(temp.name)]
@when("I create and use FileTemplateLoader with unreadable file")
def step_use_file_loader_unreadable(context):
"""Use FileTemplateLoader with unreadable file."""
try:
context.loader = FileTemplateLoader(context.mock_renderer, context.file_paths)
context.loader.load()
except Exception as e:
context.error = e
@then('the failed to load template file error should be raised')
def step_verify_failed_load_error(context):
"""Verify error mentions failed to load."""
assert "Failed to load template from file" in str(context.error)
@given("I have a valid directory path")
def step_valid_directory_path(context):
"""Create valid directory path."""
context.directory_path = Path(tempfile.mkdtemp())
context.temp_dirs.append(str(context.directory_path))
@when("I create a DirectoryTemplateLoader instance")
def step_create_directory_loader(context):
"""Create DirectoryTemplateLoader instance."""
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
@then("the DirectoryTemplateLoader should be initialized correctly")
def step_verify_directory_loader_init(context):
"""Verify DirectoryTemplateLoader initialization."""
assert context.loader is not None
assert context.loader.renderer == context.mock_renderer
assert context.loader.directory_path == context.directory_path
assert context.loader.recursive is True # default
assert context.loader.pattern == "*.j2" # default
@then("the directory path should be stored")
def step_verify_directory_path_stored(context):
"""Verify directory path is stored."""
assert hasattr(context.loader, "directory_path")
assert context.loader.directory_path == context.directory_path
@then("the recursive flag should be set correctly")
def step_verify_recursive_flag(context):
"""Verify recursive flag is set."""
assert hasattr(context.loader, "recursive")
assert context.loader.recursive is True
@then("the pattern should be set correctly")
def step_verify_pattern_set(context):
"""Verify pattern is set."""
assert hasattr(context.loader, "pattern")
assert context.loader.pattern == "*.j2"
@when("I create a DirectoryTemplateLoader with custom parameters")
def step_create_directory_loader_custom(context):
"""Create DirectoryTemplateLoader with custom parameters."""
context.loader = DirectoryTemplateLoader(
context.mock_renderer,
context.directory_path,
recursive=False,
pattern="*.txt"
)
@then("the DirectoryTemplateLoader should be initialized with custom settings")
def step_verify_directory_loader_custom_init(context):
"""Verify DirectoryTemplateLoader custom initialization."""
assert context.loader is not None
assert context.loader.renderer == context.mock_renderer
assert context.loader.directory_path == context.directory_path
@then("the recursive flag should be false")
def step_verify_recursive_false(context):
"""Verify recursive flag is false."""
assert context.loader.recursive is False
@then('the pattern should be "*.txt"')
def step_verify_pattern_txt(context):
"""Verify pattern is *.txt."""
assert context.loader.pattern == "*.txt"
@given("I have a temporary directory with template files")
def step_temp_directory_with_files(context):
"""Create temporary directory with template files."""
context.directory_path = Path(tempfile.mkdtemp())
context.temp_dirs.append(str(context.directory_path))
# Create template files
temp_files = []
for i in range(2):
temp_file = context.directory_path / f"template{i+1}.j2"
with open(temp_file, "w") as f:
f.write(f"Template {i+1} content: {{{{ variable{i+1} }}}}")
temp_files.append(str(temp_file))
context.temp_files.extend(temp_files)
@when("I create and use DirectoryTemplateLoader to load templates")
def step_use_directory_loader(context):
"""Use DirectoryTemplateLoader to load templates."""
try:
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
context.loader.load()
except Exception as e:
context.error = e
@then("the templates should be loaded from directory")
def step_verify_templates_loaded_from_directory(context):
"""Verify templates loaded from directory."""
assert context.error is None
assert context.mock_renderer.register_template.called
@then("the templates should be registered with correct names")
def step_verify_correct_template_names(context):
"""Verify templates registered with correct names."""
calls = context.mock_renderer.register_template.call_args_list
assert len(calls) > 0
# Verify template names are derived correctly
for call in calls:
template_name = call[0][0]
assert isinstance(template_name, str)
assert len(template_name) > 0
@then("the template names should use relative paths")
def step_verify_relative_path_names(context):
"""Verify template names use relative paths."""
calls = context.mock_renderer.register_template.call_args_list
for call in calls:
template_name = call[0][0]
# Should not contain absolute path elements
assert not template_name.startswith("/")
@given("I have a temporary directory with nested template files")
def step_temp_directory_nested_files(context):
"""Create temporary directory with nested template files."""
context.directory_path = Path(tempfile.mkdtemp())
context.temp_dirs.append(str(context.directory_path))
# Create root level file
root_file = context.directory_path / "root.j2"
with open(root_file, "w") as f:
f.write("Root template content")
context.temp_files.append(str(root_file))
# Create nested directory and file
nested_dir = context.directory_path / "nested"
nested_dir.mkdir()
nested_file = nested_dir / "nested.j2"
with open(nested_file, "w") as f:
f.write("Nested template content")
context.temp_files.append(str(nested_file))
@when("I create and use DirectoryTemplateLoader with non-recursive setting")
def step_use_directory_loader_non_recursive(context):
"""Use DirectoryTemplateLoader with non-recursive setting."""
try:
context.loader = DirectoryTemplateLoader(
context.mock_renderer,
context.directory_path,
recursive=False
)
context.loader.load()
except Exception as e:
context.error = e
@then("only templates from root directory should be loaded")
def step_verify_only_root_templates(context):
"""Verify only root templates loaded."""
assert context.error is None
calls = context.mock_renderer.register_template.call_args_list
# Should only have root template, not nested
assert len(calls) == 1
template_name = calls[0][0][0]
assert template_name == "root"
@then("nested templates should not be loaded")
def step_verify_nested_templates_not_loaded(context):
"""Verify nested templates not loaded."""
calls = context.mock_renderer.register_template.call_args_list
template_names = [call[0][0] for call in calls]
# Should not contain nested template names
for name in template_names:
assert "nested" not in name or "/" not in name
@given("I have a temporary directory with mixed file types")
def step_temp_directory_mixed_files(context):
"""Create temporary directory with mixed file types."""
context.directory_path = Path(tempfile.mkdtemp())
context.temp_dirs.append(str(context.directory_path))
# Create .j2 file
j2_file = context.directory_path / "template.j2"
with open(j2_file, "w") as f:
f.write("J2 template content")
context.temp_files.append(str(j2_file))
# Create .txt file
txt_file = context.directory_path / "template.txt"
with open(txt_file, "w") as f:
f.write("TXT template content")
context.temp_files.append(str(txt_file))
# Create .html file
html_file = context.directory_path / "template.html"
with open(html_file, "w") as f:
f.write("HTML template content")
context.temp_files.append(str(html_file))
@when("I create and use DirectoryTemplateLoader with custom pattern")
def step_use_directory_loader_custom_pattern(context):
"""Use DirectoryTemplateLoader with custom pattern."""
try:
context.loader = DirectoryTemplateLoader(
context.mock_renderer,
context.directory_path,
pattern="*.txt"
)
context.loader.load()
except Exception as e:
context.error = e
@then("only matching files should be loaded")
def step_verify_only_matching_files(context):
"""Verify only matching files loaded."""
assert context.error is None
calls = context.mock_renderer.register_template.call_args_list
# Should only have txt template
assert len(calls) == 1
template_name = calls[0][0][0]
assert template_name == "template"
@then("non-matching files should be ignored")
def step_verify_non_matching_ignored(context):
"""Verify non-matching files ignored."""
calls = context.mock_renderer.register_template.call_args_list
# Should not have j2 or html templates
template_names = [call[0][0] for call in calls]
assert len(template_names) == 1
assert "template" in template_names
@given("I have a non-existent directory path")
def step_non_existent_directory_path(context):
"""Create non-existent directory path."""
context.directory_path = Path("/non/existent/directory")
@when("I create and use DirectoryTemplateLoader with non-existent directory")
def step_use_directory_loader_non_existent(context):
"""Use DirectoryTemplateLoader with non-existent directory."""
try:
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
context.loader.load()
except Exception as e:
context.error = e
@then('the template directory not found error should be raised')
def step_verify_directory_not_found_error(context):
"""Verify error mentions directory not found."""
assert "Template directory not found" in str(context.error)
@given("I have a file path instead of directory")
def step_file_instead_of_directory(context):
"""Create file path instead of directory."""
temp = tempfile.NamedTemporaryFile(delete=False)
temp.write(b"content")
temp.close()
context.temp_files.append(temp.name)
context.directory_path = Path(temp.name)
@when("I create and use DirectoryTemplateLoader with file path")
def step_use_directory_loader_with_file(context):
"""Use DirectoryTemplateLoader with file path."""
try:
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
context.loader.load()
except Exception as e:
context.error = e
@then('the not a directory error should be raised')
def step_verify_not_directory_error(context):
"""Verify error mentions not a directory."""
assert "Not a directory" in str(context.error)
@given("I have a directory with unreadable template file")
def step_directory_with_unreadable_file(context):
"""Create directory with unreadable template file."""
context.directory_path = Path(tempfile.mkdtemp())
context.temp_dirs.append(str(context.directory_path))
# Create unreadable file
temp_file = context.directory_path / "template.j2"
with open(temp_file, "w") as f:
f.write("content")
# Make file unreadable
os.chmod(temp_file, 0o000)
context.temp_files.append(str(temp_file))
@when("I create and use DirectoryTemplateLoader with problematic directory")
def step_use_directory_loader_problematic(context):
"""Use DirectoryTemplateLoader with problematic directory."""
try:
context.loader = DirectoryTemplateLoader(context.mock_renderer, context.directory_path)
context.loader.load()
except Exception as e:
context.error = e
@given("I have a valid config dictionary")
def step_valid_config_dictionary(context):
"""Create valid config dictionary."""
context.template_config = {
"templates": {
"template1": "Template 1 content: {{ var1 }}",
"template2": "Template 2 content: {{ var2 }}"
}
}
@when("I create a ConfigTemplateLoader instance")
def step_create_config_loader(context):
"""Create ConfigTemplateLoader instance."""
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
@then("the ConfigTemplateLoader should be initialized correctly")
def step_verify_config_loader_init(context):
"""Verify ConfigTemplateLoader initialization."""
assert context.loader is not None
assert context.loader.renderer == context.mock_renderer
assert context.loader.config == context.template_config
@then("the config should be stored")
def step_verify_config_stored(context):
"""Verify config is stored."""
assert hasattr(context.loader, "config")
assert context.loader.config == context.template_config
@given("I have a config with string templates")
def step_config_with_string_templates(context):
"""Create config with string templates."""
context.template_config = {
"templates": {
"string_template1": "String template 1: {{ var1 }}",
"string_template2": "String template 2: {{ var2 }}"
}
}
@when("I create and use ConfigTemplateLoader to load templates")
def step_use_config_loader(context):
"""Use ConfigTemplateLoader to load templates."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@then("the string templates should be loaded")
def step_verify_string_templates_loaded(context):
"""Verify string templates loaded."""
assert context.error is None
assert context.mock_renderer.register_template.call_count == 2
@then("the string templates should be registered with correct names")
def step_verify_config_template_names(context):
"""Verify templates registered with correct names."""
calls = context.mock_renderer.register_template.call_args_list
template_names = [call[0][0] for call in calls]
assert "string_template1" in template_names
assert "string_template2" in template_names
@given("I have a config with dict templates containing content")
def step_config_with_dict_templates(context):
"""Create config with dict templates."""
context.template_config = {
"templates": {
"dict_template1": {
"content": "Dict template 1: {{ var1 }}",
"metadata": {"type": "dict"}
},
"dict_template2": {
"content": "Dict template 2: {{ var2 }}",
"metadata": {"type": "dict"}
}
}
}
@when("I create and use ConfigTemplateLoader to load dict templates")
def step_use_config_loader_dict(context):
"""Use ConfigTemplateLoader to load dict templates."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@then("the dict templates should be loaded")
def step_verify_dict_templates_loaded(context):
"""Verify dict templates loaded."""
assert context.error is None
assert context.mock_renderer.register_template.call_count == 2
@then("only the content should be registered")
def step_verify_only_content_registered(context):
"""Verify only content is registered."""
calls = context.mock_renderer.register_template.call_args_list
for call in calls:
template_content = call[0][1] # Second argument is content
assert "Dict template" in template_content
assert "{{ var" in template_content
@given("I have an empty config dictionary")
def step_empty_config_dictionary(context):
"""Create empty config dictionary."""
context.template_config = {}
@when("I create and use ConfigTemplateLoader with empty config")
def step_use_config_loader_empty(context):
"""Use ConfigTemplateLoader with empty config."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@then("no templates should be loaded")
def step_verify_no_templates_loaded(context):
"""Verify no templates loaded."""
assert context.error is None
assert context.mock_renderer.register_template.call_count == 0
@then("no errors should occur")
def step_verify_no_errors(context):
"""Verify no errors occurred."""
assert context.error is None
@given("I have a config without templates section for loaders")
def step_config_without_templates(context):
"""Create config without templates section."""
context.template_config = {
"other_section": {
"key": "value"
}
}
@when("I create and use ConfigTemplateLoader with config without templates")
def step_use_config_loader_no_templates(context):
"""Use ConfigTemplateLoader with config without templates."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@given("I have a config with invalid template definition")
def step_config_with_invalid_template(context):
"""Create config with invalid template definition."""
context.template_config = {
"templates": {
"valid_template": "Valid content",
"invalid_template": ["invalid", "list", "format"]
}
}
@when("I create and use ConfigTemplateLoader with invalid config")
def step_use_config_loader_invalid(context):
"""Use ConfigTemplateLoader with invalid config."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@then('the invalid template definition error should be raised')
def step_verify_invalid_template_error(context):
"""Verify error mentions invalid template definition."""
assert "Invalid template definition" in str(context.error)
@given("I have a config that will cause processing exception")
def step_config_causing_exception(context):
"""Create config that will cause processing exception."""
# Create a mock renderer that raises an exception
context.mock_renderer.register_template.side_effect = Exception("Mock exception")
context.template_config = {
"templates": {
"template1": "Content"
}
}
@when("I create and use ConfigTemplateLoader with problematic config")
def step_use_config_loader_problematic(context):
"""Use ConfigTemplateLoader with problematic config."""
try:
context.loader = ConfigTemplateLoader(context.mock_renderer, context.template_config)
context.loader.load()
except Exception as e:
context.error = e
@then('the failed to load from configuration error should be raised')
def step_verify_config_load_error(context):
"""Verify error mentions failed to load from configuration."""
assert "Failed to load templates from configuration" in str(context.error)
@given("I have a temporary file with content")
def step_temp_file_with_content(context):
"""Create temporary file with content."""
temp = tempfile.NamedTemporaryFile(mode="w", delete=False)
context.template_content = "Test file content: {{ variable }}"
temp.write(context.template_content)
temp.close()
context.temp_files.append(temp.name)
context.file_path = temp.name
@when("I call load_from_file with the file path")
def step_call_load_from_file(context):
"""Call load_from_file function."""
try:
context.result = load_from_file(context.file_path)
except Exception as e:
context.error = e
@then("the file content should be returned")
def step_verify_file_content_returned(context):
"""Verify file content is returned."""
assert context.error is None
assert context.result is not None
assert isinstance(context.result, str)
@then("the content should match the original")
def step_verify_content_matches(context):
"""Verify content matches original."""
assert context.result == context.template_content
@given("I have a non-existent file path for load_from_file")
def step_non_existent_file_load_from_file(context):
"""Create non-existent file path for load_from_file."""
context.file_path = "/non/existent/file.txt"
@when("I call load_from_file with non-existent path")
def step_call_load_from_file_non_existent(context):
"""Call load_from_file with non-existent path."""
try:
context.result = load_from_file(context.file_path)
except Exception as e:
context.error = e
@then("None should be returned from load_from_file")
def step_verify_none_returned(context):
"""Verify None is returned."""
assert context.error is None
assert context.result is None
@given("I have an unreadable file for load_from_file")
def step_unreadable_file_load_from_file(context):
"""Create unreadable file for load_from_file."""
temp = tempfile.NamedTemporaryFile(mode="w", delete=False)
temp.write("content")
temp.close()
# Make file unreadable
os.chmod(temp.name, 0o000)
context.temp_files.append(temp.name)
context.file_path = temp.name
@when("I call load_from_file with unreadable file")
def step_call_load_from_file_unreadable(context):
"""Call load_from_file with unreadable file."""
try:
context.result = load_from_file(context.file_path)
except Exception as e:
context.error = e
@given("I have a template string for load_from_string")
def step_template_string(context):
"""Create template string."""
context.template_content = "Template string content: {{ variable }}"
@when("I call load_from_string with the template string")
def step_call_load_from_string(context):
"""Call load_from_string function."""
try:
context.result = load_from_string(context.template_content)
except Exception as e:
context.error = e
@then("the same string should be returned")
def step_verify_same_string_returned(context):
"""Verify same string is returned."""
assert context.error is None
assert context.result is not None
@then("the returned string should be identical to input")
def step_verify_identical_string(context):
"""Verify returned string is identical."""
assert context.result == context.template_content
assert context.result is context.template_content # Should be same object
def cleanup_test_files(context):
"""Clean up temporary files and directories."""
# Clean up temp files
for temp_file in getattr(context, 'temp_files', []):
try:
if os.path.exists(temp_file):
# Restore permissions before deletion
os.chmod(temp_file, 0o644)
os.unlink(temp_file)
except (OSError, PermissionError):
pass
# Clean up temp directories
for temp_dir in getattr(context, 'temp_dirs', []):
try:
if os.path.exists(temp_dir):
# Restore permissions for all files in directory
for root, dirs, files in os.walk(temp_dir):
for d in dirs:
try:
os.chmod(os.path.join(root, d), 0o755)
except (OSError, PermissionError):
pass
for f in files:
try:
os.chmod(os.path.join(root, f), 0o644)
except (OSError, PermissionError):
pass
import shutil
shutil.rmtree(temp_dir)
except (OSError, PermissionError):
pass
# Register cleanup function
def after_scenario(context, scenario):
"""Clean up after each scenario."""
cleanup_test_files(context)