vivrichards600/AutomatedVisualTesting

Out of Memory Exception

jamesehearn opened this issue · 9 comments

Out of Memory Exception at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)

When using the Differences(string baseImage, string element, IWebDriver driver, ComparisonOptions options = null) method.

Does not happen with ALL tests that use this method, only some. When it fails, it fails consistently. Does it have to do with the element to compare being larger than a page? I'm trying to compare a div element that takes up most of the page when it fails. I've included the StackTrace below (with the non-essential bits X'd out).

Happens with multiple browsers/drivers.

Let me know what other info you need that could help out.

Result StackTrace:
at System.Drawing.Bitmap.Clone(Rectangle rect, PixelFormat format)
at AutomatedVisualTesting.Utilities.SeleniumDriver.GetScreenshotOfElement(IWebDriver driver, String elementSelector)
at AutomatedVisualTesting.Utilities.Compare.Differences(String baseImage, String element, IWebDriver driver, ComparisonOptions options)
at VisualRegressionTesting.XXX.XXX.XXX() in C:\Users\XXX
Result Message: System.OutOfMemoryException : Out of memory.

Hi James, I believe your right. I'd stick a break point on line 177 (if it get's that far) and check the values being set for the rectangle. It's tricky to know 100% without me running the same test on my machine but I'd give that a go. I found in another method I had a similar error where the height/width being used was wrong for the rectangle.

The Rectangle method:

var croppedImage = new Rectangle(element.Location.X, element.Location.Y, element.Size.Width, element.Size.Height);

is setting the width as 820 and the height as 598.

Checking that against the style, that's the Width + padding + border, and the Height + padding + border, so no margin included (screenshot attached).
2-5-2019 8-39-20 am

I'm unsure what the width and height should be for now, but will investigate.

I encountered the same issue and found a way to solve it. I use it on Chrome driver on Windows 10. It appeared to me that the screenshots that are generated by the driver are larger than my browser viewport. I tried to see if the cssPixelRatio was an issue and it seems to be the case. When I open a iPhone-viewport (375 x 667), the screenshot is twice that (750 x 1334), ergo a pixel ratio of 2. I fixed the issue by determining the pixelRatio by dividing screnshot width by width of element in current driver, and multiply cropping position & size by that:

var byteArray = ((ITakesScreenshot)driver).GetScreenshot().AsByteArray;
var screenshot = new Bitmap(new MemoryStream(byteArray));
var pixelRatio = screenshot.Size.Width / driver.FindElement(By.TagName("body")).Size.Width;
var croppedImage = new Rectangle(pixelRatio * element.Location.X, pixelRatio * element.Location.Y, pixelRatio * element.Size.Width, pixelRatio * element.Size.Height);

screenshot = screenshot.Clone(croppedImage, screenshot.PixelFormat);

Also, I realised that it was important that the element that is to be compared, has to be visible in the browser (not 100% sure though).

@vivrichards600 - can you please adjust this in the repository?

Yes, this is also how I avoid this problem. Make the screenshot "inside" the browser viewport. I use a simple image editor (IrfanView) to manually see how large my screenshots can be.

Can you make the change and submit a pull request and I'll merge it in then so it's fixed for everyone.

Thanks.

If this isn't done yet, I'll try to work on it next week. Been busy with other things for a while here, but may have some time to work on this soon.

Pull request has been made. I think I did this right (I don't use GitHub at my company, so I'm a bit rusty here). Let me know what else needs to be done.

Thanks for the contribution :)

Happy to help!