Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions Android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import java.util.Properties

// Compose ui-test-junit4-android pulls Espresso 3.5.x; align all androidx.test artifacts or
// ActivityScenario / ActivityInvoker can fail at runtime (see android/android-test#2259).
configurations.configureEach {
if (name.contains("androidTest", ignoreCase = true)) {
resolutionStrategy {
force(
"androidx.test:runner:1.7.0",
"androidx.test:rules:1.7.0",
"androidx.test:core:1.7.0",
"androidx.test:monitor:1.8.0",
"androidx.test.espresso:espresso-core:3.7.0",
"androidx.test.espresso:espresso-idling-resource:3.7.0",
)
}
}
}

plugins {
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
Expand Down Expand Up @@ -27,6 +44,7 @@ android {
defaultConfig {
minSdk = libs.versions.android.sdk.min.get().toInt()
targetSdk = libs.versions.android.sdk.compile.get().toInt()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
// skip.tools.skip-build-plugin will automatically use Skip.env properties for:
// applicationId = PRODUCT_BUNDLE_IDENTIFIER
// versionCode = CURRENT_PROJECT_VERSION
Expand All @@ -35,6 +53,7 @@ android {

buildFeatures {
buildConfig = true
compose = true
}

lint {
Expand Down Expand Up @@ -81,3 +100,19 @@ android {
}
}
}

dependencies {
// Transpiled XCTest UI test sources need SkipUnit and SkipUIAutomation on the classpath (:SkipUIAutomation appears in skipstone after an Xcode Showcase build).
androidTestImplementation(project(":SkipUnit"))
androidTestImplementation(project(":SkipUIAutomation"))

androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test)
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
debugImplementation(libs.androidx.compose.ui.test.manifest)
androidTestImplementation("androidx.test:runner:1.7.0")
androidTestImplementation("androidx.test:rules:1.7.0")
androidTestImplementation("androidx.test:core:1.7.0")
androidTestImplementation("androidx.test.ext:junit:1.3.0")
androidTestImplementation("androidx.test.uiautomator:uiautomator:2.4.0-beta02")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package showcase.module

import skip.lib.*
import skip.unit.*
import skip.uiautomation.*

@org.junit.runner.RunWith(androidx.test.ext.junit.runners.AndroidJUnit4::class)
class NavigationStackPlaygroundUITests : XCTestCase {
@Test
fun testNavigationStackPlaygroundShowsPopButton() {
val app = XCUIApplication()
app.launch()

app.tabBars.buttons["Showcase"].tap()

val searchField = app.searchFields.firstMatch
XCTAssertTrue(searchField.waitForExistence(timeout = 5.0), "Search field should appear on Showcase tab")
searchField.tap()
searchField.typeText("NavigationStack")

val row = app.staticTexts["NavigationStack"]
XCTAssertTrue(row.waitForExistence(timeout = 5.0), "Filtered list should include NavigationStack")
row.tap()

XCTAssertTrue(app.buttons["Pop"].waitForExistence(timeout = 5.0), "NavigationStack playground should show Pop button")
}
}
140 changes: 140 additions & 0 deletions Darwin/Showcase.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
499CD4512AC5B799001AE8E0 /* NavigationStackPlaygroundUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499CD4502AC5B799001AE8E0 /* NavigationStackPlaygroundUITests.swift */; };
490010192BACD83F0000DE33 /* protest_guerrilla.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 490010182BACD83F0000DE33 /* protest_guerrilla.ttf */; };
49231BAC2AC5BCEF00F98ADF /* ShowcaseApp in Frameworks */ = {isa = PBXBuildFile; productRef = 49231BAB2AC5BCEF00F98ADF /* ShowcaseApp */; };
49231BAD2AC5BCEF00F98ADF /* ShowcaseApp in Embed Frameworks */ = {isa = PBXBuildFile; productRef = 49231BAB2AC5BCEF00F98ADF /* ShowcaseApp */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
Expand All @@ -32,6 +33,8 @@
/* Begin PBXFileReference section */
490010182BACD83F0000DE33 /* protest_guerrilla.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = protest_guerrilla.ttf; path = ../Sources/Showcase/Resources/protest_guerrilla.ttf; sourceTree = "<group>"; };
4900101C2BACEA710000DE33 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
499CD4502AC5B799001AE8E0 /* NavigationStackPlaygroundUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationStackPlaygroundUITests.swift; sourceTree = "<group>"; };
499CD4572AC5B799001AE8E0 /* ShowcaseUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShowcaseUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
490A40BF2B37A3C300275405 /* Showcase.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Showcase.app; sourceTree = BUILT_PRODUCTS_DIR; };
493609562A6B7EAE00C401E2 /* Showcase */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = Showcase; path = ..; sourceTree = "<group>"; };
496EB72F2A6AE4DE00C1253A /* Skip.env */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Skip.env; path = ../Skip.env; sourceTree = "<group>"; };
Expand Down Expand Up @@ -60,10 +63,19 @@
isa = PBXGroup;
children = (
490A40BF2B37A3C300275405 /* Showcase.app */,
499CD4572AC5B799001AE8E0 /* ShowcaseUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
499CD4522AC5B799001AE8E0 /* ShowcaseUITests */ = {
isa = PBXGroup;
children = (
499CD4502AC5B799001AE8E0 /* NavigationStackPlaygroundUITests.swift */,
);
path = ShowcaseUITests;
sourceTree = "<group>";
};
49AB54462B066A7E007B79B2 /* SkipStone */ = {
isa = PBXGroup;
children = (
Expand All @@ -81,6 +93,7 @@
496EB72F2A6AE4DE00C1253B /* Showcase.xcconfig */,
493609562A6B7EAE00C401E2 /* Showcase */,
49F90C2A2A52156200F06D93 /* App */,
499CD4522AC5B799001AE8E0 /* ShowcaseUITests */,
49AB54462B066A7E007B79B2 /* SkipStone */,
490A40C02B37A3C300275405 /* Products */,
);
Expand Down Expand Up @@ -123,6 +136,24 @@
productReference = 490A40BF2B37A3C300275405 /* Showcase.app */;
productType = "com.apple.product-type.application";
};
499CD4532AC5B799001AE8E0 /* ShowcaseUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 499CD45A2AC5B799001AE8E0 /* Build configuration list for PBXNativeTarget "ShowcaseUITests" */;
buildPhases = (
499CD4542AC5B799001AE8E0 /* Sources */,
499CD4552AC5B799001AE8E0 /* Frameworks */,
499CD4562AC5B799001AE8E0 /* Resources */,
);
buildRules = (
);
dependencies = (
499CD4592AC5B799001AE8E0 /* PBXTargetDependency */,
);
name = ShowcaseUITests;
productName = ShowcaseUITests;
productReference = 499CD4572AC5B799001AE8E0 /* ShowcaseUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
Expand All @@ -132,6 +163,11 @@
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1430;
LastUpgradeCheck = 1540;
TargetAttributes = {
499CD4532AC5B799001AE8E0 = {
TestTargetID = 499CD4382AC5B799001AE8D8;
};
};
};
buildConfigurationList = 49F90C232A52156200F06D93 /* Build configuration list for PBXProject "Showcase" */;
compatibilityVersion = "Xcode 14.0";
Expand All @@ -149,10 +185,29 @@
projectRoot = "";
targets = (
499CD4382AC5B799001AE8D8 /* Showcase */,
499CD4532AC5B799001AE8E0 /* ShowcaseUITests */,
);
};
/* End PBXProject section */

