Skip to content
Merged
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
87 changes: 87 additions & 0 deletions Scripts/embed-runner-icon.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash
# Embed the WDA app icon into the wrapping XCTRunner host app so the
# installed WebDriverAgent shows the Appium logo on the iOS home screen
# instead of a blank icon.
#
# Apple's USES_XCTRUNNER auto-generates a Runner.app around UI-testing
# .xctest bundles but does not inherit icons from the test bundle's
# asset catalog. actool produces AppIcon*.png + Assets.car inside
# PlugIns/<product>.xctest/ where iOS never looks. This script lifts
# them up to the Runner.app root and patches Info.plist accordingly.
#
# Limitations:
# - Touches XCTRunner internals; may need updates across Xcode versions.
# - iOS only; tvOS uses different "Brand Assets" and is not handled.
# - Cloud device farms that re-sign WDA must preserve these changes.

set -euo pipefail

RUNNER_APP="${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}-Runner.app"
XCTEST="${RUNNER_APP}/PlugIns/${PRODUCT_NAME}.xctest"

if [ ! -d "$RUNNER_APP" ]; then
echo "warning: ${PRODUCT_NAME}-Runner.app not found at $RUNNER_APP; skipping icon embed"
exit 0
fi

if [ ! -d "$XCTEST" ]; then
echo "warning: ${PRODUCT_NAME}.xctest not found inside Runner.app; skipping icon embed"
exit 0
fi

