diff --git a/README.md b/README.md index c47fa2c..19c37fc 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,28 @@ Models used throughout the app. ### NotificationClient Schedules reminders for when network configurations expire. + +## Creating screenshots + +To facilitate creating screenshots for the App Store, use these steps: + +1. In MainView.swift: comment out sending the `searchQueryChangeDebounced` action +2. In Screenshots.swift: verify `screenshotsFolder` goes to an existing folder +3. Select the `geteduroam/getgovroam Screenshots` target +4. Select the desired destination +5. Use Product > Test (cmd-U) + +If the tests hang, try running the app on that particular simulator first. Check that the simulator is in the desired orientation: portrait for this app. + +Refer to the [Screenshot specifications](https://developer.apple.com/help/app-store-connect/reference/screenshot-specifications) to pick the desired destinations. + +Currently we use: + +- iPhone 15 Pro Max +- iPhone 8 Plus +- iPad Pro (12.9-inch) (6th generation) +- iPad Pro (12.9-inch) (2nd generation) +- Mac with 1280 x 800 pixels + +Currently we don't use: +- iPhone 15: generates screenshots with size 1178 x 2556, but App Store wants 1179 x 2556 diff --git a/Screenshots/Screenshots.swift b/Screenshots/Screenshots.swift new file mode 100644 index 0000000..95592bc --- /dev/null +++ b/Screenshots/Screenshots.swift @@ -0,0 +1,97 @@ +import XCTest + +final class Screenshots: XCTestCase { + + enum Language: String { + case en + case nl + } + + enum Scenario: String, CaseIterable { + case main + case search + case connect + case connected + + var appearance: XCUIDevice.Appearance { + switch self { + case .main: + .light + case .search: + .light + case .connect: + .light + case .connected: + .dark + } + } + } + +#if os(iOS) + func testScreenshots() throws { + let screenshotsFolder = URL(fileURLWithPath: "/Users/jkool/geteduroam-screenshots") + let simulator = ProcessInfo().environment["SIMULATOR_DEVICE_NAME"]!.replacingOccurrences(of: " ", with: "_") + let host = ProcessInfo().environment["XCTestBundlePath"]!.contains("getgovroam") ? "getgovroam" : "geteduroam" + let languages: [Language] = [.en, .nl] + let scenarios = Scenario.allCases + for language in languages { + for (index, scenario) in scenarios.enumerated() { + XCUIDevice.shared.appearance = scenario.appearance + + + let app = XCUIApplication() + app.launchArguments += ["-AppleLanguages", "(\(language))"] + app.launchArguments += ["-AppleLocale", "\"\(language)\""] + app.launchArguments += ["-Scenario", "\(scenario)"] + app.launch() + + let screenshot = app.screenshot() + let attachment = XCTAttachment(screenshot: screenshot) + let name = "\(host)-\(simulator)-\(language)-\(index)-\(scenario)" + attachment.name = name + attachment.lifetime = .keepAlways + add(attachment) + + let path = screenshotsFolder.appendingPathComponent("\(name).png") + try screenshot.image.pngData()?.write(to: path, options: .atomic) + } + } + } +#elseif os(macOS) + func testScreenshots() throws { + let languages: [Language] = [.en, .nl] + let scenarios = Scenario.allCases + for language in languages { + for (index, scenario) in scenarios.enumerated() { + XCUIDevice.shared.appearance = scenario.appearance + + let app = XCUIApplication() + app.launchArguments += ["-AppleLanguages", "(\(language))"] + app.launchArguments += ["-AppleLocale", "\"\(language)\""] + app.launchArguments += ["-Scenario", "\(scenario)"] + app.launch() + + let screenshot = app.screenshot() + let attachment = XCTAttachment(screenshot: screenshot) + let name = "mac-\(language)-\(index)-\(scenario)" + attachment.name = name + attachment.lifetime = .keepAlways + add(attachment) + + // Due to sandbox restrictions writing to disk doens't work on macOS, navigate to the test results and find the attachments there + } + } + } +#endif +} + +#if os(macOS) +extension NSImage { + func pngData() -> Data? { + guard let imageData = tiffRepresentation, let imageRep = NSBitmapImageRep(data: imageData) else { + return nil + } + return imageRep.representation(using: .png, properties: [NSBitmapImageRep.PropertyKey.compressionFactor: 1.0]) + } +} +#endif diff --git a/geteduroam.xcodeproj/project.pbxproj b/geteduroam.xcodeproj/project.pbxproj index 536b45e..7623162 100644 --- a/geteduroam.xcodeproj/project.pbxproj +++ b/geteduroam.xcodeproj/project.pbxproj @@ -24,6 +24,10 @@ C78BB7732A29D212001799ED /* LICENSE.md in Resources */ = {isa = PBXBuildFile; fileRef = C78BB7712A293D93001799ED /* LICENSE.md */; }; C7AF862A2931150A00BDEB69 /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = C7AF86292931150A00BDEB69 /* Documentation.docc */; }; C7BE4BFA291EA9CB007AA0C2 /* Main in Frameworks */ = {isa = PBXBuildFile; productRef = C7BE4BF9291EA9CB007AA0C2 /* Main */; }; + C7DAA9E22B212FDD00306C6C /* Screenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7DAA9E12B212FDD00306C6C /* Screenshots.swift */; }; + C7DAA9ED2B21A8C000306C6C /* ScreenshotScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7DAA9EC2B21A8C000306C6C /* ScreenshotScenarios.swift */; }; + C7DAA9EF2B21C64F00306C6C /* ScreenshotScenarios.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7DAA9EE2B21C64F00306C6C /* ScreenshotScenarios.swift */; }; + C7DAA9F42B21C99E00306C6C /* Screenshots.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7DAA9E12B212FDD00306C6C /* Screenshots.swift */; }; C7F45A42297A94610005508D /* AuthClient in Frameworks */ = {isa = PBXBuildFile; productRef = C7F45A41297A94610005508D /* AuthClient */; }; C7F45A48297ABC5C0005508D /* Documentation.docc in Sources */ = {isa = PBXBuildFile; fileRef = C7AF86292931150A00BDEB69 /* Documentation.docc */; }; C7F45A52297ABC5C0005508D /* Main in Frameworks */ = {isa = PBXBuildFile; productRef = C7F45A44297ABC5C0005508D /* Main */; }; @@ -35,6 +39,23 @@ C7F45A6A297AC8E30005508D /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C7F45A5D297ABD050005508D /* Preview Assets.xcassets */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + C7DAA9E52B212FDD00306C6C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7555FF73242A565900829871 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7555FF7A242A565900829871; + remoteInfo = geteduroam; + }; + C7DAA9FD2B21C9AB00306C6C /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7555FF73242A565900829871 /* Project object */; + proxyType = 1; + remoteGlobalIDString = C7F45A43297ABC5C0005508D; + remoteInfo = getgovroam; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXFileReference section */ 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; @@ -66,6 +87,11 @@ C7AF86292931150A00BDEB69 /* Documentation.docc */ = {isa = PBXFileReference; lastKnownFileType = folder.documentationcatalog; path = Documentation.docc; sourceTree = ""; }; C7C91BE02913CB54008F79FF /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; }; C7D61037291EA763007C9D6B /* GeteduroamPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = GeteduroamPackage; path = geteduroam/GeteduroamPackage; sourceTree = ""; }; + C7DAA9DF2B212FDD00306C6C /* geteduroam Screenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "geteduroam Screenshots.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + C7DAA9E12B212FDD00306C6C /* Screenshots.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Screenshots.swift; sourceTree = ""; }; + C7DAA9EC2B21A8C000306C6C /* ScreenshotScenarios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotScenarios.swift; sourceTree = ""; }; + C7DAA9EE2B21C64F00306C6C /* ScreenshotScenarios.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotScenarios.swift; sourceTree = ""; }; + C7DAA9FC2B21C99E00306C6C /* getgovroam Screenshots.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "getgovroam Screenshots.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; C7F45A57297ABC5C0005508D /* getgovroam.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = getgovroam.app; sourceTree = BUILT_PRODUCTS_DIR; }; C7F45A5A297ABD050005508D /* GetgovroamApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GetgovroamApp.swift; sourceTree = ""; }; C7F45A5B297ABD050005508D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; @@ -87,6 +113,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C7DAA9DC2B212FDD00306C6C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7DAA9F52B21C99E00306C6C /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C7F45A51297ABC5C0005508D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -115,6 +155,7 @@ C7D61036291EA763007C9D6B /* Packages */, 7555FF7D242A565900829871 /* geteduroam */, C7F45A59297ABD050005508D /* getgovroam */, + C7DAA9E02B212FDD00306C6C /* Screenshots */, 9FEB36B1E327EFCA245843CD /* Frameworks */, 7555FF7C242A565900829871 /* Products */, ); @@ -125,6 +166,8 @@ children = ( 7555FF7B242A565900829871 /* geteduroam.app */, C7F45A57297ABC5C0005508D /* getgovroam.app */, + C7DAA9DF2B212FDD00306C6C /* geteduroam Screenshots.xctest */, + C7DAA9FC2B21C99E00306C6C /* getgovroam Screenshots.xctest */, ); name = Products; sourceTree = ""; @@ -138,6 +181,7 @@ 7555FF8C242A565B00829871 /* Info.plist */, C74A11E7294C9FB600ECC19A /* Launch Screen.storyboard */, 2152FB032600AC8F00CF470E /* GeteduroamApp.swift */, + C7DAA9EC2B21A8C000306C6C /* ScreenshotScenarios.swift */, 058557BA273AAA24004C7B11 /* Assets.xcassets */, C74A11E9294CA56100ECC19A /* Fonts */, C76B786C2A86F45B00A651EB /* Localizable.xcstrings */, @@ -192,6 +236,14 @@ name = Packages; sourceTree = ""; }; + C7DAA9E02B212FDD00306C6C /* Screenshots */ = { + isa = PBXGroup; + children = ( + C7DAA9E12B212FDD00306C6C /* Screenshots.swift */, + ); + path = Screenshots; + sourceTree = ""; + }; C7F45A59297ABD050005508D /* getgovroam */ = { isa = PBXGroup; children = ( @@ -200,6 +252,7 @@ C7F45A65297ABD050005508D /* Info.plist */, C7F45A60297ABD050005508D /* Launch Screen.storyboard */, C7F45A5A297ABD050005508D /* GetgovroamApp.swift */, + C7DAA9EE2B21C64F00306C6C /* ScreenshotScenarios.swift */, C75564002AB9C64E00244B45 /* Fonts */, C7F45A5B297ABD050005508D /* Assets.xcassets */, C76B786E2A86F45B00A651EB /* Localizable.xcstrings */, @@ -240,6 +293,42 @@ productReference = 7555FF7B242A565900829871 /* geteduroam.app */; productType = "com.apple.product-type.application"; }; + C7DAA9DE2B212FDD00306C6C /* geteduroam Screenshots */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7DAA9E72B212FDE00306C6C /* Build configuration list for PBXNativeTarget "geteduroam Screenshots" */; + buildPhases = ( + C7DAA9DB2B212FDD00306C6C /* Sources */, + C7DAA9DC2B212FDD00306C6C /* Frameworks */, + C7DAA9DD2B212FDD00306C6C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + C7DAA9E62B212FDD00306C6C /* PBXTargetDependency */, + ); + name = "geteduroam Screenshots"; + productName = geteduroamUIScreenshots; + productReference = C7DAA9DF2B212FDD00306C6C /* geteduroam Screenshots.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; + C7DAA9F02B21C99E00306C6C /* getgovroam Screenshots */ = { + isa = PBXNativeTarget; + buildConfigurationList = C7DAA9F72B21C99E00306C6C /* Build configuration list for PBXNativeTarget "getgovroam Screenshots" */; + buildPhases = ( + C7DAA9F32B21C99E00306C6C /* Sources */, + C7DAA9F52B21C99E00306C6C /* Frameworks */, + C7DAA9F62B21C99E00306C6C /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + C7DAA9FE2B21C9AB00306C6C /* PBXTargetDependency */, + ); + name = "getgovroam Screenshots"; + productName = geteduroamUIScreenshots; + productReference = C7DAA9FC2B21C99E00306C6C /* getgovroam Screenshots.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; C7F45A43297ABC5C0005508D /* getgovroam */ = { isa = PBXNativeTarget; buildConfigurationList = C7F45A54297ABC5C0005508D /* Build configuration list for PBXNativeTarget "getgovroam" */; @@ -268,13 +357,20 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastSwiftUpdateCheck = 1130; + LastSwiftUpdateCheck = 1500; LastUpgradeCheck = 1430; ORGANIZATIONNAME = orgName; TargetAttributes = { 7555FF7A242A565900829871 = { CreatedOnToolsVersion = 11.3.1; }; + C7DAA9DE2B212FDD00306C6C = { + CreatedOnToolsVersion = 15.0.1; + TestTargetID = 7555FF7A242A565900829871; + }; + C7DAA9F02B21C99E00306C6C = { + TestTargetID = C7F45A43297ABC5C0005508D; + }; }; }; buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "geteduroam" */; @@ -295,6 +391,8 @@ targets = ( 7555FF7A242A565900829871 /* geteduroam */, C7F45A43297ABC5C0005508D /* getgovroam */, + C7DAA9DE2B212FDD00306C6C /* geteduroam Screenshots */, + C7DAA9F02B21C99E00306C6C /* getgovroam Screenshots */, ); }; /* End PBXProject section */ @@ -316,6 +414,20 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C7DAA9DD2B212FDD00306C6C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7DAA9F62B21C99E00306C6C /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; C7F45A49297ABC5C0005508D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -340,21 +452,52 @@ buildActionMask = 2147483647; files = ( 2152FB042600AC8F00CF470E /* GeteduroamApp.swift in Sources */, + C7DAA9ED2B21A8C000306C6C /* ScreenshotScenarios.swift in Sources */, C7AF862A2931150A00BDEB69 /* Documentation.docc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + C7DAA9DB2B212FDD00306C6C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C7DAA9E22B212FDD00306C6C /* Screenshots.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C7DAA9F32B21C99E00306C6C /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C7DAA9F42B21C99E00306C6C /* Screenshots.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C7F45A46297ABC5C0005508D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( C7F45A66297AC83D0005508D /* GetgovroamApp.swift in Sources */, C7F45A48297ABC5C0005508D /* Documentation.docc in Sources */, + C7DAA9EF2B21C64F00306C6C /* ScreenshotScenarios.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + C7DAA9E62B212FDD00306C6C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7555FF7A242A565900829871 /* geteduroam */; + targetProxy = C7DAA9E52B212FDD00306C6C /* PBXContainerItemProxy */; + }; + C7DAA9FE2B21C9AB00306C6C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = C7F45A43297ABC5C0005508D /* getgovroam */; + targetProxy = C7DAA9FD2B21C9AB00306C6C /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin XCBuildConfiguration section */ 7555FFA3242A565B00829871 /* Debug */ = { isa = XCBuildConfiguration; @@ -396,6 +539,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -462,6 +606,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -592,6 +737,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -721,6 +867,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -816,6 +963,198 @@ }; name = "Debug Test"; }; + C7DAA9E82B212FDE00306C6C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = geteduroam; + }; + name = Debug; + }; + C7DAA9E92B212FDE00306C6C /* Debug Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = geteduroam; + }; + name = "Debug Test"; + }; + C7DAA9EA2B212FDE00306C6C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = geteduroam; + }; + name = Release; + }; + C7DAA9EB2B212FDE00306C6C /* Release Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = geteduroam; + }; + name = "Release Test"; + }; + C7DAA9F82B21C99E00306C6C /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = getgovroam; + }; + name = Debug; + }; + C7DAA9F92B21C99E00306C6C /* Debug Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = getgovroam; + }; + name = "Debug Test"; + }; + C7DAA9FA2B21C99E00306C6C /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = getgovroam; + }; + name = Release; + }; + C7DAA9FB2B21C99E00306C6C /* Release Test */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = ZYJ4TZX4UU; + GCC_C_LANGUAGE_STANDARD = gnu17; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MACOSX_DEPLOYMENT_TARGET = 14.0; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.eduroam.geteduroam.screenshots; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = getgovroam; + }; + name = "Release Test"; + }; C7F45A55297ABC5C0005508D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -909,6 +1248,28 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C7DAA9E72B212FDE00306C6C /* Build configuration list for PBXNativeTarget "geteduroam Screenshots" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7DAA9E82B212FDE00306C6C /* Debug */, + C7DAA9E92B212FDE00306C6C /* Debug Test */, + C7DAA9EA2B212FDE00306C6C /* Release */, + C7DAA9EB2B212FDE00306C6C /* Release Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C7DAA9F72B21C99E00306C6C /* Build configuration list for PBXNativeTarget "getgovroam Screenshots" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C7DAA9F82B21C99E00306C6C /* Debug */, + C7DAA9F92B21C99E00306C6C /* Debug Test */, + C7DAA9FA2B21C99E00306C6C /* Release */, + C7DAA9FB2B21C99E00306C6C /* Release Test */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C7F45A54297ABC5C0005508D /* Build configuration list for PBXNativeTarget "getgovroam" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/geteduroam.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/geteduroam.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index d772ecf..e0921f6 100644 --- a/geteduroam.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/geteduroam.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -32,8 +32,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-case-paths", "state" : { - "revision" : "ed7facdd4a361514b46e3bbc6238cd41c84be4ec", - "version" : "1.1.1" + "revision" : "a5521dde99570789d8cb7c43e51418d7cd1a87ca", + "version" : "1.1.2" } }, { @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-composable-architecture", "state" : { - "revision" : "3f80eb9ed07c16a9f42ac4f23d4dafaa0494568c", - "version" : "1.5.0" + "revision" : "dcde72151de8a60eecaa1673ed3c3d110549069a", + "version" : "1.5.1" } }, { @@ -77,8 +77,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-custom-dump", "state" : { - "revision" : "65fc9e2b62727cacfab9fc60d580c284a4b9308c", - "version" : "1.1.1" + "revision" : "aedcf6f4cd486ccef5b312ccac85d4b3f6e58605", + "version" : "1.1.2" } }, { @@ -86,8 +86,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-dependencies", "state" : { - "revision" : "63301f4a181ed9aefb46dccef2dfb66466798341", - "version" : "1.1.1" + "revision" : "9783b58167f7618cb86011156e741cbc6f4cc864", + "version" : "1.1.2" } }, { @@ -108,6 +108,15 @@ "version" : "0.13.0" } }, + { + "identity" : "swift-snapshot-testing", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-snapshot-testing", + "state" : { + "revision" : "59b663f68e69f27a87b45de48cb63264b8194605", + "version" : "1.15.1" + } + }, { "identity" : "swift-syntax", "kind" : "remoteSourceControl", diff --git a/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam Screenshots.xcscheme b/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam Screenshots.xcscheme new file mode 100644 index 0000000..d80d01e --- /dev/null +++ b/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam Screenshots.xcscheme @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam.xcscheme b/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam.xcscheme index f5af0d8..b9d1579 100644 --- a/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam.xcscheme +++ b/geteduroam.xcodeproj/xcshareddata/xcschemes/geteduroam.xcscheme @@ -20,6 +20,62 @@ ReferencedContainer = "container:geteduroam.xcodeproj"> + + + + + + + + + + + + + + + + @@ -42,9 +98,9 @@ skipped = "NO"> @@ -52,9 +108,9 @@ skipped = "NO"> diff --git a/geteduroam.xcodeproj/xcshareddata/xcschemes/getgovroam Screenshots.xcscheme b/geteduroam.xcodeproj/xcshareddata/xcschemes/getgovroam Screenshots.xcscheme new file mode 100644 index 0000000..d52dc0a --- /dev/null +++ b/geteduroam.xcodeproj/xcshareddata/xcschemes/getgovroam Screenshots.xcscheme @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/geteduroam/GeteduroamApp.swift b/geteduroam/GeteduroamApp.swift index 822d75e..944f6f8 100644 --- a/geteduroam/GeteduroamApp.swift +++ b/geteduroam/GeteduroamApp.swift @@ -4,13 +4,9 @@ import Main import Models import SwiftUI -@main -struct GeteduroamApp: App { - - #if os(iOS) - @UIApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate - - @StateObject var theme = Theme( +#if os(iOS) +extension Theme { + static var theme = Theme( searchFont: .custom("OpenSans-Regular", size: 20, relativeTo: .body), errorFont: .custom("OpenSans-Regular", size: 16, relativeTo: .body), organizationNameFont: .custom("OpenSans-Bold", size: 16, relativeTo: .body), @@ -21,11 +17,10 @@ struct GeteduroamApp: App { connectedFont: .custom("OpenSans-Bold", size: 14, relativeTo: .body), infoHeaderFont: .custom("OpenSans-Bold", size: 14, relativeTo: .body), infoDetailFont: .custom("OpenSans-Regular", size: 14, relativeTo: .body)) - - #elseif os(macOS) - @NSApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate - - @StateObject var theme = Theme( +} +#elseif os(macOS) +extension Theme { + static var theme = Theme( searchFont: .system(.body, design: .default), errorFont: .system(.body, design: .default), organizationNameFont: .system(.body, design: .default).bold(), @@ -36,7 +31,19 @@ struct GeteduroamApp: App { connectedFont: .system(.body, design: .default), infoHeaderFont: .system(.body, design: .default).bold(), infoDetailFont: .system(.body, design: .default)) - #endif +} +#endif + +@main +struct GeteduroamApp: App { + +#if os(iOS) + @UIApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate +#elseif os(macOS) + @NSApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate +#endif + + @StateObject var theme = Theme.theme var store: StoreOf
! @@ -46,8 +53,19 @@ struct GeteduroamApp: App { #if os(macOS) fakeInitialWindowPositionPreference() #endif - - store = .init(initialState: .init(), reducer: { Main() }, withDependencies: { [appDelegate] in + +#if DEBUG + let initialState: Main.State + if let scenario = UserDefaults.standard.string(forKey: "Scenario"), let scenario = Scenario(rawValue: scenario) { + initialState = scenario.initialState + } else { + initialState = .init() + } +#else + let initialState = Main.State() +#endif + + store = .init(initialState: initialState, reducer: { Main() }, withDependencies: { [appDelegate] in $0.authClient = appDelegate }) } diff --git a/geteduroam/GeteduroamPackage/Package.swift b/geteduroam/GeteduroamPackage/Package.swift index e3377bd..aa5f7a8 100644 --- a/geteduroam/GeteduroamPackage/Package.swift +++ b/geteduroam/GeteduroamPackage/Package.swift @@ -47,8 +47,9 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-composable-architecture", from: "1.0.0"), .package(url: "https://github.com/pointfreeco/swift-custom-dump", from: "1.0.0"), .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.0.0"), + .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.12.0"), .package(url: "https://github.com/pointfreeco/swift-url-routing", from: "0.6.0"), - .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0") + .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -101,6 +102,7 @@ let package = Package( dependencies: [ "Connect", .product(name: "MockNetwork", package: "network-ios"), + .product(name: "SnapshotTesting", package: "swift-snapshot-testing") ]), .target( name: "DiscoveryClient", diff --git a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectFeature.swift b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectFeature.swift index 70a2587..617ac6c 100644 --- a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectFeature.swift +++ b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectFeature.swift @@ -14,11 +14,12 @@ public struct Connect: Reducer { public init() { } public struct State: Equatable { - public init(organization: Organization, selectedProfileId: Profile.ID? = nil, autoConnectOnAppear: Bool = false, loadingState: LoadingState = .initial, credentials: Credentials? = nil, destination: Destination.State? = nil) { + public init(organization: Organization, selectedProfileId: Profile.ID? = nil, autoConnectOnAppear: Bool = false, loadingState: LoadingState = .initial, providerInfo: ProviderInfo? = nil, credentials: Credentials? = nil, destination: Destination.State? = nil) { self.organization = organization self.selectedProfileId = selectedProfileId self.autoConnectOnAppear = autoConnectOnAppear self.loadingState = loadingState + self.providerInfo = providerInfo self.credentials = credentials self.destination = destination } diff --git a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-Mac.swift b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-Mac.swift index 8adfe61..0d4bb20 100644 --- a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-Mac.swift +++ b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-Mac.swift @@ -76,14 +76,14 @@ public struct ConnectView_Mac: View { Image(systemName: "doc.badge.gearshape.fill") VStack(alignment: .leading) { if #available(macOS 13.0, *) { - Text("Continue in System Settings") + Text("Continue in System Settings", bundle: .module) .font(theme.connectButtonFont) Text(""" Double-click to review the profile and then press the "Install…" button to setup the network on your computer. """, bundle: .module) .font(theme.connectedFont) } else { - Text("Continue in System Preferences") + Text("Continue in System Preferences", bundle: .module) .font(theme.connectButtonFont) Text(""" Review the profile and then press the "Install…" button to setup the network on your computer. diff --git a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-iOS.swift b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-iOS.swift index 7a404ca..79d7071 100644 --- a/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-iOS.swift +++ b/geteduroam/GeteduroamPackage/Sources/Connect/ConnectView-iOS.swift @@ -103,6 +103,7 @@ public struct ConnectView_iOS: View { } Spacer() } + .padding(20) } .onAppear { viewStore.send(.onAppear) diff --git a/geteduroam/GeteduroamPackage/Sources/Main/MainFeature.swift b/geteduroam/GeteduroamPackage/Sources/Main/MainFeature.swift index 4a10294..d66fb1c 100644 --- a/geteduroam/GeteduroamPackage/Sources/Main/MainFeature.swift +++ b/geteduroam/GeteduroamPackage/Sources/Main/MainFeature.swift @@ -16,11 +16,11 @@ public struct Main: Reducer { @Dependency(\.date.now) var now public struct State: Equatable { - public init(searchQuery: String = "", organizations: IdentifiedArrayOf = .init(uniqueElements: []), loadingState: LoadingState = .initial, destination: Destination.State? = nil) { + public init(searchQuery: String = "", organizations: IdentifiedArrayOf = .init(uniqueElements: []), loadingState: LoadingState = .initial, searchResults: IdentifiedArrayOf = .init(uniqueElements: []), destination: Destination.State? = nil) { self.searchQuery = searchQuery self.organizations = organizations self.loadingState = loadingState - self.searchResults = .init(uniqueElements: []) + self.searchResults = searchResults self.destination = destination } diff --git a/geteduroam/GeteduroamPackage/Sources/Models/Profile.swift b/geteduroam/GeteduroamPackage/Sources/Models/Profile.swift index 8b77e1e..4235e90 100644 --- a/geteduroam/GeteduroamPackage/Sources/Models/Profile.swift +++ b/geteduroam/GeteduroamPackage/Sources/Models/Profile.swift @@ -33,7 +33,7 @@ public struct Profile: Codable, Equatable, Identifiable { public let webviewEndpoint: String? public var nameOrId: String { - name?["any"] ?? id + name?.localized() ?? id } } diff --git a/geteduroam/GeteduroamPackage/Tests/ConnectTests/ConnectViewPhoneTests.swift b/geteduroam/GeteduroamPackage/Tests/ConnectTests/ConnectViewPhoneTests.swift new file mode 100644 index 0000000..0fa4253 --- /dev/null +++ b/geteduroam/GeteduroamPackage/Tests/ConnectTests/ConnectViewPhoneTests.swift @@ -0,0 +1,79 @@ +import ComposableArchitecture +import Models +import SnapshotTesting +import SwiftUI +import XCTest +@testable import Connect + +#if os(iOS) +final class ConnectViewPhoneTests: XCTestCase { + + override class func setUp() { + SnapshotTesting.diffTool = "ksdiff" + } + + let theme = Theme( + searchFont: .system(.body, design: .default), + errorFont: .system(.body, design: .default), + organizationNameFont: .system(.body, design: .default).bold(), + organizationCountryFont: .system(.footnote, design: .default), + profilesHeaderFont: .system(.body, design: .default).bold(), + profileNameFont: .system(.body, design: .default), + connectButtonFont: .system(.callout, design: .default).bold(), + connectedFont: .system(.body, design: .default), + infoHeaderFont: .system(.body, design: .default).bold(), + infoDetailFont: .system(.body, design: .default)) + + func testConnectScreen() throws { + throw XCTSkip("Work in progress") + let profile = Profile(id: "1", name: ["any": "My Profile"], default: true, type: .eapConfig) + let organization = Organization(id: "test", name: ["any": "My Test Organization"], country: "AB", profiles: [profile], geo: []) + let store = StoreOf(initialState: .init(organization: organization), reducer: { }) + + let connectView = ConnectView(store: store) + .environmentObject(theme) + + let hosting = UIHostingController(rootView: connectView) + + assertSnapshot(of: hosting, as: .image(on: .iPadMini)) + } + +} +#endif + +#if os(macOS) +final class ConnectViewMacTests: XCTestCase { + + override class func setUp() { + SnapshotTesting.diffTool = "ksdiff" + } + + let theme = Theme( + searchFont: .system(.body, design: .default), + errorFont: .system(.body, design: .default), + organizationNameFont: .system(.body, design: .default).bold(), + organizationCountryFont: .system(.footnote, design: .default), + profilesHeaderFont: .system(.body, design: .default).bold(), + profileNameFont: .system(.body, design: .default), + connectButtonFont: .system(.callout, design: .default).bold(), + connectedFont: .system(.body, design: .default), + infoHeaderFont: .system(.body, design: .default).bold(), + infoDetailFont: .system(.body, design: .default)) + + func testConnectScreenMac() throws { + throw XCTSkip("Work in progress") + let profile = Profile(id: "1", name: ["any": "My Profile"], default: true, type: .eapConfig) + let organization = Organization(id: "test", name: ["any": "My Test Organization"], country: "AB", profiles: [profile], geo: []) + let store = StoreOf(initialState: .init(organization: organization), reducer: { }) + + let connectView = ConnectView(store: store) + .environmentObject(theme) + + let hosting = NSHostingController(rootView: connectView) + hosting.view.frame = .init(origin: .zero, size: .init(width: 400, height: 640)) + + assertSnapshot(of: hosting, as: .image) + } + +} +#endif diff --git a/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreen.1.png b/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreen.1.png new file mode 100644 index 0000000..71d0895 Binary files /dev/null and b/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreen.1.png differ diff --git a/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreenMac.1.png b/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreenMac.1.png new file mode 100644 index 0000000..21c27e7 Binary files /dev/null and b/geteduroam/GeteduroamPackage/Tests/ConnectTests/__Snapshots__/ConnectViewPhoneTests/testConnectScreenMac.1.png differ diff --git a/geteduroam/ScreenshotScenarios.swift b/geteduroam/ScreenshotScenarios.swift new file mode 100644 index 0000000..3b3285e --- /dev/null +++ b/geteduroam/ScreenshotScenarios.swift @@ -0,0 +1,122 @@ +import Foundation +import Main +import Models + +#if DEBUG +extension Organization { + static var example = Organization( + id: "id", + name: [ + "any": "Example Organization (demo)", + "nl": "Voorbeeldorganisatie (demo)", + ], + country: "NL", + profiles: [ + .init( + id: "profile1", + name: [ + "any": "Profile for Staff", + "nl": "Profiel voor medewerkers" + ], + default: true, + type: .eapConfig + ), + .init( + id: "profile2", + name: [ + "any": "Profile for Students", + "nl": "Profiel voor studenten" + ], + default: true, + type: .eapConfig + ) + ], + geo: [] + ) + + static var example2 = Organization( + id: "id2", + name: [ + "any": "eduroam (demo)", + "nl": "eduroam (demo)", + ], + country: "WW", + profiles: [], + geo: [] + ) + + static var example3 = Organization( + id: "id3", + name: [ + "any": "Another Organization (demo)", + "nl": "Andere Organisatie (demo)", + ], + country: "NL", + profiles: [], + geo: [] + ) +} + +extension ProviderInfo { + static var example = ProviderInfo( + displayName: [ + .init(language: "any", value: "Example Organization"), + .init(language: "nl", value: "Voorbeeldorganisatie") + ], + description: [ + .init(language: "any", value: "Contact our helpdesk if you need assistance."), + .init(language: "nl", value: "Benader onze helpdesk als je hulp nodig hebt.") + ], + providerLocations: [], providerLogo: nil, termsOfUse: nil, helpdesk: HelpdeskDetails(emailAdress: [ + .init(language: "any", value: "helpdesk@example.com") + ], webAddress: [ + .init(language: "any", value: "https://www.example.com/helpdesk") + ])) +} + +enum Scenario: String, CaseIterable { + case main + case search + case connect + case connected + + var initialState: Main.State { + switch self { + case .main: + Main.State( + organizations: .init(uniqueElements: [.example, .example2, .example3]), + loadingState: .success + ) + + case .search: + Main.State( + searchQuery: "demo", + organizations: .init(uniqueElements: [.example, .example2, .example3]), + loadingState: .success, + searchResults: .init(uniqueElements: [.example, .example2, .example3]) + ) + + case .connect: + Main.State( + loadingState: .success, + destination: .connect( + .init( + organization: .example, + providerInfo: .example + ) + )) + + case .connected: + Main.State( + loadingState: .success, + destination: .connect( + .init( + organization: .example, + loadingState: .success(.connected), + providerInfo: .example + ) + )) + } + } +} +#endif diff --git a/getgovroam/GetgovroamApp.swift b/getgovroam/GetgovroamApp.swift index ccce535..a50e549 100644 --- a/getgovroam/GetgovroamApp.swift +++ b/getgovroam/GetgovroamApp.swift @@ -4,13 +4,9 @@ import Main import Models import SwiftUI -@main -struct GeteduroamApp: App { - - #if os(iOS) - @UIApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate - - @StateObject var theme = Theme( +#if os(iOS) +extension Theme { + static var theme = Theme( searchFont: .custom("Muli", size: 20, relativeTo: .body), errorFont: .custom("Muli", size: 16, relativeTo: .body), organizationNameFont: .custom("Muli-Bold", size: 16, relativeTo: .body), @@ -21,11 +17,10 @@ struct GeteduroamApp: App { connectedFont: .custom("Muli-Bold", size: 14, relativeTo: .body), infoHeaderFont: .custom("Muli-Bold", size: 14, relativeTo: .body), infoDetailFont: .custom("Muli", size: 14, relativeTo: .body)) - - #elseif os(macOS) - @NSApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate - - @StateObject var theme = Theme( +} +#elseif os(macOS) +extension Theme { + static var theme = Theme( searchFont: .system(.body, design: .default), errorFont: .system(.body, design: .default), organizationNameFont: .system(.body, design: .default).bold(), @@ -36,7 +31,19 @@ struct GeteduroamApp: App { connectedFont: .system(.body, design: .default), infoHeaderFont: .system(.body, design: .default).bold(), infoDetailFont: .system(.body, design: .default)) - #endif +} +#endif + +@main +struct GeteduroamApp: App { + +#if os(iOS) + @UIApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate +#elseif os(macOS) + @NSApplicationDelegateAdaptor private var appDelegate: GeteduroamAppDelegate +#endif + + @StateObject var theme = Theme.theme var store: StoreOf
! @@ -47,7 +54,18 @@ struct GeteduroamApp: App { fakeInitialWindowPositionPreference() #endif - store = .init(initialState: .init(), reducer: { Main() }, withDependencies: { [appDelegate] in +#if DEBUG + let initialState: Main.State + if let scenario = UserDefaults.standard.string(forKey: "Scenario"), let scenario = Scenario(rawValue: scenario) { + initialState = scenario.initialState + } else { + initialState = .init() + } +#else + let initialState = Main.State() +#endif + + store = .init(initialState: initialState, reducer: { Main() }, withDependencies: { [appDelegate] in $0.authClient = appDelegate }) } diff --git a/getgovroam/ScreenshotScenarios.swift b/getgovroam/ScreenshotScenarios.swift new file mode 100644 index 0000000..089f438 --- /dev/null +++ b/getgovroam/ScreenshotScenarios.swift @@ -0,0 +1,122 @@ +import Foundation +import Main +import Models + +#if DEBUG +extension Organization { + static var example = Organization( + id: "id", + name: [ + "any": "Example Organization (demo)", + "nl": "Voorbeeldorganisatie (demo)", + ], + country: "NL", + profiles: [ + .init( + id: "profile1", + name: [ + "any": "Profile for Staff", + "nl": "Profiel voor medewerkers" + ], + default: true, + type: .eapConfig + ), + .init( + id: "profile2", + name: [ + "any": "Profile for Externals", + "nl": "Profiel voor externen" + ], + default: true, + type: .eapConfig + ) + ], + geo: [] + ) + + static var example2 = Organization( + id: "id2", + name: [ + "any": "govroam (demo)", + "nl": "govroam (demo)", + ], + country: "NL", + profiles: [], + geo: [] + ) + + static var example3 = Organization( + id: "id3", + name: [ + "any": "Another Organization (demo)", + "nl": "Andere Organisatie (demo)", + ], + country: "NL", + profiles: [], + geo: [] + ) +} + +extension ProviderInfo { + static var example = ProviderInfo( + displayName: [ + .init(language: "any", value: "Example Organization"), + .init(language: "nl", value: "Voorbeeldorganisatie") + ], + description: [ + .init(language: "any", value: "Contact our helpdesk if you need assistance."), + .init(language: "nl", value: "Benader onze helpdesk als je hulp nodig hebt.") + ], + providerLocations: [], providerLogo: nil, termsOfUse: nil, helpdesk: HelpdeskDetails(emailAdress: [ + .init(language: "any", value: "helpdesk@example.com") + ], webAddress: [ + .init(language: "any", value: "https://www.example.com/helpdesk") + ])) +} + +enum Scenario: String, CaseIterable { + case main + case search + case connect + case connected + + var initialState: Main.State { + switch self { + case .main: + Main.State( + organizations: .init(uniqueElements: [.example, .example2, .example3]), + loadingState: .success + ) + + case .search: + Main.State( + searchQuery: "demo", + organizations: .init(uniqueElements: [.example, .example2, .example3]), + loadingState: .success, + searchResults: .init(uniqueElements: [.example, .example2, .example3]) + ) + + case .connect: + Main.State( + loadingState: .success, + destination: .connect( + .init( + organization: .example, + providerInfo: .example + ) + )) + + case .connected: + Main.State( + loadingState: .success, + destination: .connect( + .init( + organization: .example, + loadingState: .success(.connected), + providerInfo: .example + ) + )) + } + } +} +#endif