Skip to content

Commit

Permalink
Merge pull request #1230 from DataDog/ncreated+maciey/REPLAY-1465-uii…
Browse files Browse the repository at this point in the history
…mageview-snapshot-tests

REPLAY-1465 UIImageView snapshot tests
  • Loading branch information
maciejburda authored Mar 30, 2023
2 parents e9a9b13 + 3598a49 commit 86b5628
Show file tree
Hide file tree
Showing 9 changed files with 408 additions and 40 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "dd_logo.jpg",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ internal enum Fixture: CaseIterable {
case timePickersCountDown
case timePickersWheels
case timePickersCompact
case images

var menuItemTitle: String {
switch self {
Expand Down Expand Up @@ -52,6 +53,8 @@ internal enum Fixture: CaseIterable {
return "Time Picker (wheels)"
case .timePickersCompact:
return "Time Picker (compact)"
case .images:
return "Images"
}
}

Expand Down Expand Up @@ -85,6 +88,8 @@ internal enum Fixture: CaseIterable {
return UIStoryboard.datePickers.instantiateViewController(withIdentifier: "TimePickersWheels")
case .timePickersCompact:
return UIStoryboard.datePickers.instantiateViewController(withIdentifier: "DatePickersCompact") // sharing the same VC with `datePickersCompact`
case .images:
return UIStoryboard.images.instantiateViewController(withIdentifier: "Images")
}
}
}
Expand All @@ -93,4 +98,5 @@ internal extension UIStoryboard {
static var basic: UIStoryboard { UIStoryboard(name: "Basic", bundle: nil) }
static var inputElements: UIStoryboard { UIStoryboard(name: "InputElements", bundle: nil) }
static var datePickers: UIStoryboard { UIStoryboard(name: "InputElements-DatePickers", bundle: nil) }
static var images: UIStoryboard { UIStoryboard(name: "Images", bundle: nil) }
}
281 changes: 281 additions & 0 deletions DatadogSessionReplay/SRSnapshotTests/SRHost/Fixtures/Images.storyboard

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
616C37DA299F6913005E0472 /* InputElements.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 616C37D9299F6913005E0472 /* InputElements.storyboard */; };
6196D32429AF7EB2002EACAF /* InputElements-DatePickers.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6196D32329AF7EB2002EACAF /* InputElements-DatePickers.storyboard */; };
619C49B229952108006B66A6 /* Framer in Frameworks */ = {isa = PBXBuildFile; productRef = 619C49B129952108006B66A6 /* Framer */; };
619C49B429952E12006B66A6 /* SnapshotTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619C49B329952E12006B66A6 /* SnapshotTestCase.swift */; };
619C49B72995512A006B66A6 /* ImageComparison.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619C49B62995512A006B66A6 /* ImageComparison.swift */; };
619C49B9299551F5006B66A6 /* _snapshots_ in Resources */ = {isa = PBXBuildFile; fileRef = 619C49B8299551F5006B66A6 /* _snapshots_ */; };
Expand All @@ -22,10 +21,13 @@
61B3BC652993BEAF0032C78A /* SRSnapshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B3BC642993BEAF0032C78A /* SRSnapshotTests.swift */; };
61B3BC6D2993C06D0032C78A /* DatadogSessionReplay in Frameworks */ = {isa = PBXBuildFile; productRef = 61B3BC6C2993C06D0032C78A /* DatadogSessionReplay */; };
61B634EB299A5DB3002BEABE /* Fixtures.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61B634EA299A5DB3002BEABE /* Fixtures.swift */; };
61C06D6029D487E7007521D8 /* Framer in Frameworks */ = {isa = PBXBuildFile; productRef = 61C06D5F29D487E7007521D8 /* Framer */; };
61E7DFB7299A57A9001D7A3A /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E7DFB6299A57A9001D7A3A /* MenuViewController.swift */; };
61E7DFB9299A5A3E001D7A3A /* Basic.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 61E7DFB8299A5A3E001D7A3A /* Basic.storyboard */; };
61E7DFBB299A5C9D001D7A3A /* BasicViewControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61E7DFBA299A5C9D001D7A3A /* BasicViewControllers.swift */; };
61EC1A37299CFD7E00224FB6 /* TestUtilities in Frameworks */ = {isa = PBXBuildFile; productRef = 61EC1A36299CFD7E00224FB6 /* TestUtilities */; };
A797A95029D5958400EE73EB /* Images.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A797A94F29D5958400EE73EB /* Images.storyboard */; };
A797A95229D59E7900EE73EB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A797A95129D59E7900EE73EB /* Assets.xcassets */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -58,6 +60,8 @@
61E7DFB6299A57A9001D7A3A /* MenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = "<group>"; };
61E7DFB8299A5A3E001D7A3A /* Basic.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Basic.storyboard; sourceTree = "<group>"; };
61E7DFBA299A5C9D001D7A3A /* BasicViewControllers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasicViewControllers.swift; sourceTree = "<group>"; };
A797A94F29D5958400EE73EB /* Images.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Images.storyboard; sourceTree = "<group>"; };
A797A95129D59E7900EE73EB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -66,14 +70,14 @@
buildActionMask = 2147483647;
files = (
61B3BC6D2993C06D0032C78A /* DatadogSessionReplay in Frameworks */,
61C06D6029D487E7007521D8 /* Framer in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
61B3BC5F2993BEAF0032C78A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
619C49B229952108006B66A6 /* Framer in Frameworks */,
61EC1A37299CFD7E00224FB6 /* TestUtilities in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -120,6 +124,7 @@
61B3BC502993BE2E0032C78A /* Main.storyboard */,
61B3BC552993BE2F0032C78A /* LaunchScreen.storyboard */,
61B3BC582993BE2F0032C78A /* Info.plist */,
A797A95129D59E7900EE73EB /* Assets.xcassets */,
);
path = SRHost;
sourceTree = "<group>";
Expand Down Expand Up @@ -150,6 +155,7 @@
616C37D9299F6913005E0472 /* InputElements.storyboard */,
61A735A929A5137400001820 /* InputViewControllers.swift */,
6196D32329AF7EB2002EACAF /* InputElements-DatePickers.storyboard */,
A797A94F29D5958400EE73EB /* Images.storyboard */,
);
path = Fixtures;
sourceTree = "<group>";
Expand All @@ -172,6 +178,7 @@
name = SRHost;
packageProductDependencies = (
61B3BC6C2993C06D0032C78A /* DatadogSessionReplay */,
61C06D5F29D487E7007521D8 /* Framer */,
);
productName = SRHost;
productReference = 61B3BC472993BE2E0032C78A /* SRHost.app */;
Expand All @@ -192,7 +199,6 @@
);
name = SRSnapshotTests;
packageProductDependencies = (
619C49B129952108006B66A6 /* Framer */,
61EC1A36299CFD7E00224FB6 /* TestUtilities */,
);
productName = SRSnapshotTests;
Expand Down Expand Up @@ -228,7 +234,7 @@
);
mainGroup = 61B3BC3E2993BE2E0032C78A;
packageReferences = (
619C49B029952108006B66A6 /* XCRemoteSwiftPackageReference "Framing" */,
61C06D5E29D487E7007521D8 /* XCRemoteSwiftPackageReference "Framer" */,
);
productRefGroup = 61B3BC482993BE2E0032C78A /* Products */;
projectDirPath = "";
Expand All @@ -249,6 +255,8 @@
61B3BC572993BE2F0032C78A /* LaunchScreen.storyboard in Resources */,
61E7DFB9299A5A3E001D7A3A /* Basic.storyboard in Resources */,
61B3BC522993BE2E0032C78A /* Main.storyboard in Resources */,
A797A95229D59E7900EE73EB /* Assets.xcassets in Resources */,
A797A95029D5958400EE73EB /* Images.storyboard in Resources */,
6196D32429AF7EB2002EACAF /* InputElements-DatePickers.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -557,26 +565,26 @@
/* End XCConfigurationList section */