shopt -s nullglob
ICONS=("$XCTEST"/AppIcon*.png)
if [ ${#ICONS[@]} -eq 0 ]; then
echo "warning: no compiled AppIcon*.png found inside $XCTEST; skipping icon embed"
exit 0
fi

cp -f "${ICONS[@]}" "$RUNNER_APP/"
if [ -f "$XCTEST/Assets.car" ]; then
cp -f "$XCTEST/Assets.car" "$RUNNER_APP/"
fi

PLIST="$RUNNER_APP/Info.plist"
/usr/libexec/PlistBuddy -c "Delete :CFBundleIcons" "$PLIST" 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Delete :CFBundleIcons~ipad" "$PLIST" 2>/dev/null || true

/usr/libexec/PlistBuddy -c "Add :CFBundleIcons dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons:CFBundlePrimaryIcon dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconName string AppIcon" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles array" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons:CFBundlePrimaryIcon:CFBundleIconFiles:0 string AppIcon60x60" "$PLIST"

/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad:CFBundlePrimaryIcon dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad:CFBundlePrimaryIcon:CFBundleIconName string AppIcon" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad:CFBundlePrimaryIcon:CFBundleIconFiles array" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad:CFBundlePrimaryIcon:CFBundleIconFiles:0 string AppIcon60x60" "$PLIST"
/usr/libexec/PlistBuddy -c "Add :CFBundleIcons~ipad:CFBundlePrimaryIcon:CFBundleIconFiles:1 string AppIcon76x76" "$PLIST"

# Re-codesign since we modified the bundle after Xcode signed it.
# In a scheme post-action context Xcode's CODE_SIGN_* env vars are not exposed,
# so discover the existing signing identity from the already-signed bundle.
if [ -d "$RUNNER_APP/_CodeSignature" ]; then
# Capture the signature info once. Piping codesign straight into
# `awk ... exit` makes awk close the pipe early, killing codesign with
# SIGPIPE -- which `set -o pipefail` turns into a fatal error. That trips
# only when an Authority line exists, i.e. on every real-device build.
SIGN_INFO=$(codesign -dvv "$RUNNER_APP" 2>&1 || true)
EXISTING_IDENT="${EXPANDED_CODE_SIGN_IDENTITY:-}"
if [ -z "$EXISTING_IDENT" ]; then
EXISTING_IDENT=$(awk -F'=' '/^Authority/ {print $2; exit}' <<< "$SIGN_INFO")
fi
# Simulator builds are ad-hoc signed: there is no Authority line, but the
# bundle can still be re-signed ad-hoc with an identity of "-".
if [ -z "$EXISTING_IDENT" ] && grep -q '^Signature=adhoc' <<< "$SIGN_INFO"; then
EXISTING_IDENT="-"
fi
if [ -n "$EXISTING_IDENT" ]; then
codesign --force --sign "$EXISTING_IDENT" \
--preserve-metadata=identifier,entitlements "$RUNNER_APP"
else
echo "warning: bundle is signed but no identity discovered; signature will be invalid"
fi
fi

echo "embedded icon into $RUNNER_APP"
6 changes: 6 additions & 0 deletions WebDriverAgent.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,7 @@
F59CD6D52EF16E5E00F91287 /* XCUIElement+FBCustomActions.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CD6D32EF16E5E00F91287 /* XCUIElement+FBCustomActions.m */; };
F59CD6D62EF16E5E00F91287 /* XCUIElement+FBCustomActions.h in Headers */ = {isa = PBXBuildFile; fileRef = F59CD6D22EF16E5E00F91287 /* XCUIElement+FBCustomActions.h */; };
F59CD6D72EF16E5E00F91287 /* XCUIElement+FBCustomActions.m in Sources */ = {isa = PBXBuildFile; fileRef = F59CD6D32EF16E5E00F91287 /* XCUIElement+FBCustomActions.m */; };
A1B2C3D4E5F600000000001B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A1B2C3D4E5F600000000001A /* Assets.xcassets */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -1368,6 +1369,7 @@
EE9AB7921CAEDF0C008C271F /* FBRuntimeUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FBRuntimeUtils.m; sourceTree = "<group>"; };
EE9AB7FC1CAEE048008C271F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = WebDriverAgentRunner/Info.plist; sourceTree = SOURCE_ROOT; };
EE9AB7FD1CAEE048008C271F /* UITestingUITests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = UITestingUITests.m; path = WebDriverAgentRunner/UITestingUITests.m; sourceTree = SOURCE_ROOT; };
A1B2C3D4E5F600000000001A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = WebDriverAgentRunner/Assets.xcassets; sourceTree = SOURCE_ROOT; };
EE9AB8031CAEE182008C271F /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
EE9B75D41CF7956C00275851 /* IntegrationApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IntegrationApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
EE9B75EC1CF7956C00275851 /* IntegrationTests_1.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = IntegrationTests_1.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -2294,6 +2296,7 @@
children = (
EE9AB7FC1CAEE048008C271F /* Info.plist */,
EE9AB7FD1CAEE048008C271F /* UITestingUITests.m */,
A1B2C3D4E5F600000000001A /* Assets.xcassets */,
);
name = WebDriverAgentRunner;
path = XCTUITestRunner;
Expand Down Expand Up @@ -3110,6 +3113,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
A1B2C3D4E5F600000000001B /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -4346,6 +4350,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = EEE5CABF1C80361500CBBDD9 /* IOSSettings.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_STATIC_ANALYZER_MODE = deep;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTING_SEARCH_PATHS = YES;
Expand Down Expand Up @@ -4399,6 +4404,7 @@
isa = XCBuildConfiguration;
baseConfigurationReference = EEE5CABF1C80361500CBBDD9 /* IOSSettings.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_STATIC_ANALYZER_MODE = deep;
ENABLE_TESTING_SEARCH_PATHS = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<PostActions>
<ExecutionAction
ActionType = "Xcode.IDEStandardExecutionActionsCore.ExecutionActionType.ShellScriptAction">
<ActionContent
title = "Embed app icon into Runner.app"
scriptText = "&quot;${SRCROOT}/Scripts/embed-runner-icon.sh&quot;&#10;">
<EnvironmentBuildable>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "EEF988291C486603005CA669"
BuildableName = "WebDriverAgentRunner.xctest"
BlueprintName = "WebDriverAgentRunner"
ReferencedContainer = "container:WebDriverAgent.xcodeproj">
</BuildableReference>
</EnvironmentBuildable>
</ActionContent>
</ExecutionAction>
</PostActions>
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "icon-1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions WebDriverAgentRunner/Assets.xcassets/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading