diff --git a/Examples/Examples/BasemapGalleryExampleView.swift b/Examples/Examples/BasemapGalleryExampleView.swift index bed16d37b..574feee99 100644 --- a/Examples/Examples/BasemapGalleryExampleView.swift +++ b/Examples/Examples/BasemapGalleryExampleView.swift @@ -29,7 +29,7 @@ struct BasemapGalleryExampleView: View { ) /// The initial list of basemaps. - private let basemaps = initialBasemaps() + @State private var basemaps = initialBasemaps() var body: some View { MapView(map: map, viewpoint: initialViewpoint) diff --git a/Examples/Examples/FloorFilterExampleView.swift b/Examples/Examples/FloorFilterExampleView.swift index 51b932ef0..87a52fd2d 100644 --- a/Examples/Examples/FloorFilterExampleView.swift +++ b/Examples/Examples/FloorFilterExampleView.swift @@ -16,16 +16,8 @@ import ArcGISToolkit import ArcGIS struct FloorFilterExampleView: View { - /// Make a map from a portal item. - static func makeMap() -> Map { - Map(item: PortalItem( - portal: .arcGISOnline(connection: .anonymous), - id: Item.ID("b4b599a43a474d33946cf0df526426f5")! - )) - } - /// Determines the arrangement of the inner `FloorFilter` UI components. - private let floorFilterAlignment = Alignment.bottomLeading + private var floorFilterAlignment: Alignment { .bottomLeading } /// The height of the map view's attribution bar. @State private var attributionBarHeight = 0.0 @@ -36,6 +28,15 @@ struct FloorFilterExampleView: View { /// A Boolean value indicating whether the map is currently being navigated. @State private var isNavigating = false + /// The `Map` displayed in the `MapView`. + @State private var map = Map( + item: PortalItem( + portal: .arcGISOnline(connection: .anonymous), + id: Item.ID("b4b599a43a474d33946cf0df526426f5")! + ) + ) + + /// A Boolean value indicating whether an error was encountered while loading the map. @State private var mapLoadError = false /// The initial viewpoint of the map. @@ -48,62 +49,54 @@ struct FloorFilterExampleView: View { scale: 100_000 ) - /// The data model containing the `Map` displayed in the `MapView`. - @StateObject private var dataModel = MapDataModel( - map: makeMap() - ) - var body: some View { - MapView( - map: dataModel.map, - viewpoint: viewpoint - ) - .onAttributionBarHeightChanged { newHeight in - withAnimation { attributionBarHeight = newHeight } - } - .onNavigatingChanged { - isNavigating = $0 - } - .onViewpointChanged(kind: .centerAndScale) { - viewpoint = $0 - } - // Preserve the current viewpoint when a keyboard is presented in landscape. - .ignoresSafeArea(.keyboard, edges: .bottom) - .overlay(alignment: floorFilterAlignment) { - if isMapLoaded, - let floorManager = dataModel.map.floorManager { - FloorFilter( - floorManager: floorManager, - alignment: floorFilterAlignment, - viewpoint: $viewpoint, - isNavigating: $isNavigating - ) - .frame( - maxWidth: 400, - maxHeight: 400 - ) - .padding([.horizontal], 10) - .padding([.vertical], 10 + attributionBarHeight) - } else if mapLoadError { - Label( - "Map load error!", - systemImage: "exclamationmark.triangle" - ) - .foregroundColor(.red) - .frame( - maxWidth: .infinity, - maxHeight: .infinity, - alignment: .center - ) + MapView(map: map, viewpoint: viewpoint) + .onAttributionBarHeightChanged { newHeight in + withAnimation { attributionBarHeight = newHeight } + } + .onNavigatingChanged { + isNavigating = $0 + } + .onViewpointChanged(kind: .centerAndScale) { + viewpoint = $0 + } + // Preserve the current viewpoint when a keyboard is presented in landscape. + .ignoresSafeArea(.keyboard, edges: .bottom) + .overlay(alignment: floorFilterAlignment) { + if isMapLoaded, + let floorManager = map.floorManager { + FloorFilter( + floorManager: floorManager, + alignment: floorFilterAlignment, + viewpoint: $viewpoint, + isNavigating: $isNavigating + ) + .frame( + maxWidth: 400, + maxHeight: 400 + ) + .padding([.horizontal], 10) + .padding([.vertical], 10 + attributionBarHeight) + } else if mapLoadError { + Label( + "Map load error!", + systemImage: "exclamationmark.triangle" + ) + .foregroundColor(.red) + .frame( + maxWidth: .infinity, + maxHeight: .infinity, + alignment: .center + ) + } } - } - .task { - do { - try await dataModel.map.load() - isMapLoaded = true - } catch { - mapLoadError = true + .task { + do { + try await map.load() + isMapLoaded = true + } catch { + mapLoadError = true + } } - } } } diff --git a/UI Test Runner/UI Test Runner.xcodeproj/project.pbxproj b/UI Test Runner/UI Test Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..bf6ea6182 --- /dev/null +++ b/UI Test Runner/UI Test Runner.xcodeproj/project.pbxproj @@ -0,0 +1,525 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 7552A7542A573CBB0023DA5A /* UITestRunner.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552A7532A573CBB0023DA5A /* UITestRunner.swift */; }; + 7552A7562A573CBB0023DA5A /* Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552A7552A573CBB0023DA5A /* Tests.swift */; }; + 7552A7582A573CBD0023DA5A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7552A7572A573CBD0023DA5A /* Assets.xcassets */; }; + 7552A75B2A573CBD0023DA5A /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7552A75A2A573CBD0023DA5A /* Preview Assets.xcassets */; }; + 7552A7622A573D810023DA5A /* BookmarksTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552A7612A573D810023DA5A /* BookmarksTestView.swift */; }; + 7552A76C2A573DFB0023DA5A /* BookmarksTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7552A76B2A573DFB0023DA5A /* BookmarksTests.swift */; }; + 7552A7762A573E900023DA5A /* ArcGISToolkit in Frameworks */ = {isa = PBXBuildFile; productRef = 7552A7752A573E900023DA5A /* ArcGISToolkit */; }; + 75B236692A5CB49B00AEFACE /* BasemapGalleryTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B236682A5CB49B00AEFACE /* BasemapGalleryTestView.swift */; }; + 75B2366B2A5CB8CE00AEFACE /* BasemapGalleryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B2366A2A5CB8CE00AEFACE /* BasemapGalleryTests.swift */; }; + 75B2366D2A5CC78C00AEFACE /* FloorFilterTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B2366C2A5CC78C00AEFACE /* FloorFilterTestView.swift */; }; + 75B2366F2A5CCADC00AEFACE /* FloorFilterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75B2366E2A5CCADC00AEFACE /* FloorFilterTests.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 7552A76F2A573DFB0023DA5A /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7552A7482A573CBB0023DA5A /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7552A74F2A573CBB0023DA5A; + remoteInfo = "UI Test Runner"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 7552A7502A573CBB0023DA5A /* UI Test Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UI Test Runner.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7552A7532A573CBB0023DA5A /* UITestRunner.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITestRunner.swift; sourceTree = ""; }; + 7552A7552A573CBB0023DA5A /* Tests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tests.swift; sourceTree = ""; }; + 7552A7572A573CBD0023DA5A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7552A75A2A573CBD0023DA5A /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 7552A7612A573D810023DA5A /* BookmarksTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksTestView.swift; sourceTree = ""; }; + 7552A7642A573DA00023DA5A /* arcgis-maps-sdk-swift-toolkit */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "arcgis-maps-sdk-swift-toolkit"; path = ..; sourceTree = ""; }; + 7552A7692A573DFB0023DA5A /* UITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 7552A76B2A573DFB0023DA5A /* BookmarksTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksTests.swift; sourceTree = ""; }; + 75B236682A5CB49B00AEFACE /* BasemapGalleryTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasemapGalleryTestView.swift; sourceTree = ""; }; + 75B2366A2A5CB8CE00AEFACE /* BasemapGalleryTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BasemapGalleryTests.swift; sourceTree = ""; }; + 75B2366C2A5CC78C00AEFACE /* FloorFilterTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloorFilterTestView.swift; sourceTree = ""; }; + 75B2366E2A5CCADC00AEFACE /* FloorFilterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloorFilterTests.swift; sourceTree = ""; }; + 75CCCD612A5F691E0098B059 /* UI Test Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "UI Test Runner.entitlements"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7552A74D2A573CBB0023DA5A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7552A7762A573E900023DA5A /* ArcGISToolkit in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7552A7662A573DFB0023DA5A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7552A7472A573CBB0023DA5A = { + isa = PBXGroup; + children = ( + 7552A7632A573DA00023DA5A /* Packages */, + 7552A7522A573CBB0023DA5A /* UI Test Runner */, + 7552A76A2A573DFB0023DA5A /* UITests */, + 7552A7512A573CBB0023DA5A /* Products */, + ); + sourceTree = ""; + }; + 7552A7512A573CBB0023DA5A /* Products */ = { + isa = PBXGroup; + children = ( + 7552A7502A573CBB0023DA5A /* UI Test Runner.app */, + 7552A7692A573DFB0023DA5A /* UITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 7552A7522A573CBB0023DA5A /* UI Test Runner */ = { + isa = PBXGroup; + children = ( + 75CCCD612A5F691E0098B059 /* UI Test Runner.entitlements */, + 7552A7532A573CBB0023DA5A /* UITestRunner.swift */, + 7552A7552A573CBB0023DA5A /* Tests.swift */, + 7552A7572A573CBD0023DA5A /* Assets.xcassets */, + 7552A7592A573CBD0023DA5A /* Preview Content */, + 75B236672A5CB32700AEFACE /* TestViews */, + ); + path = "UI Test Runner"; + sourceTree = ""; + }; + 7552A7592A573CBD0023DA5A /* Preview Content */ = { + isa = PBXGroup; + children = ( + 7552A75A2A573CBD0023DA5A /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 7552A7632A573DA00023DA5A /* Packages */ = { + isa = PBXGroup; + children = ( + 7552A7642A573DA00023DA5A /* arcgis-maps-sdk-swift-toolkit */, + ); + name = Packages; + sourceTree = ""; + }; + 7552A76A2A573DFB0023DA5A /* UITests */ = { + isa = PBXGroup; + children = ( + 75B2366A2A5CB8CE00AEFACE /* BasemapGalleryTests.swift */, + 7552A76B2A573DFB0023DA5A /* BookmarksTests.swift */, + 75B2366E2A5CCADC00AEFACE /* FloorFilterTests.swift */, + ); + path = UITests; + sourceTree = ""; + }; + 75B236672A5CB32700AEFACE /* TestViews */ = { + isa = PBXGroup; + children = ( + 75B236682A5CB49B00AEFACE /* BasemapGalleryTestView.swift */, + 7552A7612A573D810023DA5A /* BookmarksTestView.swift */, + 75B2366C2A5CC78C00AEFACE /* FloorFilterTestView.swift */, + ); + path = TestViews; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 7552A74F2A573CBB0023DA5A /* UI Test Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7552A75E2A573CBD0023DA5A /* Build configuration list for PBXNativeTarget "UI Test Runner" */; + buildPhases = ( + 7552A74C2A573CBB0023DA5A /* Sources */, + 7552A74D2A573CBB0023DA5A /* Frameworks */, + 7552A74E2A573CBB0023DA5A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "UI Test Runner"; + packageProductDependencies = ( + 7552A7752A573E900023DA5A /* ArcGISToolkit */, + ); + productName = "UI Test Runner"; + productReference = 7552A7502A573CBB0023DA5A /* UI Test Runner.app */; + productType = "com.apple.product-type.application"; + }; + 7552A7682A573DFB0023DA5A /* UITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7552A7712A573DFB0023DA5A /* Build configuration list for PBXNativeTarget "UITests" */; + buildPhases = ( + 7552A7652A573DFB0023DA5A /* Sources */, + 7552A7662A573DFB0023DA5A /* Frameworks */, + 7552A7672A573DFB0023DA5A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 7552A7702A573DFB0023DA5A /* PBXTargetDependency */, + ); + name = UITests; + productName = UITests; + productReference = 7552A7692A573DFB0023DA5A /* UITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 7552A7482A573CBB0023DA5A /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1400; + LastUpgradeCheck = 1400; + TargetAttributes = { + 7552A74F2A573CBB0023DA5A = { + CreatedOnToolsVersion = 14.0; + }; + 7552A7682A573DFB0023DA5A = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 7552A74F2A573CBB0023DA5A; + }; + }; + }; + buildConfigurationList = 7552A74B2A573CBB0023DA5A /* Build configuration list for PBXProject "UI Test Runner" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 7552A7472A573CBB0023DA5A; + productRefGroup = 7552A7512A573CBB0023DA5A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7552A74F2A573CBB0023DA5A /* UI Test Runner */, + 7552A7682A573DFB0023DA5A /* UITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 7552A74E2A573CBB0023DA5A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7552A75B2A573CBD0023DA5A /* Preview Assets.xcassets in Resources */, + 7552A7582A573CBD0023DA5A /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7552A7672A573DFB0023DA5A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 7552A74C2A573CBB0023DA5A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7552A7562A573CBB0023DA5A /* Tests.swift in Sources */, + 7552A7542A573CBB0023DA5A /* UITestRunner.swift in Sources */, + 75B2366D2A5CC78C00AEFACE /* FloorFilterTestView.swift in Sources */, + 7552A7622A573D810023DA5A /* BookmarksTestView.swift in Sources */, + 75B236692A5CB49B00AEFACE /* BasemapGalleryTestView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7552A7652A573DFB0023DA5A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 75B2366F2A5CCADC00AEFACE /* FloorFilterTests.swift in Sources */, + 75B2366B2A5CB8CE00AEFACE /* BasemapGalleryTests.swift in Sources */, + 7552A76C2A573DFB0023DA5A /* BookmarksTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 7552A7702A573DFB0023DA5A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7552A74F2A573CBB0023DA5A /* UI Test Runner */; + targetProxy = 7552A76F2A573DFB0023DA5A /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 7552A75C2A573CBD0023DA5A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 7552A75D2A573CBD0023DA5A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 7552A75F2A573CBD0023DA5A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "UI Test Runner/UI Test Runner.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"UI Test Runner/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.esri.arcgis-swift-sdk-toolkit-ui-test-runner.UI-Test-Runner"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; + }; + name = Debug; + }; + 7552A7602A573CBD0023DA5A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = "UI Test Runner/UI Test Runner.entitlements"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"UI Test Runner/Preview Content\""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.esri.arcgis-swift-sdk-toolkit-ui-test-runner.UI-Test-Runner"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2,6"; + }; + name = Release; + }; + 7552A7722A573DFB0023DA5A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.esri.arcgis-swift-sdk-toolkit-ui-test-runner.UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "UI Test Runner"; + }; + name = Debug; + }; + 7552A7732A573DFB0023DA5A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "com.esri.arcgis-swift-sdk-toolkit-ui-test-runner.UITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SUPPORTS_MACCATALYST = YES; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "UI Test Runner"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 7552A74B2A573CBB0023DA5A /* Build configuration list for PBXProject "UI Test Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7552A75C2A573CBD0023DA5A /* Debug */, + 7552A75D2A573CBD0023DA5A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7552A75E2A573CBD0023DA5A /* Build configuration list for PBXNativeTarget "UI Test Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7552A75F2A573CBD0023DA5A /* Debug */, + 7552A7602A573CBD0023DA5A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7552A7712A573DFB0023DA5A /* Build configuration list for PBXNativeTarget "UITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7552A7722A573DFB0023DA5A /* Debug */, + 7552A7732A573DFB0023DA5A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 7552A7752A573E900023DA5A /* ArcGISToolkit */ = { + isa = XCSwiftPackageProductDependency; + productName = ArcGISToolkit; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 7552A7482A573CBB0023DA5A /* Project object */; +} diff --git a/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000..18d981003 --- /dev/null +++ b/UI Test Runner/UI Test Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/UI Test Runner/UI Test Runner/Assets.xcassets/AccentColor.colorset/Contents.json b/UI Test Runner/UI Test Runner/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..eb8789700 --- /dev/null +++ b/UI Test Runner/UI Test Runner/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/UI Test Runner/UI Test Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/UI Test Runner/UI Test Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000..13613e3ee --- /dev/null +++ b/UI Test Runner/UI Test Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,13 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/UI Test Runner/UI Test Runner/Assets.xcassets/Contents.json b/UI Test Runner/UI Test Runner/Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/UI Test Runner/UI Test Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/UI Test Runner/UI Test Runner/Preview Content/Preview Assets.xcassets/Contents.json b/UI Test Runner/UI Test Runner/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 000000000..73c00596a --- /dev/null +++ b/UI Test Runner/UI Test Runner/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/UI Test Runner/UI Test Runner/TestViews/BasemapGalleryTestView.swift b/UI Test Runner/UI Test Runner/TestViews/BasemapGalleryTestView.swift new file mode 100644 index 000000000..5584321e9 --- /dev/null +++ b/UI Test Runner/UI Test Runner/TestViews/BasemapGalleryTestView.swift @@ -0,0 +1,44 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS +import ArcGISToolkit +import SwiftUI + +struct BasemapGalleryTestView: View { + @State private var map = Map(basemapStyle: .arcGISImagery) + + @State private var basemaps = initialBasemaps() + + var body: some View { + MapView(map: map) + .sheet(isPresented: .constant(true)) { + BasemapGallery(items: basemaps, geoModel: map) + .style(.grid(maxItemWidth: 100)) + } + } + + private static func initialBasemaps() -> [BasemapGalleryItem] { + let identifiers = [ + "46a87c20f09e4fc48fa3c38081e0cae6", + "f33a34de3a294590ab48f246e99958c9", + "52bdc7ab7fb044d98add148764eaa30a", // <<== mismatched spatial reference + "3a8d410a4a034a2ba9738bb0860d68c4" // <<== incorrect portal item type + ] + + return identifiers.map { identifier in + let url = URL(string: "https://www.arcgis.com/home/item.html?id=\(identifier)")! + return BasemapGalleryItem(basemap: Basemap(item: PortalItem(url: url)!)) + } + } +} diff --git a/UI Test Runner/UI Test Runner/TestViews/BookmarksTestView.swift b/UI Test Runner/UI Test Runner/TestViews/BookmarksTestView.swift new file mode 100644 index 000000000..3ceaad6c4 --- /dev/null +++ b/UI Test Runner/UI Test Runner/TestViews/BookmarksTestView.swift @@ -0,0 +1,53 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS +import ArcGISToolkit +import SwiftUI + +struct BookmarksTestView: View { + /// The `Map` with predefined bookmarks. + @State private var map = Map(url: URL(string: "https://www.arcgis.com/home/item.html?id=16f1b8ba37b44dc3884afc8d5f454dd2")!)! + + /// The last selected bookmark. + @State private var selectedBookmark: Bookmark? + + /// Indicates if the `Bookmarks` component is shown or not. + /// - Remark: This allows a developer to control when the `Bookmarks` component is + /// shown/hidden, whether that be in a group of options or a standalone button. + @State private var showingBookmarks = false + + var body: some View { + MapView(map: map, viewpoint: selectedBookmark?.viewpoint) + .sheet(isPresented: $showingBookmarks) { + Bookmarks( + isPresented: $showingBookmarks, + geoModel: map + ) + .onSelectionChanged { selectedBookmark = $0 } + } + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button("Bookmarks") { + showingBookmarks.toggle() + } + } + + if let selectedBookmark { + ToolbarItem(placement: .bottomBar) { + Text(selectedBookmark.name) + } + } + } + } +} diff --git a/UI Test Runner/UI Test Runner/TestViews/FloorFilterTestView.swift b/UI Test Runner/UI Test Runner/TestViews/FloorFilterTestView.swift new file mode 100644 index 000000000..a722cca55 --- /dev/null +++ b/UI Test Runner/UI Test Runner/TestViews/FloorFilterTestView.swift @@ -0,0 +1,84 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS +import ArcGISToolkit +import SwiftUI + +struct FloorFilterTestView: View { + /// Determines the arrangement of the inner `FloorFilter` UI components. + private var floorFilterAlignment: Alignment { .bottomLeading } + + /// The height of the map view's attribution bar. + @State private var attributionBarHeight = 0.0 + + /// Determines the appropriate time to initialize the `FloorFilter`. + @State private var isMapLoaded = false + + /// A Boolean value indicating whether the map is currently being navigated. + @State private var isNavigating = false + + /// The `Map` displayed in the `MapView`. + @State private var map = Map( + item: PortalItem( + portal: .arcGISOnline(connection: .anonymous), + id: Item.ID("b4b599a43a474d33946cf0df526426f5")! + ) + ) + + /// The initial viewpoint of the map. + @State private var viewpoint: Viewpoint? = Viewpoint( + center: Point( + x: -117.19496, + y: 34.05713, + spatialReference: .wgs84 + ), + scale: 100_000 + ) + + var body: some View { + MapView(map: map, viewpoint: viewpoint) + .onAttributionBarHeightChanged { newHeight in + withAnimation { attributionBarHeight = newHeight } + } + .onNavigatingChanged { + isNavigating = $0 + } + .onViewpointChanged(kind: .centerAndScale) { + viewpoint = $0 + } + // Preserve the current viewpoint when a keyboard is presented in landscape. + .ignoresSafeArea(.keyboard, edges: .bottom) + .overlay(alignment: floorFilterAlignment) { + if isMapLoaded, + let floorManager = map.floorManager { + FloorFilter( + floorManager: floorManager, + alignment: floorFilterAlignment, + viewpoint: $viewpoint, + isNavigating: $isNavigating + ) + .frame( + maxWidth: 400, + maxHeight: 400 + ) + .padding([.horizontal], 10) + .padding([.vertical], 10 + attributionBarHeight) + } + } + .task { + try? await map.load() + isMapLoaded = map.loadStatus == .loaded + } + } +} diff --git a/UI Test Runner/UI Test Runner/Tests.swift b/UI Test Runner/UI Test Runner/Tests.swift new file mode 100644 index 000000000..92792b4e2 --- /dev/null +++ b/UI Test Runner/UI Test Runner/Tests.swift @@ -0,0 +1,27 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import SwiftUI + +struct Tests: View { + var body: some View { + NavigationView { + List { + NavigationLink("Basemap Gallery Tests", destination: BasemapGalleryTestView()) + NavigationLink("Bookmarks Tests", destination: BookmarksTestView()) + NavigationLink("Floor Filter Tests", destination: FloorFilterTestView()) + } + } + .navigationViewStyle(.stack) + } +} diff --git a/UI Test Runner/UI Test Runner/UI Test Runner.entitlements b/UI Test Runner/UI Test Runner/UI Test Runner.entitlements new file mode 100644 index 000000000..ee95ab7e5 --- /dev/null +++ b/UI Test Runner/UI Test Runner/UI Test Runner.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/UI Test Runner/UI Test Runner/UITestRunner.swift b/UI Test Runner/UI Test Runner/UITestRunner.swift new file mode 100644 index 000000000..76a604d2b --- /dev/null +++ b/UI Test Runner/UI Test Runner/UITestRunner.swift @@ -0,0 +1,28 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import ArcGIS +import SwiftUI + +@main +struct UITestRunner: App { + var body: some SwiftUI.Scene { + WindowGroup { + Tests() + } + } + + init() { + ArcGISEnvironment.apiKey = APIKey("<#APIKey#>") + } +} diff --git a/UI Test Runner/UITests/BasemapGalleryTests.swift b/UI Test Runner/UITests/BasemapGalleryTests.swift new file mode 100644 index 000000000..3bf119cf5 --- /dev/null +++ b/UI Test Runner/UITests/BasemapGalleryTests.swift @@ -0,0 +1,75 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import XCTest + +final class BasemapGalleryTests: XCTestCase { + override func setUpWithError() throws { + continueAfterFailure = false + } + + /// Test general usage of the Basemap Gallery component. + func testBasemapGallery() throws { + let app = XCUIApplication() + app.launch() + + let basemapGalleryTestsButton = app.buttons["Basemap Gallery Tests"] + let openStreetMapBlueprintButton = app.buttons["OpenStreetMap (Blueprint)"] + let nationalGeographicStyleMapButton = app.buttons["National Geographic Style Map"] + let worldImageryButton = app.buttons["World_Imagery (WGS 84)"] + let spatialReferenceErrorText = app.staticTexts["Spatial reference mismatch."] + let okButton = app.buttons["OK"] + + // Open the Basemap Gallery component test view. + XCTAssertTrue( + basemapGalleryTestsButton.exists, + "The Basemap Gallery Tests button wasn't found." + ) + basemapGalleryTestsButton.tap() + + // Select two basemaps that should open without error. + XCTAssertTrue( + openStreetMapBlueprintButton.waitForExistence(timeout: 2), + "The OpenStreetMap (Blueprint) button wasn't found within 2 seconds." + ) + openStreetMapBlueprintButton.tap() + XCTAssertTrue( + nationalGeographicStyleMapButton.exists, + "The National Geographic Style Map button wasn't found." + ) + nationalGeographicStyleMapButton.tap() + + // Select a basemap that will trigger an error. + XCTAssertTrue( + worldImageryButton.exists, + "The World Imagery button wasn't found." + ) + worldImageryButton.tap() + + // Verify that a spatial reference error was presented after a few moments. + XCTAssertTrue( + spatialReferenceErrorText.waitForExistence(timeout: 2), + "The spatial reference error text wasn't found within 2 seconds." + ) + + // Dismiss the error. + XCTAssertTrue(okButton.exists, "The OK button wasn't found.") + okButton.tap() + + // Verify that a spatial reference error was dismissed. + XCTAssertFalse( + spatialReferenceErrorText.exists, + "The spatial reference error text was unexpectedly found after dismissing the error." + ) + } +} diff --git a/UI Test Runner/UITests/BookmarksTests.swift b/UI Test Runner/UITests/BookmarksTests.swift new file mode 100644 index 000000000..363f8f3c3 --- /dev/null +++ b/UI Test Runner/UITests/BookmarksTests.swift @@ -0,0 +1,75 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import XCTest + +final class BookmarksTests: XCTestCase { + override func setUpWithError() throws { + continueAfterFailure = false + } + + /// Test general usage of the Bookmarks component. + func testBookmarks() throws { + let app = XCUIApplication() + app.launch() + + let bookmarksTestsButton = app.buttons["Bookmarks Tests"] + let bookmarksButton = app.buttons["Bookmarks"].firstMatch + let selectABookmarkText = app.staticTexts["Select a bookmark"] + let giantSequoiasButton = app.buttons["Giant Sequoias of Willamette Blvd"].firstMatch + let giantSequoiasLabel = app.staticTexts["Giant Sequoias of Willamette Blvd"] + let historicLaddsButton = app.buttons["Historic Ladd's Addition"].firstMatch + let historicLaddsLabel = app.staticTexts["Historic Ladd's Addition"] + + // Open the Bookmarks component test view. + XCTAssertTrue(bookmarksTestsButton.exists, "The Bookmarks Tests button wasn't found.") + bookmarksTestsButton.tap() + + // Open the bookmark selection view. + XCTAssertTrue(bookmarksButton.exists, "The Bookmarks button wasn't found.") + bookmarksButton.tap() + + // Verify that the directive UI label is present. + XCTAssertTrue(selectABookmarkText.exists, "The Select a bookmark text wasn't found.") + + // Select a bookmark and confirm the component notified the test view of the selection. + XCTAssertTrue(giantSequoiasButton.exists, "The Giant Sequoias button wasn't found.") + giantSequoiasButton.tap() + + // Confirm the selection was made. + XCTAssertTrue( + giantSequoiasLabel.exists, + "The Giant Sequoias label confirming the bookmark selection wasn't found." + ) + + // Verify that the bookmarks selection view is no longer present. + XCTAssertFalse( + selectABookmarkText.exists, + "The Select a bookmark text was unexpectedly found." + ) + + // Re-open the bookmark selection view. + XCTAssertTrue(bookmarksButton.exists, "The Bookmarks button wasn't found.") + bookmarksButton.tap() + + // Select a bookmark and confirm the component notified the test view of the new selection. + XCTAssertTrue(historicLaddsButton.exists, "The Historic Ladd's button wasn't found.") + historicLaddsButton.tap() + + // Confirm the selection was made. + XCTAssertTrue( + historicLaddsLabel.exists, + "The Historic Ladd's label confirming the bookmark selection wasn't found." + ) + } +} diff --git a/UI Test Runner/UITests/FloorFilterTests.swift b/UI Test Runner/UITests/FloorFilterTests.swift new file mode 100644 index 000000000..2c76f7fae --- /dev/null +++ b/UI Test Runner/UITests/FloorFilterTests.swift @@ -0,0 +1,69 @@ +// Copyright 2023 Esri. + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 + +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import XCTest + +final class FloorFilterTests: XCTestCase { + override func setUpWithError() throws { + continueAfterFailure = false + } + + /// Test general usage of the Floor Filter component. + func testFloorFilter() throws { + let app = XCUIApplication() + app.launch() + + let filterButton = app.buttons["Business"] + let researchAnnexButton = app.buttons["Research Annex"] + let latticeText = app.staticTexts["Lattice"] + let levelEightText = app.scrollViews.otherElements.staticTexts["8"] + let levelOneText = app.staticTexts["1"] + let collapseButton = app.buttons["Go Down"] + + // Open the Floor Filter component test view. + app.buttons["Floor Filter Tests"].tap() + + // Wait for floor aware data to load and then open the filter. + XCTAssertTrue( + filterButton.waitForExistence(timeout: 5), + "The filter button wasn't found within 5 seconds." + ) + filterButton.tap() + + // Select the site named "Research Annex". + XCTAssertTrue( + researchAnnexButton.waitForExistence(timeout: 2), + "The Research Annex button wasn't found within 2 seconds." + ) + researchAnnexButton.tap() + + // Select the facility named "Lattice". + XCTAssertTrue(latticeText.exists, "The Lattice text wasn't found.") + latticeText.tap() + + // Select the level labeled "8". + XCTAssertTrue(levelEightText.exists, "The level eight text wasn't found.") + levelEightText.tap() + + // Verify that the level selector is not collapsed + // and other levels are available for selection. + XCTAssertTrue(levelOneText.exists, "The level one text wasn't found.") + + // Collapse the level selector. + XCTAssertTrue(collapseButton.exists, "The collapse button wasn't found.") + collapseButton.tap() + + // Verify that the level selector is collapsed. + XCTAssertFalse(levelOneText.exists, "The collapse button was unexpectedly still present.") + } +}