Skip to content

Commit

Permalink
Merge pull request #9 from felginep/feature/inlining
Browse files Browse the repository at this point in the history
Feature/inlining
  • Loading branch information
Jurollet authored Dec 13, 2019
2 parents aee2aca + 6502537 commit 2d519dd
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 44 deletions.
8 changes: 4 additions & 4 deletions Sources/XCTestHTMLReport/Classes/HTMLTemplates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ struct HTMLTemplates
{
static let designReviewScreenshot = """
<p class=\"design_review_item list-item\">
<img class=\"design_review_screenshot\" src=\"[[PATH]]\" id=\"screenshot-[[FILENAME]]\" style=\"margin-bottom: 4px\" />
<img class=\"design_review_screenshot\" src=\"[[SOURCE]]\" id=\"screenshot-[[FILENAME]]\" style=\"margin-bottom: 4px\" />
[[NAME]]
</p>
"""
Expand All @@ -31,7 +31,7 @@ struct HTMLTemplates
<p class=\"attachment list-item\">
<span class=\"icon left text-icon\" style=\"margin-left: [[PADDING]]px\"></span>
[[NAME]]
<span class=\"icon preview-icon\" data=\"[[PATH]]\" onclick=\"showText('[[PATH]]')\"></span>
<span class=\"icon preview-icon\" data=\"[[SOURCE]]\" onclick=\"showText('[[SOURCE]]')\"></span>
</p>
"""

Expand All @@ -58,7 +58,7 @@ struct HTMLTemplates
<li onclick=\"showApplicationLogs(this);\">App Logs</li>
</ul>
</div>
<iframe id=\"test-logs-iframe\" src=\"[[LOG_PATH]]\"></iframe>
<iframe id=\"test-logs-iframe\" src=\"[[LOG_SOURCE]]\"></iframe>
</div>
<div id=\"design-review\">
<div>
Expand Down Expand Up @@ -1093,7 +1093,7 @@ struct HTMLTemplates
<span class=\"icon left screenshot-icon\" style=\"margin-left: [[PADDING]]px\"></span>
[[NAME]]
<span class=\"icon preview-icon\" data=\"[[FILENAME]]\" onclick=\"showScreenshot('[[FILENAME]]')\"></span>
<img class=\"screenshot\" src=\"[[PATH]]\" id=\"screenshot-[[FILENAME]]\"/>
<img class=\"screenshot\" src=\"[[SOURCE]]\" id=\"screenshot-[[FILENAME]]\"/>
</p>
"""

Expand Down
6 changes: 3 additions & 3 deletions Sources/XCTestHTMLReport/Classes/Models/Activity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,17 +74,17 @@ struct Activity: HTML
return attachments.filter { $0.isImage }
}

init(summary: ActionTestActivitySummary, file: ResultFile, padding: Int = 0) {
init(summary: ActionTestActivitySummary, file: ResultFile, padding: Int = 0, configuration: Configuration) {
self.uuid = summary.uuid
self.startTime = summary.start?.timeIntervalSince1970 ?? 0
self.finishTime = summary.finish?.timeIntervalSince1970 ?? 0
self.title = summary.title
self.subActivities = summary.subactivities.map {
Activity(summary: $0, file: file, padding: padding + 10)
Activity(summary: $0, file: file, padding: padding + 10, configuration: configuration)
}
self.type = ActivityType(rawValue: summary.activityType)
self.attachments = summary.attachments.map {
Attachment(attachment: $0, file: file, padding: padding + 16)
Attachment(attachment: $0, file: file, padding: padding + 16, configuration: configuration)
}
self.padding = padding
}
Expand Down
59 changes: 46 additions & 13 deletions Sources/XCTestHTMLReport/Classes/Models/Attachment.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
import XCResultKit

enum AttachmentType: String {
case unknwown = ""
case unknown = ""
case data = "public.data"
case html = "public.html"
case jpeg = "public.jpeg"
Expand All @@ -27,6 +27,23 @@ enum AttachmentType: String {
return ""
}
}

fileprivate var mimeType: String? {
switch self {
case .png:
return "image/png"
case .jpeg:
return "image/jpeg"
case .text:
return "text/plain"
case .html:
return "text/html"
case .data:
return "application/octet-stream"
case .unknown:
return nil
}
}
}

