Skip to content

Commit b4c762f

Browse files
hejsztynxkacperzolkiewskiszydlovsky
authored
feat: allowFontScaling prop (#620)
# Summary Thanks for the feature suggestion in this [issue](#492)! Implemented a `allowFontScaling` prop - when set to `true`, the font size will be scaled to satisfy the system's accessibility font size settings (default behaviour) - when set to `false`, it works independently of the current settings ## Videos `EnrichedTextInput` https://github.com/user-attachments/assets/a9fbac99-bc35-41b8-9965-f04539bfce3b `EnrichedText` https://github.com/user-attachments/assets/11469ae4-852e-48da-a43c-9800064a0e1b ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ✅ | ## Checklist - [x] E2E tests are passing - [x] Required E2E tests have been added (if applicable) --------- Co-authored-by: Kacper Żółkiewski <74975508+kacperzolkiewski@users.noreply.github.com> Co-authored-by: Mikołaj Szydłowski <9szydlowski9@gmail.com>
1 parent a253348 commit b4c762f

33 files changed

Lines changed: 421 additions & 56 deletions
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
appId: swmansion.enriched.example
2+
tags:
3+
- accessibility
4+
---
5+
- launchApp
6+
7+
- tapOn:
8+
id: "toggle-screen-button"
9+
10+
- runFlow:
11+
file: "../subflows/capture_or_assert_screenshot.yaml"
12+
env:
13+
SCREENSHOT_NAME: "font_scaling_placeholder"
14+
15+
- tapOn:
16+
id: "editor-input"
17+
18+
- inputText: "Plain "
19+
20+
- tapOn:
21+
id: "toolbar-bold"
22+
- inputText: "bold"
23+
- tapOn:
24+
id: "toolbar-bold"
25+
- inputText: " "
26+
27+
- tapOn:
28+
id: "toolbar-italic"
29+
- inputText: "italic"
30+
- tapOn:
31+
id: "toolbar-italic"
32+
- inputText: " "
33+
34+
- tapOn:
35+
id: "toolbar-underline"
36+
- inputText: "underline"
37+
- tapOn:
38+
id: "toolbar-underline"
39+
- inputText: " "
40+
41+
- tapOn:
42+
id: "toolbar-strikethrough"
43+
- inputText: "strike-through"
44+
- tapOn:
45+
id: "toolbar-strikethrough"
46+
- inputText: " "
47+
48+
- tapOn:
49+
id: "toolbar-inline-code"
50+
- inputText: "code"
51+
- tapOn:
52+
id: "toolbar-inline-code"
53+
54+
- runFlow:
55+
file: "../subflows/capture_or_assert_screenshot.yaml"
56+
env:
57+
SCREENSHOT_NAME: "font_scaling"
20.5 KB
Loading
8.66 KB
Loading
35.2 KB
Loading
14.1 KB
Loading
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
appId: swmansion.enriched.example
2+
tags:
3+
- accessibility
4+
---
5+
# Validates that text alignment is displayed correctly
6+
- launchApp
7+
8+
- tapOn:
9+
id: 'toggle-screen-button'
10+
11+
- tapOn:
12+
id: 'toggle-enriched-text-screen-button'
13+
14+
- runFlow:
15+
file: '../subflows/set_enriched_text_value.yaml'
16+
env:
17+
VALUE: >
18+
<html>
19+
<p>Example</p>
20+
<p>Text</p>
21+
<h6>Heading 6</h6>
22+
<ol>
23+
<li>Element 1</li>
24+
<li>Element 2</li>
25+
</ol>
26+
</html>
27+
28+
- scroll
29+
30+
- runFlow:
31+
file: '../subflows/capture_or_assert_screenshot.yaml'
32+
env:
33+
SCREENSHOT_NAME: 'font_scaling'
27.4 KB
Loading
45.7 KB
Loading

.maestro/scripts/run-tests.sh

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,25 @@ app_installed() {
7171
fi
7272
}
7373

74+
# Adjusts the system's text-size setting.
75+
set_font_scale() {
76+
case "$1" in
77+
default) ios_size="large"; android_scale="1.0" ;;
78+
large) ios_size="accessibility-large"; android_scale="1.5" ;;
79+
*) echo "set_font_scale: unknown size '$1'" >&2; return 1 ;;
80+
esac
81+
if [ "$PLATFORM" = ios ]; then
82+
xcrun simctl ui "$DEVICE_ID" content_size "$ios_size"
83+
else
84+
adb -s "$DEVICE_ID" shell settings put system font_scale "$android_scale"
85+
fi
86+
}
87+
88+
# Guarantees the font scale is restored on any exit.
89+
# Without this, the accessibility tests below would leave the device
90+
# in a scaled-up state.
91+
trap 'set_font_scale default' EXIT
92+
7493
if [ -n "$REBUILD" ] || ! app_installed; then
7594
[ -n "$REBUILD" ] && echo "=== rebuild requested, building and installing ==="
7695
[ -z "$REBUILD" ] && echo "=== App ($BUNDLE_ID) not found, building and installing ==="
@@ -97,6 +116,50 @@ esac
97116
ASSETS_DIR="$MAESTRO_ROOT/assets"
98117
[ -d "$ASSETS_DIR" ] && FLOWS="$ASSETS_DIR $FLOWS"
99118

