unoplatform / uno

Open-source platform for building cross-platform native Mobile, Web, Desktop and Embedded apps quickly. Create rich, C#/XAML, single-codebase apps from any IDE. Hot Reload included! 90m+ NuGet Downloads!!
https://platform.uno
Apache License 2.0
9.08k stars 736 forks source link

[UI Tests] Move image based tests to runtime tests #9811

Open jeromelaban opened 2 years ago

jeromelaban commented 2 years ago

What would you like to be added:

Many UI tests on Android and iOS are using "remote" screenshots which take a significant amount of time to run (1 second per screenshot in general) that do not validate actual UI interactions.

Moving these UI tests (most of which are using ImageAssert) to be Runtime Tests would help decrease significantly the CI build time.

Here's a (non-exhaustive) list of test that could be migrated:

Why is this needed:

More performant CI, with more platforms to be validated as part of the runtime tests.

amelield commented 2 years ago

When_Stretch() is using screenshots. So if the screenshot doesn't work in web assembly, should exclude Wasm from that test? I was trying to find a workaround that reproduce the same results(without much success). Or do anyone know a good way to make it works.

jeromelaban commented 2 years ago

That's correct. WebAssembly cannot make screenshots at this time, so we need to skip this test using #if !__WASM__.

amelield commented 2 years ago

In Skia, I can't find what kind of import or interface could make TakeScreenshot(String) works; I see there are possibilities (in Runtimes or others places) but non of those I tried fixed the TakeScreenshot not existing in context.

jeromelaban commented 2 years ago

Here are a few of those, using the RenderTargetBitmap API (an equivalent of TakeScreenshot, but in-app): https://github.com/unoplatform/uno/blob/aa9311da1926bd52df96ec152cb7585d3c8d74a3/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_Opacity.cs#L37-L72

amelield commented 2 years ago

Thank you

amelield commented 2 years ago

Do I need to put a link to an image in the Image_Brush and if so where can I find it?

jeromelaban commented 2 years ago

@amelield which image are you referring to?

amelield commented 2 years ago

@jeromelaban The image who create that comportment here. I am not sure where it come from in the code. It is also possible it is not needed.

jeromelaban commented 2 years ago

This is what await renderer.RenderAsync(SUT); does. You won't be able to "see" the image, but ImageAssert will be able to use it to make validations.

amelield commented 2 years ago

@jeromelaban I need some guidance. When I use var fill = new RawBitmap(renderer, X); With X being a Windows UI rectangle that have the ImageBrush as fill or whit a border around. Fill has an heigh and weight but has pixels = null and because of that failed any color comparison. Skia ImageBrush.ImageBrush is not a Framework element and is really hard to manipulate by itself. var fill = new RawBitmap(renderer, brush); Throws a not implemented error. S Windows.UI.Xaml.Media.ImageBrush does not throw exception but the pixels are still null. I tried to use Rect.Rect in lieu of the Windows UI rectangle but I did not find a way to include ImageBrush as a fill or a child.
When I try to create a new FrameworkElement that return a ImageBrush I receive init() not implemented. So I thought it was a dead end but it might be the way to go. What should I do next?

jeromelaban commented 2 years ago

RenderTargetBitmap only renders UIElements indeed. The best way to do this is to render a parent element (let's call it A), like a Border or a Grid, then use the control (called B) that applies the brush to get the its relative coordinates (using B.TransformToVisual(A)) and then do the pixels comparisons with those coordinates.

This method already does the coordinates conversion, so it may help: https://github.com/unoplatform/uno/blob/aa9311da1926bd52df96ec152cb7585d3c8d74a3/src/Uno.UI.RuntimeTests/Helpers/ImageAssert.cs#L43

amelield commented 2 years ago

HasColorAtChild(RawBitmap screenshot, UIElement child, double x, double y, Color expectedColor, byte tolerance = 0, [CallerLineNumber] int line = 0) use a UIElement and Brush is not one. Using A.Background or brush give a cannot convert Windows.UI.Xaml.Media.ImageBrush; into a Windows.UI.Xaml.Element; With the A element (grid or border), the test simply cannot fail, no matter the color difference. That method would be perfect to use for that if it was not the case.

I also tried to use B.TransformToVisual(A). In my case A is a Grid but I am not sure which control B would be (it is probably very simple). I thought that grid was the control that applied the background. I looked at helpers and documentation without finding the answer.

Edit: That might not be the problem (or the only problem) since all the pixels bytes are at 0 in all the RawBitmap and buffers. I will investigate that further.

jeromelaban commented 2 years ago

If all the pixel bytes are at 0, it probably means that the screenshot failed, somehow. Let's discuss this tomorrow :)