Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
1cc0801
chore: create input specific spans
exploIF Jan 26, 2026
b483fc1
fix: updating ordered list indexes
exploIF Jan 26, 2026
26647cd
chore: generic parser
exploIF Jan 26, 2026
ec8eaff
Merge remote-tracking branch 'origin/main' into @exploif/common-parse…
exploIF Jan 26, 2026
0704001
Merge remote-tracking branch 'origin/main' into @exploif/common-parse…
exploIF Jan 27, 2026
0931803
Merge branch 'main' into @exploif/common-parser-android
exploIF Jan 27, 2026
2b9fbfa
chore: refactor js structure
exploIF Jan 27, 2026
873b8ad
chore: refactor js structure
exploIF Jan 27, 2026
62ac41b
feat: wip EnrichedText
exploIF Jan 27, 2026
1d664d0
Merge remote-tracking branch 'origin/main' into @exploif/android-enri…
exploIF Jan 27, 2026
f2b75ca
feat: improve example app
exploIF Jan 27, 2026
4b867cb
feat: allow customizing press styles
exploIF Jan 27, 2026
5a14138
feat: tiny example improvement
exploIF Jan 27, 2026
e0b11a1
Merge remote-tracking branch 'origin/main' into @exploif/android-enri…
exploIF Feb 27, 2026
4c1ccb1
chore: resolve conflicts
exploIF Feb 27, 2026
28d4999
Merge branch 'main' into @exploif/android-enriched-text
kacperzolkiewski Apr 2, 2026
2ede83a
Merge branch 'main' into @exploif/android-enriched-text
kacperzolkiewski Apr 7, 2026
d28ae30
Merge branch 'main' into @exploif/android-enriched-text
kacperzolkiewski Apr 15, 2026
b758125
fix: refacto e2e structure
kacperzolkiewski Apr 15, 2026
e8d9a4c
test: add e2e tests for enriched text
kacperzolkiewski Apr 16, 2026
ec23efd
fix: displaying async images
kacperzolkiewski Apr 16, 2026
320c8f2
Update .maestro/enrichedText/flows/mention_press.yaml
kacperzolkiewski Apr 16, 2026
b7bf958
fix: e2e tests
kacperzolkiewski Apr 16, 2026
44359f7
fix: move enriched text styles to defaultHtmlStyle file
kacperzolkiewski Apr 16, 2026
8c1cd9b
fix: make link/mention clickable when selectable is true
kacperzolkiewski Apr 16, 2026
fe00d71
fix: revert changes from EnrichedTextMovementMethod
kacperzolkiewski Apr 16, 2026
b575499
Update android/src/main/java/com/swmansion/enriched/text/EnrichedText…
kacperzolkiewski Apr 17, 2026
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
10 changes: 10 additions & 0 deletions .maestro/enrichedInput/subflows/capture_or_assert_screenshot.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
appId: swmansion.enriched.example
---
- tapOn:
id: 'blur-button'

- runFlow:
file: '../../subflows/capture_or_assert_screenshot.yaml'
env:
ELEMENT_ID: 'editor-input'
SCREENSHOT_PREFIX: 'enrichedInput'
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ appId: swmansion.enriched.example
timeout: 10000

- addMedia:
- "../assets/sample_image.jpg"
- "../../assets/sample_image.jpg"

- tapOn:
id: "image-modal-submit-button"
Expand Down
25 changes: 25 additions & 0 deletions .maestro/enrichedText/flows/custom_styles_display.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
appId: swmansion.enriched.example
---
# Validates that custom styles are displayed correctly
- launchApp

Comment thread
kacperzolkiewski marked this conversation as resolved.
- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: >
<html>
<p><a href="https://www.google.com">Link</a></p>
<p><mention text="@John Doe" indicator="@" id="1" type="user">@John Doe</mention> </p>
<p><img src="https://picsum.photos/id/1/200/200" width="80" height="80"/></p>
</html>

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'custom_styles_display'
39 changes: 39 additions & 0 deletions .maestro/enrichedText/flows/empty_list_elements_display.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
appId: swmansion.enriched.example
tags:
- android-only
---
# Validates that lists with empty items are parsed and displayed correctly
- launchApp

- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: >
<html>
<ol>
<li>First</li>
<li></li>
<li>Third</li>
</ol>
<ul>
<li>First</li>
<li></li>
<li>Third</li>
</ul>
<ul data-type="checkbox">
<li>First</li>
<li></li>
<li>Third</li>
</ul>
</html>

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'empty_list_elements_display'
27 changes: 27 additions & 0 deletions .maestro/enrichedText/flows/inline_styles_display.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
appId: swmansion.enriched.example
tags:
- android-only
---
# Validates that inline styles are displayed correctly
- launchApp

- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: >
<html>
<p>Plain text</p>
<p><b>Bold</b> <i>Italic</i> <u>Underline</u> <s>Strike</s> <code>Code</code> </p>
<p><b><i><u><s>Combined</s></u></i></b></p>
</html>

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'inline_styles_display'
25 changes: 25 additions & 0 deletions .maestro/enrichedText/flows/link_press.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
appId: swmansion.enriched.example
tags:
- android-only
---
# Validates that link press events are triggered correctly
- launchApp

- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: '<html><p><a href="https://www.google.com">Link</a></p></html>'

- tapOn:
text: 'Link'

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'link_press'
25 changes: 25 additions & 0 deletions .maestro/enrichedText/flows/mention_press.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
appId: swmansion.enriched.example
tags:
- android-only
---
# Validates that mention press events are triggered correctly
- launchApp

- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: '<html><p><mention text="@John Doe" indicator="@" id="1" type="user">@John Doe</mention></p></html>'

- tapOn:
text: '@John Doe'

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'mention_press'
45 changes: 45 additions & 0 deletions .maestro/enrichedText/flows/paragraph_styles_display.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
appId: swmansion.enriched.example
tags:
- android-only
---
# Validates that paragraph styles are displayed correctly
- launchApp

- tapOn:
id: 'toggle-screen-button'

- tapOn:
id: 'toggle-enriched-text-screen-button'

- runFlow:
file: '../subflows/set_enriched_text_value.yaml'
env:
VALUE: >
<html>
<h1>Heading 1</h1>
<h2>Heading 2</h2>
<h3>Heading 3</h3>
<h4>Heading 4</h4>
<h5>Heading 5</h5>
<h6>Heading 6</h6>
<codeblock>
<p>Code block</p>
</codeblock>
<blockquote>
<p>Blockquote</p>
</blockquote>
<ul>
<li>Unordered list</li>
</ul>
<ol>
<li>Ordered list</li>
</ol>
<ul data-type="checkbox">
<li>Checkbox list</li>
</ul>
</html>

- runFlow:
file: '../subflows/capture_or_assert_screenshot.yaml'
env:
SCREENSHOT_NAME: 'paragraph_styles_display'
Comment thread
kacperzolkiewski marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
appId: swmansion.enriched.example
---
- runFlow:
file: '../../subflows/capture_or_assert_screenshot.yaml'
env:
ELEMENT_ID: 'enriched-text'
SCREENSHOT_PREFIX: 'enrichedText'
19 changes: 19 additions & 0 deletions .maestro/enrichedText/subflows/set_enriched_text_value.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
appId: swmansion.enriched.example
---

- tapOn:
id: "set-enriched-text-button"

- waitForAnimationToEnd
- extendedWaitUntil:
visible:
id: "value-modal-input"
timeout: 10000

- tapOn:
id: "value-modal-input"

- inputText: ${VALUE}

- tapOn:
id: "value-modal-submit-button"
11 changes: 6 additions & 5 deletions .maestro/scripts/run-tests.sh
Comment thread
kacperzolkiewski marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
# --rebuild Force a rebuild and install, even if the app is
# already installed on the device.
# flow ... One or more Maestro flow files or directories to run.
# Defaults to .maestro/flows if omitted.
# Defaults to all component suites if omitted.
#
# Examples:
# ./run-tests.sh --platform ios
# ./run-tests.sh --platform android --update-screenshots .maestro/flows/core_controls_smoke.yaml
# ./run-tests.sh --platform android --update-screenshots .maestro/enrichedInput/flows/core_controls_smoke.yaml
# ./run-tests.sh --platform ios --rebuild

set -euo pipefail
Expand All @@ -35,7 +35,8 @@ fi

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
SCREENSHOT_ROOT="$REPO_ROOT/.maestro/screenshots"
MAESTRO_ROOT="$REPO_ROOT/.maestro"
SCREENSHOT_ROOT="$MAESTRO_ROOT"
BUNDLE_ID="swmansion.enriched.example"

PLATFORM=""
Expand All @@ -52,7 +53,7 @@ while [ $# -gt 0 ]; do
esac
done

[ -z "$FLOWS" ] && FLOWS=".maestro/flows"
[ -z "$FLOWS" ] && FLOWS=".maestro/enrichedInput/flows .maestro/enrichedText/flows"

case "$PLATFORM" in
ios) SETUP="$SCRIPT_DIR/setup-ios-simulator.sh" ;;
Expand Down Expand Up @@ -93,7 +94,7 @@ esac