enum AttachmentName: RawRepresentable {
Expand Down Expand Up @@ -60,19 +77,21 @@ struct Attachment: HTML
{
let padding: Int
let filename: String
let path: String
let content: RenderingContent
let type: AttachmentType
let name: AttachmentName?

init(attachment: ActionTestAttachment, file: ResultFile, padding: Int = 0) {
init(attachment: ActionTestAttachment, file: ResultFile, padding: Int = 0, configuration: Configuration) {
self.filename = attachment.filename ?? ""
self.type = AttachmentType(rawValue: attachment.uniformTypeIdentifier) ?? .unknwown
self.type = AttachmentType(rawValue: attachment.uniformTypeIdentifier) ?? .unknown
self.name = attachment.name.map(AttachmentName.init(rawValue:))
if let id = attachment.payloadRef?.id,
let url = file.exportPayload(id: id) {
self.path = url.relativePath
if let id = attachment.payloadRef?.id {
self.content = file.exportPayloadContent(
id: id,
renderingMode: renderingMode
)
} else {
self.path = ""
self.content = .none
}
self.padding = padding
}
Expand All @@ -83,11 +102,25 @@ struct Attachment: HTML
return "Screenshot"
case .text, .html, .data:
return "File"
case .unknwown:
case .unknown:
return "Attachment"
}
}


var source: String? {
switch content {
case let .data(data):
guard let mimeType = type.mimeType else {
return nil
}
return "data:\(mimeType);base64,\(data.base64EncodedString())"
case let .url(url):
return url.relativePath
case .none:
return nil
}
}

var displayName: String {
switch name {
case .some(.custom(let customName)):
Expand All @@ -101,7 +134,7 @@ struct Attachment: HTML
switch type {
case .png, .jpeg:
return true
case .text, .html, .data, .unknwown:
case .text, .html, .data, .unknown:
return false
}
}
Expand All @@ -114,15 +147,15 @@ struct Attachment: HTML
return HTMLTemplates.screenshot
case .text, .html, .data:
return HTMLTemplates.text
case .unknwown:
case .unknown:
return ""
}
}

var htmlPlaceholderValues: [String: String] {
return [
"PADDING": String(padding),
"PATH": path,
"SOURCE": source ?? "",
"FILENAME": filename,
"NAME": displayName
]
Expand Down
17 changes: 17 additions & 0 deletions Sources/XCTestHTMLReport/Classes/Models/Configuration.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Configuration.swift
// XCTestHTMLReport
//
// Created by Pierre Felgines on 13/12/2019.
//

import Foundation

enum RenderingMode {
case inline
case linking
}

struct Configuration {
let renderingMode: RenderingMode
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ struct DesignReviewScreenshot: HTML

var htmlPlaceholderValues: [String: String] {
return [
"PATH": attachment.path,
"SOURCE": attachment.source ?? "",
"FILENAME": attachment.filename,
"NAME": attachment.displayName
]
Expand Down
14 changes: 14 additions & 0 deletions Sources/XCTestHTMLReport/Classes/Models/RenderingContent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// RenderingContent.swift
// XCTestHTMLReport
//
// Created by Pierre Felgines on 09/12/2019.
//

import Foundation

enum RenderingContent {
case data(Data)
case url(URL)
case none
}
43 changes: 43 additions & 0 deletions Sources/XCTestHTMLReport/Classes/Models/ResultFile.swift
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ class ResultFile {
}
}

func exportPayloadData(id: String) -> Data? {
guard let savedURL = file.exportPayload(id: id) else {
Logger.warning("Can't export payload with id \(id)")
return nil
}
do {
return try Data(contentsOf: savedURL)
} catch {
Logger.warning("Can't get content of \(savedURL)")
return nil
}
}

func getInvocationRecord() -> ActionsInvocationRecord? {
return file.getInvocationRecord()
}
Expand Down Expand Up @@ -71,5 +84,35 @@ class ResultFile {
return nil
}
}

func exportLogsData(id: String) -> Data? {
guard let logSection = file.getLogs(id: id) else {
Logger.warning("Can't get logss with id \(id)")
return nil
}
return logSection.emittedOutput?.data(using: .utf8)
}
}

extension ResultFile {

func exportPayloadContent(id: String,
renderingMode: RenderingMode) -> RenderingContent {
switch renderingMode {
case .inline:
return exportPayloadData(id: id).map(RenderingContent.data) ?? .none
case .linking:
return exportPayload(id: id).map(RenderingContent.url) ?? .none
}
}

func exportLogsContent(id: String,
renderingMode: RenderingMode) -> RenderingContent {
switch renderingMode {
case .inline:
return exportLogsData(id: id).map(RenderingContent.data) ?? .none
case .linking:
return exportLogs(id: id).map(RenderingContent.url) ?? .none
}
}
}
29 changes: 21 additions & 8 deletions Sources/XCTestHTMLReport/Classes/Models/Run.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct Run: HTML
let runDestination: RunDestination
let testSummaries: [TestSummary]
let designReviews: [DesignReview]
let logPath: String
let logContent: RenderingContent
var status: Status {
return testSummaries.reduce(true, { (accumulator: Bool, summary: TestSummary) -> Bool in
return accumulator && summary.status == .success
Expand All @@ -39,7 +39,7 @@ struct Run: HTML
return allTests.filter { $0.status == .failure }.count
}

init?(action: ActionRecord, file: ResultFile) {
init?(action: ActionRecord, file: ResultFile, configuration: Configuration) {
self.runDestination = RunDestination(record: action.runDestination)

guard
Expand All @@ -51,27 +51,40 @@ struct Run: HTML

// TODO: (Pierre Felgines) 02/10/2019 Use only emittedOutput from logs objects
// For now XCResultKit do not handle logs
if let logReference = action.actionResult.logRef,
let url = file.exportLogs(id: logReference.id) {
self.logPath = url.relativePath
if let logReference = action.actionResult.logRef {
self.logContent = file.exportLogsContent(
id: logReference.id,
renderingMode: renderingMode
)
} else {
Logger.warning("Can't find test reference for action \(action.title ?? "")")
self.logPath = ""
self.logContent = .none
}
self.testSummaries = testPlanSummaries.summaries
.flatMap { $0.testableSummaries }
.map { TestSummary(summary: $0, file: file) }
.map { TestSummary(summary: $0, file: file, configuration: configuration) }
self.designReviews = testSummaries.map(DesignReview.init)
}

private var logSource: String? {
switch logContent {
case let .url(url):
return url.relativePath
case let .data(data):
return "data:text/plain;base64,\(data.base64EncodedString())"
case .none:
return nil
}
}

// PRAGMA MARK: - HTML

var htmlTemplate = HTMLTemplates.run

var htmlPlaceholderValues: [String: String] {
return [
"DEVICE_IDENTIFIER": runDestination.targetDevice.uniqueIdentifier,
"LOG_PATH": logPath,
"LOG_SOURCE": logSource ?? "",
"N_OF_TESTS": String(numberOfTests),
"N_OF_PASSED_TESTS": String(numberOfPassedTests),
"N_OF_FAILED_TESTS": String(numberOfFailedTests),
Expand Down
4 changes: 2 additions & 2 deletions Sources/XCTestHTMLReport/Classes/Models/Summary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct Summary
{
let runs: [Run]

init(resultPaths: [String]) {
init(resultPaths: [String], configuration: Configuration) {
var runs: [Run] = []
for resultPath in resultPaths {
Logger.step("Parsing \(resultPath)")
Expand All @@ -24,7 +24,7 @@ struct Summary
break
}
let resultRuns = invocationRecord.actions.compactMap {
Run(action: $0, file: resultFile)
Run(action: $0, file: resultFile, configuration: configuration)
}
runs.append(contentsOf: resultRuns)
}
Expand Down
10 changes: 5 additions & 5 deletions Sources/XCTestHTMLReport/Classes/Models/Test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,22 @@ struct Test: HTML
return a == 0 ? subTests.count : a
}

init(group: ActionTestSummaryGroup, file: ResultFile) {
init(group: ActionTestSummaryGroup, file: ResultFile, configuration: Configuration) {
self.uuid = NSUUID().uuidString
self.identifier = group.identifier
self.duration = group.duration
self.name = group.name
if group.subtests.isEmpty {
self.subTests = group.subtestGroups.map { Test(group: $0, file: file) }
self.subTests = group.subtestGroups.map { Test(group: $0, file: file, configuration: configuration) }
} else {
self.subTests = group.subtests.map { Test(metadata: $0, file: file) }
self.subTests = group.subtests.map { Test(metadata: $0, file: file, configuration: configuration) }
}
self.objectClass = .testSummaryGroup
self.activities = []
self.status = .unknown // ???: Usefull?
}

init(metadata: ActionTestMetadata, file: ResultFile) {
init(metadata: ActionTestMetadata, file: ResultFile, configuration: Configuration) {
self.uuid = NSUUID().uuidString
self.identifier = metadata.identifier
self.duration = metadata.duration ?? 0
Expand All @@ -96,7 +96,7 @@ struct Test: HTML
if let id = metadata.summaryRef?.id,
let actionTestSummary = file.getActionTestSummary(id: id) {
self.activities = actionTestSummary.activitySummaries.map {
Activity(summary: $0, file: file, padding: 20)
Activity(summary: $0, file: file, padding: 20, configuration: configuration)
}
} else {
self.activities = []
Expand Down
Loading

0 comments on commit 2d519dd

Please sign in to comment.