/* Begin XCRemoteSwiftPackageReference section */
619C49B029952108006B66A6 /* XCRemoteSwiftPackageReference "Framing" */ = {
61C06D5E29D487E7007521D8 /* XCRemoteSwiftPackageReference "Framer" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/ncreated/Framing";
repositoryURL = "https://github.com/ncreated/Framer";
requirement = {
branch = "ship-framer";
branch = "ncreated-patch-1";
kind = branch;
};
};
/* End XCRemoteSwiftPackageReference section */

/* Begin XCSwiftPackageProductDependency section */
619C49B129952108006B66A6 /* Framer */ = {
isa = XCSwiftPackageProductDependency;
package = 619C49B029952108006B66A6 /* XCRemoteSwiftPackageReference "Framing" */;
productName = Framer;
};
61B3BC6C2993C06D0032C78A /* DatadogSessionReplay */ = {
isa = XCSwiftPackageProductDependency;
productName = DatadogSessionReplay;
};
61C06D5F29D487E7007521D8 /* Framer */ = {
isa = XCSwiftPackageProductDependency;
package = 61C06D5E29D487E7007521D8 /* XCRemoteSwiftPackageReference "Framer" */;
productName = Framer;
};
61EC1A36299CFD7E00224FB6 /* TestUtilities */ = {
isa = XCSwiftPackageProductDependency;
productName = TestUtilities;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
Expand All @@ -38,6 +39,16 @@
ReferencedContainer = "container:SRSnapshotTests.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DatadogSessionReplayTests"
BuildableName = "DatadogSessionReplayTests"
BlueprintName = "DatadogSessionReplayTests"
ReferencedContainer = "container:..">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ final class SRSnapshotTests: SnapshotTestCase {
)
}


func testDatePickers() throws {
let vc1 = show(fixture: .datePickersInline) as! DatePickersInlineViewController
vc1.set(date: .mockDecember15th2019At10AMUTC())
Expand Down Expand Up @@ -256,4 +255,23 @@ final class SRSnapshotTests: SnapshotTestCase {
record: recordingMode
)
}

func testImages() throws {
show(fixture: .images)

var image = try takeSnapshot(configuration: .init(privacy: .allowAll))
DDAssertSnapshotTest(
newImage: image,

snapshotLocation: .folder(named: snapshotsFolderName, fileNameSuffix: "-allowAll-privacy"),
record: recordingMode
)

image = try takeSnapshot(configuration: .init(privacy: .maskAll))
DDAssertSnapshotTest(
newImage: image,
snapshotLocation: .folder(named: snapshotsFolderName, fileNameSuffix: "-maskAll-privacy"),
record: recordingMode
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ internal func renderImage(for wireframes: [SRWireframe]) -> UIImage {

let frame = wireframes[0].toFrame()
let canvas = FramerCanvas.create(size: CGSize(width: frame.width, height: frame.height))
canvas.draw(blueprint: Blueprint(id: "snapshot", frames: wireframes.map { $0.toFrame() }))
canvas.draw(
blueprint: Blueprint(
id: "snapshot",
contents: wireframes.map { .frame($0.toFrame()) }
)
)
return canvas.image
}

Expand Down Expand Up @@ -74,17 +79,14 @@ private extension SRImageWireframe {
y: CGFloat(y),
width: CGFloat(width),
height: CGFloat(height),
style: .init(lineWidth: 1, lineColor: .black, fillColor: .red),
annotation: .init(
text: "IMG \(width) x \(height)",
style: .init(size: .small, position: .top, alignment: .trailing)
)
style: frameStyle(border: border, style: shapeStyle),
content: frameContent(base64ImageString: base64)
)
}
}

private func frameStyle(border: SRShapeBorder?, style: SRShapeStyle?) -> BlueprintFrameStyle {
var fs = BlueprintFrameStyle(
private func frameStyle(border: SRShapeBorder?, style: SRShapeStyle?) -> BlueprintFrame.Style {
var fs = BlueprintFrame.Style(
lineWidth: 0,
lineColor: .clear,
fillColor: .clear,
Expand All @@ -106,34 +108,49 @@ private func frameStyle(border: SRShapeBorder?, style: SRShapeStyle?) -> Bluepri
return fs
}

private func frameContent(text: String, textStyle: SRTextStyle?, textPosition: SRTextPosition?) -> BlueprintFrameContent {
var fc = BlueprintFrameContent(
text: text,
textColor: .clear,
font: .systemFont(ofSize: 8)
)

if let textStyle = textStyle {
fc.textColor = UIColor(hexString: textStyle.color)
fc.font = .systemFont(ofSize: CGFloat(textStyle.size))
}
private func frameContent(text: String, textStyle: SRTextStyle?, textPosition: SRTextPosition?) -> BlueprintFrame.Content {
var horizontalAlignment: BlueprintFrame.Content.Alignment = .leading
var verticalAlignment: BlueprintFrame.Content.Alignment = .leading

if let textPosition = textPosition {
switch textPosition.alignment?.horizontal {
case .left?: fc.horizontalAlignment = .leading
case .center?: fc.horizontalAlignment = .center
case .right?: fc.horizontalAlignment = .trailing
case .left?: horizontalAlignment = .leading
case .center?: horizontalAlignment = .center
case .right?: horizontalAlignment = .trailing
default: break
}
switch textPosition.alignment?.vertical {
case .top?: fc.verticalAlignment = .leading
case .center?: fc.verticalAlignment = .center
case .bottom?: fc.verticalAlignment = .trailing
case .top?: verticalAlignment = .leading
case .center?: verticalAlignment = .center
case .bottom?: verticalAlignment = .trailing
default: break
}
}

return fc
let contentType: BlueprintFrame.Content.ContentType
if let textStyle = textStyle {
contentType = .text(
text: text,
color: UIColor(hexString: textStyle.color),
font: .systemFont(ofSize: CGFloat(textStyle.size))
)
} else {
contentType = .text(text: text, color: .clear, font: .systemFont(ofSize: 8))
}

return .init(
contentType: contentType,
horizontalAlignment: horizontalAlignment,
verticalAlignment: verticalAlignment
)
}

private func frameContent(base64ImageString: String?) -> BlueprintFrame.Content {
let base64Data = base64ImageString?.data(using: .utf8) ?? Data()
let imageData = Data(base64Encoded: base64Data) ?? Data()
let image = UIImage(data: imageData, scale: UIScreen.main.scale) ?? UIImage()
let contentType: BlueprintFrame.Content.ContentType = .image(image: image)
return .init(contentType: contentType)
}

private extension UIColor {
Expand Down

0 comments on commit 86b5628

Please sign in to comment.