# Maestro resolves addMedia paths by walking the workspace inputs. Since assets
# live outside the flows directory, always include it so media files are found.
ASSETS_DIR=".maestro/assets"
ASSETS_DIR="$MAESTRO_ROOT/assets"
[ -d "$ASSETS_DIR" ] && FLOWS="$ASSETS_DIR $FLOWS"

echo "=== Running maestro tests ==="
Expand Down
11 changes: 4 additions & 7 deletions .maestro/subflows/capture_or_assert_screenshot.yaml
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
appId: swmansion.enriched.example
---
- tapOn:
id: "blur-button"

- runFlow:
when:
true: ${UPDATE_SCREENSHOTS === "true"}
commands:
- takeScreenshot:
path: "${SCREENSHOT_ROOT}/${maestro.platform}/${SCREENSHOT_NAME}"
path: "${SCREENSHOT_ROOT}/${SCREENSHOT_PREFIX}/screenshots/${maestro.platform}/${SCREENSHOT_NAME}"
cropOn:
id: "editor-input"
id: "${ELEMENT_ID}"

- runFlow:
when:
true: ${UPDATE_SCREENSHOTS !== "true"}
commands:
- assertScreenshot:
path: "${SCREENSHOT_ROOT}/${maestro.platform}/${SCREENSHOT_NAME}"
path: "${SCREENSHOT_ROOT}/${SCREENSHOT_PREFIX}/screenshots/${maestro.platform}/${SCREENSHOT_NAME}"
thresholdPercentage: 100
cropOn:
id: "editor-input"
id: "${ELEMENT_ID}"
10 changes: 5 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ yarn test

### E2E tests

We use [Maestro](https://maestro.mobile.dev/) for end-to-end testing. Flows live in `.maestro/flows/` and shared subflows in `.maestro/subflows/`.
We use [Maestro](https://maestro.mobile.dev/) for end-to-end testing. Flows live in `.maestro/enrichedInput/flows/` and `.maestro/enrichedText/flows/`. Shared subflows live in `.maestro/subflows/`, with component-specific subflows in `.maestro/enrichedInput/subflows/` and `.maestro/enrichedText/subflows/`.

#### Prerequisites

Expand Down Expand Up @@ -117,26 +117,26 @@ You can target specific flows or force a rebuild:

```sh
# Run a single flow
yarn test:e2e:ios .maestro/flows/core_controls_smoke.yaml
yarn test:e2e:ios .maestro/enrichedInput/flows/core_controls_smoke.yaml

# Force a fresh build even if the app is already installed
yarn test:e2e:android --rebuild
```

#### Visual regression tests

Some flows compare a screenshot of the editor against a saved baseline in `.maestro/screenshots/`. By default the baseline is asserted. Pass `--update-screenshots` to capture new baselines instead:
Some flows compare a screenshot of the editor against a saved baseline in `.maestro/enrichedInput/screenshots/` or `.maestro/enrichedText/screenshots/`. By default the baseline is asserted. Pass `--update-screenshots` to capture new baselines instead:

```sh
# Update baselines on both platforms
yarn test:e2e:mobile --update-screenshots

# Single platform
yarn test:e2e:ios --update-screenshots
yarn test:e2e:android --update-screenshots .maestro/flows/inline_styles_visual.yaml
yarn test:e2e:android --update-screenshots .maestro/enrichedInput/flows/inline_styles_visual.yaml
```

Always review newly saved screenshots in `.maestro/screenshots/` before committing them.
Always review newly saved screenshots in `.maestro/enrichedInput/screenshots/` and `.maestro/enrichedText/screenshots/` before committing them.

#### Troubleshooting: flaky Android tests on macOS

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
import com.swmansion.enriched.common.ResourceManager
import com.swmansion.enriched.text.EnrichedTextViewManager
import com.swmansion.enriched.textinput.EnrichedTextInputViewManager
import java.util.ArrayList

Expand All @@ -13,6 +14,7 @@ class ReactNativeEnrichedPackage : ReactPackage {
ResourceManager.init(reactContext.applicationContext)
val viewManagers: MutableList<ViewManager<*, *>> = ArrayList()
viewManagers.add(EnrichedTextInputViewManager())
viewManagers.add(EnrichedTextViewManager())
return viewManagers
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ object EnrichedConstants {
// Object Replacement Character
const val ORC = '\uFFFC'
const val ORC_STRING = "\uFFFC"

const val TEXT_DEFAULT_FONT_SIZE = 16f
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ data class MentionStyle(
val color: Int,
val backgroundColor: Int,
val underline: Boolean,
val pressColor: Int? = null,
val pressBackgroundColor: Int? = null,
)
Loading
Loading