From 63e84eb206ec32c21e199aa8c42e10adf72dde14 Mon Sep 17 00:00:00 2001
From: Dariusz Rybicki <dariusz@elixxir.io>
Date: Mon, 15 Aug 2022 13:57:33 +0100
Subject: [PATCH] Add MakeAppScreenshot functor

---
 Package.swift                                 |  4 +-
 .../ReportingFeature/MakeAppScreenshot.swift  | 53 +++++++++++++++++++
 2 files changed, 56 insertions(+), 1 deletion(-)
 create mode 100644 Sources/ReportingFeature/MakeAppScreenshot.swift

diff --git a/Package.swift b/Package.swift
index ea792a43..5147b831 100644
--- a/Package.swift
+++ b/Package.swift
@@ -746,7 +746,9 @@ let package = Package(
         ),
         .target(
             name: "ReportingFeature",
-            dependencies: []
+            dependencies: [
+                .product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
+            ]
         ),
     ]
 )
diff --git a/Sources/ReportingFeature/MakeAppScreenshot.swift b/Sources/ReportingFeature/MakeAppScreenshot.swift
new file mode 100644
index 00000000..7d44af87
--- /dev/null
+++ b/Sources/ReportingFeature/MakeAppScreenshot.swift
@@ -0,0 +1,53 @@
+import Foundation
+import UIKit
+import XCTestDynamicOverlay
+
+public struct MakeAppScreenshot {
+    public enum Error: Swift.Error, Equatable {
+        case unableToGetForegroundWindowScene
+        case unableToGetKeyWindow
+    }
+
+    public var run: () throws -> UIImage
+
+    public func callAsFunction() throws -> UIImage {
+        try run()
+    }
+}
+
+extension MakeAppScreenshot {
+    public static let live = MakeAppScreenshot {
+        let scene: UIWindowScene? = UIApplication.shared.connectedScenes
+            .filter { $0.activationState == .foregroundActive }
+            .compactMap { $0 as? UIWindowScene }
+            .first
+
+        guard let scene = scene else {
+            throw Error.unableToGetForegroundWindowScene
+        }
+
+        let window: UIWindow? = scene.windows.first(where: \.isKeyWindow)
+
+        guard let keyWindow = window else {
+            throw Error.unableToGetKeyWindow
+        }
+
+        let rendererFormat = UIGraphicsImageRendererFormat()
+        rendererFormat.scale = scene.screen.scale
+
+        let renderer = UIGraphicsImageRenderer(
+            bounds: keyWindow.bounds,
+            format: rendererFormat
+        )
+
+        return renderer.image { ctx in
+            keyWindow.layer.render(in: ctx.cgContext)
+        }
+    }
+}
+
+extension MakeAppScreenshot {
+    public static let unimplemented = MakeAppScreenshot(
+        run: XCTUnimplemented("\(Self.self)")
+    )
+}
-- 
GitLab