diff --git a/.github/wiki/Project-Configurations.md b/.github/wiki/Project-Configurations.md index 45b687e9..403e6206 100644 --- a/.github/wiki/Project-Configurations.md +++ b/.github/wiki/Project-Configurations.md @@ -15,7 +15,7 @@ There are 3 default targets in a project: - {ProjectName} - {ProjectName}Tests -- {ProjectName}UITests +- {ProjectName}KIFUITests ### Schemes diff --git a/.github/wiki/Standard-File-Organization.md b/.github/wiki/Standard-File-Organization.md index 885f3f11..762f7cb9 100644 --- a/.github/wiki/Standard-File-Organization.md +++ b/.github/wiki/Standard-File-Organization.md @@ -103,10 +103,9 @@ To keep all current and upcoming iOS projects aligned, we standardize an iOS pro │   ├── Data+Decode.swift │   ├── String+Data.swift │   └── TestError.swift -└── {ProjectName}UITests +└── {ProjectName}KIFUITests    ├── Configurations    │   └── Plists -    ├── Resources    └── Sources    ├── AccessibilityIdentifiers    │   ├── Login @@ -121,9 +120,7 @@ To keep all current and upcoming iOS projects aligned, we standardize an iOS pro    │   ├── Login    │   └── Home    └── Utilities -    ├── Data+Decode.swift -    ├── String+Data.swift -    └── TestError.swift +    └── KIF+Swift.swift ``` ## README.md @@ -146,6 +143,6 @@ This folder contains the main sources of the project. There are three sub-folder This folder contains the unit testing and integration testing of the main project. -## {ProjectName}UITests +## {ProjectName}KIFUITests -This folder contains the UI testing of the main project. +This folder contains the KIF UI testing of the main project. Use KIF instead of XCUITest for speed and reliability. diff --git a/.github/workflows/automatic_pull_request_review.yml b/.github/workflows/automatic_pull_request_review.yml index 8b5b107c..3f42072e 100644 --- a/.github/workflows/automatic_pull_request_review.yml +++ b/.github/workflows/automatic_pull_request_review.yml @@ -4,16 +4,15 @@ on: pull_request: types: [opened, reopened, edited, synchronize] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: review_pull_request: name: Pull request review by Danger runs-on: macOS-12 steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v2 with: fetch-depth: 0 diff --git a/.github/workflows/deploy_app_store.yml b/.github/workflows/deploy_app_store.yml index 0277e1fc..5bcb5663 100644 --- a/.github/workflows/deploy_app_store.yml +++ b/.github/workflows/deploy_app_store.yml @@ -10,6 +10,10 @@ on: branches: [ master, main ] workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: lint: name: Lint @@ -29,11 +33,6 @@ jobs: name: Build runs-on: macOS-latest steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - name: Checkout Repo uses: actions/checkout@v2 # Set fetch-depth (default: 1) to get whole tree diff --git a/.github/workflows/deploy_production_firebase.yml b/.github/workflows/deploy_production_firebase.yml index 6a36f2da..67e22e30 100644 --- a/.github/workflows/deploy_production_firebase.yml +++ b/.github/workflows/deploy_production_firebase.yml @@ -10,6 +10,10 @@ on: branches: [ release/** ] workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: Lint: name: lint @@ -29,11 +33,6 @@ jobs: name: Build runs-on: macOS-latest steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v2 # Set fetch-depth (default: 1) to get whole tree with: diff --git a/.github/workflows/deploy_staging_firebase.yml b/.github/workflows/deploy_staging_firebase.yml index 4d9534fa..3c6eb30e 100644 --- a/.github/workflows/deploy_staging_firebase.yml +++ b/.github/workflows/deploy_staging_firebase.yml @@ -10,6 +10,10 @@ on: branches: [ develop ] workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: lint: name: Lint @@ -29,11 +33,6 @@ jobs: name: Build runs-on: macOS-latest steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v2 # Set fetch-depth (default: 1) to get whole tree with: diff --git a/.github/workflows/test_install_script.yml b/.github/workflows/test_install_script.yml index 115a66d3..b7378e84 100644 --- a/.github/workflows/test_install_script.yml +++ b/.github/workflows/test_install_script.yml @@ -4,16 +4,15 @@ on: push: branches: [ feature/**, bug/**, chore/** ] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: Test: name: Test runs-on: macOS-12 steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - uses: actions/checkout@v2 with: fetch-depth: 0 diff --git a/.github/workflows/test_upload_build_to_test_flight.yml b/.github/workflows/test_upload_build_to_test_flight.yml index bbaa2043..04c7c863 100644 --- a/.github/workflows/test_upload_build_to_test_flight.yml +++ b/.github/workflows/test_upload_build_to_test_flight.yml @@ -11,16 +11,15 @@ name: Test Upload Build to TestFlight on: pull_request +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build: name: Build runs-on: macOS-12 steps: - - name: Cancel Previous Runs - uses: styfle/cancel-workflow-action@0.5.0 - with: - access_token: ${{ github.token }} - - name: Checkout Repo uses: actions/checkout@v2 with: diff --git a/.swiftlint.yml b/.swiftlint.yml index 1dd0b0c1..4ca7db79 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,7 +1,7 @@ included: - {PROJECT_NAME} - {PROJECT_NAME}Tests - - {PROJECT_NAME}UITests + - {PROJECT_NAME}KIFUITests excluded: - {PROJECT_NAME}Tests/Sources/Mocks/Sourcery/AutoMockable.generated.swift diff --git a/Podfile b/Podfile index fb6ca9ed..78044a23 100644 --- a/Podfile +++ b/Podfile @@ -7,9 +7,7 @@ def testing_pods pod 'Nimble' pod 'RxNimble', subspecs: ['RxBlocking', 'RxTest'] pod 'RxSwift' - # TODO: Remove or update the version of `1.8.0` to the newest version (not 1.8.1) when init a new project. - # Currently, there is a bug on `1.8.1` - the newest version. - pod 'Sourcery', '1.8.0' + pod 'Sourcery' pod 'SwiftFormat/CLI' end @@ -32,19 +30,22 @@ target '{PROJECT_NAME}' do pod 'IQKeyboardManagerSwift' pod 'NimbleExtension', :git => 'https://github.com/nimblehq/NimbleExtension', :branch => 'master' pod 'R.swift' - pod 'Resolver' # Needs Cocoapods on iOS 11 to support Resolver + pod 'Factory' # Development pod 'SwiftLint' pod 'Wormholy', :configurations => ['Debug Staging', 'Debug Production'] + pod 'xcbeautify' target '{PROJECT_NAME}Tests' do inherit! :search_paths testing_pods end - target '{PROJECT_NAME}UITests' do + target '{PROJECT_NAME}KIFUITests' do testing_pods + pod 'KIF', :configurations => ['Debug Staging', 'Debug Production'] + pod 'KIF/IdentifierTests', :configurations => ['Debug Staging', 'Debug Production'] end end diff --git a/Project.swift b/Project.swift index 35637162..92d63a5e 100644 --- a/Project.swift +++ b/Project.swift @@ -19,11 +19,12 @@ extension Project { targets: [ .mainTarget(name: name, bundleId: bundleId), .testsTarget(name: name, bundleId: bundleId), - .uiTestsTarget(name: name, bundleId: bundleId) + .kifUITestsTarget(name: name, bundleId: bundleId), ], schemes: [ .productionScheme(name: name), - .stagingScheme(name: name) + .stagingScheme(name: name), + .kifUITestsScheme(name: name) ] ) } diff --git a/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift b/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift index 7d11f044..8694c4c9 100644 --- a/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift +++ b/Tuist/ProjectDescriptionHelpers/Scheme+Initializing.swift @@ -9,7 +9,10 @@ extension Scheme { name: name, shared: true, buildAction: .buildAction(targets: ["\(name)"]), - testAction: .targets(["\(name)Tests", "\(name)UITests"], configuration: debugConfigName), + testAction: .targets( + ["\(name)Tests", "\(name)KIFUITests"], + configuration: debugConfigName + ), runAction: .runAction(configuration: debugConfigName), archiveAction: .archiveAction(configuration: releaseConfigName), profileAction: .profileAction(configuration: debugConfigName), @@ -24,11 +27,24 @@ extension Scheme { name: "\(name) Staging", shared: true, buildAction: .buildAction(targets: ["\(name)"]), - testAction: .targets(["\(name)Tests", "\(name)UITests"], configuration: debugConfigName), + testAction: .targets( + ["\(name)Tests", "\(name)KIFUITests"], + configuration: debugConfigName + ), runAction: .runAction(configuration: debugConfigName), archiveAction: .archiveAction(configuration: releaseConfigName), profileAction: .profileAction(configuration: debugConfigName), analyzeAction: .analyzeAction(configuration: debugConfigName) ) } + + public static func kifUITestsScheme(name: String) -> Scheme { + let debugConfigName = BuildConfiguration.debugStaging.name + let releaseConfigName = BuildConfiguration.releaseStaging.name + return Scheme( + name: "\(name)KIFUITests", + shared: false, + hidden: true + ) + } } diff --git a/Tuist/ProjectDescriptionHelpers/Target+Initializing.swift b/Tuist/ProjectDescriptionHelpers/Target+Initializing.swift index 26a083f0..5e2158db 100644 --- a/Tuist/ProjectDescriptionHelpers/Target+Initializing.swift +++ b/Tuist/ProjectDescriptionHelpers/Target+Initializing.swift @@ -48,18 +48,17 @@ extension Target { ) } - public static func uiTestsTarget(name: String, bundleId: String) -> Target { - let targetName = "\(name)UITests" + public static func kifUITestsTarget(name: String, bundleId: String) -> Target { + let targetName = "\(name)KIFUITests" return Target( name: targetName, platform: .iOS, - product: .uiTests, + product: .unitTests, bundleId: bundleId, infoPlist: "\(targetName)/\(plistsPath)/Info.plist", sources: ["\(targetName)/**"], resources: [ "\(targetName)/**/.gitkeep", // To include empty folders - "\(targetName)/Resources/**/*" ], dependencies: [.target(name: name)] ) diff --git a/fastlane/Constants/Constant.swift b/fastlane/Constants/Constant.swift index ab0b25f1..adc32ed8 100644 --- a/fastlane/Constants/Constant.swift +++ b/fastlane/Constants/Constant.swift @@ -71,7 +71,7 @@ enum Constant { // MARK: - Test static let testTarget: String = "\(projectName)Tests" - static let uiTestTarget: String = "\(projectName)UITests" + static let kifUITestTarget: String = "\(projectName)KIFUITests" } extension Constant { diff --git a/fastlane/Fastfile.swift b/fastlane/Fastfile.swift index 027204a0..f6724110 100644 --- a/fastlane/Fastfile.swift +++ b/fastlane/Fastfile.swift @@ -137,7 +137,10 @@ class Fastfile: LaneFile { desc("Build and Test project") Test.buildAndTest( environment: .staging, - targets: [Constant.testTarget, Constant.uiTestTarget], + targets: [ + Constant.testTarget, + Constant.kifUITestTarget + ], devices: Constant.devices ) } diff --git a/fastlane/Helpers/Build.swift b/fastlane/Helpers/Build.swift index 4bcbf283..b1e3682f 100644 --- a/fastlane/Helpers/Build.swift +++ b/fastlane/Helpers/Build.swift @@ -57,7 +57,7 @@ enum Build { ]), buildPath: .userDefined(Constant.buildPath), derivedDataPath: .userDefined(Constant.derivedDataPath), - xcodebuildFormatter: "xcpretty" // Default `xcbeautify` will never work + xcodebuildFormatter: "Pods/xcbeautify/xcbeautify" ) } } diff --git a/fastlane/Helpers/Test.swift b/fastlane/Helpers/Test.swift index 46e91908..bb4188d8 100644 --- a/fastlane/Helpers/Test.swift +++ b/fastlane/Helpers/Test.swift @@ -19,7 +19,7 @@ enum Test { onlyTesting: targets, codeCoverage: .userDefined(true), outputDirectory: Constant.testOutputDirectoryPath, - xcodebuildFormatter: "xcpretty", + xcodebuildFormatter: "Pods/xcbeautify/xcbeautify", resultBundle: .userDefined(true), failBuild: .userDefined(false) ) diff --git a/make.sh b/make.sh index 8b4686ef..25c00fbc 100644 --- a/make.sh +++ b/make.sh @@ -123,8 +123,8 @@ rename_folder(){ # Rename test folder structure rename_folder "${CONSTANT_PROJECT_NAME}Tests" "${PROJECT_NAME_NO_SPACES}Tests" -# Rename UI Test folder structure -rename_folder "${CONSTANT_PROJECT_NAME}UITests" "${PROJECT_NAME_NO_SPACES}UITests" +# Rename KIF UI Test folder structure +rename_folder "${CONSTANT_PROJECT_NAME}KIFUITests" "${PROJECT_NAME_NO_SPACES}KIFUITests" # Rename app folder structure rename_folder "${CONSTANT_PROJECT_NAME}" "${PROJECT_NAME_NO_SPACES}" diff --git a/{PROJECT_NAME}UITests/Configurations/Plists/Info.plist b/{PROJECT_NAME}KIFUITests/Configurations/Plists/Info.plist similarity index 100% rename from {PROJECT_NAME}UITests/Configurations/Plists/Info.plist rename to {PROJECT_NAME}KIFUITests/Configurations/Plists/Info.plist diff --git a/{PROJECT_NAME}KIFUITests/Sources/Specs/Application/ApplicationSpec.swift b/{PROJECT_NAME}KIFUITests/Sources/Specs/Application/ApplicationSpec.swift new file mode 100644 index 00000000..8dded39b --- /dev/null +++ b/{PROJECT_NAME}KIFUITests/Sources/Specs/Application/ApplicationSpec.swift @@ -0,0 +1,31 @@ +// +// ApplicationSpec.swift +// + +import Foundation +import Nimble +import Quick + +final class ApplicationSpec: QuickSpec { + + override func spec() { + + describe("a {PROJECT_NAME} screen") { + + beforeEach { + // Navigate to the testing screen + } + + afterEach { + // Navigate to neutral state + } + + context("when opens") { + + it("shows its UI components") { + self.tester().waitForView(withAccessibilityLabel: "Hello") + } + } + } + } +} diff --git a/{PROJECT_NAME}KIFUITests/Sources/Utilities/KIF+Swift.swift b/{PROJECT_NAME}KIFUITests/Sources/Utilities/KIF+Swift.swift new file mode 100644 index 00000000..b7b69cd9 --- /dev/null +++ b/{PROJECT_NAME}KIFUITests/Sources/Utilities/KIF+Swift.swift @@ -0,0 +1,17 @@ +// swiftlint:disable:this file_name +// +// KIF+Swift.swift +// + +import KIF + +extension XCTestCase { + + func tester(file: String = #file, _ line: Int = #line) -> KIFUITestActor { + return KIFUITestActor(inFile: file, atLine: line, delegate: self) + } + + func system(file: String = #file, _ line: Int = #line) -> KIFSystemTestActor { + return KIFSystemTestActor(inFile: file, atLine: line, delegate: self) + } +} diff --git a/{PROJECT_NAME}Tests/Sources/Specs/Supports/Extensions/Foundation/OptionalUnwrapSpec.swift b/{PROJECT_NAME}Tests/Sources/Specs/Supports/Extensions/Foundation/OptionalUnwrapSpec.swift index 58221e9c..c6952037 100644 --- a/{PROJECT_NAME}Tests/Sources/Specs/Supports/Extensions/Foundation/OptionalUnwrapSpec.swift +++ b/{PROJECT_NAME}Tests/Sources/Specs/Supports/Extensions/Foundation/OptionalUnwrapSpec.swift @@ -1,3 +1,7 @@ +// +// OptionalUnwrapSpec.swift +// + import Nimble import Quick @@ -26,7 +30,7 @@ final class OptionalUnwrapSpec: QuickSpec { } it("returns empty string") { - expect(value.string) == "" + expect(value.string.isEmpty) == true } } } diff --git a/{PROJECT_NAME}UITests/Resources/.gitkeep b/{PROJECT_NAME}UITests/Resources/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/{PROJECT_NAME}UITests/Sources/Specs/Application/ApplicationSpec.swift b/{PROJECT_NAME}UITests/Sources/Specs/Application/ApplicationSpec.swift deleted file mode 100644 index 8cac465b..00000000 --- a/{PROJECT_NAME}UITests/Sources/Specs/Application/ApplicationSpec.swift +++ /dev/null @@ -1,30 +0,0 @@ -import Foundation -import Nimble -import Quick - -final class ApplicationSpec: QuickSpec { - - override func spec() { - - var app: XCUIApplication! - - describe("a {PROJECT_NAME} app") { - - beforeEach { - app = XCUIApplication() - app.launch() - } - - afterEach { - app.terminate() - } - - context("when opens") { - - it("empty tests") { - expect(true) == true - } - } - } - } -}