mirror of
https://github.com/passepartoutvpn/passepartout-apple.git
synced 2024-12-24 02:21:00 +00:00
Autogenerate screenshots for all platforms (#998)
Unframed for now. - Split Main/TV targets - Extend ProfileManager for screenshot scenarios - Rename UITesting to UIAccessibility Active profile looks very big on TV simulator, temporarily commented `.padding(.top, 50)` in ActiveProfileView. Closes #974
This commit is contained in:
parent
a626722224
commit
f441a2eed0
@ -55,12 +55,12 @@ let package = Package(
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
.library(
|
.library(
|
||||||
name: "UILibrary",
|
name: "UIAccessibility",
|
||||||
targets: ["UILibrary"]
|
targets: ["UIAccessibility"]
|
||||||
),
|
),
|
||||||
.library(
|
.library(
|
||||||
name: "UITesting",
|
name: "UILibrary",
|
||||||
targets: ["UITesting"]
|
targets: ["UILibrary"]
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
@ -186,20 +186,20 @@ let package = Package(
|
|||||||
.product(name: "PassepartoutWireGuardGo", package: "passepartoutkit-source-wireguard-go")
|
.product(name: "PassepartoutWireGuardGo", package: "passepartoutkit-source-wireguard-go")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
|
.target(
|
||||||
|
name: "UIAccessibility"
|
||||||
|
),
|
||||||
.target(
|
.target(
|
||||||
name: "UILibrary",
|
name: "UILibrary",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
"CommonAPI",
|
"CommonAPI",
|
||||||
"CommonLibrary",
|
"CommonLibrary",
|
||||||
"UITesting"
|
"UIAccessibility"
|
||||||
],
|
],
|
||||||
resources: [
|
resources: [
|
||||||
.process("Resources")
|
.process("Resources")
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
.target(
|
|
||||||
name: "UITesting"
|
|
||||||
),
|
|
||||||
.testTarget(
|
.testTarget(
|
||||||
name: "AppUIMainTests",
|
name: "AppUIMainTests",
|
||||||
dependencies: ["AppUIMain"]
|
dependencies: ["AppUIMain"]
|
||||||
|
@ -27,7 +27,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
struct InstalledProfileView: View, Routable {
|
struct InstalledProfileView: View, Routable {
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
struct ProfileContextMenu: View, Routable {
|
struct ProfileContextMenu: View, Routable {
|
||||||
enum Style {
|
enum Style {
|
||||||
|
@ -25,9 +25,13 @@
|
|||||||
|
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
|
|
||||||
struct ModuleViewModifier<T>: ViewModifier where T: ModuleBuilder & Equatable {
|
struct ModuleViewModifier<T>: ViewModifier where T: ModuleBuilder & Equatable {
|
||||||
|
|
||||||
|
@Environment(\.isUITesting)
|
||||||
|
private var isUITesting
|
||||||
|
|
||||||
@ObservedObject
|
@ObservedObject
|
||||||
var editor: ProfileEditor
|
var editor: ProfileEditor
|
||||||
|
|
||||||
@ -37,7 +41,9 @@ struct ModuleViewModifier<T>: ViewModifier where T: ModuleBuilder & Equatable {
|
|||||||
Form {
|
Form {
|
||||||
content
|
content
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if !isUITesting {
|
||||||
UUIDSection(uuid: draft.id)
|
UUIDSection(uuid: draft.id)
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.themeForm()
|
.themeForm()
|
||||||
|
@ -37,5 +37,6 @@ struct ProfileNameSection: View {
|
|||||||
placeholder: Strings.Placeholders.Profile.name,
|
placeholder: Strings.Placeholders.Profile.name,
|
||||||
footer: Strings.Views.Profile.Sections.Name.footer
|
footer: Strings.Views.Profile.Sections.Name.footer
|
||||||
)
|
)
|
||||||
|
.uiAccessibility(.Profile.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,7 @@ private extension ProfileEditView {
|
|||||||
.contentShape(.rect)
|
.contentShape(.rect)
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
|
.uiAccessibility(.Profile.moduleLink)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,14 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
|
|
||||||
struct ModuleListView: View, Routable {
|
struct ModuleListView: View, Routable {
|
||||||
static let generalModuleId = UUID()
|
static let generalModuleId = UUID()
|
||||||
|
|
||||||
|
@Environment(\.isUITesting)
|
||||||
|
private var isUITesting
|
||||||
|
|
||||||
@ObservedObject
|
@ObservedObject
|
||||||
var profileEditor: ProfileEditor
|
var profileEditor: ProfileEditor
|
||||||
|
|
||||||
@ -58,6 +62,7 @@ struct ModuleListView: View, Routable {
|
|||||||
NavigationLink(value: ProfileSplitView.Detail.module(id: module.id)) {
|
NavigationLink(value: ProfileSplitView.Detail.module(id: module.id)) {
|
||||||
moduleRow(for: module)
|
moduleRow(for: module)
|
||||||
}
|
}
|
||||||
|
.uiAccessibility(.Profile.moduleLink)
|
||||||
}
|
}
|
||||||
.onMove(perform: moveModules)
|
.onMove(perform: moveModules)
|
||||||
}
|
}
|
||||||
@ -82,11 +87,13 @@ private extension ModuleListView {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
Spacer()
|
Spacer()
|
||||||
|
if !isUITesting {
|
||||||
EditorModuleToggle(profileEditor: profileEditor, module: module) {
|
EditorModuleToggle(profileEditor: profileEditor, module: module) {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
func toolbarContent() -> some View {
|
func toolbarContent() -> some View {
|
||||||
|
@ -29,6 +29,7 @@ import CommonAPI
|
|||||||
import CommonLibrary
|
import CommonLibrary
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
|
|
||||||
extension VPNProviderServerView {
|
extension VPNProviderServerView {
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
@ -129,6 +130,7 @@ private extension VPNProviderServerView.ContentView {
|
|||||||
} label: {
|
} label: {
|
||||||
ThemeCountryText(code)
|
ThemeCountryText(code)
|
||||||
}
|
}
|
||||||
|
.uiAccessibility(.VPNServers.countryGroup)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
|
|
||||||
struct ActiveProfileView: View {
|
struct ActiveProfileView: View {
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ struct ActiveProfileView: View {
|
|||||||
.clipShape(RoundedRectangle(cornerRadius: 50))
|
.clipShape(RoundedRectangle(cornerRadius: 50))
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 100)
|
.padding(.horizontal, 100)
|
||||||
.padding(.top, 50)
|
// .padding(.top, 50)
|
||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
}
|
}
|
||||||
@ -86,6 +87,7 @@ private extension ActiveProfileView {
|
|||||||
.font(.title)
|
.font(.title)
|
||||||
.fontWeight(theme.relevantWeight)
|
.fontWeight(theme.relevantWeight)
|
||||||
.frame(maxWidth: .infinity, alignment: .leading)
|
.frame(maxWidth: .infinity, alignment: .leading)
|
||||||
|
.uiAccessibility(.App.installedProfile)
|
||||||
}
|
}
|
||||||
|
|
||||||
var statusView: some View {
|
var statusView: some View {
|
||||||
|
@ -27,6 +27,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
|
|
||||||
struct ProfileListView: View {
|
struct ProfileListView: View {
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ private extension ProfileListView {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
.focused($focusedField, equals: .profile(preview.id))
|
.focused($focusedField, equals: .profile(preview.id))
|
||||||
|
.uiAccessibility(.App.ProfileList.profile)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleView(for preview: ProfilePreview) -> some View {
|
func toggleView(for preview: ProfilePreview) -> some View {
|
||||||
|
@ -29,6 +29,8 @@ public struct AccessibilityInfo: Equatable, Sendable {
|
|||||||
public enum ElementType: Sendable {
|
public enum ElementType: Sendable {
|
||||||
case button
|
case button
|
||||||
|
|
||||||
|
case link
|
||||||
|
|
||||||
case menu
|
case menu
|
||||||
|
|
||||||
case menuItem
|
case menuItem
|
@ -33,14 +33,14 @@ extension AccessibilityInfo {
|
|||||||
public static let connectTo = AccessibilityInfo("app.profileMenu.connectTo", .menuItem)
|
public static let connectTo = AccessibilityInfo("app.profileMenu.connectTo", .menuItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ProfileList {
|
||||||
|
public static let profile = AccessibilityInfo("app.profileList.profile", .button)
|
||||||
|
}
|
||||||
|
|
||||||
public static let installedProfile = AccessibilityInfo("app.installedProfile", .text)
|
public static let installedProfile = AccessibilityInfo("app.installedProfile", .text)
|
||||||
|
|
||||||
public static let profileToggle = AccessibilityInfo("app.profileToggle", .button)
|
public static let profileToggle = AccessibilityInfo("app.profileToggle", .button)
|
||||||
|
|
||||||
public static let profileMenu = AccessibilityInfo("app.profileMenu", .menu)
|
public static let profileMenu = AccessibilityInfo("app.profileMenu", .menu)
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Profile {
|
|
||||||
public static let cancel = AccessibilityInfo("profile.cancel", .button)
|
|
||||||
}
|
|
||||||
}
|
}
|
36
Library/Sources/UIAccessibility/Screens/Profile.swift
Normal file
36
Library/Sources/UIAccessibility/Screens/Profile.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// Profile.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 12/2/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension AccessibilityInfo {
|
||||||
|
public enum Profile {
|
||||||
|
public static let name = AccessibilityInfo("profile.name", .text)
|
||||||
|
|
||||||
|
public static let moduleLink = AccessibilityInfo("profile.moduleLink", .link)
|
||||||
|
|
||||||
|
public static let cancel = AccessibilityInfo("profile.cancel", .button)
|
||||||
|
}
|
||||||
|
}
|
32
Library/Sources/UIAccessibility/Screens/VPNServers.swift
Normal file
32
Library/Sources/UIAccessibility/Screens/VPNServers.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// VPNServers.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 12/9/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension AccessibilityInfo {
|
||||||
|
public enum VPNServers {
|
||||||
|
public static let countryGroup = AccessibilityInfo("vpnServers.countryGroup", .button)
|
||||||
|
}
|
||||||
|
}
|
@ -28,7 +28,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import Foundation
|
import Foundation
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public final class AppContext: ObservableObject, Sendable {
|
public final class AppContext: ObservableObject, Sendable {
|
||||||
|
@ -8,11 +8,11 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
0E08447C2CF86F2A00ECED7C /* XCTestCase+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E08447B2CF86F2A00ECED7C /* XCTestCase+Extensions.swift */; };
|
0E08447C2CF86F2A00ECED7C /* XCTestCase+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E08447B2CF86F2A00ECED7C /* XCTestCase+Extensions.swift */; };
|
||||||
0E2D68DC2CF7CF7500DC95BC /* UITesting in Frameworks */ = {isa = PBXBuildFile; productRef = 0E2D68DB2CF7CF7500DC95BC /* UITesting */; };
|
|
||||||
0E3E22962CE53510005135DF /* AppUIMain in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, macos, ); productRef = 0E3E22952CE53510005135DF /* AppUIMain */; };
|
0E3E22962CE53510005135DF /* AppUIMain in Frameworks */ = {isa = PBXBuildFile; platformFilters = (ios, macos, ); productRef = 0E3E22952CE53510005135DF /* AppUIMain */; };
|
||||||
0E3E22982CE53510005135DF /* AppUITV in Frameworks */ = {isa = PBXBuildFile; platformFilters = (tvos, ); productRef = 0E3E22972CE53510005135DF /* AppUITV */; };
|
0E3E22982CE53510005135DF /* AppUITV in Frameworks */ = {isa = PBXBuildFile; platformFilters = (tvos, ); productRef = 0E3E22972CE53510005135DF /* AppUITV */; };
|
||||||
0E3FF4BA2CE3AFBC00BFF640 /* Profiles.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 0E3FF4B72CE3AFBC00BFF640 /* Profiles.sqlite */; };
|
0E3FF4BA2CE3AFBC00BFF640 /* Profiles.sqlite in Resources */ = {isa = PBXBuildFile; fileRef = 0E3FF4B72CE3AFBC00BFF640 /* Profiles.sqlite */; };
|
||||||
0E3FF4BB2CE3AFBC00BFF640 /* MigrationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3FF4B92CE3AFBC00BFF640 /* MigrationManagerTests.swift */; };
|
0E3FF4BB2CE3AFBC00BFF640 /* MigrationManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3FF4B92CE3AFBC00BFF640 /* MigrationManagerTests.swift */; };
|
||||||
|
0E418AB52D074F0E00D33D47 /* VPNServersScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E418AB42D074F0E00D33D47 /* VPNServersScreen.swift */; platformFilters = (ios, macos, ); };
|
||||||
0E483E812CE64D6B00584B32 /* TunnelContext+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E483E7F2CE64D6B00584B32 /* TunnelContext+Shared.swift */; };
|
0E483E812CE64D6B00584B32 /* TunnelContext+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E483E7F2CE64D6B00584B32 /* TunnelContext+Shared.swift */; };
|
||||||
0E60512C2CE5393C00F763D4 /* PassepartoutImplementations in Frameworks */ = {isa = PBXBuildFile; productRef = 0E60512B2CE5393C00F763D4 /* PassepartoutImplementations */; };
|
0E60512C2CE5393C00F763D4 /* PassepartoutImplementations in Frameworks */ = {isa = PBXBuildFile; productRef = 0E60512B2CE5393C00F763D4 /* PassepartoutImplementations */; };
|
||||||
0E6EEEE32CF8CABA0076E2B0 /* AppContext+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */; };
|
0E6EEEE32CF8CABA0076E2B0 /* AppContext+Testing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */; };
|
||||||
@ -23,9 +23,9 @@
|
|||||||
0E7C3CCD2C9AF44600B72E69 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7C3CCC2C9AF44600B72E69 /* AppDelegate.swift */; };
|
0E7C3CCD2C9AF44600B72E69 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7C3CCC2C9AF44600B72E69 /* AppDelegate.swift */; };
|
||||||
0E7E3D692B9345FD002BBDB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E7E3D5C2B9345FD002BBDB4 /* Assets.xcassets */; };
|
0E7E3D692B9345FD002BBDB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0E7E3D5C2B9345FD002BBDB4 /* Assets.xcassets */; };
|
||||||
0E7E3D6B2B9345FD002BBDB4 /* PassepartoutApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7E3D5F2B9345FD002BBDB4 /* PassepartoutApp.swift */; };
|
0E7E3D6B2B9345FD002BBDB4 /* PassepartoutApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7E3D5F2B9345FD002BBDB4 /* PassepartoutApp.swift */; };
|
||||||
0E7F460E2CF7F01600B1C53A /* FlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F460B2CF7F01600B1C53A /* FlowTests.swift */; };
|
0E7F460E2CF7F01600B1C53A /* FlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F460B2CF7F01600B1C53A /* FlowTests.swift */; platformFilters = (ios, macos, ); };
|
||||||
0E7F460F2CF7F01600B1C53A /* XCUIApplication+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F460C2CF7F01600B1C53A /* XCUIApplication+Extensions.swift */; };
|
0E7F460F2CF7F01600B1C53A /* XCUIApplication+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F460C2CF7F01600B1C53A /* XCUIApplication+Extensions.swift */; };
|
||||||
0E7F46122CF7F44C00B1C53A /* AppScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F46102CF7F44C00B1C53A /* AppScreen.swift */; };
|
0E7F46122CF7F44C00B1C53A /* AppScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7F46102CF7F44C00B1C53A /* AppScreen.swift */; platformFilters = (ios, macos, ); };
|
||||||
0E81955A2CFDA75200CC8FFD /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8195592CFDA75200CC8FFD /* Dependencies.swift */; };
|
0E81955A2CFDA75200CC8FFD /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8195592CFDA75200CC8FFD /* Dependencies.swift */; };
|
||||||
0E81955B2CFDA7BF00CC8FFD /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8195592CFDA75200CC8FFD /* Dependencies.swift */; };
|
0E81955B2CFDA7BF00CC8FFD /* Dependencies.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8195592CFDA75200CC8FFD /* Dependencies.swift */; };
|
||||||
0E8DFD482D05FA7000531CDE /* TunnelContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD472D05FA7000531CDE /* TunnelContext.swift */; };
|
0E8DFD482D05FA7000531CDE /* TunnelContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD472D05FA7000531CDE /* TunnelContext.swift */; };
|
||||||
@ -36,10 +36,14 @@
|
|||||||
0E8DFD532D05FE5A00531CDE /* Dependencies+PassepartoutKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD4C2D05FE5A00531CDE /* Dependencies+PassepartoutKit.swift */; };
|
0E8DFD532D05FE5A00531CDE /* Dependencies+PassepartoutKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD4C2D05FE5A00531CDE /* Dependencies+PassepartoutKit.swift */; };
|
||||||
0E8DFD542D05FE5A00531CDE /* Dependencies+IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD4B2D05FE5A00531CDE /* Dependencies+IAPManager.swift */; };
|
0E8DFD542D05FE5A00531CDE /* Dependencies+IAPManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD4B2D05FE5A00531CDE /* Dependencies+IAPManager.swift */; };
|
||||||
0E8DFD562D05FE5A00531CDE /* Dependencies+CoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD492D05FE5A00531CDE /* Dependencies+CoreData.swift */; };
|
0E8DFD562D05FE5A00531CDE /* Dependencies+CoreData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E8DFD492D05FE5A00531CDE /* Dependencies+CoreData.swift */; };
|
||||||
0E916B782CF80FD60072921A /* ProfileEditorScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */; };
|
0E916B782CF80FD60072921A /* ProfileEditorScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */; platformFilters = (ios, macos, ); };
|
||||||
0E916B7C2CF811EB0072921A /* XCUIElement+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E916B7B2CF811EB0072921A /* XCUIElement+Extensions.swift */; };
|
0E916B7C2CF811EB0072921A /* XCUIElement+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E916B7B2CF811EB0072921A /* XCUIElement+Extensions.swift */; };
|
||||||
0E94EE582B93554B00588243 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7E3D672B9345FD002BBDB4 /* PacketTunnelProvider.swift */; };
|
0E94EE582B93554B00588243 /* PacketTunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E7E3D672B9345FD002BBDB4 /* PacketTunnelProvider.swift */; };
|
||||||
0EAD6A1B2CF7F79A00CC1F02 /* ScreenshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */; };
|
0EA6340C2D088C8200180D7C /* UIAccessibility in Frameworks */ = {isa = PBXBuildFile; productRef = 0EA6340B2D088C8200180D7C /* UIAccessibility */; };
|
||||||
|
0EA6340E2D08995800180D7C /* ScreenshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA6340D2D08995800180D7C /* ScreenshotTests.swift */; platformFilters = (tvos, ); };
|
||||||
|
0EA634122D08997300180D7C /* FlowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA634112D08997300180D7C /* FlowTests.swift */; platformFilters = (tvos, ); };
|
||||||
|
0EA634142D08998700180D7C /* AppScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA634132D08998700180D7C /* AppScreen.swift */; platformFilters = (tvos, ); };
|
||||||
|
0EAD6A1B2CF7F79A00CC1F02 /* ScreenshotTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */; platformFilters = (ios, macos, ); };
|
||||||
0EAEC8A92D05DB8D001AA50C /* DefaultAppProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAEC8A62D05DB8D001AA50C /* DefaultAppProcessor.swift */; };
|
0EAEC8A92D05DB8D001AA50C /* DefaultAppProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAEC8A62D05DB8D001AA50C /* DefaultAppProcessor.swift */; };
|
||||||
0EAEC8AA2D05DB8D001AA50C /* DefaultTunnelProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAEC8A72D05DB8D001AA50C /* DefaultTunnelProcessor.swift */; };
|
0EAEC8AA2D05DB8D001AA50C /* DefaultTunnelProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EAEC8A72D05DB8D001AA50C /* DefaultTunnelProcessor.swift */; };
|
||||||
0EB08B982CA46F4900A02591 /* AppPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0EB08B962CA46F4900A02591 /* AppPlist.strings */; };
|
0EB08B982CA46F4900A02591 /* AppPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 0EB08B962CA46F4900A02591 /* AppPlist.strings */; };
|
||||||
@ -47,7 +51,7 @@
|
|||||||
0EC066D12C7DC47600D88A94 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0EC066D02C7DC47600D88A94 /* LaunchScreen.storyboard */; platformFilter = ios; };
|
0EC066D12C7DC47600D88A94 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0EC066D02C7DC47600D88A94 /* LaunchScreen.storyboard */; platformFilter = ios; };
|
||||||
0EC332CA2B8A1808000B9C2F /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EC332C92B8A1808000B9C2F /* NetworkExtension.framework */; };
|
0EC332CA2B8A1808000B9C2F /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0EC332C92B8A1808000B9C2F /* NetworkExtension.framework */; };
|
||||||
0EC332D22B8A1808000B9C2F /* PassepartoutTunnel.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0EC332C82B8A1808000B9C2F /* PassepartoutTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
0EC332D22B8A1808000B9C2F /* PassepartoutTunnel.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0EC332C82B8A1808000B9C2F /* PassepartoutTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
0EC418D22CF86B7400AC6F2F /* ProfileMenuScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC418D12CF86B7400AC6F2F /* ProfileMenuScreen.swift */; };
|
0EC418D22CF86B7400AC6F2F /* ProfileMenuScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC418D12CF86B7400AC6F2F /* ProfileMenuScreen.swift */; platformFilters = (ios, macos, ); };
|
||||||
0EC797422B9378E000C093B7 /* AppContext+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC797402B9378E000C093B7 /* AppContext+Shared.swift */; };
|
0EC797422B9378E000C093B7 /* AppContext+Shared.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EC797402B9378E000C093B7 /* AppContext+Shared.swift */; };
|
||||||
0ED61CF82CD0418C008FE259 /* App+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED61CF72CD0418C008FE259 /* App+macOS.swift */; };
|
0ED61CF82CD0418C008FE259 /* App+macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED61CF72CD0418C008FE259 /* App+macOS.swift */; };
|
||||||
0ED61CFA2CD04192008FE259 /* App+iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED61CF92CD04192008FE259 /* App+iOS.swift */; };
|
0ED61CFA2CD04192008FE259 /* App+iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED61CF92CD04192008FE259 /* App+iOS.swift */; };
|
||||||
@ -142,6 +146,7 @@
|
|||||||
0E3FF4AE2CE3AF6F00BFF640 /* PassepartoutTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PassepartoutTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
0E3FF4AE2CE3AF6F00BFF640 /* PassepartoutTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = PassepartoutTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
0E3FF4B72CE3AFBC00BFF640 /* Profiles.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = Profiles.sqlite; sourceTree = "<group>"; };
|
0E3FF4B72CE3AFBC00BFF640 /* Profiles.sqlite */ = {isa = PBXFileReference; lastKnownFileType = file; path = Profiles.sqlite; sourceTree = "<group>"; };
|
||||||
0E3FF4B92CE3AFBC00BFF640 /* MigrationManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationManagerTests.swift; sourceTree = "<group>"; };
|
0E3FF4B92CE3AFBC00BFF640 /* MigrationManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationManagerTests.swift; sourceTree = "<group>"; };
|
||||||
|
0E418AB42D074F0E00D33D47 /* VPNServersScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNServersScreen.swift; sourceTree = "<group>"; };
|
||||||
0E483E7F2CE64D6B00584B32 /* TunnelContext+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelContext+Shared.swift"; sourceTree = "<group>"; };
|
0E483E7F2CE64D6B00584B32 /* TunnelContext+Shared.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelContext+Shared.swift"; sourceTree = "<group>"; };
|
||||||
0E5DFDDC2CDB8F9100F2DE70 /* Passepartout.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Passepartout.storekit; sourceTree = "<group>"; };
|
0E5DFDDC2CDB8F9100F2DE70 /* Passepartout.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Passepartout.storekit; sourceTree = "<group>"; };
|
||||||
0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+Testing.swift"; sourceTree = "<group>"; };
|
0E6EEEE12CF8CABA0076E2B0 /* AppContext+Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+Testing.swift"; sourceTree = "<group>"; };
|
||||||
@ -171,6 +176,9 @@
|
|||||||
0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditorScreen.swift; sourceTree = "<group>"; };
|
0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileEditorScreen.swift; sourceTree = "<group>"; };
|
||||||
0E916B7B2CF811EB0072921A /* XCUIElement+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIElement+Extensions.swift"; sourceTree = "<group>"; };
|
0E916B7B2CF811EB0072921A /* XCUIElement+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCUIElement+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
0E94EE5C2B93570600588243 /* Tunnel.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Tunnel.plist; sourceTree = "<group>"; };
|
0E94EE5C2B93570600588243 /* Tunnel.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Tunnel.plist; sourceTree = "<group>"; };
|
||||||
|
0EA6340D2D08995800180D7C /* ScreenshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotTests.swift; sourceTree = "<group>"; };
|
||||||
|
0EA634112D08997300180D7C /* FlowTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlowTests.swift; sourceTree = "<group>"; };
|
||||||
|
0EA634132D08998700180D7C /* AppScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppScreen.swift; sourceTree = "<group>"; };
|
||||||
0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotTests.swift; sourceTree = "<group>"; };
|
0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotTests.swift; sourceTree = "<group>"; };
|
||||||
0EAEC8A62D05DB8D001AA50C /* DefaultAppProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultAppProcessor.swift; sourceTree = "<group>"; };
|
0EAEC8A62D05DB8D001AA50C /* DefaultAppProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultAppProcessor.swift; sourceTree = "<group>"; };
|
||||||
0EAEC8A72D05DB8D001AA50C /* DefaultTunnelProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTunnelProcessor.swift; sourceTree = "<group>"; };
|
0EAEC8A72D05DB8D001AA50C /* DefaultTunnelProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultTunnelProcessor.swift; sourceTree = "<group>"; };
|
||||||
@ -213,7 +221,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0E2D68DC2CF7CF7500DC95BC /* UITesting in Frameworks */,
|
0EA6340C2D088C8200180D7C /* UIAccessibility in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -297,6 +305,16 @@
|
|||||||
path = Resources;
|
path = Resources;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
0E418AB72D0752D100D33D47 /* TV */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0EA634102D08996500180D7C /* Screens */,
|
||||||
|
0EA634112D08997300180D7C /* FlowTests.swift */,
|
||||||
|
0EA6340D2D08995800180D7C /* ScreenshotTests.swift */,
|
||||||
|
);
|
||||||
|
path = TV;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
0E757F112CD0CFFC006E13E1 /* LoginItem */ = {
|
0E757F112CD0CFFC006E13E1 /* LoginItem */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -366,9 +384,8 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0E916B7A2CF811DE0072921A /* Extensions */,
|
0E916B7A2CF811DE0072921A /* Extensions */,
|
||||||
0E916B7E2CF81A110072921A /* Screens */,
|
0EC418C92CF81C6A00AC6F2F /* Main */,
|
||||||
0E7F460B2CF7F01600B1C53A /* FlowTests.swift */,
|
0E418AB72D0752D100D33D47 /* TV */,
|
||||||
0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */,
|
|
||||||
);
|
);
|
||||||
path = UITests;
|
path = UITests;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -408,7 +425,18 @@
|
|||||||
0E916B7E2CF81A110072921A /* Screens */ = {
|
0E916B7E2CF81A110072921A /* Screens */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0EC418C92CF81C6A00AC6F2F /* Main */,
|
0E7F46102CF7F44C00B1C53A /* AppScreen.swift */,
|
||||||
|
0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */,
|
||||||
|
0EC418D12CF86B7400AC6F2F /* ProfileMenuScreen.swift */,
|
||||||
|
0E418AB42D074F0E00D33D47 /* VPNServersScreen.swift */,
|
||||||
|
);
|
||||||
|
path = Screens;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
0EA634102D08996500180D7C /* Screens */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
0EA634132D08998700180D7C /* AppScreen.swift */,
|
||||||
);
|
);
|
||||||
path = Screens;
|
path = Screens;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -416,9 +444,9 @@
|
|||||||
0EC418C92CF81C6A00AC6F2F /* Main */ = {
|
0EC418C92CF81C6A00AC6F2F /* Main */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0E7F46102CF7F44C00B1C53A /* AppScreen.swift */,
|
0E916B7E2CF81A110072921A /* Screens */,
|
||||||
0E916B772CF80FD60072921A /* ProfileEditorScreen.swift */,
|
0E7F460B2CF7F01600B1C53A /* FlowTests.swift */,
|
||||||
0EC418D12CF86B7400AC6F2F /* ProfileMenuScreen.swift */,
|
0EAD6A1A2CF7F79A00CC1F02 /* ScreenshotTests.swift */,
|
||||||
);
|
);
|
||||||
path = Main;
|
path = Main;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -527,7 +555,7 @@
|
|||||||
);
|
);
|
||||||
name = PassepartoutUITests;
|
name = PassepartoutUITests;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
0E2D68DB2CF7CF7500DC95BC /* UITesting */,
|
0EA6340B2D088C8200180D7C /* UIAccessibility */,
|
||||||
);
|
);
|
||||||
productName = PassepartoutUITests;
|
productName = PassepartoutUITests;
|
||||||
productReference = 0E78FE4C2CF799F400B0C5BF /* PassepartoutUITests.xctest */;
|
productReference = 0E78FE4C2CF799F400B0C5BF /* PassepartoutUITests.xctest */;
|
||||||
@ -742,11 +770,15 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
0E08447C2CF86F2A00ECED7C /* XCTestCase+Extensions.swift in Sources */,
|
0E08447C2CF86F2A00ECED7C /* XCTestCase+Extensions.swift in Sources */,
|
||||||
|
0EA6340E2D08995800180D7C /* ScreenshotTests.swift in Sources */,
|
||||||
|
0EA634122D08997300180D7C /* FlowTests.swift in Sources */,
|
||||||
0E7F460E2CF7F01600B1C53A /* FlowTests.swift in Sources */,
|
0E7F460E2CF7F01600B1C53A /* FlowTests.swift in Sources */,
|
||||||
0E916B782CF80FD60072921A /* ProfileEditorScreen.swift in Sources */,
|
0E916B782CF80FD60072921A /* ProfileEditorScreen.swift in Sources */,
|
||||||
|
0EA634142D08998700180D7C /* AppScreen.swift in Sources */,
|
||||||
0E916B7C2CF811EB0072921A /* XCUIElement+Extensions.swift in Sources */,
|
0E916B7C2CF811EB0072921A /* XCUIElement+Extensions.swift in Sources */,
|
||||||
0EAD6A1B2CF7F79A00CC1F02 /* ScreenshotTests.swift in Sources */,
|
0EAD6A1B2CF7F79A00CC1F02 /* ScreenshotTests.swift in Sources */,
|
||||||
0E7F460F2CF7F01600B1C53A /* XCUIApplication+Extensions.swift in Sources */,
|
0E7F460F2CF7F01600B1C53A /* XCUIApplication+Extensions.swift in Sources */,
|
||||||
|
0E418AB52D074F0E00D33D47 /* VPNServersScreen.swift in Sources */,
|
||||||
0EC418D22CF86B7400AC6F2F /* ProfileMenuScreen.swift in Sources */,
|
0EC418D22CF86B7400AC6F2F /* ProfileMenuScreen.swift in Sources */,
|
||||||
0E7F46122CF7F44C00B1C53A /* AppScreen.swift in Sources */,
|
0E7F46122CF7F44C00B1C53A /* AppScreen.swift in Sources */,
|
||||||
);
|
);
|
||||||
@ -1349,10 +1381,6 @@
|
|||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
0E2D68DB2CF7CF7500DC95BC /* UITesting */ = {
|
|
||||||
isa = XCSwiftPackageProductDependency;
|
|
||||||
productName = UITesting;
|
|
||||||
};
|
|
||||||
0E3E22952CE53510005135DF /* AppUIMain */ = {
|
0E3E22952CE53510005135DF /* AppUIMain */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = AppUIMain;
|
productName = AppUIMain;
|
||||||
@ -1373,6 +1401,10 @@
|
|||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = TunnelLibrary;
|
productName = TunnelLibrary;
|
||||||
};
|
};
|
||||||
|
0EA6340B2D088C8200180D7C /* UIAccessibility */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = UIAccessibility;
|
||||||
|
};
|
||||||
0EBE80DB2BF55C0E00E36A20 /* TunnelLibrary */ = {
|
0EBE80DB2BF55C0E00E36A20 /* TunnelLibrary */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = TunnelLibrary;
|
productName = TunnelLibrary;
|
||||||
|
@ -85,7 +85,7 @@
|
|||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "-pp_ui_testing"
|
argument = "-pp_ui_testing"
|
||||||
isEnabled = "NO">
|
isEnabled = "YES">
|
||||||
</CommandLineArgument>
|
</CommandLineArgument>
|
||||||
<CommandLineArgument
|
<CommandLineArgument
|
||||||
argument = "-pp_fake_migration"
|
argument = "-pp_fake_migration"
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
import CommonLibrary
|
import CommonLibrary
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import UIAccessibility
|
||||||
import UILibrary
|
import UILibrary
|
||||||
import UITesting
|
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
final class AppDelegate: NSObject {
|
final class AppDelegate: NSObject {
|
||||||
|
@ -32,8 +32,8 @@ import CommonUtils
|
|||||||
import Foundation
|
import Foundation
|
||||||
import LegacyV2
|
import LegacyV2
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
|
import UIAccessibility
|
||||||
import UILibrary
|
import UILibrary
|
||||||
import UITesting
|
|
||||||
|
|
||||||
extension AppContext {
|
extension AppContext {
|
||||||
static let shared: AppContext = {
|
static let shared: AppContext = {
|
||||||
|
@ -48,7 +48,10 @@ extension AppContext {
|
|||||||
)
|
)
|
||||||
let tunnelEnvironment = InMemoryEnvironment()
|
let tunnelEnvironment = InMemoryEnvironment()
|
||||||
let tunnel = ExtendedTunnel(
|
let tunnel = ExtendedTunnel(
|
||||||
tunnel: Tunnel(strategy: FakeTunnelStrategy(environment: tunnelEnvironment)),
|
tunnel: Tunnel(strategy: FakeTunnelStrategy(
|
||||||
|
environment: tunnelEnvironment,
|
||||||
|
dataCountDelta: DataCount(2 * 1200000, 1200000)
|
||||||
|
)),
|
||||||
environment: tunnelEnvironment,
|
environment: tunnelEnvironment,
|
||||||
processor: processor,
|
processor: processor,
|
||||||
interval: Constants.shared.tunnel.refreshInterval
|
interval: Constants.shared.tunnel.refreshInterval
|
||||||
|
@ -52,10 +52,47 @@ extension ProfileManager {
|
|||||||
assert((moduleBuilder as? any ProviderSelecting)?.providerId == parameters.providerId)
|
assert((moduleBuilder as? any ProviderSelecting)?.providerId == parameters.providerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if parameters.name == "Hide.me",
|
if parameters.name == "Hide.me" {
|
||||||
var ovpnBuilder = moduleBuilder as? OpenVPNModule.Builder {
|
if var ovpnBuilder = moduleBuilder as? OpenVPNModule.Builder {
|
||||||
|
#if !os(tvOS)
|
||||||
ovpnBuilder.isInteractive = true
|
ovpnBuilder.isInteractive = true
|
||||||
|
#endif
|
||||||
|
ovpnBuilder.providerEntity = mockHideMeEntity
|
||||||
moduleBuilder = ovpnBuilder
|
moduleBuilder = ovpnBuilder
|
||||||
|
} else if var onDemandBuilder = moduleBuilder as? OnDemandModule.Builder {
|
||||||
|
#if !os(tvOS)
|
||||||
|
onDemandBuilder.isEnabled = true
|
||||||
|
#endif
|
||||||
|
onDemandBuilder.policy = .excluding
|
||||||
|
onDemandBuilder.withSSIDs = [
|
||||||
|
"Friend's House": false,
|
||||||
|
"My Home Network": true,
|
||||||
|
"Safe Wi-Fi": true
|
||||||
|
]
|
||||||
|
moduleBuilder = onDemandBuilder
|
||||||
|
} else if var dnsBuilder = moduleBuilder as? DNSModule.Builder {
|
||||||
|
dnsBuilder.protocolType = .https
|
||||||
|
dnsBuilder.dohURL = "https://cloudflare-dns.com/dns-query"
|
||||||
|
dnsBuilder.servers = ["1.1.1.1", "1.0.0.1"]
|
||||||
|
dnsBuilder.domainName = "my-domain.com"
|
||||||
|
dnsBuilder.searchDomains = ["search-one.com", "search-two.org"]
|
||||||
|
moduleBuilder = dnsBuilder
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if parameters.name == "My VPS" {
|
||||||
|
if var ovpnBuilder = moduleBuilder as? OpenVPNModule.Builder {
|
||||||
|
var cfgBuilder = OpenVPN.Configuration.Builder()
|
||||||
|
cfgBuilder.ca = .init(pem: "...")
|
||||||
|
cfgBuilder.remotes = [
|
||||||
|
ExtendedEndpoint(rawValue: "1.2.3.4:UDP:1234")!
|
||||||
|
]
|
||||||
|
ovpnBuilder.configurationBuilder = cfgBuilder
|
||||||
|
moduleBuilder = ovpnBuilder
|
||||||
|
} else if var onDemandBuilder = moduleBuilder as? OnDemandModule.Builder {
|
||||||
|
onDemandBuilder.isEnabled = true
|
||||||
|
moduleBuilder = onDemandBuilder
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let module = try moduleBuilder.tryBuild()
|
let module = try moduleBuilder.tryBuild()
|
||||||
@ -99,9 +136,47 @@ private extension ProfileManager {
|
|||||||
static let mockParameters: [Parameters] = [
|
static let mockParameters: [Parameters] = [
|
||||||
Parameters("CloudFlare DoT", false, false, [.dns]),
|
Parameters("CloudFlare DoT", false, false, [.dns]),
|
||||||
Parameters("Coffee VPN", true, false, [.wireGuard, .onDemand]),
|
Parameters("Coffee VPN", true, false, [.wireGuard, .onDemand]),
|
||||||
Parameters("Hide.me", true, true, [.openVPN, .onDemand, .ip], .hideme),
|
Parameters("Hide.me", true, true, [.openVPN, .onDemand, .dns, .ip], .hideme),
|
||||||
Parameters("My VPS", true, true, [.openVPN]),
|
Parameters("My VPS", true, true, [.openVPN, .onDemand]),
|
||||||
Parameters("Office", true, false, [.onDemand, .httpProxy]),
|
Parameters("Office", true, false, [.onDemand, .httpProxy]),
|
||||||
Parameters("Personal DoH", false, false, [.dns, .onDemand])
|
Parameters("Personal DoH", false, false, [.dns, .onDemand])
|
||||||
]
|
]
|
||||||
|
|
||||||
|
static var mockHideMeEntity: VPNEntity<OpenVPN.Configuration> {
|
||||||
|
do {
|
||||||
|
var cfgBuilder = OpenVPN.Configuration.Builder()
|
||||||
|
cfgBuilder.ca = .init(pem: "...")
|
||||||
|
let cfg = try cfgBuilder.tryBuild(isClient: false)
|
||||||
|
let cfgData = try JSONEncoder().encode(cfg)
|
||||||
|
|
||||||
|
let preset = AnyVPNPreset(
|
||||||
|
providerId: .hideme,
|
||||||
|
presetId: "default",
|
||||||
|
description: "Default",
|
||||||
|
endpoints: [.init(.udp, 1194)],
|
||||||
|
configurationIdentifier: "OpenVPN",
|
||||||
|
configuration: cfgData
|
||||||
|
)
|
||||||
|
|
||||||
|
return VPNEntity(
|
||||||
|
server: .init(
|
||||||
|
provider: .init(
|
||||||
|
id: .hideme,
|
||||||
|
serverId: "be-v4",
|
||||||
|
supportedConfigurationIdentifiers: ["OpenVPN"],
|
||||||
|
supportedPresetIds: nil,
|
||||||
|
categoryName: "",
|
||||||
|
countryCode: "BE",
|
||||||
|
otherCountryCodes: nil,
|
||||||
|
area: nil
|
||||||
|
),
|
||||||
|
hostname: "be-v4.hideservers.net",
|
||||||
|
ipAddresses: nil
|
||||||
|
),
|
||||||
|
preset: try preset.ofType(OpenVPN.Configuration.self)
|
||||||
|
)
|
||||||
|
} catch {
|
||||||
|
fatalError("Unable to build Hide.me entity: \(error)")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
import AppUIMain
|
import AppUIMain
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
extension AppDelegate: UIApplicationDelegate {
|
extension AppDelegate: UIApplicationDelegate {
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||||
|
@ -31,7 +31,7 @@ import CommonLibrary
|
|||||||
import CommonUtils
|
import CommonUtils
|
||||||
import PassepartoutKit
|
import PassepartoutKit
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
extension AppDelegate: NSApplicationDelegate {
|
extension AppDelegate: NSApplicationDelegate {
|
||||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
import AppUITV
|
import AppUITV
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
|
|
||||||
extension AppDelegate: UIApplicationDelegate {
|
extension AppDelegate: UIApplicationDelegate {
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
protocol XCUIApplicationProviding {
|
protocol XCUIApplicationProviding {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
extension XCUIElement {
|
extension XCUIElement {
|
||||||
@ -44,14 +44,14 @@ private extension XCUIElement {
|
|||||||
func query(for elementType: AccessibilityInfo.ElementType) -> XCUIElementQuery {
|
func query(for elementType: AccessibilityInfo.ElementType) -> XCUIElementQuery {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
switch elementType {
|
switch elementType {
|
||||||
case .button, .menu, .menuItem:
|
case .button, .link, .menu, .menuItem:
|
||||||
return buttons
|
return buttons
|
||||||
case .text:
|
case .text:
|
||||||
return staticTexts
|
return staticTexts
|
||||||
}
|
}
|
||||||
#else
|
#elseif os(macOS)
|
||||||
switch elementType {
|
switch elementType {
|
||||||
case .button:
|
case .button, .link:
|
||||||
return buttons
|
return buttons
|
||||||
case .menu:
|
case .menu:
|
||||||
return menuButtons
|
return menuButtons
|
||||||
@ -60,6 +60,13 @@ private extension XCUIElement {
|
|||||||
case .text:
|
case .text:
|
||||||
return staticTexts
|
return staticTexts
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
switch elementType {
|
||||||
|
case .button, .link, .menu, .menuItem:
|
||||||
|
return buttons
|
||||||
|
case .text:
|
||||||
|
return staticTexts
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UITesting
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@ -41,23 +42,42 @@ final class FlowTests: XCTestCase {
|
|||||||
try await Task.sleep(for: .seconds(2))
|
try await Task.sleep(for: .seconds(2))
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMainConnected() async throws {
|
func testConnect() {
|
||||||
AppScreen(app: app)
|
AppScreen(app: app)
|
||||||
.waitForProfiles()
|
.waitForProfiles()
|
||||||
.enableProfile(at: 2)
|
.enableProfile(at: 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testEditProfile() async throws {
|
func testEditProfile() {
|
||||||
AppScreen(app: app)
|
AppScreen(app: app)
|
||||||
.waitForProfiles()
|
.waitForProfiles()
|
||||||
.openProfileMenu(at: 2)
|
.openProfileMenu(at: 2)
|
||||||
.editProfile()
|
.editProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
func testConnectToProviderServer() async throws {
|
func testEditProfileModule() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.openProfileMenu(at: 2)
|
||||||
|
.editProfile()
|
||||||
|
.enterModule(at: 1)
|
||||||
|
.leaveModule()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConnectToProviderServer() {
|
||||||
AppScreen(app: app)
|
AppScreen(app: app)
|
||||||
.waitForProfiles()
|
.waitForProfiles()
|
||||||
.openProfileMenu(at: 2)
|
.openProfileMenu(at: 2)
|
||||||
.connectToProfile()
|
.connectToProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
func testDiscloseProviderCountry() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.openProfileMenu(at: 2)
|
||||||
|
.connectToProfile()
|
||||||
|
.discloseCountry(at: 2)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
@ -24,7 +24,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
57
Passepartout/UITests/Main/Screens/ProfileEditorScreen.swift
Normal file
57
Passepartout/UITests/Main/Screens/ProfileEditorScreen.swift
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
//
|
||||||
|
// ProfileEditorScreen.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 11/28/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
struct ProfileEditorScreen {
|
||||||
|
let app: XCUIApplication
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func enterModule(at index: Int) -> Self {
|
||||||
|
let moduleLink = app.get(.Profile.moduleLink, at: index)
|
||||||
|
moduleLink.tap()
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func leaveModule() -> Self {
|
||||||
|
#if os(iOS)
|
||||||
|
let backButton = app.navigationBars.element(boundBy: 1).buttons.element(boundBy: 0)
|
||||||
|
XCTAssertTrue(backButton.waitForExistence(timeout: 1.0))
|
||||||
|
backButton.tap()
|
||||||
|
#endif
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func closeProfile() -> AppScreen {
|
||||||
|
let cancelButton = app.get(.Profile.cancel)
|
||||||
|
cancelButton.tap()
|
||||||
|
return AppScreen(app: app)
|
||||||
|
}
|
||||||
|
}
|
@ -24,7 +24,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@ -32,16 +32,17 @@ struct ProfileMenuScreen {
|
|||||||
let app: XCUIApplication
|
let app: XCUIApplication
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func editProfile() -> ProfileEditorScreen {
|
func connectToProfile() -> VPNServersScreen {
|
||||||
let editButton = app.get(.App.ProfileMenu.edit)
|
let connectToButton = app.get(.App.ProfileMenu.connectTo)
|
||||||
editButton.tap()
|
connectToButton.tap()
|
||||||
return ProfileEditorScreen(app: app)
|
return VPNServersScreen(app: app)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func connectToProfile() -> AppScreen {
|
func editProfile() -> ProfileEditorScreen {
|
||||||
let connectToButton = app.get(.App.ProfileMenu.connectTo)
|
let editButton = app.get(.App.ProfileMenu.edit)
|
||||||
connectToButton.tap()
|
editButton.tap()
|
||||||
return AppScreen(app: app)
|
_ = app.get(.Profile.name)
|
||||||
|
return ProfileEditorScreen(app: app)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
//
|
//
|
||||||
// ProfileEditorScreen.swift
|
// VPNServersScreen.swift
|
||||||
// Passepartout
|
// Passepartout
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 11/28/24.
|
// Created by Davide De Rosa on 12/9/24.
|
||||||
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
//
|
//
|
||||||
// https://github.com/passepartoutvpn
|
// https://github.com/passepartoutvpn
|
||||||
@ -24,17 +24,17 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import UITesting
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
struct ProfileEditorScreen {
|
struct VPNServersScreen {
|
||||||
let app: XCUIApplication
|
let app: XCUIApplication
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
func closeProfile() -> AppScreen {
|
func discloseCountry(at index: Int) -> Self {
|
||||||
let cancelButton = app.get(.Profile.cancel)
|
let group = app.get(.VPNServers.countryGroup, at: index)
|
||||||
cancelButton.tap()
|
group.tap()
|
||||||
return AppScreen(app: app)
|
return self
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,7 +23,8 @@
|
|||||||
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UITesting
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@ -50,7 +51,7 @@ final class ScreenshotTests: XCTestCase, XCUIApplicationProviding {
|
|||||||
.enableProfile(at: 0)
|
.enableProfile(at: 0)
|
||||||
|
|
||||||
try await Task.sleep(for: .seconds(2))
|
try await Task.sleep(for: .seconds(2))
|
||||||
try snapshot("1_MainConnected")
|
try snapshot("1_Connected")
|
||||||
|
|
||||||
let profile = root
|
let profile = root
|
||||||
.openProfileMenu(at: 2)
|
.openProfileMenu(at: 2)
|
||||||
@ -60,12 +61,29 @@ final class ScreenshotTests: XCTestCase, XCUIApplicationProviding {
|
|||||||
try snapshot("2_ProfileEditor", target: .sheet)
|
try snapshot("2_ProfileEditor", target: .sheet)
|
||||||
|
|
||||||
profile
|
profile
|
||||||
|
.enterModule(at: 1)
|
||||||
|
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
try snapshot("3_OnDemand", target: .sheet)
|
||||||
|
|
||||||
|
profile
|
||||||
|
.leaveModule()
|
||||||
|
.enterModule(at: 2)
|
||||||
|
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
try snapshot("4_DNS", target: .sheet)
|
||||||
|
|
||||||
|
profile
|
||||||
|
.leaveModule()
|
||||||
.closeProfile()
|
.closeProfile()
|
||||||
.openProfileMenu(at: 2)
|
.openProfileMenu(at: 2)
|
||||||
.connectToProfile()
|
.connectToProfile()
|
||||||
|
#if os(iOS)
|
||||||
|
.discloseCountry(at: 2)
|
||||||
|
#endif
|
||||||
|
|
||||||
try await Task.sleep(for: .seconds(2))
|
try await Task.sleep(for: .seconds(2))
|
||||||
try snapshot("3_ProviderServers", target: .sheet)
|
try snapshot("5_ProviderServers", target: .sheet)
|
||||||
|
|
||||||
print("Saved to: \(ScreenshotDestination.temporary.url)")
|
print("Saved to: \(ScreenshotDestination.temporary.url)")
|
||||||
}
|
}
|
71
Passepartout/UITests/TV/FlowTests.swift
Normal file
71
Passepartout/UITests/TV/FlowTests.swift
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// FlowTests.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 12/10/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
final class FlowTests: XCTestCase {
|
||||||
|
private var app: XCUIApplication!
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
app = XCUIApplication()
|
||||||
|
app.appArguments = [.uiTesting]
|
||||||
|
app.launch()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDown() async throws {
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
func testShow() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testPresentProfiles() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.presentInitialProfiles()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testConnect() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.presentInitialProfiles()
|
||||||
|
.enableProfile(up: 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testReconnectToOtherProfile() {
|
||||||
|
AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.presentInitialProfiles()
|
||||||
|
.enableProfile(up: 1)
|
||||||
|
.presentProfilesWhileConnected()
|
||||||
|
.enableProfile(up: 0)
|
||||||
|
}
|
||||||
|
}
|
66
Passepartout/UITests/TV/Screens/AppScreen.swift
Normal file
66
Passepartout/UITests/TV/Screens/AppScreen.swift
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// AppScreen.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 12/10/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
struct AppScreen {
|
||||||
|
let app: XCUIApplication
|
||||||
|
|
||||||
|
private let remote: XCUIRemote = .shared
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func waitForProfiles() -> Self {
|
||||||
|
app.get(.App.installedProfile)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func presentInitialProfiles() -> Self {
|
||||||
|
remote.press(.down)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func enableProfile(up: Int) -> Self {
|
||||||
|
let profileButton = app.get(.App.ProfileList.profile)
|
||||||
|
remote.press(.right)
|
||||||
|
for _ in 0..<up {
|
||||||
|
remote.press(.up)
|
||||||
|
}
|
||||||
|
remote.press(.select)
|
||||||
|
profileButton.waitForNonExistence(timeout: 1.0)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
@discardableResult
|
||||||
|
func presentProfilesWhileConnected() -> Self {
|
||||||
|
remote.press(.down)
|
||||||
|
_ = app.get(.App.ProfileList.profile)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
66
Passepartout/UITests/TV/ScreenshotTests.swift
Normal file
66
Passepartout/UITests/TV/ScreenshotTests.swift
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// ScreenshotTests.swift
|
||||||
|
// Passepartout
|
||||||
|
//
|
||||||
|
// Created by Davide De Rosa on 12/10/24.
|
||||||
|
// Copyright (c) 2024 Davide De Rosa. All rights reserved.
|
||||||
|
//
|
||||||
|
// https://github.com/passepartoutvpn
|
||||||
|
//
|
||||||
|
// This file is part of Passepartout.
|
||||||
|
//
|
||||||
|
// Passepartout is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// Passepartout is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Passepartout. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import UIAccessibility
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
final class ScreenshotTests: XCTestCase, XCUIApplicationProviding {
|
||||||
|
let app: XCUIApplication = {
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.appArguments = [.uiTesting]
|
||||||
|
return app
|
||||||
|
}()
|
||||||
|
|
||||||
|
override func setUp() async throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
app.launch()
|
||||||
|
}
|
||||||
|
|
||||||
|
func testTakeScreenshots() async throws {
|
||||||
|
let root = AppScreen(app: app)
|
||||||
|
.waitForProfiles()
|
||||||
|
.presentInitialProfiles()
|
||||||
|
.enableProfile(up: 1)
|
||||||
|
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
try snapshot("1_Connected")
|
||||||
|
|
||||||
|
root
|
||||||
|
.presentProfilesWhileConnected()
|
||||||
|
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
try snapshot("2_ConnectedWithProfileList")
|
||||||
|
|
||||||
|
root
|
||||||
|
.enableProfile(up: 0)
|
||||||
|
|
||||||
|
try await Task.sleep(for: .seconds(2))
|
||||||
|
try snapshot("3_OnDemand")
|
||||||
|
|
||||||
|
print("Saved to: \(ScreenshotDestination.temporary.url)")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user