f648cb1fd8
* Update the FileIOAlias naming to make the cache, project root and engine root paths more clear The alias of `@root@`, `@assets@`, and `@projectplatformcache@` has been collapsed to `@projectproductassets@` The alias of `@devroot@` and `@engroot@` has been collapsed to `@engroot@` The alias of `@devassets@` and `@projectroot@` has been collapsed to `@projectroot@` Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated use of devassets and devroot properties in python Those properties now use projectroot and engroot Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updating the alias @engroot@ alias path comment in each platform specific LocalFileIO_*.cpp file Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed hardcoded size of 9 for the product asset alias. The ResolvePath function now just appends the @projectproductassets@ alias with the input path Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Remove duplicate @projectproductassets@ check in ProcessFileTreeRequest Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fix for typos in Hydra python test Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated LocalFileIO::Copy call on Windows to use the Unicode aware CopyFileW API Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the AWSMetreicsGemAllocatorFixture to properly suppress asset cache write errors for Test file creation. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed unneeded call to set the @projectproductasstes@ alias at the bottom of the AssetSeedManagerTest SetUp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Added a deprecated alias map to the FileIO System When a deprecated alias is accessed, the FileIO System logs an AZ_Error and indicates the alias that should be used Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated python test scripts to use the projectroot binding Retrieving the AutomatedTesting project path based on "<devroot>/AutomatedTesting" has been removed. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated references to devroot and devgame within the codebase The GetAbsoluteDevGameFolderPath functions has been replaced with direct call to AZ::Utils::GetProjectPath The GetAbsoluteDevRootFolderPath functions has been replaced with direct calls to AZ::Utils::GetEnginePath Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated <engroot>/AutomatedTesting references to projectroot Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced references that assumes the project path is <engroot>/AutomatedTesting with <projectroot> in the AutomatedTesting python test Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Correct casing in emfxworkspace file Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed newly added AppendPathParts function Removed the Path constructors which accepts a PathIterable instance The PathIterable isn't safe to return to a user of the Path class as it might be referencing temporary paths supplied via PathView arguments Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed unused parameter warning Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Undid change to the LexicallyProximate function to set the path result to the base path. It needs to return the *this path if the pathResult is empty Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Moved the LocalFileIO ConvertToAbsolutePath implementations to AZ::Utils Fixed the ConvertToAbsolutePath implementation for Unix platforms to use a buffer that is size PATH_MAX(4096 on all our supported Unix platforms). Because the buffer before was AZ::IO::MaxPathLength which as a size of 1024, this was resulting in the Unix `realpath` function smashing the stack when it converts a path to an absolute path that is longer than 1024 characters Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the EditorCore.Tests to attach the AZ Environment to the EditorCore shared library that is statically loaded on launch. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed for DeprecatedAlaisesKeyVisitor Visit function causing the non string_view overloads being hidden causing a hidden base class function warning Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Changed the AWSMetricsGemMock to use a temporary for writing test assets Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the LocalFileIO::ResolvePath function to use HasRootPath to determine if a path starts with a root path such as "D:", "D:/" or "/" IsAbsolute was not the corect check as the path of "D:" is a relative path. To be absolute according to the Windows the path must have a root directory. i.e "D:/" or "D:\" Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed absolute path comment from LocalFile_UnixLike.cpp and LocalFile_Android.cpp FindFiles implementations Updated the ConvertToAlias to supply an AZ::IO::FixedMaxPath Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced usage of the @projectproductassets@ alias with @engroot@ when referring to the LmbrCentral source folder in the CopyDependencyBuilderTest and the SeedBuilderTests Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the ScriptCanvas Upgrade Tool to output backed up files to the Project User Path instead of the engine root Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed whitespacing issues in Application.cpp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Remove unnecessary creation of a FixedMaxPath in the UpgradeTool.cpp Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Modified testSeedFolder variable in the SeedBuilderTests to use the @engroot@ alias instead of @projectproductassets@/.. alias when referring to the LmbrCentral Gem source path Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated references to the Project Asset Cache in the PythonTests. Those tests no longer use the logic `azlmbr.paths.projectroot / "Cache" / "pc"` to retrieve a path to the cache root but instead the `azlmbr.paths.projectproductassets` constant Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Fixed the FileIO Deprecated Alias test on Windows Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removing @projectsourceassets@ alias, as it is only used once. Updated the PhysX EditorSystemComponent.cpp to query the ProjectPath form the SettingsRegistry. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Replaced @projectproductassets@ alias with @products@ Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Rollback changes to the PhysX EditorSystemComponent.cpp The changes to use the ProjectPath from the SettingsRegistry has been implemented in PR #4497 Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
302 lines
14 KiB
Python
Executable File
302 lines
14 KiB
Python
Executable File
"""
|
|
Copyright (c) Contributors to the Open 3D Engine Project.
|
|
For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
|
|
SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
"""
|
|
|
|
import azlmbr.bus
|
|
import azlmbr.atomtools
|
|
import azlmbr.materialeditor
|
|
import azlmbr.name
|
|
import azlmbr.render
|
|
import azlmbr.paths
|
|
import azlmbr.atom
|
|
import sys
|
|
import os.path
|
|
import filecmp
|
|
|
|
g_engroot = azlmbr.paths.engroot
|
|
sys.path.append(os.path.join(g_engroot, 'Tests', 'Atom', 'Automated'))
|
|
|
|
g_materialTestFolder = os.path.join(g_engroot,'Gems','Atom','TestData','TestData','Materials','StandardPbrTestCases')
|
|
|
|
# Change this to True to replace the expected screenshot images
|
|
g_replaceExpectedScreenshots = False
|
|
|
|
# This delay gives the material, model, and textures time to fully load before taking the screenshot
|
|
# [GFX TODO][ATOM-4819] Replace this with a callback mechanism that will allow the test to continue as soon as the content is fully loaded
|
|
g_defaultDelayFrames = 10
|
|
|
|
g_screenshotsTaken = 0
|
|
# Track the number of material screenshots that are not identical for a report at the end
|
|
g_materialsDontMatch = []
|
|
# Track screenshots that were not checked for equality because either the actual or expected file didn't exist
|
|
g_missingScreenshots = []
|
|
# Track screenshots operations that failed
|
|
g_failedScreenshots = []
|
|
|
|
class ScreenshotHelper:
|
|
"""
|
|
A helper to capture screenshots and wait for them.
|
|
"""
|
|
|
|
def __init__(self, idle_wait_frames_callback):
|
|
super().__init__()
|
|
self.done = False
|
|
self.capturedScreenshot = False
|
|
self.max_frames_to_wait = 60
|
|
|
|
self.idle_wait_frames_callback = idle_wait_frames_callback
|
|
|
|
def capture_screenshot_blocking(self, filename):
|
|
"""
|
|
Capture a screenshot and block the execution until the screenshot has been written to the disk.
|
|
"""
|
|
self.handler = azlmbr.atom.FrameCaptureNotificationBusHandler()
|
|
self.handler.connect()
|
|
self.handler.add_callback('OnCaptureFinished', self.on_screenshot_captured)
|
|
|
|
self.done = False
|
|
self.capturedScreenshot = False
|
|
success = azlmbr.atom.FrameCaptureRequestBus(azlmbr.bus.Broadcast, "CaptureScreenshot", filename)
|
|
if success:
|
|
self.wait_until_screenshot()
|
|
print("Screenshot taken.")
|
|
else:
|
|
print("screenshot failed")
|
|
return self.capturedScreenshot
|
|
|
|
def on_screenshot_captured(self, parameters):
|
|
# the parameters come in as a tuple
|
|
if parameters[0] == azlmbr.atom.FrameCaptureResult_Success:
|
|
print("screenshot saved: {}".format(parameters[1]))
|
|
self.capturedScreenshot = True
|
|
else:
|
|
print("screenshot failed: {}".format(parameters[1]))
|
|
self.done = True
|
|
self.handler.disconnect();
|
|
|
|
def wait_until_screenshot(self):
|
|
frames_waited = 0
|
|
while self.done == False:
|
|
self.idle_wait_frames_callback(1)
|
|
if frames_waited > self.max_frames_to_wait:
|
|
print("timeout while waiting for the screenshot to be written")
|
|
self.handler.disconnect()
|
|
break
|
|
else:
|
|
frames_waited = frames_waited + 1
|
|
print("(waited {} frames)".format(frames_waited))
|
|
|
|
def ToRadians(degrees):
|
|
return 3.14159 * degrees / 180.0;
|
|
|
|
def OpenMaterial(filename):
|
|
documentId = azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(azlmbr.bus.Broadcast, 'OpenDocument', os.path.join(g_materialTestFolder, filename))
|
|
return documentId
|
|
|
|
def CloseMaterial(documentId):
|
|
azlmbr.atomtools.AtomToolsDocumentSystemRequestBus(azlmbr.bus.Broadcast, 'CloseDocument', documentId)
|
|
|
|
def SelectLightingPreset(presetName):
|
|
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, 'SelectLightingPresetByName', presetName)
|
|
|
|
def SelectModelPreset(presetName):
|
|
azlmbr.materialeditor.MaterialViewportRequestBus(azlmbr.bus.Broadcast, 'SelectModelPresetByName', presetName)
|
|
|
|
def SetCameraDistance(distance):
|
|
azlmbr.render.ArcBallControllerRequestBus(azlmbr.bus.Broadcast, 'SetDistance', distance)
|
|
|
|
def SetCameraHeading(heading):
|
|
azlmbr.render.ArcBallControllerRequestBus(azlmbr.bus.Broadcast, 'SetHeading', heading)
|
|
|
|
def SetCameraPitch(pitch):
|
|
azlmbr.render.ArcBallControllerRequestBus(azlmbr.bus.Broadcast, 'SetPitch', pitch)
|
|
|
|
def IdleFrames(numFrames):
|
|
azlmbr.atomtools.general.idle_wait_frames(numFrames)
|
|
|
|
def CaptureScreenshot(screenshotOutputPath):
|
|
print("Capturing screenshot to " + screenshotOutputPath + " ...")
|
|
return ScreenshotHelper(azlmbr.atomtools.general.idle_wait_frames).capture_screenshot_blocking(screenshotOutputPath)
|
|
|
|
def ResizeViewport(width, height):
|
|
# This locks the size of the render target to the desired resolution
|
|
azlmbr.atomtools.AtomToolsMainWindowRequestBus(azlmbr.bus.Broadcast, 'LockViewportRenderTargetSize', width, height)
|
|
# This resizes the window to closely match the render target resolution so it doesn't appear stretched while the script is running
|
|
azlmbr.atomtools.AtomToolsMainWindowRequestBus(azlmbr.bus.Broadcast, 'ResizeViewportRenderTarget', width, height)
|
|
|
|
def ReleaseViewportResolutionLock():
|
|
azlmbr.atomtools.AtomToolsMainWindowRequestBus(azlmbr.bus.Broadcast, 'UnlockViewportRenderTargetSize')
|
|
|
|
def GenerateMaterialScreenshot(materialName,
|
|
uniqueSuffix="",
|
|
cameraHeading=-30.0,
|
|
cameraPitch=20.0,
|
|
cameraDistance=1.25,
|
|
lighting="Neutral Urban (Alt)",
|
|
model="Shader Ball",
|
|
delayFrames=g_defaultDelayFrames):
|
|
"""
|
|
Opens a material, takes a screenshot in the material editor viewport, and saves the file to ppm.
|
|
Also sets the camera position, lighting preset, and model for the screenshot.
|
|
The screenshots will be saved in g_materialTestFolder.
|
|
If g_replaceExpectedScreenshots is true, it will replace the baseline "expected" screenshots. Otherwise,
|
|
the screenshots will be saved alongside the "expected" screenshots for comparison.
|
|
|
|
@param materialName name of the material file to process, not including the path or ".material" extension.
|
|
@param uniqueSuffix optional name for this particular screenshot configuration. Used to make a unique filename
|
|
when taking multiple screenshots of the same material.
|
|
@param cameraHeading heading of the camera in degrees.
|
|
@param cameraPitch pitch of the camera in degrees.
|
|
@param cameraDistance distance of the camera from the center point.
|
|
@param lighting name of the lighting configuration to use.
|
|
@param model name of the model configuration to use.
|
|
@param delayFrames number of frames to delay before taking a screenshot, so the content has time to load.
|
|
"""
|
|
|
|
print("GenerateMaterialScreenshot('{}', '{}')...".format(materialName, uniqueSuffix))
|
|
|
|
global g_screenshotsTaken
|
|
global g_materialsDontMatch
|
|
global g_missingScreenshots
|
|
global g_failedScreenshots
|
|
|
|
documentId = OpenMaterial(materialName + '.material')
|
|
SelectLightingPreset(lighting)
|
|
SelectModelPreset(model)
|
|
SetCameraDistance(cameraDistance)
|
|
SetCameraHeading(ToRadians(cameraHeading))
|
|
SetCameraPitch(ToRadians(-cameraPitch))
|
|
|
|
IdleFrames(g_defaultDelayFrames); # The UI needs to time to process the changed scene data
|
|
|
|
# This delay gives the material, model, and textures time to fully load before taking the screenshot
|
|
# [GFX TODO][ATOM-4819] Replace this with a callback mechanism that will allow the test to continue as soon as the content is fully loaded
|
|
IdleFrames(delayFrames)
|
|
|
|
screenshotsFolder = os.path.join(g_materialTestFolder, "Screenshots")
|
|
uniqueFileName = materialName
|
|
if len(uniqueSuffix) > 0:
|
|
uniqueFileName = uniqueFileName + "." + uniqueSuffix
|
|
# Note we use .ppm instead of .dds because more tools support it (especially BeyondCompare and ReviewBoard).
|
|
expectedScreenshotPath = os.path.join(screenshotsFolder, uniqueFileName + ".expected.ppm")
|
|
actualScreenshotPath = os.path.join(screenshotsFolder, uniqueFileName + ".actual.ppm")
|
|
|
|
captureScreenshotPath = ""
|
|
if g_replaceExpectedScreenshots:
|
|
captureScreenshotPath = expectedScreenshotPath
|
|
else:
|
|
captureScreenshotPath = actualScreenshotPath
|
|
|
|
screenshotSuccess = CaptureScreenshot(captureScreenshotPath)
|
|
|
|
if screenshotSuccess:
|
|
g_screenshotsTaken = g_screenshotsTaken + 1
|
|
|
|
CloseMaterial(documentId)
|
|
|
|
if not screenshotSuccess:
|
|
g_failedScreenshots.append(captureScreenshotPath)
|
|
elif not os.path.exists(expectedScreenshotPath):
|
|
g_missingScreenshots.append(expectedScreenshotPath)
|
|
elif not os.path.exists(actualScreenshotPath):
|
|
g_missingScreenshots.append(actualScreenshotPath)
|
|
elif not filecmp.cmp(expectedScreenshotPath, actualScreenshotPath):
|
|
g_materialsDontMatch.append(actualScreenshotPath)
|
|
|
|
|
|
def GenerateAllMaterialScreenshots():
|
|
"""
|
|
Takes screenshots of a list of material files and saves them in g_replaceExpectedScreenshots
|
|
"""
|
|
|
|
# First open any material to ensure the tab bar shows up before we resize the viewport. Otherwise the First
|
|
# screenshot might have a different size from the others.
|
|
OpenMaterial('001_DefaultWhite.material')
|
|
# [GFX TODO][ATOM-4909] We have to use the strange viewport size because of limitations in both the RPI and QT. The RPI doesn't provide
|
|
# ResizeViewportRenderTarget() support on both dx12 and vulkan. And QT can't resize to specific resolutions in device-pixel units (we can
|
|
# achieve 999x999 and 1001x1001 but not 1000x1000 for example).
|
|
ResizeViewport(999, 999)
|
|
IdleFrames(g_defaultDelayFrames); # Allows the UI to refresh before continuing; otherwise the viewport will appear stretched while the user waits a second for the screen capture.
|
|
|
|
GenerateMaterialScreenshot('001_DefaultWhite')
|
|
GenerateMaterialScreenshot('002_BaseColorLerp')
|
|
GenerateMaterialScreenshot('002_BaseColorLinearLight')
|
|
GenerateMaterialScreenshot('002_BaseColorMultiply')
|
|
GenerateMaterialScreenshot('003_MetalMatte')
|
|
GenerateMaterialScreenshot('003_MetalPolished')
|
|
GenerateMaterialScreenshot('004_MetalMap')
|
|
GenerateMaterialScreenshot('005_RoughnessMap')
|
|
GenerateMaterialScreenshot('006_SpecularF0Map')
|
|
GenerateMaterialScreenshot('007_MultiscatteringCompensationOff')
|
|
GenerateMaterialScreenshot('007_MultiscatteringCompensationOn')
|
|
GenerateMaterialScreenshot('008_NormalMap')
|
|
GenerateMaterialScreenshot('008_NormalMap_Bevels')
|
|
GenerateMaterialScreenshot('009_Opacity_Blended', lighting="Neutral Urban", model="Cube (Beveled)")
|
|
GenerateMaterialScreenshot('009_Opacity_Cutout_PackedAlpha_DoubleSided', lighting="Neutral Urban", model="Cube (Beveled)")
|
|
GenerateMaterialScreenshot('009_Opacity_Cutout_SplitAlpha_DoubleSided', lighting="Neutral Urban", model="Cube (Beveled)")
|
|
GenerateMaterialScreenshot('009_Opacity_Cutout_SplitAlpha_SingleSided', lighting="Neutral Urban", model="Cube (Beveled)")
|
|
GenerateMaterialScreenshot('010_AmbientOcclusion')
|
|
GenerateMaterialScreenshot('011_Emissive')
|
|
GenerateMaterialScreenshot('012_Parallax_POM', model="Cube", cameraHeading=-35.0, cameraPitch=35.0)
|
|
GenerateMaterialScreenshot('013_SpecularAA_Off', lighting="Dark Test Lighting")
|
|
GenerateMaterialScreenshot('013_SpecularAA_On', lighting="Dark Test Lighting")
|
|
GenerateMaterialScreenshot('100_UvTiling_AmbientOcclusion')
|
|
GenerateMaterialScreenshot('100_UvTiling_BaseColor')
|
|
GenerateMaterialScreenshot('100_UvTiling_Emissive')
|
|
GenerateMaterialScreenshot('100_UvTiling_Metallic')
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal')
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_Rotate20', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_Rotate90', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_ScaleOnlyU', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_ScaleOnlyV', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_ScaleUniform', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Normal_Dome_TransformAll', model="Cube", lighting="Dark Test Lighting", cameraHeading=225.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Opacity', lighting="Neutral Urban")
|
|
GenerateMaterialScreenshot('100_UvTiling_Parallax_A', uniqueSuffix="Angle1", model="Cube", cameraHeading=35.0, cameraPitch=35.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Parallax_A', uniqueSuffix="Angle2", model="Cube", cameraHeading=125.0, cameraPitch=35.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Parallax_B', uniqueSuffix="Angle1", model="Cube", cameraHeading=0.0, cameraPitch=45.0, cameraDistance=1.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Parallax_B', uniqueSuffix="Angle2", model="Cube", cameraHeading=90.0, cameraPitch=45.0, cameraDistance=1.0)
|
|
GenerateMaterialScreenshot('100_UvTiling_Roughness')
|
|
GenerateMaterialScreenshot('100_UvTiling_SpecularF0')
|
|
|
|
ReleaseViewportResolutionLock()
|
|
|
|
|
|
def main():
|
|
global g_screenshotsTaken
|
|
global g_materialsDontMatch
|
|
global g_missingScreenshots
|
|
global g_failedScreenshots
|
|
g_screenshotsTaken = 0
|
|
g_materialsDontMatch = []
|
|
g_missingScreenshots = []
|
|
g_failedScreenshots = []
|
|
|
|
print("==== Begin screenshot script ==========================================================")
|
|
|
|
GenerateAllMaterialScreenshots()
|
|
|
|
print("==== Summary Report ===================================================================")
|
|
|
|
print("Screenshots taken: {}".format(g_screenshotsTaken))
|
|
|
|
print("Screenshots failed: {}".format(len(g_failedScreenshots)))
|
|
print(g_failedScreenshots)
|
|
|
|
print("Missing screenshots: {}".format(len(g_missingScreenshots)))
|
|
print(g_missingScreenshots)
|
|
|
|
print("\n(The following stats are for informational purposes. A mismatched file doesn't necessarily mean a test failed. Mismatched files will need to be image-diffed in another tool.)")
|
|
|
|
print("Mismatched screenshots: {}".format(len(g_materialsDontMatch)))
|
|
print(g_materialsDontMatch)
|
|
|
|
print("==== End screenshot script ============================================================")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|