""" E2E test: Real Blender addon testing in Docker with ZERO mocks. This test validates the entire addon workflow in an actual Blender instance: 1. Package addon as zip 2. Install in real Blender (in Docker container) 3. Enable the addon 4. Execute texture generation with real text (including umlauts) 5. Verify texture is created successfully NO MOCKS: - Real bpy (Blender Python API) - Real PIL (bundled with addon) - Real addon code (generate_texture_image) - Real Docker container with actual Blender """ import pytest from pathlib import Path import tarfile import io def test_shader_creation_with_texture_generates_successfully( blender_container, addon_package, tmp_path ): """ E2E test: Install addon in real Blender and create texture shader. This test uses ZERO mocks - everything runs in real Blender in Docker. Test scenario (the exact bug case): - Text: "böhm Kabel" + "NYY" (German umlauts) - Dimensions: 4096x512 - Expected: Texture generated successfully with actual text rendering - Bug symptom: "Failed to generate texture image" error OR PIL import error Asserts: - No "Failed to generate texture image" error - No PIL import errors (addon dependencies must work) - Texture exists in bpy.data.images - Texture has correct dimensions (4096x512) - Shader nodes created and connected """ # Copy test script to container using tar archive test_script = Path(__file__).parent / "scripts" / "test_texture_generation.py" # Create tar archive with test script tar_stream = io.BytesIO() with tarfile.open(fileobj=tar_stream, mode='w') as tar: # Add test script script_info = tarfile.TarInfo(name='test_script.py') script_info.size = test_script.stat().st_size with open(test_script, 'rb') as f: tar.addfile(script_info, f) tar_stream.seek(0) blender_container.put_archive('/addon-test', tar_stream) # Copy addon package to container addon_tar_stream = io.BytesIO() with tarfile.open(fileobj=addon_tar_stream, mode='w') as tar: addon_info = tarfile.TarInfo(name='text_texture_generator.zip') addon_info.size = addon_package.stat().st_size with open(addon_package, 'rb') as f: tar.addfile(addon_info, f) addon_tar_stream.seek(0) blender_container.put_archive('/addon-test', addon_tar_stream) container_script_path = "/addon-test/test_script.py" container_addon_path = "/addon-test/text_texture_generator.zip" # Install addon in Blender install_cmd = [ "/usr/local/bin/run_blender.sh", "--background", "--python-expr", ( "import bpy; " f"bpy.ops.preferences.addon_install(filepath='{container_addon_path}'); " "bpy.ops.preferences.addon_enable(module='text_texture_generator'); " "bpy.ops.wm.save_userpref()" ) ] install_result = blender_container.exec_run( install_cmd, workdir="/addon-test" ) # Check installation succeeded assert install_result.exit_code == 0, ( f"Addon installation failed with exit code {install_result.exit_code}\n" f"Output: {install_result.output.decode('utf-8', errors='replace')}" ) # Run the test script in Blender test_cmd = [ "/usr/local/bin/run_blender.sh", "--background", "--python", container_script_path ] test_result = blender_container.exec_run( test_cmd, workdir="/addon-test" ) output = test_result.output.decode('utf-8', errors='replace') # Parse output for results print("\n=== Blender Test Output ===") print(output) print("=== End Output ===\n") # Assert: Script must exit with success code assert test_result.exit_code == 0, ( f"Test script failed with exit code {test_result.exit_code}\n" f"Output: {output}" ) # Assert: Must see SUCCESS marker in output assert "SUCCESS" in output, ( f"Expected SUCCESS marker in output, got:\n{output}" ) # Assert: Must NOT see failure to generate texture assert "Failed to generate texture image" not in output, ( f"Texture generation failed - bug still present!\n{output}" ) # Assert: PIL must be available (no dependency errors allowed) assert "ERROR: PIL dependency not available" not in output, ( f"PIL dependency not properly installed by Blender!\n{output}" ) # Assert: Texture was created with correct dimensions assert "created with size 4096x512" in output, ( f"Texture not created with expected dimensions\n{output}" ) # Assert: Shader nodes were created and connected assert "Shader nodes created and connected" in output, ( f"Shader nodes not properly set up\n{output}" )