Skip to content

Commit 2d519dd

Browse files
author
Jurollet
authored
Merge pull request #9 from felginep/feature/inlining
Feature/inlining
2 parents aee2aca + 6502537 commit 2d519dd

16 files changed

+169
-44
lines changed

Sources/XCTestHTMLReport/Classes/HTMLTemplates.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ struct HTMLTemplates
55
{
66
static let designReviewScreenshot = """
77
<p class=\"design_review_item list-item\">
8-
<img class=\"design_review_screenshot\" src=\"[[PATH]]\" id=\"screenshot-[[FILENAME]]\" style=\"margin-bottom: 4px\" />
8+
<img class=\"design_review_screenshot\" src=\"[[SOURCE]]\" id=\"screenshot-[[FILENAME]]\" style=\"margin-bottom: 4px\" />
99
[[NAME]]
1010
</p>
1111
"""
@@ -31,7 +31,7 @@ struct HTMLTemplates
3131
<p class=\"attachment list-item\">
3232
<span class=\"icon left text-icon\" style=\"margin-left: [[PADDING]]px\"></span>
3333
[[NAME]]
34-
<span class=\"icon preview-icon\" data=\"[[PATH]]\" onclick=\"showText('[[PATH]]')\"></span>
34+
<span class=\"icon preview-icon\" data=\"[[SOURCE]]\" onclick=\"showText('[[SOURCE]]')\"></span>
3535
</p>
3636
"""
3737

@@ -58,7 +58,7 @@ struct HTMLTemplates
5858
<li onclick=\"showApplicationLogs(this);\">App Logs</li>
5959
</ul>
6060
</div>
61-
<iframe id=\"test-logs-iframe\" src=\"[[LOG_PATH]]\"></iframe>
61+
<iframe id=\"test-logs-iframe\" src=\"[[LOG_SOURCE]]\"></iframe>
6262
</div>
6363
<div id=\"design-review\">
6464
<div>
@@ -1093,7 +1093,7 @@ struct HTMLTemplates
10931093
<span class=\"icon left screenshot-icon\" style=\"margin-left: [[PADDING]]px\"></span>
10941094
[[NAME]]
10951095
<span class=\"icon preview-icon\" data=\"[[FILENAME]]\" onclick=\"showScreenshot('[[FILENAME]]')\"></span>
1096-
<img class=\"screenshot\" src=\"[[PATH]]\" id=\"screenshot-[[FILENAME]]\"/>
1096+
<img class=\"screenshot\" src=\"[[SOURCE]]\" id=\"screenshot-[[FILENAME]]\"/>
10971097
</p>
10981098
"""
10991099

Sources/XCTestHTMLReport/Classes/Models/Activity.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,17 +74,17 @@ struct Activity: HTML
7474
return attachments.filter { $0.isImage }
7575
}
7676

77-
init(summary: ActionTestActivitySummary, file: ResultFile, padding: Int = 0) {
77+
init(summary: ActionTestActivitySummary, file: ResultFile, padding: Int = 0, configuration: Configuration) {
7878
self.uuid = summary.uuid
7979
self.startTime = summary.start?.timeIntervalSince1970 ?? 0
8080
self.finishTime = summary.finish?.timeIntervalSince1970 ?? 0
8181
self.title = summary.title
8282
self.subActivities = summary.subactivities.map {
83-
Activity(summary: $0, file: file, padding: padding + 10)
83+
Activity(summary: $0, file: file, padding: padding + 10, configuration: configuration)
8484
}
8585
self.type = ActivityType(rawValue: summary.activityType)
8686
self.attachments = summary.attachments.map {
87-
Attachment(attachment: $0, file: file, padding: padding + 16)
87+
Attachment(attachment: $0, file: file, padding: padding + 16, configuration: configuration)
8888
}
8989
self.padding = padding
9090
}

Sources/XCTestHTMLReport/Classes/Models/Attachment.swift

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import Foundation
1010
import XCResultKit
1111

1212
enum AttachmentType: String {
13-
case unknwown = ""
13+
case unknown = ""
1414
case data = "public.data"
1515
case html = "public.html"
1616
case jpeg = "public.jpeg"
@@ -27,6 +27,23 @@ enum AttachmentType: String {
2727
return ""
2828
}
2929
}
30+
31+
fileprivate var mimeType: String? {
32+
switch self {
33+
case .png:
34+
return "image/png"
35+
case .jpeg:
36+
return "image/jpeg"
37+
case .text:
38+
return "text/plain"
39+
case .html:
40+
return "text/html"
41+
case .data:
42+
return "application/octet-stream"
43+
case .unknown:
44+
return nil
45+
}
46+
}
3047
}
3148

