Add CLUE screens to the automatic screenshot generation process

This commit is contained in:
Antonio 2020-03-19 23:19:22 +01:00
parent 0d33821c88
commit 542f5ca8c8
11 changed files with 187 additions and 107 deletions

View file

@ -10,9 +10,29 @@ import Foundation
import CoreBluetooth import CoreBluetooth
extension BlePeripheral { extension BlePeripheral {
// MARK: - Custom properties
private struct CustomPropertiesKeys {
static var adafruitLightResponseDataTimer: Timer?
}
private var adafruitLightResponseDataTimer: Timer? {
get {
return objc_getAssociatedObject(self, &CustomPropertiesKeys.adafruitLightResponseDataTimer) as! Timer?
}
set {
objc_setAssociatedObject(self, &CustomPropertiesKeys.adafruitLightResponseDataTimer, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}
// MARK: - Actions // MARK: - Actions
func adafruitLightEnable(responseHandler: @escaping(Result<(Float, UUID), Error>) -> Void, completion: ((Result<Void, Error>) -> Void)?) { func adafruitLightEnable(responseHandler: @escaping(Result<(Float, UUID), Error>) -> Void, completion: ((Result<Void, Error>) -> Void)?) {
adafruitLightResponseDataTimer = Timer.scheduledTimer(withTimeInterval: BlePeripheral.kAdafruitSensorDefaultPeriod, repeats: true) { [weak self] _ in
guard let self = self else { return }
guard let value = self.adafruitLightLastValue() else { return }
responseHandler(.success((value, self.identifier)))
}
completion?(.success(())) completion?(.success(()))
} }
@ -21,6 +41,8 @@ extension BlePeripheral {
} }
func adafruitLightDisable() { func adafruitLightDisable() {
adafruitLightResponseDataTimer?.invalidate()
adafruitLightResponseDataTimer = nil
} }
func adafruitLightLastValue() -> Float? { func adafruitLightLastValue() -> Float? {

View file

@ -29,8 +29,7 @@ extension BlePeripheral {
return self.adafruitManufacturerData()?.boardModel == .clue_nRF52840 return self.adafruitManufacturerData()?.boardModel == .clue_nRF52840
} }
func adafruitQuaternionDisable() { func adafruitQuaternionDisable() {
} }
func adafruitQuaternionLastValue() -> QuaternionValue? { func adafruitQuaternionLastValue() -> QuaternionValue? {

View file

@ -18,7 +18,7 @@ struct Config {
static let isDebugEnabled = _isDebugAssertConfiguration() static let isDebugEnabled = _isDebugAssertConfiguration()
// Fastlane snapshots // Fastlane snapshots
private static let areFastlaneSnapshotsRunning = UserDefaults.standard.bool(forKey: "FASTLANE_SNAPSHOT") static let areFastlaneSnapshotsRunning = UserDefaults.standard.bool(forKey: "FASTLANE_SNAPSHOT")
// Bluetooth // Bluetooth
#if SIMULATEBLUETOOTH #if SIMULATEBLUETOOTH

View file

@ -69,4 +69,10 @@ struct QuaternionUtils {
let twistNormalized = twist.normalized let twistNormalized = twist.normalized
return twistNormalized return twistNormalized
} }
static func isQuaternionValid(_ quaternion: simd_quatf) -> Bool {
let vector = quaternion.vector
return vector.x.isFinite && vector.y.isFinite && vector.z.isFinite && vector.w.isFinite
}
} }

View file

@ -30,7 +30,7 @@ class AccelerometerViewController: ModuleViewController {
// Load scene // Load scene
if let scene = AdafruitBoardsManager.shared.currentBoard?.assetScene { if let scene = AdafruitBoardsManager.shared.currentBoard?.assetScene {
boardNode = scene.rootNode.childNode(withName: "root", recursively: false)! boardNode = scene.rootNode.childNode(withName: "root", recursively: false)
// Setup scene // Setup scene
sceneView.scene = scene sceneView.scene = scene

View file

@ -163,7 +163,7 @@ class HomeViewController: UIViewController {
if board.isToneGeneratorEnabled { if board.isToneGeneratorEnabled {
result.append(.tone) result.append(.tone)
} }
if (!board.isQuaternionEnabled || Config.isDebugEnabled) && board.isAccelerometerEnabled { if (!board.isQuaternionEnabled || (Config.isDebugEnabled && !Config.areFastlaneSnapshotsRunning)) && board.isAccelerometerEnabled {
result.append(.accelerometer) result.append(.accelerometer)
} }
if board.isQuaternionEnabled { if board.isQuaternionEnabled {

View file

@ -48,9 +48,9 @@ class PuppetViewController: UIViewController {
let scene = SCNScene(named: "Sparky_Gold1.scn")! let scene = SCNScene(named: "Sparky_Gold1.scn")!
scene.background.contents = UIColor.clear scene.background.contents = UIColor.clear
jawNode = scene.rootNode.childNode(withName: "jaw", recursively: true)! jawNode = scene.rootNode.childNode(withName: "jaw", recursively: true)
headNode = scene.rootNode.childNode(withName: "SparkyHead", recursively: true)! headNode = scene.rootNode.childNode(withName: "SparkyHead", recursively: true)
sparkyFaceNode = scene.rootNode.childNode(withName: "Face", recursively: true)! sparkyFaceNode = scene.rootNode.childNode(withName: "Face", recursively: true)
// Setup scene // Setup scene
sceneView.scene = scene sceneView.scene = scene

View file

@ -33,7 +33,7 @@ class QuaternionViewController: ModuleViewController {
// Load scene // Load scene
if let scene = AdafruitBoardsManager.shared.currentBoard?.assetScene { if let scene = AdafruitBoardsManager.shared.currentBoard?.assetScene {
boardNode = scene.rootNode.childNode(withName: "root", recursively: false)! boardNode = scene.rootNode.childNode(withName: "root", recursively: false)
// Setup scene // Setup scene
sceneView.scene = scene sceneView.scene = scene
@ -88,8 +88,13 @@ class QuaternionViewController: ModuleViewController {
if QuaternionViewController.kIsZAxisDisabled { if QuaternionViewController.kIsZAxisDisabled {
// Calculate rotation around the z axis. // Calculate rotation around the z axis.
let twist = QuaternionUtils.twist_decomposition(rotation: scnQuaternion, direction: simd_float3(0, 0, 1)) let twist = QuaternionUtils.twist_decomposition(rotation: scnQuaternion, direction: simd_float3(0, 0, 1))
// Remove z axis rotation if QuaternionUtils.isQuaternionValid(twist) { // Check twist singularity
boardNode.simdOrientation = scnQuaternion * twist.inverse // Remove z axis rotation
boardNode.simdOrientation = scnQuaternion * twist.inverse
}
else {
boardNode.simdOrientation = scnQuaternion
}
} }
else { else {
boardNode.simdOrientation = scnQuaternion boardNode.simdOrientation = scnQuaternion

View file

@ -28,7 +28,7 @@ class TipWelcomeViewController: TipAnimationViewController {
} }
} }
private var circuitNode: SCNNode! private var boardNode: SCNNode!
// MARK: - Lifecycle // MARK: - Lifecycle
override func viewDidLoad() { override func viewDidLoad() {
@ -38,7 +38,7 @@ class TipWelcomeViewController: TipAnimationViewController {
let scene = SCNScene(named: "clue.scn")! let scene = SCNScene(named: "clue.scn")!
scene.background.contents = UIColor.clear scene.background.contents = UIColor.clear
circuitNode = scene.rootNode.childNode(withName: "root", recursively: false)! boardNode = scene.rootNode.childNode(withName: "root", recursively: false)!
// Setup scene // Setup scene
sceneView.scene = scene sceneView.scene = scene
@ -56,13 +56,13 @@ class TipWelcomeViewController: TipAnimationViewController {
sceneView.alpha = 1 sceneView.alpha = 1
sceneView.transform = .identity sceneView.transform = .identity
circuitNode.opacity = 1 boardNode.opacity = 1
circuitNode.removeAllActions() boardNode.removeAllActions()
circuitNode.removeAllAnimations() boardNode.removeAllAnimations()
//circuitNode.position = SCNVector3(0, -5, 0) //circuitNode.position = SCNVector3(0, -5, 0)
circuitNode.localTranslate(by: SCNVector3(0, -5, 0)) boardNode.localTranslate(by: SCNVector3(0, -5, 0))
circuitNode.scale = SCNVector3(0.3, 0.3, 0.3) boardNode.scale = SCNVector3(0.3, 0.3, 0.3)
circuitNode.rotation = SCNVector4(0, 50 * CGFloat.pi / 180, 0, 1) boardNode.rotation = SCNVector4(0, 50 * CGFloat.pi / 180, 0, 1)
} }
private func animateIntro() { private func animateIntro() {
@ -76,8 +76,8 @@ class TipWelcomeViewController: TipAnimationViewController {
]) ])
// appearAction.timingMode = .easeOut // appearAction.timingMode = .easeOut
circuitNode.runAction(appearAction, forKey: "intro") { boardNode.runAction(appearAction, forKey: "intro") {
self.circuitNode.runAction( self.boardNode.runAction(
SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: -2 * .pi, z: 0, duration: 30)) SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: -2 * .pi, z: 0, duration: 30))
) )
} }
@ -116,10 +116,10 @@ class TipWelcomeViewController: TipAnimationViewController {
animateIntro() animateIntro()
} else { } else {
// If coming from intro, stop the animations and restore the rotation // If coming from intro, stop the animations and restore the rotation
let isTransitioningFromIntro = circuitNode.action(forKey: "intro") != nil let isTransitioningFromIntro = boardNode.action(forKey: "intro") != nil
if isTransitioningFromIntro { if isTransitioningFromIntro {
circuitNode.removeAction(forKey: "intro") boardNode.removeAction(forKey: "intro")
self.circuitNode.runAction( self.boardNode.runAction(
SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: -2 * .pi, z: 0, duration: 30)) SCNAction.repeatForever(SCNAction.rotateBy(x: 0, y: -2 * .pi, z: 0, duration: 30))
) )
} }

View file

@ -26,70 +26,104 @@ class BluefruitPlaygroundUITests: XCTestCase {
override func tearDown() { override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class. // Put teardown code here. This method is called after the invocation of each test method in the class.
} }
func testSnapshots() { func testSnapsthotsClue() {
/*
// UI tests must launch the application that they test.
let app = XCUIApplication() let app = XCUIApplication()
app.launch() let elementsQuery = app.scrollViews.otherElements
*/
// Use recording to get started writing UI tests. sleep(1) // Wait for the intro animation
// Use XCTAssert and related functions to verify your tests produce the correct results.
let app = XCUIApplication()
let scrollViewsQuery = app.scrollViews
let elementsQuery = scrollViewsQuery.otherElements
sleep(2) // Wait for the intro animation
snapshot("01a_Welcome") snapshot("01a_Welcome")
elementsQuery.buttons["LET'S GET STARTED..."].tap() elementsQuery.buttons["LET'S GET STARTED..."].tap()
snapshot("01b_PowerUp") snapshot("01b_PowerUp")
elementsQuery.buttons["NEXT"].tap() elementsQuery.buttons["NEXT"].tap()
snapshot("01c_Discover") snapshot("01c_Discover")
elementsQuery.buttons["BEGIN PAIRING"].tap() elementsQuery.buttons["FIND DEVICES"].tap()
let tablesQuery = app.tables let tablesQuery = app.tables
tablesQuery.staticTexts["Simulated Peripheral"].tap()
// CLUE
snapshot("02_Modules") snapshot("01d_Scanner")
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["CLUE"]/*[[".cells.staticTexts[\"CLUE\"]",".staticTexts[\"CLUE\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Control LED color & animation"]/*[[".cells.staticTexts[\"Control LED color & animation\"]",".staticTexts[\"Control LED color & animation\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap() snapshot("02_CLUE_Modules")
let element = scrollViewsQuery.children(matching: .other).element tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["NeoPixels"]/*[[".cells.staticTexts[\"NeoPixels\"]",".staticTexts[\"NeoPixels\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
element.children(matching: .other).element(boundBy: 0).children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element(boundBy: 0).children(matching: .other).element(boundBy: 0).children(matching: .other).element(boundBy: 0).children(matching: .other).element.children(matching: .other).element.children(matching: .button).element.tap() sleep(1)
snapshot("03_Neopixels_LightSequence") snapshot("03_CLUE_Neopixels_LightSequence")
elementsQuery.staticTexts["Light Sequence"].swipeLeft() elementsQuery.staticTexts["Light Sequence"].swipeLeft()
element.children(matching: .other).element(boundBy: 1).children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element(boundBy: 0).children(matching: .other).element(boundBy: 1).children(matching: .button).element(boundBy: 2).tap() snapshot("04a_CLUE_Neopixels_ColorPalette")
snapshot("04a_Neopixels_ColorPalette")
elementsQuery.staticTexts["Color Palette"].swipeLeft() elementsQuery.staticTexts["Color Palette"].swipeLeft()
element.children(matching: .other).element(boundBy: 2).children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element.children(matching: .other).element(boundBy: 0).children(matching: .other).element(boundBy: 0).children(matching: .other).element.children(matching: .other).element.tap() snapshot("04b_CLUE_Neopixels_ColorWheel")
snapshot("04b_Neopixels_ColorWheel")
app.navigationBars["NeoPixels"].buttons["Modules"].tap() app.navigationBars["NeoPixels"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["View continuous light sensor readings"]/*[[".cells.staticTexts[\"View continuous light sensor readings\"]",".staticTexts[\"View continuous light sensor readings\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("05_LightSensor")
app.navigationBars["Light Sensor"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Button Status"]/*[[".cells.staticTexts[\"Button Status\"]",".staticTexts[\"Button Status\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("06_ButtonStatus")
app.navigationBars["Button Status"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Turn CPB into a musical instrument"]/*[[".cells.staticTexts[\"Turn CPB into a musical instrument\"]",".staticTexts[\"Turn CPB into a musical instrument\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("07_ToneGenerator")
app.navigationBars["Tone Generator"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Accelerometer"]/*[[".cells.staticTexts[\"Accelerometer\"]",".staticTexts[\"Accelerometer\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("08_Accelerometer")
app.navigationBars["Accelerometer"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["View current temperature readings"]/*[[".cells.staticTexts[\"View current temperature readings\"]",".staticTexts[\"View current temperature readings\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("09_Temperature")
app.navigationBars["Temperature"].buttons["Modules"].tap()
tablesQuery.staticTexts["Puppets"].tap()
snapshot("10_Puppets")
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Light Sensor"]/*[[".cells.staticTexts[\"Light Sensor\"]",".staticTexts[\"Light Sensor\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("05a_CLUE_LightSensor")
elementsQuery.staticTexts["Luminance Reading"].swipeLeft()
snapshot("05b_CLUE_LightSensor_Chart")
app.navigationBars["Light Sensor"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Button Status"]/*[[".cells.staticTexts[\"Button Status\"]",".staticTexts[\"Button Status\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("06_CLUE_ButtonStatus")
app.navigationBars["Button Status"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Tone Generator"]/*[[".cells.staticTexts[\"Tone Generator\"]",".staticTexts[\"Tone Generator\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("07_CLUE_ToneGenerator")
app.navigationBars["Tone Generator"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Orientation"]/*[[".cells.staticTexts[\"Orientation\"]",".staticTexts[\"Orientation\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("08_CLUE_Orientation")
app.navigationBars["Orientation"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Temperature"]/*[[".cells.staticTexts[\"Temperature\"]",".staticTexts[\"Temperature\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("09_CLUE_Temperature")
app.navigationBars["Temperature"].buttons["Modules"].tap()
/*
let buttonStatusStaticText = tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Button Status"]/*[[".cells.staticTexts[\"Button Status\"]",".staticTexts[\"Button Status\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/
buttonStatusStaticText.swipeUp() // Swipe up to see more modules
*/
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Humidity"]/*[[".cells.staticTexts[\"Humidity\"]",".staticTexts[\"Humidity\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("10_CLUE_Humidity")
app.navigationBars["Humidity"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Pressure"]/*[[".cells.staticTexts[\"Pressure\"]",".staticTexts[\"Pressure\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("11_CLUE_Pressure")
app.navigationBars["Pressure"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Puppets"]/*[[".cells.staticTexts[\"Puppets\"]",".staticTexts[\"Puppets\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
sleep(2) // Wait for the puppet animation
snapshot("12_Puppets")
app.navigationBars["Puppets"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Disconnect"]/*[[".cells.staticTexts[\"Disconnect\"]",".staticTexts[\"Disconnect\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
app.alerts.scrollViews.otherElements.buttons["OK"].tap()
// CPB
XCUIApplication().tables/*@START_MENU_TOKEN@*/.staticTexts["CPB"]/*[[".cells.staticTexts[\"CPB\"]",".staticTexts[\"CPB\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["NeoPixels"]/*[[".cells.staticTexts[\"NeoPixels\"]",".staticTexts[\"NeoPixels\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("03_CPB_Neopixels_LightSequence")
elementsQuery.staticTexts["Light Sequence"].swipeLeft()
snapshot("04a_CPB_Neopixels_ColorPalette")
elementsQuery.staticTexts["Color Palette"].swipeLeft()
snapshot("04b_CPB_Neopixels_ColorWheel")
app.navigationBars["NeoPixels"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Light Sensor"]/*[[".cells.staticTexts[\"Light Sensor\"]",".staticTexts[\"Light Sensor\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("05a_CPB_LightSensor")
elementsQuery.staticTexts["Luminance Reading"].swipeLeft()
snapshot("05b_CPB_LightSensor_Chart")
app.navigationBars["Light Sensor"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Button Status"]/*[[".cells.staticTexts[\"Button Status\"]",".staticTexts[\"Button Status\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("06_CPB_ButtonStatus")
app.navigationBars["Button Status"].buttons["Modules"].tap()
tablesQuery/*@START_MENU_TOKEN@*/.staticTexts["Accelerometer"]/*[[".cells.staticTexts[\"Accelerometer\"]",".staticTexts[\"Accelerometer\"]"],[[[-1,1],[-1,0]]],[0]]@END_MENU_TOKEN@*/.tap()
snapshot("08_CPB_Accelerometer")
app.navigationBars["Accelerometer"].buttons["Modules"].tap()
} }
func testLaunchPerformance() { func testLaunchPerformance() {

View file

@ -5,6 +5,16 @@ GEM
addressable (2.7.0) addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0) public_suffix (>= 2.0.2, < 5.0)
atomos (0.1.3) atomos (0.1.3)
aws-eventstream (1.0.3)
aws-sdk (2.11.471)
aws-sdk-resources (= 2.11.471)
aws-sdk-core (2.11.471)
aws-sigv4 (~> 1.0)
jmespath (~> 1.0)
aws-sdk-resources (2.11.471)
aws-sdk-core (= 2.11.471)
aws-sigv4 (1.1.1)
aws-eventstream (~> 1.0, >= 1.0.2)
babosa (1.0.3) babosa (1.0.3)
claide (1.0.3) claide (1.0.3)
colored (1.2) colored (1.2)
@ -13,13 +23,13 @@ GEM
highline (~> 1.7.2) highline (~> 1.7.2)
declarative (0.0.10) declarative (0.0.10)
declarative-option (0.1.0) declarative-option (0.1.0)
digest-crc (0.4.1) digest-crc (0.5.1)
domain_name (0.5.20190701) domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0) unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.5) dotenv (2.7.5)
emoji_regex (1.0.1) emoji_regex (1.0.1)
excon (0.71.1) excon (0.73.0)
faraday (0.17.1) faraday (0.17.3)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6) faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4) faraday (>= 0.7.4)
@ -27,9 +37,10 @@ GEM
faraday_middleware (0.13.1) faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0) faraday (>= 0.7.4, < 1.0)
fastimage (2.1.7) fastimage (2.1.7)
fastlane (2.138.0) fastlane (2.143.0)
CFPropertyList (>= 2.3, < 4.0.0) CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0) addressable (>= 2.3, < 3.0.0)
aws-sdk (~> 2.3)
babosa (>= 1.0.2, < 2.0.0) babosa (>= 1.0.2, < 2.0.0)
bundler (>= 1.12.0, < 3.0.0) bundler (>= 1.12.0, < 3.0.0)
colored colored
@ -42,7 +53,7 @@ GEM
faraday_middleware (~> 0.13.1) faraday_middleware (~> 0.13.1)
fastimage (>= 2.1.0, < 3.0.0) fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0) gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0) google-api-client (>= 0.29.2, < 0.37.0)
google-cloud-storage (>= 1.15.0, < 2.0.0) google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0) highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0) json (< 3.0.0)
@ -65,41 +76,44 @@ GEM
xcpretty (~> 0.3.0) xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3) xcpretty-travis-formatter (>= 0.0.3)
gh_inspector (1.1.3) gh_inspector (1.1.3)
google-api-client (0.23.9) google-api-client (0.36.4)
addressable (~> 2.5, >= 2.5.1) addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0) googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0) httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0) mini_mime (~> 1.0)
representable (~> 3.0) representable (~> 3.0)
retriable (>= 2.0, < 4.0) retriable (>= 2.0, < 4.0)
signet (~> 0.9) signet (~> 0.12)
google-cloud-core (1.4.1) google-cloud-core (1.5.0)
google-cloud-env (~> 1.0) google-cloud-env (~> 1.0)
google-cloud-env (1.3.0) google-cloud-errors (~> 1.0)
faraday (~> 0.11) google-cloud-env (1.3.1)
google-cloud-storage (1.16.0) faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.0.0)
google-cloud-storage (1.25.1)
addressable (~> 2.5)
digest-crc (~> 0.4) digest-crc (~> 0.4)
google-api-client (~> 0.23) google-api-client (~> 0.33)
google-cloud-core (~> 1.2) google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0) googleauth (~> 0.9)
googleauth (0.6.7) mini_mime (~> 1.0)
faraday (~> 0.12) googleauth (0.11.0)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0) jwt (>= 1.4, < 3.0)
memoist (~> 0.16) memoist (~> 0.16)
multi_json (~> 1.11) multi_json (~> 1.11)
os (>= 0.9, < 2.0) os (>= 0.9, < 2.0)
signet (~> 0.7) signet (~> 0.12)
highline (1.7.10) highline (1.7.10)
http-cookie (1.0.3) http-cookie (1.0.3)
domain_name (~> 0.5) domain_name (~> 0.5)
httpclient (2.8.3) httpclient (2.8.3)
jmespath (1.4.0)
json (2.3.0) json (2.3.0)
jwt (2.1.0) jwt (2.1.0)
memoist (0.16.2) memoist (0.16.2)
mime-types (3.3) mini_magick (4.10.1)
mime-types-data (~> 3.2015) mini_mime (1.0.2)
mime-types-data (3.2019.1009)
mini_magick (4.9.5)
multi_json (1.14.1) multi_json (1.14.1)
multi_xml (0.6.0) multi_xml (0.6.0)
multipart-post (2.0.0) multipart-post (2.0.0)
@ -116,29 +130,29 @@ GEM
rouge (2.0.7) rouge (2.0.7)
rubyzip (1.3.0) rubyzip (1.3.0)
security (0.1.3) security (0.1.3)
signet (0.12.0) signet (0.13.0)
addressable (~> 2.3) addressable (~> 2.3)
faraday (~> 0.9) faraday (>= 0.17.3, < 2.0)
jwt (>= 1.5, < 3.0) jwt (>= 1.5, < 3.0)
multi_json (~> 1.10) multi_json (~> 1.10)
simctl (1.6.7) simctl (1.6.8)
CFPropertyList CFPropertyList
naturally naturally
slack-notifier (2.3.2) slack-notifier (2.3.2)
terminal-notifier (2.0.0) terminal-notifier (2.0.0)
terminal-table (1.8.0) terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1) unicode-display_width (~> 1.1, >= 1.1.1)
tty-cursor (0.7.0) tty-cursor (0.7.1)
tty-screen (0.7.0) tty-screen (0.7.1)
tty-spinner (0.9.2) tty-spinner (0.9.3)
tty-cursor (~> 0.7) tty-cursor (~> 0.7)
uber (0.1.0) uber (0.1.0)
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.6) unf_ext (0.0.7.6)
unicode-display_width (1.6.0) unicode-display_width (1.7.0)
word_wrap (1.0.0) word_wrap (1.0.0)
xcodeproj (1.14.0) xcodeproj (1.15.0)
CFPropertyList (>= 2.3.3, < 4.0) CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3) atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0) claide (>= 1.0.2, < 2.0)