/* Begin PBXContainerItemProxy section */
499CD4582AC5B799001AE8E0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 49F90C202A52156200F06D93 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 499CD4382AC5B799001AE8D8;
remoteInfo = Showcase;
};
/* End PBXContainerItemProxy section */

/* Begin PBXTargetDependency section */
499CD4592AC5B799001AE8E0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 499CD4382AC5B799001AE8D8 /* Showcase */;
targetProxy = 499CD4582AC5B799001AE8E0 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin PBXResourcesBuildPhase section */
499CD43E2AC5B799001AE8D8 /* Resources */ = {
isa = PBXResourcesBuildPhase;
Expand All @@ -166,6 +221,16 @@
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXResourcesBuildPhase section */
499CD4562AC5B799001AE8E0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
499CD4452AC5B869001AE8D8 /* Run skip gradle */ = {
isa = PBXShellScriptBuildPhase;
Expand Down Expand Up @@ -197,8 +262,26 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
499CD4542AC5B799001AE8E0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
499CD4512AC5B799001AE8E0 /* NavigationStackPlaygroundUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXFrameworksBuildPhase section */
499CD4552AC5B799001AE8E0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */

/* Begin XCBuildConfiguration section */
499CD4422AC5B799001AE8D8 /* Debug */ = {
isa = XCBuildConfiguration;
Expand Down Expand Up @@ -264,6 +347,54 @@
};
name = Release;
};
499CD45B2AC5B799001AE8E0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 198;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.12.3;
PRODUCT_BUNDLE_IDENTIFIER = org.appfair.app.ShowcaseLite.ShowcaseUITests;
PRODUCT_NAME = ShowcaseUITests;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = 1;
TEST_TARGET_NAME = Showcase;
};
name = Debug;
};
499CD45C2AC5B799001AE8E0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 198;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@loader_path/Frameworks",
);
MARKETING_VERSION = 1.12.3;
PRODUCT_BUNDLE_IDENTIFIER = org.appfair.app.ShowcaseLite.ShowcaseUITests;
PRODUCT_NAME = ShowcaseUITests;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
SUPPORTS_MACCATALYST = NO;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = 1;
TEST_TARGET_NAME = Showcase;
};
name = Release;
};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
Expand All @@ -276,6 +407,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
499CD45A2AC5B799001AE8E0 /* Build configuration list for PBXNativeTarget "ShowcaseUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
499CD45B2AC5B799001AE8E0 /* Debug */,
499CD45C2AC5B799001AE8E0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
49F90C232A52156200F06D93 /* Build configuration list for PBXProject "Showcase" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Expand Down
26 changes: 26 additions & 0 deletions Darwin/Showcase.xcodeproj/xcshareddata/xcschemes/Showcase.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@
ReferencedContainer = "container:Showcase.xcodeproj">
</BuildableReference>
</BuildActionEntry>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "NO"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "499CD4532AC5B799001AE8E0"
BuildableName = "ShowcaseUITests.xctest"
BlueprintName = "ShowcaseUITests"
ReferencedContainer = "container:Showcase.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
Expand All @@ -29,6 +43,18 @@
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "499CD4532AC5B799001AE8E0"
BuildableName = "ShowcaseUITests.xctest"
BlueprintName = "ShowcaseUITests"
ReferencedContainer = "container:Showcase.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand Down
30 changes: 30 additions & 0 deletions Darwin/ShowcaseUITests/NavigationStackPlaygroundUITests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Copyright 2023–2025 Skip
import XCTest

@MainActor
final class NavigationStackPlaygroundUITests: XCTestCase, Sendable {
private var app: XCUIApplication!

override func setUp() async throws {
try await super.setUp()
continueAfterFailure = false
app = XCUIApplication()
app.launchArguments.append("-UITestingResetShowcaseSearch")
app.launch()
}

func testNavigationStackPlaygroundShowsPopButton() throws {
app.tabBars.buttons["Showcase"].tap()

let searchField = app.searchFields.firstMatch
XCTAssertTrue(searchField.waitForExistence(timeout: 5), "Search field should appear on Showcase tab")
searchField.tap()
searchField.typeText("NavigationStack")

let row = app.staticTexts["NavigationStack"]
XCTAssertTrue(row.waitForExistence(timeout: 5), "Filtered list should include NavigationStack")
row.tap()

XCTAssertTrue(app.buttons["Pop"].waitForExistence(timeout: 5), "NavigationStack playground should show Pop button")
}
}
2 changes: 2 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@ let package = Package(
.package(url: "https://source.skip.tools/skip-marketplace.git", "0.2.1"..<"2.0.0"),
.package(url: "https://source.skip.tools/skip-authentication-services.git", "0.0.2"..<"2.0.0"),
.package(url: "https://source.skip.tools/skip-notify.git", "0.1.4"..<"2.0.0"),
.package(path: "../skip-ui-automation"),
],
targets: [
.target(name: "Showcase", dependencies: [
.product(name: "SkipUI", package: "skip-ui"),
.product(name: "SkipUIAutomation", package: "skip-ui-automation"),
.product(name: "SkipAV", package: "skip-av"),
.product(name: "SkipKit", package: "skip-kit"),
.product(name: "SkipSQL", package: "skip-sql"),
Expand Down
Loading
Loading