3249
enum AttachmentName: RawRepresentable {
@@ -60,19 +77,21 @@ struct Attachment: HTML
6077
{
6178
let padding: Int
6279
let filename: String
63-
let path: String
80+
let content: RenderingContent
6481
let type: AttachmentType
6582
let name: AttachmentName?
6683

67-
init(attachment: ActionTestAttachment, file: ResultFile, padding: Int = 0) {
84+
init(attachment: ActionTestAttachment, file: ResultFile, padding: Int = 0, configuration: Configuration) {
6885
self.filename = attachment.filename ?? ""
69-
self.type = AttachmentType(rawValue: attachment.uniformTypeIdentifier) ?? .unknwown
86+
self.type = AttachmentType(rawValue: attachment.uniformTypeIdentifier) ?? .unknown
7087
self.name = attachment.name.map(AttachmentName.init(rawValue:))
71-
if let id = attachment.payloadRef?.id,
72-
let url = file.exportPayload(id: id) {
73-
self.path = url.relativePath
88+
if let id = attachment.payloadRef?.id {
89+
self.content = file.exportPayloadContent(
90+
id: id,
91+
renderingMode: renderingMode
92+
)
7493
} else {
75-
self.path = ""
94+
self.content = .none
7695
}
7796
self.padding = padding
7897
}
@@ -83,11 +102,25 @@ struct Attachment: HTML
83102
return "Screenshot"
84103
case .text, .html, .data:
85104
return "File"
86-
case .unknwown:
105+
case .unknown:
87106
return "Attachment"
88107
}
89108
}
90-
109+
110+
var source: String? {
111+
switch content {
112+
case let .data(data):
113+
guard let mimeType = type.mimeType else {
114+
return nil
115+
}
116+
return "data:\(mimeType);base64,\(data.base64EncodedString())"
117+
case let .url(url):
118+
return url.relativePath
119+
case .none:
120+
return nil
121+
}
122+
}
123+
91124
var displayName: String {
92125
switch name {
93126
case .some(.custom(let customName)):
@@ -101,7 +134,7 @@ struct Attachment: HTML
101134
switch type {
102135
case .png, .jpeg:
103136
return true
104-
case .text, .html, .data, .unknwown:
137+
case .text, .html, .data, .unknown:
105138
return false
106139
}
107140
}
@@ -114,15 +147,15 @@ struct Attachment: HTML
114147
return HTMLTemplates.screenshot
115148
case .text, .html, .data:
116149
return HTMLTemplates.text
117-
case .unknwown:
150+
case .unknown:
118151
return ""
119152
}
120153
}
121154

122155
var htmlPlaceholderValues: [String: String] {
123156
return [
124157
"PADDING": String(padding),
125-
"PATH": path,
158+
"SOURCE": source ?? "",
126159
"FILENAME": filename,
127160
"NAME": displayName
128161
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//
2+
// Configuration.swift
3+
// XCTestHTMLReport
4+
//
5+
// Created by Pierre Felgines on 13/12/2019.
6+
//
7+
8+
import Foundation
9+
10+
enum RenderingMode {
11+
case inline
12+
case linking
13+
}
14+
15+
struct Configuration {
16+
let renderingMode: RenderingMode
17+
}

Sources/XCTestHTMLReport/Classes/Models/DesignReviewScreenshot.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ struct DesignReviewScreenshot: HTML
2222

2323
var htmlPlaceholderValues: [String: String] {
2424
return [
25-
"PATH": attachment.path,
25+
"SOURCE": attachment.source ?? "",
2626
"FILENAME": attachment.filename,
2727
"NAME": attachment.displayName
2828
]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// RenderingContent.swift
3+
// XCTestHTMLReport
4+
//
5+
// Created by Pierre Felgines on 09/12/2019.
6+
//
7+
8+
import Foundation
9+
10+
enum RenderingContent {
11+
case data(Data)
12+
case url(URL)
13+
case none
14+
}

Sources/XCTestHTMLReport/Classes/Models/ResultFile.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ class ResultFile {
3939
}
4040
}
4141

42+
func exportPayloadData(id: String) -> Data? {
43+
guard let savedURL = file.exportPayload(id: id) else {
44+
Logger.warning("Can't export payload with id \(id)")
45+
return nil
46+
}
47+
do {
48+
return try Data(contentsOf: savedURL)
49+
} catch {
50+
Logger.warning("Can't get content of \(savedURL)")
51+
return nil
52+
}
53+
}
54+
4255
func getInvocationRecord() -> ActionsInvocationRecord? {
4356
return file.getInvocationRecord()
4457
}
@@ -71,5 +84,35 @@ class ResultFile {
7184
return nil
7285
}
7386
}
87+
88+
func exportLogsData(id: String) -> Data? {
89+
guard let logSection = file.getLogs(id: id) else {
90+
Logger.warning("Can't get logss with id \(id)")
91+
return nil
92+
}
93+
return logSection.emittedOutput?.data(using: .utf8)
94+
}
7495
}
7596

97+
extension ResultFile {
98+
99+
func exportPayloadContent(id: String,
100+
renderingMode: RenderingMode) -> RenderingContent {
101+
switch renderingMode {
102+
case .inline:
103+
return exportPayloadData(id: id).map(RenderingContent.data) ?? .none
104+
case .linking:
105+
return exportPayload(id: id).map(RenderingContent.url) ?? .none
106+
}
107+
}
108+
109+
func exportLogsContent(id: String,
110+
renderingMode: RenderingMode) -> RenderingContent {
111+
switch renderingMode {
112+
case .inline:
113+
return exportLogsData(id: id).map(RenderingContent.data) ?? .none
114+
case .linking:
115+
return exportLogs(id: id).map(RenderingContent.url) ?? .none
116+
}
117+
}
118+
}

Sources/XCTestHTMLReport/Classes/Models/Run.swift

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct Run: HTML
1414
let runDestination: RunDestination
1515
let testSummaries: [TestSummary]
1616
let designReviews: [DesignReview]
17-
let logPath: String
17+
let logContent: RenderingContent
1818
var status: Status {
1919
return testSummaries.reduce(true, { (accumulator: Bool, summary: TestSummary) -> Bool in
2020
return accumulator && summary.status == .success
@@ -39,7 +39,7 @@ struct Run: HTML
3939
return allTests.filter { $0.status == .failure }.count
4040
}
4141

42-
init?(action: ActionRecord, file: ResultFile) {
42+
init?(action: ActionRecord, file: ResultFile, configuration: Configuration) {
4343
self.runDestination = RunDestination(record: action.runDestination)
4444

4545
guard
@@ -51,27 +51,40 @@ struct Run: HTML
5151

5252
// TODO: (Pierre Felgines) 02/10/2019 Use only emittedOutput from logs objects
5353
// For now XCResultKit do not handle logs
54-
if let logReference = action.actionResult.logRef,
55-
let url = file.exportLogs(id: logReference.id) {
56-
self.logPath = url.relativePath
54+
if let logReference = action.actionResult.logRef {
55+
self.logContent = file.exportLogsContent(
56+
id: logReference.id,
57+
renderingMode: renderingMode
58+
)
5759
} else {
5860
Logger.warning("Can't find test reference for action \(action.title ?? "")")
59-
self.logPath = ""
61+
self.logContent = .none
6062
}
6163
self.testSummaries = testPlanSummaries.summaries
6264
.flatMap { $0.testableSummaries }
63-
.map { TestSummary(summary: $0, file: file) }
65+
.map { TestSummary(summary: $0, file: file, configuration: configuration) }
6466
self.designReviews = testSummaries.map(DesignReview.init)
6567
}
6668

69+
private var logSource: String? {
70+
switch logContent {
71+
case let .url(url):
72+
return url.relativePath
73+
case let .data(data):
74+
return "data:text/plain;base64,\(data.base64EncodedString())"
75+
case .none:
76+
return nil
77+
}
78+
}
79+
6780
// PRAGMA MARK: - HTML
6881

6982
var htmlTemplate = HTMLTemplates.run
7083

7184
var htmlPlaceholderValues: [String: String] {
7285
return [
7386
"DEVICE_IDENTIFIER": runDestination.targetDevice.uniqueIdentifier,
74-
"LOG_PATH": logPath,
87+
"LOG_SOURCE": logSource ?? "",
7588
"N_OF_TESTS": String(numberOfTests),
7689
"N_OF_PASSED_TESTS": String(numberOfPassedTests),
7790
"N_OF_FAILED_TESTS": String(numberOfFailedTests),

Sources/XCTestHTMLReport/Classes/Models/Summary.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct Summary
1313
{
1414
let runs: [Run]
1515

16-
init(resultPaths: [String]) {
16+
init(resultPaths: [String], configuration: Configuration) {
1717
var runs: [Run] = []
1818
for resultPath in resultPaths {
1919
Logger.step("Parsing \(resultPath)")
@@ -24,7 +24,7 @@ struct Summary
2424
break
2525
}
2626
let resultRuns = invocationRecord.actions.compactMap {
27-
Run(action: $0, file: resultFile)
27+
Run(action: $0, file: resultFile, configuration: configuration)
2828
}
2929
runs.append(contentsOf: resultRuns)
3030
}

Sources/XCTestHTMLReport/Classes/Models/Test.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,22 @@ struct Test: HTML
7070
return a == 0 ? subTests.count : a
7171
}
7272

73-
init(group: ActionTestSummaryGroup, file: ResultFile) {
73+
init(group: ActionTestSummaryGroup, file: ResultFile, configuration: Configuration) {
7474
self.uuid = NSUUID().uuidString
7575
self.identifier = group.identifier
7676
self.duration = group.duration
7777
self.name = group.name
7878
if group.subtests.isEmpty {
79-
self.subTests = group.subtestGroups.map { Test(group: $0, file: file) }
79+
self.subTests = group.subtestGroups.map { Test(group: $0, file: file, configuration: configuration) }
8080
} else {
81-
self.subTests = group.subtests.map { Test(metadata: $0, file: file) }
81+
self.subTests = group.subtests.map { Test(metadata: $0, file: file, configuration: configuration) }
8282
}
8383
self.objectClass = .testSummaryGroup
8484
self.activities = []
8585
self.status = .unknown // ???: Usefull?
8686
}
8787

88-
init(metadata: ActionTestMetadata, file: ResultFile) {
88+
init(metadata: ActionTestMetadata, file: ResultFile, configuration: Configuration) {
8989
self.uuid = NSUUID().uuidString
9090
self.identifier = metadata.identifier
9191
self.duration = metadata.duration ?? 0
@@ -96,7 +96,7 @@ struct Test: HTML
9696
if let id = metadata.summaryRef?.id,
9797
let actionTestSummary = file.getActionTestSummary(id: id) {
9898
self.activities = actionTestSummary.activitySummaries.map {
99-
Activity(summary: $0, file: file, padding: 20)
99+
Activity(summary: $0, file: file, padding: 20, configuration: configuration)
100100
}
101101
} else {
102102
self.activities = []

0 commit comments

Comments
 (0)