119+
# A previous run could have died before its EXIT trap fired (e.g. SIGKILL),
120+
# leaving the device scaled. Force a known state before the normal tests.
121+
set_font_scale default
122+
123+
# maestro exits non-zero when the tag filter matches zero flows. That's not a
124+
# real failure for us (e.g. running a single flow that has no accessibility
125+
# variant), and letting it propagate aborts latter test suites.
126+
run_maestro() {
127+
local tmp rc
128+
tmp=$(mktemp)
129+
# `script` allocates a pseudo-TTY so maestro keeps
130+
# ANSI colors when piped through `tee`.
131+
if [[ "$OSTYPE" == darwin* ]]; then
132+
script -q /dev/null maestro test "$@" 2>&1 | tee "$tmp"
133+
else
134+
local cmd
135+
cmd=$(printf '%q ' maestro test "$@")
136+
script -qc "$cmd" /dev/null 2>&1 | tee "$tmp"
137+
fi
138+
rc=${PIPESTATUS[0]}
139+
if [ "$rc" -ne 0 ] && grep -q "did not match any Flows" "$tmp"; then
140+
echo "warn: no flows matched the tag filter — treating as success" >&2
141+
rc=0
142+
fi
143+
rm -f "$tmp"
144+
return "$rc"
145+
}
146+
147+
set +e
148+
100149
echo "=== Running maestro tests ==="
101150
# shellcheck disable=SC2086
102-
maestro test --device "$DEVICE_ID" $EXTRA $FLOWS
151+
run_maestro --device "$DEVICE_ID" --exclude-tags accessibility $EXTRA $FLOWS
152+
EXIT_REGULAR=$?
153+
154+
# These are the tests that require changing the system's settings
155+
# - something maestro cannot run internally
156+
echo "=== Running maestro accessibility tests ==="
157+
set_font_scale large
158+
159+
# shellcheck disable=SC2086
160+
run_maestro --device "$DEVICE_ID" --include-tags accessibility $EXTRA $FLOWS
161+
EXIT_A11Y=$?
162+
163+
set -e
164+
165+
exit $(( EXIT_REGULAR != 0 || EXIT_A11Y != 0 ))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.swmansion.enriched.common
2+
3+
import com.facebook.react.bridge.ReadableMap
4+
import com.facebook.react.uimanager.PixelUtil
5+
6+
internal const val ALLOW_FONT_SCALING_PROP = "allowFontScaling"
7+
8+
// Converts a logical font-unit value to pixels.
9+
// Respects the system font scaling, depending on the `allowFontScaling` value
10+
internal fun pixelFromSpOrDp(
11+
value: Float,
12+
allowFontScaling: Boolean,
13+
): Float =
14+
if (allowFontScaling) {
15+
PixelUtil.toPixelFromSP(value)
16+
} else {
17+
PixelUtil.toPixelFromDIP(value)
18+
}
19+
20+
internal fun pixelFromSpOrDp(
21+
value: Double,
22+
allowFontScaling: Boolean,
23+
): Float =
24+
if (allowFontScaling) {
25+
PixelUtil.toPixelFromSP(value)
26+
} else {
27+
PixelUtil.toPixelFromDIP(value)
28+
}
29+
30+
// Reads allowFontScaling from a serialized prop map (used in MeasurementStore
31+
// where no view instance is available yet).
32+
internal fun allowFontScalingFromProps(props: ReadableMap?): Boolean {
33+
if (props == null) return EnrichedConstants.ALLOW_FONT_SCALING_DEFAULT
34+
if (!props.hasKey(ALLOW_FONT_SCALING_PROP) || props.isNull(ALLOW_FONT_SCALING_PROP)) return EnrichedConstants.ALLOW_FONT_SCALING_DEFAULT
35+
return props.getBoolean(ALLOW_FONT_SCALING_PROP)
36+
}

0 commit comments

Comments
 (0)