public void WhenEqualBmp() { ImageAssert.AreEqual(Properties.Resources.SquareBmp, Properties.Resources.SquareBmp); ImageAssert.AreEqual(Properties.Resources.SquareBmp, Properties.Resources.SquareBmp, _ => { }); }
[Timeout(450 * 1000)] // Increase timeout to handle complex scenes with many shaders and XR variants public IEnumerator Run(GraphicsTestCase testCase) { #if UNITY_EDITOR while (SceneView.sceneViews.Count > 0) { var sceneView = SceneView.sceneViews[0] as SceneView; sceneView.Close(); } #endif SceneManagement.SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var testSettingsInScene = Object.FindObjectOfType <GraphicsTestSettings>(); var vfxTestSettingsInScene = Object.FindObjectOfType <VFXGraphicsTestSettings>(); var imageComparisonSettings = new ImageComparisonSettings() { AverageCorrectnessThreshold = VFXGraphicsTestSettings.defaultAverageCorrectnessThreshold }; if (testSettingsInScene != null) { imageComparisonSettings = testSettingsInScene.ImageComparisonSettings; } if (XRGraphicsAutomatedTests.enabled) { bool xrCompatible = vfxTestSettingsInScene != null ? vfxTestSettingsInScene.xrCompatible : true; Unity.Testing.XR.Runtime.ConfigureMockHMD.SetupTest(xrCompatible, 0, imageComparisonSettings); } //Setup frame rate capture float simulateTime = VFXGraphicsTestSettings.defaultSimulateTime; int captureFrameRate = VFXGraphicsTestSettings.defaultCaptureFrameRate; if (vfxTestSettingsInScene != null) { simulateTime = vfxTestSettingsInScene.simulateTime; captureFrameRate = vfxTestSettingsInScene.captureFrameRate; } float period = 1.0f / captureFrameRate; Time.captureFramerate = captureFrameRate; UnityEngine.VFX.VFXManager.fixedTimeStep = period; UnityEngine.VFX.VFXManager.maxDeltaTime = period; //Waiting for the capture frame rate to be effective const int maxFrameWaiting = 8; int maxFrame = maxFrameWaiting; while (Time.deltaTime != period && maxFrame-- > 0) { yield return(new WaitForEndOfFrame()); } Assert.Greater(maxFrame, 0); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera) { var vfxComponents = Resources.FindObjectsOfTypeAll <VisualEffect>(); var rt = RenderTexture.GetTemporary(imageComparisonSettings.TargetWidth, imageComparisonSettings.TargetHeight, 24); camera.targetTexture = rt; //Waiting for the rendering to be ready, if at least one component has been culled, camera is ready maxFrame = maxFrameWaiting; while (vfxComponents.All(o => o.culled) && maxFrame-- > 0) { yield return(new WaitForEndOfFrame()); } Assert.Greater(maxFrame, 0); foreach (var component in vfxComponents) { component.Reinit(); } #if UNITY_EDITOR //When we change the graph, if animator was already enable, we should reinitialize animator to force all BindValues var animators = Resources.FindObjectsOfTypeAll <Animator>(); foreach (var animator in animators) { animator.Rebind(); } var audioSources = Resources.FindObjectsOfTypeAll <AudioSource>(); #endif var paramBinders = Resources.FindObjectsOfTypeAll <VFXPropertyBinder>(); foreach (var paramBinder in paramBinders) { var binders = paramBinder.GetPropertyBinders <VFXBinderBase>(); foreach (var binder in binders) { binder.Reset(); } } if (XRGraphicsAutomatedTests.running) { camera.targetTexture = null; } int waitFrameCount = (int)(simulateTime / period); int startFrameIndex = Time.frameCount; int expectedFrameIndex = startFrameIndex + waitFrameCount; while (Time.frameCount != expectedFrameIndex) { yield return(new WaitForEndOfFrame()); #if UNITY_EDITOR foreach (var audioSource in audioSources) { if (audioSource.clip != null && audioSource.playOnAwake) { audioSource.PlayDelayed(Mathf.Repeat(simulateTime, audioSource.clip.length)); } } #endif } try { camera.targetTexture = null; ImageAssert.AreEqual(testCase.ReferenceImage, camera, imageComparisonSettings); } finally { RenderTexture.ReleaseTemporary(rt); } } }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Arbitrary wait for 5 frames for the scene to load, and other stuff to happen (like Realtime GI to appear ...) for (int i = 0; i < 5; ++i) { yield return(null); } // Load the test settings var settings = GameObject.FindObjectOfType <HDRP_TestSettings>(); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera == null) { camera = GameObject.FindObjectOfType <Camera>(); } if (camera == null) { Assert.Fail("Missing camera for graphic tests."); } Time.captureFramerate = settings.captureFramerate; if (XRSystem.testModeEnabled) { if (settings.xrCompatible) { XRSystem.automatedTestRunning = true; // Increase tolerance to account for slight changes due to float precision settings.ImageComparisonSettings.AverageCorrectnessThreshold *= settings.xrThresholdMultiplier; settings.ImageComparisonSettings.PerPixelCorrectnessThreshold *= settings.xrThresholdMultiplier; } else { // Skip incompatible XR tests yield break; } } if (settings.doBeforeTest != null) { settings.doBeforeTest.Invoke(); // Wait again one frame, to be sure. yield return(null); } for (int i = 0; i < settings.waitFrames; ++i) { yield return(null); } var settingsSG = (GameObject.FindObjectOfType <HDRP_TestSettings>() as HDRP_ShaderGraph_TestSettings); if (settingsSG == null || !settingsSG.compareSGtoBI) { // Standard Test ImageAssert.AreEqual(testCase.ReferenceImage, camera, settings?.ImageComparisonSettings); if (settings.checkMemoryAllocation) { // Does it allocate memory when it renders what's on camera? bool allocatesMemory = false; try { // GC alloc from Camera.CustomRender (case 1206364) int gcAllocThreshold = 2; #if UNITY_2019_3 // In case playmode tests for XR are enabled in 2019.3 we allow one GC alloc from XRSystem:120 if (XRSystem.testModeEnabled) { gcAllocThreshold += 1; } #endif ImageAssert.AllocatesMemory(camera, settings?.ImageComparisonSettings, gcAllocThreshold); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on camera"); } } } else { if (settingsSG.sgObjs == null) { Assert.Fail("Missing Shader Graph objects in test scene."); } if (settingsSG.biObjs == null) { Assert.Fail("Missing comparison objects in test scene."); } settingsSG.sgObjs.SetActive(true); settingsSG.biObjs.SetActive(false); yield return(null); // Wait a frame yield return(null); bool sgFail = false; bool biFail = false; // First test: Shader Graph try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { sgFail = true; } settingsSG.sgObjs.SetActive(false); settingsSG.biObjs.SetActive(true); settingsSG.biObjs.transform.position = settingsSG.sgObjs.transform.position; // Move to the same location. yield return(null); // Wait a frame yield return(null); // Second test: HDRP/Lit Materials try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { biFail = true; } // Informs which ImageAssert failed, if any. if (sgFail && biFail) { Assert.Fail("Both Shader Graph and Non-Shader Graph Objects failed to match the reference image"); } else if (sgFail) { Assert.Fail("Shader Graph Objects failed."); } else if (biFail) { Assert.Fail("Non-Shader Graph Objects failed to match Shader Graph objects."); } } }
public IEnumerator Run(GraphicsTestCase testCase) { CleanUp(); SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); //Get Test settings //ignore instead of failing, because some scenes might not be used for GraphicsTest var settings = Object.FindObjectOfType <GraphicsTestSettingsCustom>(); if (settings == null) { Assert.Ignore("Ignoring this test for GraphicsTest because couldn't find GraphicsTestSettingsCustom"); } #if !UNITY_EDITOR Screen.SetResolution(settings.ImageComparisonSettings.TargetWidth, settings.ImageComparisonSettings.TargetHeight, false); #endif var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); //var settings = Object.FindObjectOfType<UniversalGraphicsTestSettings>(); //Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); //Scene scene = SceneManager.GetActiveScene(); yield return(null); int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } if (XRGraphicsAutomatedTests.enabled) { waitFrames = Unity.Testing.XR.Runtime.ConfigureMockHMD.SetupTest(true, waitFrames, settings.ImageComparisonSettings); } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); }
public void WhenNotEqual() { using (var app = Application.AttachOrLaunch(ExeFileName, "SizeWindow")) { var window = app.MainWindow; var fileName = Path.Combine(TestContext.CurrentContext.TestDirectory, @"Images\button.png"); var exception = Assert.Throws <NUnit.Framework.AssertionException>(() => ImageAssert.AreEqual(fileName, window)); Assert.AreEqual("Sizes did not match\r\nExpected: {Width=200, Height=100}\r\nActual: {Width=300, Height=300}", exception.Message); } }
public void When_Text_is_Constrained_Then_Clipping_is_Applied() { Run("Uno.UI.Samples.Content.UITests.TextBlockControl.TextBlock_ConstrainedByContainer"); // 1) Take a screenshot of the whole sample // 2) Switch opacity of text to zero // 3) Take new screenshot // 4) Compare Right zone -- must be identical // 5) Compare Bottom zone -- must be identical // 6) Do the same for subsequent text block in sample (1 to 5) // // +-sampleRootPanel------------+--------------+ // | | | // | +-borderX---------------+ | // | | [textX]Lorem ipsum... | | // | +-----------------------+ Right zone | // | | | | // | | Bottom zone | | // | | | | // +----+-----------------------+--------------+ // (1) using var sampleScreenshot = this.TakeScreenshot("fullSample", ignoreInSnapshotCompare: true); var sampleRect = _app.GetPhysicalRect("sampleRootPanel"); using var _ = new AssertionScope(); Test("text1", "border1"); Test("text2", "border2"); Test("text3", "border3"); Test("text4", "border4"); Test("text5", "border5"); void Test(string textControl, string borderControl) { var textRect = _app.GetPhysicalRect(borderControl); // (2) _app.Marked(textControl).SetDependencyPropertyValue("Opacity", "0"); // (3) using var afterScreenshot = this.TakeScreenshot("sample-" + textControl, ignoreInSnapshotCompare: true); // (4) using (var s = new AssertionScope("Right zone")) { var rect1 = new AppRect( x: textRect.Right, y: sampleRect.Y, width: sampleRect.Right - textRect.Right, height: sampleRect.Height) .DeflateBy(1f); ImageAssert.AreEqual(sampleScreenshot, rect1, afterScreenshot, rect1); } // (5) using (var s = new AssertionScope("Bottom zone")) { var rect2 = new AppRect( x: textRect.X, y: textRect.Bottom, width: textRect.Width, height: sampleRect.Height - textRect.Bottom) .DeflateBy(1f); ImageAssert.AreEqual(sampleScreenshot, rect2, afterScreenshot, rect2); } } }
public IEnumerator Run(GraphicsTestCase testCase) { // #if ENABLE_VR // // XRTODO: Fix XR tests on macOS or disable them from Yamato directly // if (XRGraphicsAutomatedTests.enabled && (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)) // Assert.Ignore("Universal XR tests do not run on macOS."); // #endif SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); var gltf = Object.FindObjectOfType <GltfBoundsAsset>(); Assert.IsNotNull(gltf, "Invalid test scene, couldn't find GltfAsset"); var task = gltf.Load(gltf.FullUrl); while (!task.IsCompleted) { yield return(null); } // position camera based on AABB var cam = cameras.First(); FrameBoundsCamera.FrameBounds(cam, gltf.transform, gltf.bounds); // #if ENABLE_VR // if (XRGraphicsAutomatedTests.enabled) // { // if (settings.XRCompatible) // { // XRGraphicsAutomatedTests.running = true; // } // else // { // Assert.Ignore("Test scene is not compatible with XR and will be skipped."); // } // } // #endif Scene scene = SceneManager.GetActiveScene(); yield return(null); int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); try { ImageAssert.AllocatesMemory(mainCamera, settings?.ImageComparisonSettings); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } }
public void WhenEqualBmpPng() { ImageAssert.AreEqual(Properties.Resources.SquareBmp, Properties.Resources.SquarePng); ImageAssert.AreEqual(Properties.Resources.SquarePng, Properties.Resources.SquareBmp); }
public IEnumerator Run(GraphicsTestCase testCase) { // #if ENABLE_VR // // XRTODO: Fix XR tests on macOS or disable them from Yamato directly // if (XRGraphicsAutomatedTests.enabled && (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)) // Assert.Ignore("Universal XR tests do not run on macOS."); // #endif SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); var gltf = Object.FindObjectOfType <GltfBoundsAsset>(); Assert.IsNotNull(gltf, "Invalid test scene, couldn't find GltfAsset"); var task = gltf.Load(gltf.FullUrl); while (!task.IsCompleted) { yield return(null); } var success = task.Result; if (success && !gltf.currentSceneId.HasValue) { // glTF has no default scene. Fallback to the first scene success = gltf.InstantiateScene(0); } IEnumerable <Camera> cameras; Camera testCamera = null; if (success && gltf.sceneInstance?.cameras != null && gltf.sceneInstance.cameras.Count > 0) { // Look for glTF cameras cameras = gltf.sceneInstance.cameras; foreach (var cam in cameras) { if (testCamera == null) { testCamera = cam; } cam.backgroundColor = new Color(1f, 1f, 1f, 0f); cam.clearFlags = CameraClearFlags.SolidColor; #if USING_HDRP var hdAdd = cam.gameObject.AddComponent <HDAdditionalCameraData>(); if (hdAdd != null) { hdAdd.clearColorMode = HDAdditionalCameraData.ClearColorMode.Color; hdAdd.backgroundColorHDR = new Color(1, 1, 1, 0); } #endif } } else { // position main camera based on AABB cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()).Where(x => x != null); testCamera = cameras.First(); FrameBoundsCamera.FrameBounds(testCamera, gltf.transform, gltf.bounds); } if (success) { var animation = gltf.gameObject.transform.GetComponentInChildren <Animation>(); if (animation != null && animation.clip != null) { animation.Stop(); var clip = animation.clip; animation.clip.SampleAnimation(animation.gameObject, clip.length * .5f); // animation.Sample(); } } // #if ENABLE_VR // if (XRGraphicsAutomatedTests.enabled) // { // if (settings.XRCompatible) // { // XRGraphicsAutomatedTests.running = true; // } // else // { // Assert.Ignore("Test scene is not compatible with XR and will be skipped."); // } // } // #endif Scene scene = SceneManager.GetActiveScene(); yield return(null); int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, testCamera, settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? // bool allocatesMemory = false; // var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>(); // try // { // ImageAssert.AllocatesMemory(mainCamera, settings?.ImageComparisonSettings); // } // catch (AssertionException) // { // allocatesMemory = true; // } // if (allocatesMemory) // Assert.Fail("Allocated memory when rendering what is on main camera"); }
public void AreEqual_WithTotallyDifferentImages_ThrowsAssertionException() { Assert.That(() => ImageAssert.AreEqual(Texture2D.whiteTexture, Texture2D.blackTexture), Throws.InstanceOf <AssertionException>()); }
public void AreEqual_WithNullCamera_ThrowsArgumentNullException() { Assert.That(() => ImageAssert.AreEqual(new Texture2D(1, 1), (Camera)null), Throws.ArgumentNullException); }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); Scene scene = SceneManager.GetActiveScene(); if (scene.name.Substring(3, 4).Equals("_xr_")) { #if ENABLE_VR && ENABLE_VR_MODULE Assume.That((Application.platform != RuntimePlatform.OSXEditor && Application.platform != RuntimePlatform.OSXPlayer), "Stereo Universal tests do not run on MacOSX."); XRSettings.LoadDeviceByName("MockHMD"); yield return(null); XRSettings.enabled = true; yield return(null); XRSettings.gameViewRenderMode = GameViewRenderMode.BothEyes; yield return(null); foreach (var camera in cameras) { camera.stereoTargetEye = StereoTargetEyeMask.Both; } #else yield return(null); #endif } else { #if ENABLE_VR && ENABLE_VR_MODULE XRSettings.enabled = false; #endif yield return(null); } for (int i = 0; i < settings.WaitFrames; i++) { yield return(null); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); // 2D Renderer is currently allocating memory, skip it as it will always fail GC alloc tests. var additionalCameraData = mainCamera.GetUniversalAdditionalCameraData(); bool is2DRenderer = additionalCameraData.scriptableRenderer is Renderer2D; // Post-processing is allocating memory. Case https://fogbugz.unity3d.com/f/cases/1227490/ bool isPostProcessingEnabled = additionalCameraData.renderPostProcessing; if (!is2DRenderer && !isPostProcessingEnabled) { try { ImageAssert.AllocatesMemory(mainCamera, settings?.ImageComparisonSettings); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } } }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); //Get Test settings //ignore instead of failing, because some scenes might not be used for GraphicsTest var settings = Object.FindObjectOfType <GraphicsTestSettingsCustom>(); if (settings == null) { Assert.Ignore("Ignoring this test for GraphicsTest because couldn't find GraphicsTestSettingsCustom"); } #if !UNITY_EDITOR Screen.SetResolution(settings.ImageComparisonSettings.TargetWidth, settings.ImageComparisonSettings.TargetHeight, false); #endif var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); //var settings = Object.FindObjectOfType<UniversalGraphicsTestSettings>(); //Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); //Scene scene = SceneManager.GetActiveScene(); yield return(null); int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } //Grpahics Test Framework does not support multi-camera test for Mac Standalone //This is my workaround as it works if (Application.platform == RuntimePlatform.OSXPlayer && settings.ImageComparisonSettings.UseBackBuffer) { settings.ImageComparisonSettings.UseBackBuffer = false; settings.gameObject.AddComponent <MultiCamFix>(); for (int i = 0; i < waitFrames; i++) { yield return(null); } } else { for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <HDRPUTS_GraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find HDRPyUTS_GraphicsTestSettings"); Scene scene = SceneManager.GetActiveScene(); if (scene.name.Substring(3, 4).Equals("_xr_")) { #if ENABLE_VR && ENABLE_VR_MODULE Assume.That((Application.platform != RuntimePlatform.OSXEditor && Application.platform != RuntimePlatform.OSXPlayer), "Stereo HDRP tests do not run on MacOSX."); XRSettings.LoadDeviceByName("MockHMD"); yield return(null); XRSettings.enabled = true; yield return(null); XRSettings.gameViewRenderMode = GameViewRenderMode.BothEyes; yield return(null); foreach (var camera in cameras) { camera.stereoTargetEye = StereoTargetEyeMask.Both; } #else yield return(null); #endif } else { #if ENABLE_VR && ENABLE_VR_MODULE XRSettings.enabled = false; #endif yield return(null); } int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); // 2D Renderer is currently allocating memory, skip it as it will always fail GC alloc tests. //var additionalCameraData = mainCamera.GetHDRPAdditionalCameraData(); bool is2DRenderer = false; // additionalCameraData.scriptableRenderer is Renderer2D; if (!is2DRenderer) { try { ImageAssert.AllocatesMemory(mainCamera, settings.ImageComparisonSettings); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } } }
public void WhenEqualPng() { ImageAssert.AreEqual(Properties.Resources.SquarePng, Properties.Resources.SquarePng); ImageAssert.AreEqual(Properties.Resources.SquarePng, Properties.Resources.SquarePng, _ => { }); }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Arbitrary wait for 5 frames for the scene to load, and other stuff to happen (like Realtime GI to appear ...) for (int i = 0; i < 5; ++i) { yield return(null); } // Load the test settings var settings = GameObject.FindObjectOfType <HDRP_TestSettings>(); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera == null) { camera = GameObject.FindObjectOfType <Camera>(); } if (camera == null) { Assert.Fail("Missing camera for graphic tests."); } Time.captureFramerate = settings.captureFramerate; if (settings.doBeforeTest != null) { settings.doBeforeTest.Invoke(); // Wait again one frame, to be sure. yield return(null); } for (int i = 0; i < settings.waitFrames; ++i) { yield return(null); } var settingsSG = (GameObject.FindObjectOfType <HDRP_TestSettings>() as HDRP_ShaderGraph_TestSettings); if (settingsSG == null || !settingsSG.compareSGtoBI) { // Standard Test ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } else { if (settingsSG.sgObjs == null) { Assert.Fail("Missing Shader Graph objects in test scene."); } if (settingsSG.biObjs == null) { Assert.Fail("Missing comparison objects in test scene."); } settingsSG.sgObjs.SetActive(true); settingsSG.biObjs.SetActive(false); yield return(null); // Wait a frame yield return(null); bool sgFail = false; bool biFail = false; // First test: Shader Graph try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { sgFail = true; } settingsSG.sgObjs.SetActive(false); settingsSG.biObjs.SetActive(true); settingsSG.biObjs.transform.position = settingsSG.sgObjs.transform.position; // Move to the same location. yield return(null); // Wait a frame yield return(null); // Second test: HDRP/Lit Materials try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { biFail = true; } // Informs which ImageAssert failed, if any. if (sgFail && biFail) { Assert.Fail("Both Shader Graph and Non-Shader Graph Objects failed to match the reference image"); } else if (sgFail) { Assert.Fail("Shader Graph Objects failed."); } else if (biFail) { Assert.Fail("Non-Shader Graph Objects failed to match Shader Graph objects."); } } }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <LWGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find LWGraphicsTestSettings"); // Stereo screen capture on Mac generates monoscopic images and won't be fixed. Assume.That((Application.platform != RuntimePlatform.OSXEditor && Application.platform != RuntimePlatform.OSXPlayer), "Stereo tests do not run on MacOSX."); var referenceImage = testCase.ReferenceImage; // make sure we're rendering in the same size as the reference image, otherwise this is not really comparable. Screen.SetResolution(referenceImage.width, referenceImage.height, FullScreenMode.Windowed); XRSettings.gameViewRenderMode = GameViewRenderMode.BothEyes; yield return(null); foreach (var camera in cameras) { camera.stereoTargetEye = StereoTargetEyeMask.Both; } var tempScreenshotFile = Path.ChangeExtension(Path.GetTempFileName(), ".png"); // clean up previous file if it happens to exist at this point if (FileAvailable(tempScreenshotFile)) { System.IO.File.Delete(tempScreenshotFile); } for (int i = 0; i < settings.WaitFrames; i++) { yield return(null); } // wait for rendering to complete yield return(new WaitForEndOfFrame()); // we'll take a screenshot here, as what we want to compare is the actual result on-screen. // ScreenCapture.CaptureScreenshotAsTexture --> does not work since colorspace is wrong, would need colorspace change and thus color compression // ScreenCapture.CaptureScreenshotIntoRenderTexture --> does not work since texture is flipped, would need another pass // so we need to capture and reload the resulting file. ScreenCapture.CaptureScreenshot(tempScreenshotFile); // NOTE: there's discussions around whether Unity has actually documented this correctly. // Unity says: next frame MUST have the file ready // Community says: not true, file write might take longer, so have to explicitly check the file handle before use // https://forum.unity.com/threads/how-to-wait-for-capturescreen-to-complete.172194/ yield return(null); while (!FileAvailable(tempScreenshotFile)) { yield return(null); } // load the screenshot back into memory and change to the same format as we want to compare with var actualImage = new Texture2D(1, 1); actualImage.LoadImage(System.IO.File.ReadAllBytes(tempScreenshotFile)); if (actualImage.width != referenceImage.width || actualImage.height != referenceImage.height) { Debug.LogWarning("[" + testCase.ScenePath + "] Image size differs (ref: " + referenceImage.width + "x" + referenceImage.height + " vs. actual: " + actualImage.width + "x" + actualImage.height + "). " + (Application.isEditor ? " is your GameView set to a different resolution than the reference images?" : "is your build size different than the reference images?")); actualImage = ChangeTextureSize(actualImage, referenceImage.width, referenceImage.height); } // ref is usually in RGB24 or RGBA32 while actual is in ARGB32, we need to convert formats if (referenceImage.format != actualImage.format) { actualImage = ChangeTextureFormat(actualImage, referenceImage.format); } // delete temporary file File.Delete(tempScreenshotFile); // for testing // File.WriteAllBytes("reference.png", referenceImage.EncodeToPNG()); // File.WriteAllBytes("actual.png", actualImage.EncodeToPNG()); ImageAssert.AreEqual(referenceImage, actualImage, settings.ImageComparisonSettings); }
public IEnumerator Run(GraphicsTestCase testCase) { // XRTODO: Fix XR tests on macOS or disable them from Yamato directly if (XRSystem.testModeEnabled && (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)) { Assert.Ignore("Universal XR tests do not run on macOS."); } SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); if (XRSystem.testModeEnabled) { if (settings.XRCompatible) { XRSystem.automatedTestRunning = true; } else { Assert.Ignore("Test scene is not compatible with XR and will be skipped."); } } Scene scene = SceneManager.GetActiveScene(); yield return(null); int waitFrames = settings.WaitFrames; if (settings.ImageComparisonSettings.UseBackBuffer && settings.WaitFrames < 1) { waitFrames = 1; } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); // 2D Renderer is currently allocating memory, skip it as it will always fail GC alloc tests. var additionalCameraData = mainCamera.GetUniversalAdditionalCameraData(); bool is2DRenderer = additionalCameraData.scriptableRenderer is Renderer2D; if (!is2DRenderer) { try { ImageAssert.AllocatesMemory(mainCamera, settings?.ImageComparisonSettings); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } } }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); Scene scene = SceneManager.GetActiveScene(); if (scene.name.Substring(3, 4).Equals("_xr_")) { Assume.That((Application.platform != RuntimePlatform.OSXEditor && Application.platform != RuntimePlatform.OSXPlayer), "Stereo Universal tests do not run on MacOSX."); XRSettings.LoadDeviceByName("MockHMD"); yield return(null); XRSettings.enabled = true; yield return(null); XRSettings.gameViewRenderMode = GameViewRenderMode.BothEyes; yield return(null); foreach (var camera in cameras) { camera.stereoTargetEye = StereoTargetEyeMask.Both; } } else { XRSettings.enabled = false; yield return(null); } for (int i = 0; i < settings.WaitFrames; i++) { yield return(null); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(null); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); #if CHECK_ALLOCATIONS_WHEN_RENDERING // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); try { ImageAssert.AllocatesMemory(mainCamera, 512, 512); // 512 used for height and width to render } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } #endif }
private void TestOpacityFinalState([CallerMemberName] string testName = null) { var match = Regex.Match(testName, @"When_Opacity_(?<type>\w+)_With_FillBehavior(?<fill>\w+)_Then_(?<expected>\w+)"); if (!match.Success) { throw new InvalidOperationException("Invalid test name."); } var type = match.Groups["type"].Value; var fill = match.Groups["fill"].Value; var expected = match.Groups["expected"].Value; bool isSame = false, isGray = false, isDifferent = false; switch (type) { case "Completed" when expected == "Hold": isGray = true; break; case "Completed" when expected == "Rollback": isSame = true; break; case "Paused": isDifferent = true; break; case "Canceled": isSame = true; break; default: throw new InvalidOperationException("Invalid test name."); } Run(_finalStateOpacityTestControl, skipInitialScreenshot: true); var initial = TakeScreenshot("Initial", ignoreInSnapshotCompare: true); var element = _app.WaitForElement($"{type}AnimationHost_{fill}").Single().Rect; _app.Marked("StartButton").FastTap(); _app.WaitForDependencyPropertyValue(_app.Marked("Status"), "Text", "Completed"); // Assert var final = TakeScreenshot("Final", ignoreInSnapshotCompare: true); if (isSame) { ImageAssert.AreEqual(initial, final, element); } else if (isGray) { ImageAssert.HasColorAt(final, element.CenterX, element.CenterY, Color.LightGray); } else if (isDifferent) { ImageAssert.AreNotEqual(initial, final, element); ImageAssert.DoesNotHaveColorAt(final, element.CenterX, element.CenterY, Color.LightGray); } }
public IEnumerator Run(GraphicsTestCase testCase) { #if UNITY_EDITOR while (SceneView.sceneViews.Count > 0) { var sceneView = SceneView.sceneViews[0] as SceneView; sceneView.Close(); } #endif SceneManagement.SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera) { var vfxComponents = Resources.FindObjectsOfTypeAll <VisualEffect>(); #if UNITY_EDITOR var vfxAssets = vfxComponents.Select(o => o.visualEffectAsset).Where(o => o != null).Distinct(); foreach (var vfx in vfxAssets) { //Use Reflection as workaround of the access issue in .net 4 (TODO : Clean this as soon as possible) //var graph = vfx.GetResource().GetOrCreateGraph(); is possible with .net 3.5 but compilation fail with 4.0 var visualEffectAssetExt = AppDomain.CurrentDomain.GetAssemblies().Select(o => o.GetType("UnityEditor.VFX.VisualEffectAssetExtensions")) .Where(o => o != null) .FirstOrDefault(); var fnGetResource = visualEffectAssetExt.GetMethod("GetResource"); fnGetResource = fnGetResource.MakeGenericMethod(new Type[] { typeof(VisualEffectAsset) }); var resource = fnGetResource.Invoke(null, new object[] { vfx }); var fnGetOrCreate = visualEffectAssetExt.GetMethod("GetOrCreateGraph"); var graph = fnGetOrCreate.Invoke(null, new object[] { resource }) as VFXGraph; graph.RecompileIfNeeded(); } #endif var rt = RenderTexture.GetTemporary(captureSize, captureSize, 24); camera.targetTexture = rt; foreach (var component in vfxComponents) { component.Reinit(); } #if UNITY_EDITOR //When we change the graph, if animator was already enable, we should reinitialize animator to force all BindValues var animators = Resources.FindObjectsOfTypeAll <Animator>(); foreach (var animator in animators) { animator.Rebind(); } var audioSources = Resources.FindObjectsOfTypeAll <AudioSource>(); #endif var paramBinders = Resources.FindObjectsOfTypeAll <VFXPropertyBinder>(); foreach (var paramBinder in paramBinders) { var binders = paramBinder.GetParameterBinders <VFXBinderBase>(); foreach (var binder in binders) { binder.Reset(); } } int waitFrameCount = (int)(simulateTime / frequency); int startFrameIndex = Time.frameCount; int expectedFrameIndex = startFrameIndex + waitFrameCount; while (Time.frameCount != expectedFrameIndex) { yield return(null); #if UNITY_EDITOR foreach (var audioSource in audioSources) { if (audioSource.clip != null && audioSource.playOnAwake) { audioSource.PlayDelayed(Mathf.Repeat(simulateTime, audioSource.clip.length)); } } #endif } Texture2D actual = null; try { camera.targetTexture = null; actual = new Texture2D(captureSize, captureSize, TextureFormat.RGB24, false); RenderTexture.active = rt; actual.ReadPixels(new Rect(0, 0, captureSize, captureSize), 0, 0); RenderTexture.active = null; actual.Apply(); var imageComparisonSettings = new ImageComparisonSettings() { AverageCorrectnessThreshold = 5e-4f }; var testSettingsInScene = Object.FindObjectOfType <GraphicsTestSettings>(); if (testSettingsInScene != null) { imageComparisonSettings.AverageCorrectnessThreshold = testSettingsInScene.ImageComparisonSettings.AverageCorrectnessThreshold; } if (!ExcludedTestsButKeepLoadScene.Any(o => testCase.ScenePath.Contains(o)) && !(SystemInfo.graphicsDeviceType == GraphicsDeviceType.Metal && UnstableMetalTests.Any(o => testCase.ScenePath.Contains(o)))) { ImageAssert.AreEqual(testCase.ReferenceImage, actual, imageComparisonSettings); } else { Debug.LogFormat("GraphicTest '{0}' result has been ignored", testCase.ReferenceImage); } } finally { RenderTexture.ReleaseTemporary(rt); if (actual != null) { UnityEngine.Object.Destroy(actual); } } } }
public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Always wait one frame for scene load yield return(null); var cameras = GameObject.FindGameObjectsWithTag("MainCamera").Select(x => x.GetComponent <Camera>()); var settings = Object.FindObjectOfType <UniversalGraphicsTestSettings>(); Assert.IsNotNull(settings, "Invalid test scene, couldn't find UniversalGraphicsTestSettings"); int waitFrames = Unity.Testing.XR.Runtime.ConfigureMockHMD.SetupTest(settings.XRCompatible, settings.WaitFrames, settings.ImageComparisonSettings); Scene scene = SceneManager.GetActiveScene(); yield return(null); if (settings.ImageComparisonSettings.UseBackBuffer && waitFrames < 1) { waitFrames = 1; } for (int i = 0; i < waitFrames; i++) { yield return(new WaitForEndOfFrame()); } #if UNITY_ANDROID // On Android first scene often needs a bit more frames to load all the assets // otherwise the screenshot is just a black screen if (!wasFirstSceneRan) { for (int i = 0; i < firstSceneAdditionalFrames; i++) { yield return(new WaitForEndOfFrame()); } wasFirstSceneRan = true; } #endif ImageAssert.AreEqual(testCase.ReferenceImage, cameras.Where(x => x != null), settings.ImageComparisonSettings); // Does it allocate memory when it renders what's on the main camera? bool allocatesMemory = false; var mainCamera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); try { ImageAssert.AllocatesMemory(mainCamera, settings?.ImageComparisonSettings); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on main camera"); } }
[Timeout(300 * 1000)] // Set timeout to 5 minutes to handle complex scenes with many shaders (default timeout is 3 minutes) public IEnumerator Run(GraphicsTestCase testCase) { SceneManager.LoadScene(testCase.ScenePath); // Arbitrary wait for 5 frames for the scene to load, and other stuff to happen (like Realtime GI to appear ...) for (int i = 0; i < 5; ++i) { yield return(null); } // Load the test settings var settings = GameObject.FindObjectOfType <HDRP_TestSettings>(); var camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent <Camera>(); if (camera == null) { camera = GameObject.FindObjectOfType <Camera>(); } if (camera == null) { Assert.Fail("Missing camera for graphic tests."); } Time.captureFramerate = settings.captureFramerate; if (XRGraphicsAutomatedTests.enabled) { if (settings.xrCompatible) { XRGraphicsAutomatedTests.running = true; // Increase tolerance to account for slight changes due to float precision settings.ImageComparisonSettings.AverageCorrectnessThreshold *= settings.xrThresholdMultiplier; settings.ImageComparisonSettings.PerPixelCorrectnessThreshold *= settings.xrThresholdMultiplier; // Increase number of volumetric slices to compensate for initial half-resolution due to XR single-pass optimization foreach (var volume in GameObject.FindObjectsOfType <Volume>()) { if (volume.profile.TryGet <Fog>(out Fog fog)) { fog.volumeSliceCount.value *= 2; } } } else { Assert.Ignore("Test scene is not compatible with XR and will be skipped."); } } if (HDRenderPipeline.enableRenderGraphTests) { if (!settings.renderGraphCompatible) { Assert.Ignore("Test scene is not compatible with Render Graph and will be skipped."); } } if (settings.doBeforeTest != null) { settings.doBeforeTest.Invoke(); // Wait again one frame, to be sure. yield return(null); } // Reset temporal effects on hdCamera HDCamera.GetOrCreate(camera).Reset(); for (int i = 0; i < settings.waitFrames; ++i) { yield return(null); } var settingsSG = (GameObject.FindObjectOfType <HDRP_TestSettings>() as HDRP_ShaderGraph_TestSettings); if (settingsSG == null || !settingsSG.compareSGtoBI) { // Standard Test ImageAssert.AreEqual(testCase.ReferenceImage, camera, settings?.ImageComparisonSettings); if (settings.checkMemoryAllocation) { // Does it allocate memory when it renders what's on camera? bool allocatesMemory = false; try { // GC alloc from Camera.CustomRender (case 1206364) int gcAllocThreshold = 2; ImageAssert.AllocatesMemory(camera, settings?.ImageComparisonSettings, gcAllocThreshold); } catch (AssertionException) { allocatesMemory = true; } if (allocatesMemory) { Assert.Fail("Allocated memory when rendering what is on camera"); } } } else { if (settingsSG.sgObjs == null) { Assert.Fail("Missing Shader Graph objects in test scene."); } if (settingsSG.biObjs == null) { Assert.Fail("Missing comparison objects in test scene."); } settingsSG.sgObjs.SetActive(true); settingsSG.biObjs.SetActive(false); yield return(null); // Wait a frame yield return(null); bool sgFail = false; bool biFail = false; // First test: Shader Graph try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { sgFail = true; } settingsSG.sgObjs.SetActive(false); settingsSG.biObjs.SetActive(true); settingsSG.biObjs.transform.position = settingsSG.sgObjs.transform.position; // Move to the same location. yield return(null); // Wait a frame yield return(null); // Second test: HDRP/Lit Materials try { ImageAssert.AreEqual(testCase.ReferenceImage, camera, (settings != null)?settings.ImageComparisonSettings:null); } catch (AssertionException) { biFail = true; } // Informs which ImageAssert failed, if any. if (sgFail && biFail) { Assert.Fail("Both Shader Graph and Non-Shader Graph Objects failed to match the reference image"); } else if (sgFail) { Assert.Fail("Shader Graph Objects failed."); } else if (biFail) { Assert.Fail("Non-Shader Graph Objects failed to match Shader Graph objects."); } } }
private void TestTransformsFinalState([CallerMemberName] string testName = null) { var match = Regex.Match(testName, @"When_Transforms_(?<type>\w+)_With_FillBehavior(?<fill>\w+)_Then_(?<expected>\w+)"); if (!match.Success) { throw new InvalidOperationException("Invalid test name."); } var type = match.Groups["type"].Value; var fill = match.Groups["fill"].Value; var expected = match.Groups["expected"].Value; int expectedDelta, tolerance = 0; switch (type) { case "Completed" when expected == "Hold": expectedDelta = 150; break; case "Completed" when expected == "Rollback": expectedDelta = 0; break; case "Paused": expectedDelta = 150 / 2; tolerance = 50; // We only want to validate that the element is not at 0 or 150 break; case "Canceled": expectedDelta = 0; break; default: throw new InvalidOperationException("Invalid test name."); } Run(_finalStateTransformsTestControl, skipInitialScreenshot: true); using var initial = TakeScreenshot("Initial", ignoreInSnapshotCompare: true); var initialLocation = _app.WaitForElement($"{type}AnimationHost_{fill}").Single().Rect; var scale = ((int)initialLocation.Width) / 50; expectedDelta *= scale; tolerance *= scale; _app.Marked("StartButton").FastTap(); _app.WaitForDependencyPropertyValue(_app.Marked("Status"), "Text", "Completed"); // Assert using var final = TakeScreenshot("Final", ignoreInSnapshotCompare: true); var finalLocation = _app.WaitForElement($"{type}AnimationHost_{fill}").Single().Rect; var actualDelta = finalLocation.Y - initialLocation.Y; // For some reason, the finalLocation might not reflect the effective location of the control, // instead we rely on pixel validation ... // Assert.IsTrue(Math.Abs(actualDelta - expectedDelta) <= tolerance); if (expectedDelta > 0) { ImageAssert.AreNotEqual(initial, final, initialLocation); } else { ImageAssert.AreEqual(initial, final, initialLocation); } }