Skip to content

Commit 66b1db4

Browse files
Add support for specifying the UI testing screenshot behavior in a scheme test action (#942)
* Support for specifying UI testing snapshot behavior in scheme test action * Add tests for new screenshot scheme options * Update changelog * Add new fields to Scheme.Test json encoding * Only save values to JSON if they aren't the defaults * Using new defaults constants
1 parent ce05129 commit 66b1db4

File tree

5 files changed

+89
-1
lines changed

5 files changed

+89
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Added support for DocC Catalogs [#1091](https://github.com/yonaskolb/XcodeGen/pull/1091) @brevansio
88
- Added support for "driver-extension" and "system-extension" product types [#1092](https://github.com/yonaskolb/XcodeGen/issues/1092) @vgorloff
99
- Add support for conditionally linking dependencies for specific platforms [#1087](https://github.com/yonaskolb/XcodeGen/pull/1087) @daltonclaybrook
10+
- Add ability to specify UI testing screenshot behavior in test schemes [#942](https://github.com/yonaskolb/XcodeGen/pull/942) @daltonclaybrook
1011

1112
### Changed
1213
- **Breaking**: Rename the `platform` field on `Dependency` to `platformFilter` [#1087](https://github.com/yonaskolb/XcodeGen/pull/1087) @daltonclaybrook

Docs/ProjectSpec.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,8 @@ A multiline script can be written using the various YAML multiline methods, for
814814
- [ ] **coverageTargets**: **[String]** - a list of targets to gather code coverage. Each entry can either be a simple string, or a string using [Project Reference](#project-reference)
815815
- [ ] **targets**: **[[Test Target](#test-target)]** - a list of targets to test. Each entry can either be a simple string, or a [Test Target](#test-target)
816816
- [ ] **customLLDBInit**: **String** - the absolute path to the custom `.lldbinit` file
817+
- [ ] **captureScreenshotsAutomatically**: **Bool** - indicates whether screenshots should be captured automatically while UI Testing. This defaults to true.
818+
- [ ] **deleteScreenshotsWhenEachTestSucceeds**: **Bool** - whether successful UI tests should cause automatically-captured screenshots to be deleted. If `captureScreenshotsAutomatically` is false, this value is ignored. This defaults to true.
817819

818820
#### Test Target
819821
- [x] **name**: **String** - The name of the target

Sources/ProjectSpec/Scheme.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ public struct Scheme: Equatable {
164164
public static let gatherCoverageDataDefault = false
165165
public static let disableMainThreadCheckerDefault = false
166166
public static let debugEnabledDefault = true
167+
public static let captureScreenshotsAutomaticallyDefault = true
168+
public static let deleteScreenshotsWhenEachTestSucceedsDefault = true
167169

168170
public var config: String?
169171
public var gatherCoverageData: Bool
@@ -178,6 +180,8 @@ public struct Scheme: Equatable {
178180
public var region: String?
179181
public var debugEnabled: Bool
180182
public var customLLDBInit: String?
183+
public var captureScreenshotsAutomatically: Bool
184+
public var deleteScreenshotsWhenEachTestSucceeds: Bool
181185

182186
public struct TestTarget: Equatable, ExpressibleByStringLiteral {
183187
public static let randomExecutionOrderDefault = false
@@ -236,7 +240,9 @@ public struct Scheme: Equatable {
236240
language: String? = nil,
237241
region: String? = nil,
238242
debugEnabled: Bool = debugEnabledDefault,
239-
customLLDBInit: String? = nil
243+
customLLDBInit: String? = nil,
244+
captureScreenshotsAutomatically: Bool = captureScreenshotsAutomaticallyDefault,
245+
deleteScreenshotsWhenEachTestSucceeds: Bool = deleteScreenshotsWhenEachTestSucceedsDefault
240246
) {
241247
self.config = config
242248
self.gatherCoverageData = gatherCoverageData
@@ -251,6 +257,8 @@ public struct Scheme: Equatable {
251257
self.region = region
252258
self.debugEnabled = debugEnabled
253259
self.customLLDBInit = customLLDBInit
260+
self.captureScreenshotsAutomatically = captureScreenshotsAutomatically
261+
self.deleteScreenshotsWhenEachTestSucceeds = deleteScreenshotsWhenEachTestSucceeds
254262
}
255263

256264
public var shouldUseLaunchSchemeArgsEnv: Bool {
@@ -475,6 +483,8 @@ extension Scheme.Test: JSONObjectConvertible {
475483
region = jsonDictionary.json(atKeyPath: "region")
476484
debugEnabled = jsonDictionary.json(atKeyPath: "debugEnabled") ?? Scheme.Test.debugEnabledDefault
477485
customLLDBInit = jsonDictionary.json(atKeyPath: "customLLDBInit")
486+
captureScreenshotsAutomatically = jsonDictionary.json(atKeyPath: "captureScreenshotsAutomatically") ?? Scheme.Test.captureScreenshotsAutomaticallyDefault
487+
deleteScreenshotsWhenEachTestSucceeds = jsonDictionary.json(atKeyPath: "deleteScreenshotsWhenEachTestSucceeds") ?? Scheme.Test.deleteScreenshotsWhenEachTestSucceedsDefault
478488
}
479489
}
480490

@@ -508,6 +518,14 @@ extension Scheme.Test: JSONEncodable {
508518
dict["customLLDBInit"] = customLLDBInit
509519
}
510520

521+
if captureScreenshotsAutomatically != Scheme.Test.captureScreenshotsAutomaticallyDefault {
522+
dict["captureScreenshotsAutomatically"] = captureScreenshotsAutomatically
523+
}
524+
525+
if deleteScreenshotsWhenEachTestSucceeds != Scheme.Test.deleteScreenshotsWhenEachTestSucceedsDefault {
526+
dict["deleteScreenshotsWhenEachTestSucceeds"] = deleteScreenshotsWhenEachTestSucceeds
527+
}
528+
511529
return dict
512530
}
513531
}

Sources/XcodeGenKit/SchemeGenerator.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ public class SchemeGenerator {
228228
environmentVariables: testVariables,
229229
language: scheme.test?.language,
230230
region: scheme.test?.region,
231+
systemAttachmentLifetime: scheme.test?.systemAttachmentLifetime,
231232
customLLDBInitFile: scheme.test?.customLLDBInit
232233
)
233234

@@ -448,3 +449,16 @@ extension PBXProductType {
448449
}
449450
}
450451
}
452+
453+
extension Scheme.Test {
454+
var systemAttachmentLifetime: XCScheme.TestAction.AttachmentLifetime? {
455+
switch (captureScreenshotsAutomatically, deleteScreenshotsWhenEachTestSucceeds) {
456+
case (false, _):
457+
return .keepNever
458+
case (true, false):
459+
return .keepAlways
460+
case (true, true):
461+
return nil
462+
}
463+
}
464+
}

Tests/XcodeGenKitTests/SchemeGeneratorTests.swift

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ class SchemeGeneratorTests: XCTestCase {
108108
try expect(xcscheme.launchAction?.locationScenarioReference?.identifier) == "New York, NY, USA"
109109
try expect(xcscheme.launchAction?.customLLDBInitFile) == "/sample/.lldbinit"
110110
try expect(xcscheme.testAction?.customLLDBInitFile) == "/test/.lldbinit"
111+
try expect(xcscheme.testAction?.systemAttachmentLifetime).to.beNil()
111112
}
112113

113114
let frameworkTarget = Scheme.BuildTarget(target: .local(framework.name), buildTypes: [.archiving])
@@ -445,6 +446,42 @@ class SchemeGeneratorTests: XCTestCase {
445446
let xcscheme = try unwrap(xcodeProject.sharedData?.schemes.first)
446447
try expect(xcscheme.launchAction?.macroExpansion?.buildableName) == "MyApp.app"
447448
}
449+
450+
$0.it("generates scheme capturing screenshots automatically and deleting on success") {
451+
let xcscheme = try self.makeSnapshotScheme(
452+
buildTarget: buildTarget,
453+
captureScreenshotsAutomatically: true,
454+
deleteScreenshotsWhenEachTestSucceeds: true)
455+
456+
try expect(xcscheme.testAction?.systemAttachmentLifetime).to.beNil()
457+
}
458+
459+
$0.it("generates scheme capturing screenshots and not deleting") {
460+
let xcscheme = try self.makeSnapshotScheme(
461+
buildTarget: buildTarget,
462+
captureScreenshotsAutomatically: true,
463+
deleteScreenshotsWhenEachTestSucceeds: false)
464+
465+
try expect(xcscheme.testAction?.systemAttachmentLifetime) == .keepAlways
466+
}
467+
468+
$0.it("generates scheme not capturing screenshots") {
469+
let xcscheme = try self.makeSnapshotScheme(
470+
buildTarget: buildTarget,
471+
captureScreenshotsAutomatically: false,
472+
deleteScreenshotsWhenEachTestSucceeds: false)
473+
474+
try expect(xcscheme.testAction?.systemAttachmentLifetime) == .keepNever
475+
}
476+
477+
$0.it("ignores screenshot delete preference when not capturing screenshots") {
478+
let xcscheme = try self.makeSnapshotScheme(
479+
buildTarget: buildTarget,
480+
captureScreenshotsAutomatically: false,
481+
deleteScreenshotsWhenEachTestSucceeds: true)
482+
483+
try expect(xcscheme.testAction?.systemAttachmentLifetime) == .keepNever
484+
}
448485
}
449486
}
450487

@@ -503,4 +540,20 @@ class SchemeGeneratorTests: XCTestCase {
503540
let xcodeProject = try project.generateXcodeProject()
504541
return try unwrap(xcodeProject.sharedData?.schemes.first)
505542
}
543+
544+
private func makeSnapshotScheme(buildTarget: Scheme.BuildTarget, captureScreenshotsAutomatically: Bool, deleteScreenshotsWhenEachTestSucceeds: Bool) throws -> XCScheme {
545+
let scheme = Scheme(
546+
name: "MyScheme",
547+
build: Scheme.Build(targets: [buildTarget]),
548+
run: Scheme.Run(config: "Debug"),
549+
test: Scheme.Test(config: "Debug", captureScreenshotsAutomatically: captureScreenshotsAutomatically, deleteScreenshotsWhenEachTestSucceeds: deleteScreenshotsWhenEachTestSucceeds)
550+
)
551+
let project = Project(
552+
name: "test",
553+
targets: [app, framework],
554+
schemes: [scheme]
555+
)
556+
let xcodeProject = try project.generateXcodeProject()
557+
return try unwrap(xcodeProject.sharedData?.schemes.first)
558+
}
506559
}

0 commit comments

Comments
 (0)