Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update snapshot to support both Swift 3 and Swift 2.3 #6218

Merged
merged 1 commit into from Sep 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions snapshot/example/Example.xcodeproj/project.pbxproj
Expand Up @@ -291,9 +291,11 @@
};
CA0BF15D1A1117FD007D51BE = {
CreatedOnToolsVersion = 6.1;
LastSwiftMigration = 0800;
};
CAF3CF371B33E9AB006CEDE9 = {
CreatedOnToolsVersion = 7.0;
LastSwiftMigration = 0800;
TestTargetID = CA0BF15D1A1117FD007D51BE;
};
};
Expand Down Expand Up @@ -598,6 +600,7 @@
INFOPLIST_FILE = Example/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
Expand All @@ -608,6 +611,7 @@
INFOPLIST_FILE = Example/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
};
name = Release;
};
Expand All @@ -624,6 +628,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.krausefx.ExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = Example;
USES_XCTRUNNER = YES;
};
Expand All @@ -641,6 +646,7 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = com.krausefx.ExampleUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 3.0;
TEST_TARGET_NAME = Example;
USES_XCTRUNNER = YES;
};
Expand All @@ -656,6 +662,7 @@
2FE467701D5A605000E9FF83 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
2FE467801D5A608A00E9FF83 /* Build configuration list for PBXNativeTarget "ExampleTVUITests" */ = {
isa = XCConfigurationList;
Expand All @@ -664,6 +671,7 @@
2FE467821D5A608A00E9FF83 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
CA0BF1591A1117FD007D51BE /* Build configuration list for PBXProject "Example" */ = {
isa = XCConfigurationList;
Expand Down
8 changes: 4 additions & 4 deletions snapshot/example/ExampleUITests/ExampleUITests.swift
Expand Up @@ -23,17 +23,17 @@ class ExampleUITests: XCTestCase {
{
snapshot("0Launch")
let tabBar = XCUIApplication().tabBars
let secondButton = tabBar.buttons.elementBoundByIndex(1)
let secondButton = tabBar.buttons.element(boundBy: 1)

XCUIDevice().orientation = UIDeviceOrientation.LandscapeLeft
XCUIDevice().orientation = UIDeviceOrientation.landscapeLeft
snapshot("1LandscapeLeft")

secondButton.tap()
XCUIDevice().orientation = UIDeviceOrientation.LandscapeRight
XCUIDevice().orientation = UIDeviceOrientation.landscapeRight
snapshot("2LandscapeRight")

secondButton.tap()
XCUIDevice().orientation = UIDeviceOrientation.Portrait
XCUIDevice().orientation = UIDeviceOrientation.portrait
snapshot("3Portrait")
}
}
52 changes: 26 additions & 26 deletions snapshot/lib/assets/SnapshotHelper.swift
Expand Up @@ -12,84 +12,84 @@ import XCTest
var deviceLanguage = ""
var locale = ""

@available(*, deprecated, message="use setupSnapshot: instead")
func setLanguage(app: XCUIApplication) {
@available(*, deprecated, message: "use setupSnapshot: instead")
func setLanguage(_ app: XCUIApplication) {
setupSnapshot(app)
}

func setupSnapshot(app: XCUIApplication) {
func setupSnapshot(_ app: XCUIApplication) {
Snapshot.setupSnapshot(app)
}

func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator)
}

public class Snapshot: NSObject {
open class Snapshot: NSObject {

public class func setupSnapshot(app: XCUIApplication) {
open class func setupSnapshot(_ app: XCUIApplication) {
setLanguage(app)
setLocale(app)
setLaunchArguments(app)
}

class func setLanguage(app: XCUIApplication) {
class func setLanguage(_ app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("language.txt")
let path = prefix.appendingPathComponent("language.txt")

do {
let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
deviceLanguage = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
let trimCharacterSet = CharacterSet.whitespacesAndNewlines
deviceLanguage = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
} catch {
print("Couldn't detect/set language...")
}
}

class func setLocale(app: XCUIApplication) {
class func setLocale(_ app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("locale.txt")
let path = prefix.appendingPathComponent("locale.txt")

do {
let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
locale = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
let trimCharacterSet = CharacterSet.whitespacesAndNewlines
locale = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue).trimmingCharacters(in: trimCharacterSet) as String
} catch {
print("Couldn't detect/set locale...")
}
if locale.isEmpty {
locale = NSLocale(localeIdentifier: deviceLanguage).localeIdentifier
locale = Locale(identifier: deviceLanguage).identifier
}
app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
}

class func setLaunchArguments(app: XCUIApplication) {
class func setLaunchArguments(_ app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("snapshot-launch_arguments.txt")
let path = prefix.appendingPathComponent("snapshot-launch_arguments.txt")
app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]

do {
let launchArguments = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
let launchArguments = try NSString(contentsOfFile: path, encoding: String.Encoding.utf8.rawValue) as String
let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
let matches = regex.matchesInString(launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
let matches = regex.matches(in: launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
let results = matches.map { result -> String in
(launchArguments as NSString).substringWithRange(result.range)
(launchArguments as NSString).substring(with: result.range)
}
app.launchArguments += results
} catch {
print("Couldn't detect/set launch_arguments...")
}
}

public class func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
open class func snapshot(_ name: String, waitForLoadingIndicator: Bool = true) {
if waitForLoadingIndicator {
waitForLoadingIndicatorToDisappear()
}
Expand All @@ -101,7 +101,7 @@ public class Snapshot: NSObject {
#if os(tvOS)
XCUIApplication().childrenMatchingType(.Browser).count
#else
XCUIDevice.sharedDevice().orientation = .Unknown
XCUIDevice.shared().orientation = .unknown
#endif
}

Expand All @@ -110,17 +110,17 @@ public class Snapshot: NSObject {
return;
#endif

let query = XCUIApplication().statusBars.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Other)
let query = XCUIApplication().statusBars.children(matching: .other).element(boundBy: 1).children(matching: .other)

while (0..<query.count).map({ query.elementBoundByIndex($0) }).contains({ $0.isLoadingIndicator }) {
while (0..<query.count).map({ query.element(boundBy: $0) }).contains(where: { $0.isLoadingIndicator }) {
sleep(1)
print("Waiting for loading indicator to disappear...")
}
}

class func pathPrefix() -> NSString? {
if let path = NSProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
return path.stringByAppendingPathComponent("Library/Caches/tools.fastlane")
if let path = ProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
return path.appendingPathComponent("Library/Caches/tools.fastlane") as NSString?
}
print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
return nil
Expand Down
140 changes: 140 additions & 0 deletions snapshot/lib/assets/SnapshotHelper2-3.swift
@@ -0,0 +1,140 @@
//
// SnapshotHelper.swift
// Example
//
// Created by Felix Krause on 10/8/15.
// Copyright © 2015 Felix Krause. All rights reserved.
//

// This file should be used if your UI Tests are written in Swift 2.3

import Foundation
import XCTest

var deviceLanguage = ""
var locale = ""

@available(*, deprecated, message="use setupSnapshot: instead")
func setLanguage(app: XCUIApplication) {
setupSnapshot(app)
}

func setupSnapshot(app: XCUIApplication) {
Snapshot.setupSnapshot(app)
}

func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
Snapshot.snapshot(name, waitForLoadingIndicator: waitForLoadingIndicator)
}

public class Snapshot: NSObject {

public class func setupSnapshot(app: XCUIApplication) {
setLanguage(app)
setLocale(app)
setLaunchArguments(app)
}

class func setLanguage(app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("language.txt")

do {
let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
deviceLanguage = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
app.launchArguments += ["-AppleLanguages", "(\(deviceLanguage))"]
} catch {
print("Couldn't detect/set language...")
}
}

class func setLocale(app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("locale.txt")

do {
let trimCharacterSet = NSCharacterSet.whitespaceAndNewlineCharacterSet()
locale = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding).stringByTrimmingCharactersInSet(trimCharacterSet) as String
} catch {
print("Couldn't detect/set locale...")
}
if locale.isEmpty {
locale = NSLocale(localeIdentifier: deviceLanguage).localeIdentifier
}
app.launchArguments += ["-AppleLocale", "\"\(locale)\""]
}

class func setLaunchArguments(app: XCUIApplication) {
guard let prefix = pathPrefix() else {
return
}

let path = prefix.stringByAppendingPathComponent("snapshot-launch_arguments.txt")
app.launchArguments += ["-FASTLANE_SNAPSHOT", "YES", "-ui_testing"]

do {
let launchArguments = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding) as String
let regex = try NSRegularExpression(pattern: "(\\\".+?\\\"|\\S+)", options: [])
let matches = regex.matchesInString(launchArguments, options: [], range: NSRange(location:0, length:launchArguments.characters.count))
let results = matches.map { result -> String in
(launchArguments as NSString).substringWithRange(result.range)
}
app.launchArguments += results
} catch {
print("Couldn't detect/set launch_arguments...")
}
}

public class func snapshot(name: String, waitForLoadingIndicator: Bool = true) {
if waitForLoadingIndicator {
waitForLoadingIndicatorToDisappear()
}

print("snapshot: \(name)") // more information about this, check out https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work

sleep(1) // Waiting for the animation to be finished (kind of)

#if os(tvOS)
XCUIApplication().childrenMatchingType(.Browser).count
#else
XCUIDevice.sharedDevice().orientation = .Unknown
#endif
}

class func waitForLoadingIndicatorToDisappear() {
#if os(tvOS)
return;
#endif

let query = XCUIApplication().statusBars.childrenMatchingType(.Other).elementBoundByIndex(1).childrenMatchingType(.Other)

while (0..<query.count).map({ query.elementBoundByIndex($0) }).contains({ $0.isLoadingIndicator }) {
sleep(1)
print("Waiting for loading indicator to disappear...")
}
}

class func pathPrefix() -> NSString? {
if let path = NSProcessInfo().environment["SIMULATOR_HOST_HOME"] as NSString? {
return path.stringByAppendingPathComponent("Library/Caches/tools.fastlane")
}
print("Couldn't find Snapshot configuration files at ~/Library/Caches/tools.fastlane")
return nil
}
}

extension XCUIElement {
var isLoadingIndicator: Bool {
return self.frame.size == CGSize(width: 10, height: 20)
}
}

// Please don't remove the lines below
// They are used to detect outdated configuration files
// SnapshotHelperVersion [1.2]
6 changes: 4 additions & 2 deletions snapshot/lib/snapshot/setup.rb
Expand Up @@ -10,9 +10,11 @@ def self.create(path)

File.write(snapfile_path, File.read("#{Snapshot::ROOT}/lib/assets/SnapfileTemplate"))
File.write(File.join(path, 'SnapshotHelper.swift'), File.read("#{Snapshot::ROOT}/lib/assets/SnapshotHelper.swift"))
File.write(File.join(path, 'SnapshotHelper2-3.swift'), File.read("#{Snapshot::ROOT}/lib/assets/SnapshotHelper2-3.swift"))

puts "Successfully created SnapshotHelper.swift '#{File.join(path, 'SnapshotHelper.swift')}'".green
puts "Successfully created new Snapfile at '#{snapfile_path}'".green
puts "✅ Successfully created SnapshotHelper.swift '#{File.join(path, 'SnapshotHelper.swift')}'".green
puts "✅ Successfully created SnapshotHelper2-3.swift '#{File.join(path, 'SnapshotHelper2-3.swift')} (if your UI tests are written in Swift 2.3)'".green
puts "✅ Successfully created new Snapfile at '#{snapfile_path}'".green

puts "-------------------------------------------------------".yellow
puts "Open your Xcode project and make sure to do the following:".yellow
Expand Down