From 3df8fb85b2eb49551cde3f667af53b4fb0262bb4 Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Tue, 9 Jun 2026 15:32:12 -0300 Subject: [PATCH 01/23] feat: install react-native-owl --- .github/workflows/visual-regression-ios.yml | 120 +++++++++++ VISUAL_REGRESSION.md | 34 +++ app/owls/OwlRoot.tsx | 76 +++++++ app/owls/fixtures/SmokeFixture.tsx | 169 +++++++++++++++ app/owls/fixtures/index.tsx | 55 +++++ index.js | 8 +- ios/Podfile.lock | 228 ++++++++++---------- owl.config.json | 15 ++ package.json | 7 + pnpm-lock.yaml | 76 +++++++ tests/owl/smoke.owl.tsx | 26 +++ 11 files changed, 699 insertions(+), 115 deletions(-) create mode 100644 .github/workflows/visual-regression-ios.yml create mode 100644 VISUAL_REGRESSION.md create mode 100644 app/owls/OwlRoot.tsx create mode 100644 app/owls/fixtures/SmokeFixture.tsx create mode 100644 app/owls/fixtures/index.tsx create mode 100644 owl.config.json create mode 100644 tests/owl/smoke.owl.tsx diff --git a/.github/workflows/visual-regression-ios.yml b/.github/workflows/visual-regression-ios.yml new file mode 100644 index 00000000000..bdb4aa0d3ee --- /dev/null +++ b/.github/workflows/visual-regression-ios.yml @@ -0,0 +1,120 @@ +name: Visual Regression iOS + +on: + workflow_dispatch: + inputs: + update_baseline: + description: 'Generate fresh baseline images instead of comparing against committed ones' + required: false + type: boolean + default: false + test_path_pattern: + description: 'Optional Owl testPathPattern' + required: false + type: string + test_name_pattern: + description: 'Optional Owl testNamePattern' + required: false + type: string + pull_request: + paths: + - '.github/workflows/visual-regression-ios.yml' + - 'app/owls/**' + - 'tests/owl/**' + - '.owl/baseline/**' + - 'owl.config.json' + - 'index.js' + - 'package.json' + - 'pnpm-lock.yaml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + visual-regression-ios: + if: ${{ github.repository == 'RocketChat/Rocket.Chat.ReactNative' }} + runs-on: macos-26 + timeout-minutes: 60 + env: + USE_OWL: true + RUNNING_E2E_TESTS: true + OWL_DEVICE: iPhone 16 Pro + UPDATE_BASELINE: ${{ github.event_name == 'workflow_dispatch' && inputs.update_baseline || 'false' }} + TEST_PATH_PATTERN: ${{ github.event_name == 'workflow_dispatch' && inputs.test_path_pattern || '' }} + TEST_NAME_PATTERN: ${{ github.event_name == 'workflow_dispatch' && inputs.test_name_pattern || '' }} + + steps: + - name: Checkout repository + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + + - name: Checkout and Setup Node + uses: ./.github/actions/setup-node + + - name: Set up Xcode + uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 + with: + xcode-version: '26.2.0' + + - name: Set up Ruby + uses: ruby/setup-ruby@7372622e62b60b3cb750dcd2b9e32c247ffec26a # v1.302.0 + with: + ruby-version: 2.7.7 + bundler-cache: true + + - name: Cache CocoaPods and derived data + uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 + with: + path: | + ios/Pods + ~/Library/Caches/CocoaPods + ~/.cocoapods/repos + ~/Library/Developer/Xcode/DerivedData + key: visual-regression-ios-${{ runner.os }}-${{ hashFiles('ios/Podfile.lock', 'ios/Podfile') }} + restore-keys: | + visual-regression-ios-${{ runner.os }}- + + - name: Install CocoaPods + run: pnpm pod-install + + - name: Boot simulator + run: | + xcrun simctl boot "$OWL_DEVICE" || true + xcrun simctl bootstatus "$OWL_DEVICE" -b + xcrun simctl spawn booted defaults write -g UIAnimationDragCoefficient -float 10 + + - name: Require committed baselines for compare mode + if: env.UPDATE_BASELINE != 'true' + run: | + test -d .owl/baseline/ios + find .owl/baseline/ios -name '*.png' -print -quit | grep -q . + + - name: Build Owl app + run: pnpm owl:build:ios + + - name: Run Owl tests + shell: bash + run: | + set -euo pipefail + + args=() + if [[ -n "$TEST_PATH_PATTERN" ]]; then + args+=(--testPathPattern "$TEST_PATH_PATTERN") + fi + if [[ -n "$TEST_NAME_PATTERN" ]]; then + args+=(--testNamePattern "$TEST_NAME_PATTERN") + fi + + if [[ "$UPDATE_BASELINE" == "true" ]]; then + pnpm owl:test:update:ios -- "${args[@]}" + else + pnpm owl:test:ios -- "${args[@]}" + fi + + - name: Upload Owl artifacts + if: always() + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: owl-ios-results + path: .owl + retention-days: 7 diff --git a/VISUAL_REGRESSION.md b/VISUAL_REGRESSION.md new file mode 100644 index 00000000000..df9c340170f --- /dev/null +++ b/VISUAL_REGRESSION.md @@ -0,0 +1,34 @@ +# Visual Regression Testing + +This repo now has an isolated `react-native-owl` harness behind `USE_OWL=true`. + +## Local iOS flow + +1. Build the fixture app: + `pnpm owl:build:ios` +2. Generate or refresh baselines: + `pnpm owl:test:update:ios` +3. Compare against committed baselines: + `pnpm owl:test:ios` + +Optional Jest filters can be forwarded to Owl: + +- `pnpm owl:test:ios -- --testPathPattern='tests/owl/smoke.owl.tsx'` +- `pnpm owl:test:ios -- --testNamePattern='expanded fixture state'` + +## Layout + +- `app/owls/` contains the isolated render harness and reusable fixtures. +- `tests/owl/` contains Owl test files. +- `.owl/baseline/ios/` is expected to be committed once baselines are approved. + +## GitHub Actions + +Use `.github/workflows/visual-regression-ios.yml`. + +- `workflow_dispatch` supports `update_baseline=true` to generate fresh baselines and upload them as an artifact. +- Pull requests touching Owl files will run compare mode and require committed iOS baseline images. + +## Current constraint + +Formidable's published Owl docs still state support only up to React Native `0.70.x`. This repo is on React Native `0.81.5`, so treat the integration as experimental until the first end-to-end run is validated in CI and on a local simulator. diff --git a/app/owls/OwlRoot.tsx b/app/owls/OwlRoot.tsx new file mode 100644 index 00000000000..bb6d74dfdff --- /dev/null +++ b/app/owls/OwlRoot.tsx @@ -0,0 +1,76 @@ +import React from 'react'; +import { StatusBar, StyleSheet } from 'react-native'; +import { GestureHandlerRootView } from 'react-native-gesture-handler'; +import RNBootSplash from 'react-native-bootsplash'; +import { SafeAreaProvider } from 'react-native-safe-area-context'; +import { Provider } from 'react-redux'; + +import { setUser } from '../actions/login'; +import { selectServerRequest } from '../actions/server'; +import MessageContext from '../containers/message/Context'; +import { colors } from '../lib/constants/colors'; +import { initStore } from '../lib/store/auxStore'; +import { createMockedStore } from '../reducers/mockedStore'; +import { ThemeContext } from '../theme'; +import { renderOwlFixture } from './fixtures'; + +const styles = StyleSheet.create({ + fill: { + flex: 1 + } +}); + +const baseUrl = 'https://open.rocket.chat'; +const store = createMockedStore(); + +initStore(store); +store.dispatch(selectServerRequest(baseUrl, '8.0.0')); +store.dispatch(setUser({ id: 'abc', username: 'rocket.cat', name: 'Rocket Cat', roles: ['user'] })); + +type Props = { + fixture?: string; +}; + +const OwlRoot = ({ fixture }: Props) => { + React.useEffect(() => { + RNBootSplash.hide({ fade: false }); + }, []); + + return ( + + + + {}, + onLongPress: () => {}, + reactionInit: () => {}, + onErrorPress: () => {}, + replyBroadcast: () => {}, + onReactionPress: () => {}, + onDiscussionPress: () => {}, + onReactionLongPress: () => {}, + threadBadgeColor: colors.light.badgeBackgroundLevel1 + }}> + + + {renderOwlFixture(fixture)} + + + + + + ); +}; + +export default OwlRoot; diff --git a/app/owls/fixtures/SmokeFixture.tsx b/app/owls/fixtures/SmokeFixture.tsx new file mode 100644 index 00000000000..5b6652bf098 --- /dev/null +++ b/app/owls/fixtures/SmokeFixture.tsx @@ -0,0 +1,169 @@ +import React from 'react'; +import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native'; + +import { colors } from '../../lib/constants/colors'; + +const styles = StyleSheet.create({ + scrollView: { + flex: 1, + backgroundColor: colors.light.surfaceTint + }, + content: { + padding: 24, + gap: 16 + }, + header: { + gap: 6 + }, + eyebrow: { + color: colors.light.fontInfo, + fontSize: 13, + fontWeight: '700', + letterSpacing: 1, + textTransform: 'uppercase' + }, + title: { + color: colors.light.fontTitlesLabels, + fontSize: 28, + fontWeight: '700' + }, + subtitle: { + color: colors.light.fontSecondaryInfo, + fontSize: 16, + lineHeight: 24 + }, + card: { + backgroundColor: colors.light.surfaceRoom, + borderColor: colors.light.strokeExtraLight, + borderRadius: 20, + borderWidth: 1, + padding: 20, + gap: 16 + }, + cardHeader: { + gap: 8 + }, + cardTitle: { + color: colors.light.fontTitlesLabels, + fontSize: 20, + fontWeight: '700' + }, + cardBody: { + color: colors.light.fontDefault, + fontSize: 15, + lineHeight: 22 + }, + statsRow: { + flexDirection: 'row', + gap: 12 + }, + stat: { + flex: 1, + backgroundColor: colors.light.surfaceHover, + borderRadius: 14, + padding: 12 + }, + statLabel: { + color: colors.light.fontHint, + fontSize: 12, + fontWeight: '600', + textTransform: 'uppercase' + }, + statValue: { + color: colors.light.fontTitlesLabels, + fontSize: 20, + fontWeight: '700', + marginTop: 6 + }, + cta: { + alignItems: 'center', + backgroundColor: colors.light.buttonBackgroundPrimaryDefault, + borderRadius: 14, + paddingHorizontal: 16, + paddingVertical: 14 + }, + ctaPressed: { + backgroundColor: colors.light.buttonBackgroundPrimaryPress + }, + ctaLabel: { + color: colors.light.buttonFontPrimary, + fontSize: 16, + fontWeight: '700' + }, + expandedPanel: { + backgroundColor: colors.light.statusBackgroundInfo, + borderRadius: 14, + padding: 16, + gap: 8 + }, + expandedTitle: { + color: colors.light.statusFontInfo, + fontSize: 16, + fontWeight: '700' + }, + expandedBody: { + color: colors.light.fontDefault, + fontSize: 14, + lineHeight: 20 + } +}); + +const stats = [ + { label: 'Alerts', value: '03' }, + { label: 'Unread', value: '12' }, + { label: 'Rooms', value: '128' } +]; + +const SmokeFixture = () => { + const [expanded, setExpanded] = React.useState(false); + + return ( + + + Visual Regression Harness + Rocket.Chat mobile fixture + + This isolated surface is intentionally deterministic so new Owl regressions can land without depending on login, sync or + live server data. + + + + + + Smoke fixture + + Use this as the first committed baseline, then add focused fixtures beside it for each regression under test. + + + + + {stats.map(stat => ( + + {stat.label} + {stat.value} + + ))} + + + setExpanded(value => !value)} + style={({ pressed }) => [styles.cta, (pressed || expanded) && styles.ctaPressed]} + testID='owl-smoke-toggle'> + {expanded ? 'Hide regression details' : 'Show regression details'} + + + {expanded ? ( + + Expanded state + + This second state exists to prove Owl can drive the fixture and compare more than one screenshot in CI. + + + ) : null} + + + ); +}; + +export default SmokeFixture; diff --git a/app/owls/fixtures/index.tsx b/app/owls/fixtures/index.tsx new file mode 100644 index 00000000000..4113b214a68 --- /dev/null +++ b/app/owls/fixtures/index.tsx @@ -0,0 +1,55 @@ +import React from 'react'; +import { StyleSheet, Text, View } from 'react-native'; + +import { colors } from '../../lib/constants/colors'; +import SmokeFixture from './SmokeFixture'; + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + backgroundColor: colors.light.surfaceTint, + padding: 24 + }, + title: { + color: colors.light.fontDanger, + fontSize: 20, + fontWeight: '700', + textAlign: 'center' + }, + body: { + color: colors.light.fontSecondaryInfo, + fontSize: 15, + lineHeight: 22, + marginTop: 8, + textAlign: 'center' + } +}); + +const fixtures = { + smoke: SmokeFixture +}; + +const UnknownFixture = ({ fixture }: { fixture: string }) => ( + + Unknown Owl fixture + {`No visual regression fixture is registered for "${fixture}".`} + +); + +type FixtureName = keyof typeof fixtures; + +export const renderOwlFixture = (fixture?: string): React.ReactNode => { + if (!fixture) { + return ; + } + + const resolvedFixture = fixtures[fixture as FixtureName]; + if (resolvedFixture) { + const ResolvedFixture = resolvedFixture; + return ; + } + + return ; +}; diff --git a/index.js b/index.js index 9c3fd8555b5..d6f49afdd35 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,13 @@ import DeviceInfo from 'react-native-device-info'; import { name as appName } from './app.json'; -if (process.env.USE_STORYBOOK) { +if (process.env.USE_OWL) { + AppRegistry.registerComponent(appName, () => { + const OwlRoot = require('./app/owls/OwlRoot').default; + + return () => ; + }); +} else if (process.env.USE_STORYBOOK) { AppRegistry.registerComponent(appName, () => require('./.rnstorybook/index').default); } else { if (!__DEV__) { diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 651983a6475..d251bccdaf4 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3982,29 +3982,29 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90 - BugsnagReactNative: 2078dec76e54db9f6e687743af45dc3673cb32ab - BVLinearGradient: 7815a70ab485b7b155186dd0cc836363e0288cad + BugsnagReactNative: f3c40a61779de6de394e472407b4d14f27d30c1b + BVLinearGradient: 34a999fda29036898a09c6a6b728b0b4189e1a44 DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb - EXApplication: 1e98d4b1dccdf30627f92917f4b2c5a53c330e5f - EXAV: b60fcf142fae6684d295bc28cd7cfcb3335570ea - EXConstants: 805f35b1b295c542ca6acce836f21a1f9ee104d5 - EXNotifications: 983f04ad4ad879b181179e326bf220541e478386 - Expo: 6118272de314ed3d4bc74de3b1229b8f5b324ef1 - ExpoAppleAuthentication: 9413ae9a5e631a424cc04c1b13b0694dbab7d594 - ExpoAsset: f867e55ceb428aab99e1e8c082b5aee7c159ea18 - ExpoCamera: 6a326deb45ba840749652e4c15198317aa78497e - ExpoDevice: 6327c3c200816795708885adf540d26ecab83d1a - ExpoDocumentPicker: 7cd9e71a0f66fb19eb0a586d6f26eee1284692e0 - ExpoFileSystem: 858a44267a3e6e9057e0888ad7c7cfbf55d52063 - ExpoFont: 35ac6191ed86bbf56b3ebd2d9154eda9fad5b509 - ExpoHaptics: d3a6375d8dcc3a1083d003bc2298ff654fafb536 - ExpoImage: 686f972bff29525733aa13357f6691dc90aa03d8 - ExpoKeepAwake: 55f75eca6499bb9e4231ebad6f3e9cb8f99c0296 - ExpoLocalAuthentication: 8a31808565da7af926dd9b595e98594d8b1553b6 - ExpoModulesCore: 91a57f1d109cf53fe58d44fcf6b68a777561549a - ExpoSystemUI: 2ad325f361a2fcd96a464e8574e19935c461c9cc - ExpoVideoThumbnails: 503a79271416c8723f04b55ea4737282513ebe4f - ExpoWebBrowser: 17b064c621789e41d4816c95c93f429b84971f52 + EXApplication: 13420f8139864183f8a04fd6099077bdf8cfb186 + EXAV: c2de1057f4d9b0bcbdd908c6f2dcff48ece36f2b + EXConstants: 6c818a84354d194cb4d5d78990108a7c0f590e30 + EXNotifications: 66e91bc2cde4123b371773fd479bacd3cd699e79 + Expo: 595a1f6bf379ffadd2c19cfcdd1f62a4f130428e + ExpoAppleAuthentication: 31bb6cdc57d7169e5d994fff7ec4b97c62423534 + ExpoAsset: d999f3bbd998a750f3b74cb913229848901b926b + ExpoCamera: 44705f35b32741582d00c69187c8ee59669ed46e + ExpoDevice: 0773c782b055558ca9b40b74aa4a8133a66cd0d2 + ExpoDocumentPicker: 774b0d1f41468f79148e8201afd094ca852e9e42 + ExpoFileSystem: aefcd337b94b874f88752ebefc52813b84992fad + ExpoFont: 26bbea90749b8dd0b69effc9fab54248e684f290 + ExpoHaptics: 7240781406f4563c3f4eb1e72864302a8c643fd0 + ExpoImage: f6bcd30bb98d4c484869668fbc32834bb3ee5bfb + ExpoKeepAwake: 44bf6715bc1d2ddb17afe19d927cd039cda123f0 + ExpoLocalAuthentication: a5d1c60718a852faa1852ef76298d8a167dc99f5 + ExpoModulesCore: e80c5fef91bcdfcbe3acba33ddc53666be4a7fcc + ExpoSystemUI: 4611247a411f231229f7e04449856035bd18ba21 + ExpoVideoThumbnails: 9fccaa03acb8991317d1c26909003ea2bc064d73 + ExpoWebBrowser: 88b116cd378d9609c776c0903fe4070fca461588 fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6 FBLazyVector: 5beb8028d5a2e75dd9634917f23e23d3a061d2aa Firebase: 6a8f201c61eda24e98f1ce2b44b1b9c2caf525cc @@ -4028,109 +4028,109 @@ SPEC CHECKSUMS: libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 MMKV: 1a8e7dbce7f9cad02c52e1b1091d07bd843aefaf MMKVCore: f2dd4c9befea04277a55e84e7812f930537993df - MobileCrypto: 41cd66d5588e979cf95d1ff6ae2eec88eb284ef1 + MobileCrypto: 4065a6dbb9f17ee844a16a47992105ee9485af43 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 - NitroMmkv: 4a2d747ce97a4ae740b3cb3a3853366813faf831 - NitroModules: 18e41c298d86fc753fc754969fa9f84044e70711 + NitroMmkv: c4126230c8e2f1aa47bf03f79aaacd8efcd38427 + NitroModules: 48aec2edf6b27107348200ba5d0cb12c831fe02c PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 - RCT-Folly: 846fda9475e61ec7bcbf8a3fe81edfcaeb090669 + RCT-Folly: 59ec0ac1f2f39672a0c6e6cecdd39383b764646f RCTDeprecation: 5eb1d2eeff5fb91151e8a8eef45b6c7658b6c897 RCTRequired: cebcf9442fc296c9b89ac791dfd463021d9f6f23 RCTTypeSafety: b99aa872829ee18f6e777e0ef55852521c5a6788 React: 914f8695f9bf38e6418228c2ffb70021e559f92f React-callinvoker: 23cd4e33928608bd0cc35357597568b8b9a5f068 - React-Core: 6a0a97598e9455348113bfe4c573fe8edac34469 - React-CoreModules: a88a6ca48b668401b9780e272e2a607e70f9f955 - React-cxxreact: 06265fd7e8d5c3b6b49e00d328ef76e5f1ae9c8b + React-Core: 895a479e2e0331f48af3ad919bece917926a0b7d + React-CoreModules: dfa38212cf3a91f2eb84ccd43d747d006d33449e + React-cxxreact: 7a4e2c77e564792252131e63270f6184d93343b3 React-debug: 29aed758c756956a51b4560223edbd15191ca4c5 - React-defaultsnativemodule: c406bf7cd78036efffb7dec9df469257a1bca58c - React-domnativemodule: 925ea5ff8cb05c68e910057e6349e5898cce00f3 - React-Fabric: 13130d0a70f17e913865b04673ee64603d6c42fe - React-FabricComponents: 1f01ea24a1314bf9abcac4743bb7ad8791336be6 - React-FabricImage: f364dc54fcf8b0ef77192674a009aa4f65b34d75 - React-featureflags: 32217ac18a8c216fc571044186fb04164af72772 - React-featureflagsnativemodule: 9c552bb908a7434baa846002ee1752a77b1a5520 - React-graphics: 3034a698e46e947f74a443e761f1feef742e9d71 - React-hermes: a852be3ab9e1f515e46ba3ea9f48c31d4a9df437 - React-idlecallbacksnativemodule: c43fe1f2221b0548cc366bf15f88efb3b3221bbf - React-ImageManager: 7efd7b19cdfaa3a82482e9e6ac0b56606a3ec271 - React-jserrorhandler: 597057d0b9d158c03e02aa376a4a95f64f46a910 - React-jsi: 7b53959aea60909ac6bbe4dd0bdec6c10d7dc597 - React-jsiexecutor: 19938072af05ade148474bac41e0324a2d733f44 - React-jsinspector: eb6bb244a75cbd56f32767daf2efdb344e2ff10c - React-jsinspectorcdp: 727f37537e9c7ab22b6b86c802d879efae5e2757 - React-jsinspectornetwork: 11d47e644701c58038ef8d7f54a405ddd62b3b16 - React-jsinspectortracing: 8875637e6c65b3b9a3852b006856562e874e7a78 - React-jsitooling: b6e6a2551459a6ef9e1529df2ea981fa27ed3a91 - React-jsitracing: 879e2b2f80dd33d84175989de0a8db5d662505db - React-logger: a913317214a26565cd4c045347edf1bcacb80a3f - React-Mapbuffer: 017336879e2e0fb7537bbc08c24f34e2384c9260 - React-microtasksnativemodule: 63ee6730cec233feab9cdcc0c100dc28a12e4165 - react-native-a11y-order: 20b33ff538af60d8b8a7f7284115a7febc9034d4 - react-native-background-timer: 4638ae3bee00320753647900b21260b10587b6f7 - react-native-cameraroll: ae31ba7ee17d31c5ee05d7bb248742e3af482783 - react-native-cookies: d648ab7025833b977c0b19e142503034f5f29411 - react-native-external-keyboard: db51d3a78d68c1f87fef41c67353a7c0ddbe51dd - react-native-keyboard-controller: c4ca61f44d66c2f8987a7e67e9b78e80dc965c45 - react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187 - react-native-restart: f6f591aeb40194c41b9b5013901f00e6cf7d0f29 - react-native-safe-area-context: 0a3b034bb63a5b684dd2f5fffd3c90ef6ed41ee8 - react-native-slider: 6201419b3e3f7c6b7cf2068e0c01274fa86a1da5 - react-native-webrtc: e8f0ce746353adc2744a2b933645e1aeb41eaa74 - react-native-webview: 83c663c5bdf1357d3e7c00986260cb888ea0e328 - React-NativeModulesApple: cbceb3c4cb726838c461b13802a76cefa6f3476f + React-defaultsnativemodule: ee4e3ca63b29c8b91448a6760d72063196ed0796 + React-domnativemodule: 4d29aad12ebb2b5aa34043e5bdd191a92821f3aa + React-Fabric: 21f78a4856240d39a663a52c452e223c5e412098 + React-FabricComponents: 13fc0ac39a488cea00c83ffa7b16113f024d66e6 + React-FabricImage: 8961abe0372d20679ee093d144aaf5fb1227bf41 + React-featureflags: 018934f958e6b83907e71631599b02144e6b17f4 + React-featureflagsnativemodule: 89fef5751203b7d3cdde43e1e10407983735a4b4 + React-graphics: 1c62dd11f47071482ca90238981f0147cce4089d + React-hermes: 36704d7354fff9c9e3fbb2490e8eeb2ac027f6f0 + React-idlecallbacksnativemodule: 5f7cbecc1479b53e665f2cd6c2af2c21a80d2ffd + React-ImageManager: 4cb6318bb2bcc947106e29f9297a1c24c85a9233 + React-jserrorhandler: 4b9344f5794cfe8946f8752d38094649f53dd3f3 + React-jsi: 3a8c6f94a52033b0cca53c38d9bb568306aa9dc1 + React-jsiexecutor: d7cf79b1c2771c6b21c46691a96dd2e32d4454c7 + React-jsinspector: 651483ea1d79859e0ed21b86e9042b2a3f4d2b40 + React-jsinspectorcdp: c800035023789b8bf32b4f5a4c9003c2dc28ee49 + React-jsinspectornetwork: 249ee46e9de930d773ff6e4726aa8eeb5854b589 + React-jsinspectortracing: 80e251e13a6071607f06f0e39e03d3f2ce2645cb + React-jsitooling: 6ce395671d0139ec1c4721953a4d3d92172fc06f + React-jsitracing: 4a4d89334b14d96de0387876751528433d1d2fbd + React-logger: 8bcfaf06f8c536fb9e9760526cf3d17ccd53e4ce + React-Mapbuffer: 4649384414066eb77e30a3124dbb48732a3aa173 + React-microtasksnativemodule: e39f94cc96d61b8174a5cfb2d5862a73fa8c0d35 + react-native-a11y-order: b8de113a5775cc77e0c60574a6779d9aa6f3110c + react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe + react-native-cameraroll: aa5f6fe38b5574f1066a37ceaad5ece494a157a5 + react-native-cookies: f54fcded06bb0cda05c11d86788020b43528a26c + react-native-external-keyboard: 70a377298bf484a159a76de4debd951a82d0ff87 + react-native-keyboard-controller: ef239acc614d5d520b07853be6bfa6e87b7770db + react-native-netinfo: f0a9899081c185db1de5bb2fdc1c88c202a059ac + react-native-restart: 733a51ad137f15b0f8dc34c4082e55af7da00979 + react-native-safe-area-context: fea29ae0275beaa22f72d0a8be1eb0ab09c3feae + react-native-slider: 99493fd3e7254ea482be59fbd94467e737d2b849 + react-native-webrtc: b5062b745a26c99835efdf0d6c027c9b2ee7ddbc + react-native-webview: 21fdd62caca650645e429b4a84941626612616ef + React-NativeModulesApple: 8ce162c145e6b9767bb37a090c77d3d28f7d32b5 React-oscompat: eb0626e8ba1a2c61673c991bf9dc21834898475d - React-perflogger: 509e1f9a3ee28df71b0a66de806ac515ce951246 - React-performancetimeline: 9ce28cce1cded27410c293283f99fe62bebdb920 + React-perflogger: d0d0d1b884120fa0a13bd38ac5e9c3c8e8bfe82a + React-performancetimeline: ae60fb7a7447c44d4d3227fc4eeba606403aaee3 React-RCTActionSheet: 30fe8f9f8d86db4a25ff34595a658ecd837485fc - React-RCTAnimation: 3126eb1cb8e7a6ca33a52fd833d8018aa9311af1 - React-RCTAppDelegate: b03981c790aa40cf26e0f78cc0f1f2df8287ead4 - React-RCTBlob: 53c35e85c85d6bdaa55dc81a0b290d4e78431095 - React-RCTFabric: 59ad9008775f123019c508efff260594a8509791 - React-RCTFBReactNativeSpec: 82b605ab4f6f8da0a7ad88641161df5a0bafb1fb - React-RCTImage: 074b2faa71a152a456c974e118b60c9eeda94a64 - React-RCTLinking: e5ca17a4f7ae2ad7b0c0483be77e1b383ecd0a8a - React-RCTNetwork: c508d7548c9eceac30a8100a846ea00033a03366 - React-RCTRuntime: 6979568c0bc276fe785e085894f954fa15e0ec7e - React-RCTSettings: dd84c857a4fce42c1e08c1dabcda894e25af4a6e - React-RCTText: 6e4b177d047f98bccb90d6fb1ebdd3391cf8b299 - React-RCTVibration: 9572d4a06a0c92650bcc62913e50eb2a89f19fb6 + React-RCTAnimation: e86dacf8a982f42341a44ec87ea8a30964a15f9f + React-RCTAppDelegate: d7214067e796732b5d22960270593945f1ab8a14 + React-RCTBlob: af1fc227a5aa55564afbe84530a8bd28834fda15 + React-RCTFabric: 8d92e851cc6cdf9771c52a18b144424c92b72082 + React-RCTFBReactNativeSpec: c9ec2130e3c9366d30a85886e1776210054763f5 + React-RCTImage: 70a10a5b957ca124b8d0b0fdeec369f11194782c + React-RCTLinking: 67f8a024192b4844c40ace955c54bb34f40d47f0 + React-RCTNetwork: a7679ee67e7d34797a00cefaa879a3f9ea8cee9c + React-RCTRuntime: 3d25c69970924b597c339aead60168026d7cbc2c + React-RCTSettings: 18d8674195383c4fd51b9fc98ee815b329fba7e4 + React-RCTText: 125574af8e29d0ceb430cbe2a03381d62ba45a47 + React-RCTVibration: e96d43017757197d46834c50a0acfb78429c9b30 React-rendererconsistency: a7b47f8b186af64ff8509c8caec4114a2f1ae63f - React-renderercss: 9845c5063b3a2d0462ed4e4c7fc34219a5d608ed - React-rendererdebug: 3905e346c06347b86c6e49d427062cdd638a3044 - React-RuntimeApple: 97233caf2b635c40819bf5be38d818777f8229ab - React-RuntimeCore: dc41f86fcdf1fbb42a5b8388a29bf59dfa56b2f8 - React-runtimeexecutor: d16d045faaf6cd7de8d1aa8e31a51c13d8db84a4 - React-RuntimeHermes: 5a9d132554c8d6b416d794cd4ac7d927b2f88f7b - React-runtimescheduler: 689d805d43c28b8fb1ab390914e042d10e2ea2ab - React-timing: c39eeb992274aeaeb9f4666dc97a36a31d33fe94 - React-utils: 2f9ba0088251788ad66aa1855ff99ed2424024d2 - ReactAppDependencyProvider: 1bcd3527ac0390a1c898c114f81ff954be35ed79 - ReactCodegen: 7fadc30654a54b3a0d62df08f55e2211e25486ee - ReactCommon: 6d0fa86a4510730da7c72560e0ced14258292ab9 - ReactNativeIncallManager: dccd3e7499caa3bb73d3acfedf4fb0360f1a87d5 - RNBootSplash: 7fcc9a58ae343aeb1a1dd49f9030832fe432c544 - RNCallKeep: 1930a01d8caf48f018be4f2db0c9f03405c2f977 - RNCAsyncStorage: fd44f4b03e007e642e98df6726737bc66e9ba609 - RNCClipboard: e560338bf6cc4656a09ff90610b62ddc0dbdad65 - RNCMaskedView: d707a83784c67099b54b37d056ababb2767ce15e - RNConfigReader: 27bab37cca5e6b87766ffd73b8b8818ee46e3416 - RNCPicker: 35fc66f352403cdfe99d53b541f5180482ca2bc5 - RNDateTimePicker: ca1dc7e24d0b4839877f0ab619e7bca5db715289 - RNDeviceInfo: 900bd20e1fd3bfd894e7384cc4a83880c0341bd3 - RNFBAnalytics: 2e8b8ffcd2bb3d59a43ecbe09571c73c56edef7a - RNFBApp: a448037d2df74af9d374a0b765be12ff1e844dc0 - RNFBCrashlytics: c3bb5533f9957eddc88f3ea383583309a4ce9f89 - RNFileViewer: f9424017fa643c115c1444e11292e84fb16ddd68 - RNGestureHandler: b8d2e75c2e88fc2a1f6be3b3beeeed80b88fa37d - RNImageCropPicker: 0a63af4b79e514c1edd6c3152f19300c5ed85312 - RNLocalize: ca86348d88b9a89da0e700af58d428ab3f343c4e - RNReanimated: e1690cdd7f215cfb96a3b7986b81889867dfdb4f - RNScreens: 2e9c41cd099b1ca50136af8d57c3594214d0086a - RNSVG: 94a1be05fab4043354bcf7104f0f9b0e2231ef05 - RNTrueSheet: 53f29088da313dabff8b81d7c4d52afd8e609cfa - RNWorklets: ab618bf7d1c7fd2cb793b9f0f39c3e29274b3ebf + React-renderercss: 0a5b6b7aefc3f5e46a61b0e41b1179a0750cf077 + React-rendererdebug: 7da01af21ab31661c3040ef647e6e2bc55575771 + React-RuntimeApple: 788ca3b8e5485a46654e8a316d4c1e40bf82c5d4 + React-RuntimeCore: 1730e6e5cba6f0af4e0319f891da6426b491e39f + React-runtimeexecutor: 79894322e55268854dc04ff1bee083f24725f6c8 + React-RuntimeHermes: 86bf03cbf11ef05803a2e32087667c8a3cc45f72 + React-runtimescheduler: 70601d598a8a71582fa69a9ba488a27c5d12790d + React-timing: 5717558f0bea206d7557df53015ee9efe1eb57b2 + React-utils: 55e54e497e3d3f373ebfcf844eb77e24ed013356 + ReactAppDependencyProvider: c277c5b231881ad4f00cd59e3aa0671b99d7ebee + ReactCodegen: d4cfdf9ed5667b032f0805c241892dac25d0e438 + ReactCommon: 5cfd842fcd893bb40fc835f98fadc60c42906a20 + ReactNativeIncallManager: 65a85aed033c1d9ec66f98a943cca51c61a210e9 + RNBootSplash: d8407c268d5159ea026dc741ec867ebbe4708f25 + RNCallKeep: 94bbe46b807ccf58e9f6ec11bc4d6087323a1954 + RNCAsyncStorage: 8857fb173af29664cb90897903902dc8533e36cc + RNCClipboard: 4eea71d801c880175c12f6ab14332ca86fed935f + RNCMaskedView: 8bfc13a356455b15d56114738f4d2a804769c1bf + RNConfigReader: d800c517ac6da93d94df342580584fe029f3cbc2 + RNCPicker: 5ecdf273a7a933dea82838515cc17c402fcf3ff7 + RNDateTimePicker: 05e53e54b95e4e4b7dc1b7141b7749a1daa5e622 + RNDeviceInfo: b899ce37a403a4dea52b7cb85e16e49c04a5b88e + RNFBAnalytics: 9e013537d8aa83f9b46971bb15d43c0ed9eabec2 + RNFBApp: fda4a8b08fe31bea8492808106aa638d1bb595b7 + RNFBCrashlytics: 02234987b4cffb39119af52253bf3d70acec0818 + RNFileViewer: 83cc066ad795b1f986791d03b56fe0ee14b6a69f + RNGestureHandler: 9339994ea5d1ff6ad2679b7d0cc3d49053111369 + RNImageCropPicker: 6fd841bab847a912a03c3c464b44cd19692ca513 + RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b + RNReanimated: 2635ec9d061c5eba3987bcc604443d78f363d3f7 + RNScreens: 871305075ddf1291411b051d86da9e0d9289de02 + RNSVG: 9be2bc57df95a874e8c4b0f7dd71866139f321d2 + RNTrueSheet: 559ba620896714b7518da840f2ae3aa6c8983680 + RNWorklets: daa0a3e7946a9c4042f3a962c87a12dc5bc0badd SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf SDWebImageAVIFCoder: afe194a084e851f70228e4be35ef651df0fc5c57 SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c @@ -4138,7 +4138,7 @@ SPEC CHECKSUMS: simdjson: 7bb9e33d87737cec966e7b427773c67baa4458fe SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 TOCropViewController: 80b8985ad794298fb69d3341de183f33d1853654 - WatermelonDB: 4c846c8cb94eef3cba90fa034d15310163226703 + WatermelonDB: b34772e634f59bb1170214901a5c8841e7334813 Yoga: 1e91d83a5286cfd3b725eade59274c92270540d4 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 diff --git a/owl.config.json b/owl.config.json new file mode 100644 index 00000000000..9ddf3b827af --- /dev/null +++ b/owl.config.json @@ -0,0 +1,15 @@ +{ + "ios": { + "workspace": "ios/RocketChatRN.xcworkspace", + "scheme": "RocketChat", + "configuration": "Release", + "device": "iPhone 16 Pro", + "quiet": true + }, + "android": { + "packageName": "chat.rocket.reactnative", + "buildType": "Release", + "quiet": true + }, + "report": true +} diff --git a/package.json b/package.json index 568a7b80ccf..b806fb7e3bd 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,12 @@ "start": "react-native start", "test": "TZ=UTC jest", "test-update": "TZ=UTC jest --updateSnapshot", + "owl:build:ios": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl build --platform ios", + "owl:test:ios": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl test --platform ios", + "owl:test:update:ios": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl test --platform ios --update", + "owl:build:android": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl build --platform android", + "owl:test:android": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl test --platform android", + "owl:test:update:android": "USE_OWL=true RUNNING_E2E_TESTS=true pnpm exec owl test --platform android --update", "lint": "eslint . && tsc", "prettier-lint": "prettier --write . && pnpm lint", "ios": "npx react-native run-ios", @@ -217,6 +223,7 @@ "prettier": "2.8.8", "react-dom": "19.1.0", "react-native-dotenv": "3.4.8", + "react-native-owl": "1.5.0", "storybook": "~9.0.9", "typescript": "~5.9.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 862110b7d22..1f302d88050 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -538,6 +538,9 @@ importers: react-native-dotenv: specifier: 3.4.8 version: 3.4.8(@babel/runtime@7.25.9) + react-native-owl: + specifier: 1.5.0 + version: 1.5.0(react-native@0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) storybook: specifier: ~9.0.9 version: 9.0.18(@testing-library/dom@10.4.1)(prettier@2.8.8) @@ -3138,6 +3141,9 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ajv@7.2.4: + resolution: {integrity: sha512-nBeQgg/ZZA3u3SYxyaDvpvDtgZ/EZPF547ARgZBrG9Bhu1vKDwAIjtIf+sDtJUKa2zOcEbmRLBRSyMraS/Oy1A==} + ajv@8.18.0: resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} @@ -4821,6 +4827,11 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + harmony-reflect@1.6.2: resolution: {integrity: sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==} @@ -6163,6 +6174,10 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pixelmatch@5.3.0: + resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} + hasBin: true + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -6179,6 +6194,10 @@ packages: resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} engines: {node: '>=4.0.0'} + pngjs@6.0.0: + resolution: {integrity: sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg==} + engines: {node: '>=12.13.0'} + polished@4.3.1: resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} engines: {node: '>=10'} @@ -6513,6 +6532,13 @@ packages: react-native: '*' react-native-gesture-handler: '*' + react-native-owl@1.5.0: + resolution: {integrity: sha512-hk5/TeLp3+DMgzgYsQ4tWFXQfpMCFLcf/9q935oz7KcC9/uMj9y/ktXaCgCXIZ2Mt7mW3b6RXHAq/jfokyx+FA==} + hasBin: true + peerDependencies: + react: ^17 || ^18 + react-native: ^0 + react-native-picker-select@9.0.1: resolution: {integrity: sha512-iIhb82OSH1vqB/HoipvbuX3RCzmeaQmIASlaRbv6X8imNjzh1DH/LaKoF4+DAZJLT0iX7QG79vpwZu8wjWap3Q==} peerDependencies: @@ -7461,6 +7487,11 @@ packages: resolution: {integrity: sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==} deprecated: You are using an outdated version of ua-parser-js. Please update to ua-parser-js v0.7.33 / v1.0.33 / v2.0.0 (or later) to avoid ReDoS vulnerability [CVE-2022-25927](https://github.com/advisories/GHSA-fhg7-m89q-25r3) + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -7685,6 +7716,9 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wordwrapjs@4.0.1: resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} engines: {node: '>=8.0.0'} @@ -11232,6 +11266,13 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ajv@7.2.4: + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + ajv@8.18.0: dependencies: fast-deep-equal: 3.1.3 @@ -13157,6 +13198,15 @@ snapshots: graphemer@1.4.0: {} + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + harmony-reflect@1.6.2: {} has-bigints@1.1.0: {} @@ -14814,6 +14864,10 @@ snapshots: pirates@4.0.7: {} + pixelmatch@5.3.0: + dependencies: + pngjs: 6.0.0 + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -14830,6 +14884,8 @@ snapshots: pngjs@3.4.0: {} + pngjs@6.0.0: {} + polished@4.3.1: dependencies: '@babel/runtime': 7.25.9 @@ -15183,6 +15239,21 @@ snapshots: react-native: 0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0) react-native-gesture-handler: 2.28.0(react-native@0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) + react-native-owl@1.5.0(react-native@0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0): + dependencies: + ajv: 7.2.4 + execa: 5.1.1 + handlebars: 4.7.9 + pixelmatch: 5.3.0 + pngjs: 6.0.0 + react: 19.1.0 + react-native: 0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0) + ws: 8.18.3 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + react-native-picker-select@9.0.1(@react-native-picker/picker@2.11.4(react-native@0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0)): dependencies: '@react-native-picker/picker': 2.11.4(react-native@0.81.5(@babel/core@7.25.9)(@react-native-community/cli@20.0.0(typescript@5.9.3))(@react-native/metro-config@0.81.5(@babel/core@7.25.9))(@types/react@19.1.17)(react@19.1.0))(react@19.1.0) @@ -16264,6 +16335,9 @@ snapshots: ua-parser-js@1.0.2: {} + uglify-js@3.19.3: + optional: true + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -16532,6 +16606,8 @@ snapshots: word-wrap@1.2.5: {} + wordwrap@1.0.0: {} + wordwrapjs@4.0.1: dependencies: reduce-flatten: 2.0.0 diff --git a/tests/owl/smoke.owl.tsx b/tests/owl/smoke.owl.tsx new file mode 100644 index 00000000000..05107219a7d --- /dev/null +++ b/tests/owl/smoke.owl.tsx @@ -0,0 +1,26 @@ +/* eslint-env jest */ + +import { press, reload, takeScreenshot, toExist } from 'react-native-owl'; + +jest.setTimeout(60000); + +describe('Owl smoke fixture', () => { + beforeEach(async () => { + await reload(); + }); + + it('matches the default fixture state', async () => { + const screen = await takeScreenshot('smoke-initial'); + + expect(screen).toMatchBaseline(); + }); + + it('matches the expanded fixture state', async () => { + await press('owl-smoke-toggle'); + await toExist('owl-smoke-expanded'); + + const screen = await takeScreenshot('smoke-expanded'); + + expect(screen).toMatchBaseline(); + }); +}); From 855d8c1d36e5394f120ff523ef9d3a9f8456e2ce Mon Sep 17 00:00:00 2001 From: OtavioStasiak Date: Tue, 9 Jun 2026 18:13:45 -0300 Subject: [PATCH 02/23] fix: blank space on actionSheet --- app/owls/fixtures/ActionSheetsFixture.tsx | 110 ++++++++++++++++++ app/owls/fixtures/index.tsx | 4 +- app/views/DirectoryView/Options.tsx | 4 +- .../MediaAutoDownloadView/ListPicker.tsx | 7 +- .../RoomsListView/components/ServersList.tsx | 5 +- .../ListPicker.tsx | 2 +- tests/owl/actionSheets.owl.tsx | 50 ++++++++ 7 files changed, 170 insertions(+), 12 deletions(-) create mode 100644 app/owls/fixtures/ActionSheetsFixture.tsx create mode 100644 tests/owl/actionSheets.owl.tsx diff --git a/app/owls/fixtures/ActionSheetsFixture.tsx b/app/owls/fixtures/ActionSheetsFixture.tsx new file mode 100644 index 00000000000..bc567628782 --- /dev/null +++ b/app/owls/fixtures/ActionSheetsFixture.tsx @@ -0,0 +1,110 @@ +import React from 'react'; +import { ScrollView, StyleSheet, Text, View } from 'react-native'; + +import { ActionSheetProvider, useActionSheet } from '../../containers/ActionSheet'; +import Button from '../../containers/Button'; +import { colors } from '../../lib/constants/colors'; +import DirectoryOptions from '../../views/DirectoryView/Options'; +import MediaAutoDownloadListPicker from '../../views/MediaAutoDownloadView/ListPicker'; +import ServersList from '../../views/RoomsListView/components/ServersList'; +import UserNotificationPreferencesListPicker from '../../views/UserNotificationPreferencesView/ListPicker'; + +const styles = StyleSheet.create({ + scrollView: { + flex: 1, + backgroundColor: colors.light.surfaceTint + }, + content: { + padding: 24, + gap: 16 + }, + title: { + color: colors.light.fontTitlesLabels, + fontSize: 22, + fontWeight: '700' + }, + subtitle: { + color: colors.light.fontSecondaryInfo, + fontSize: 15, + lineHeight: 22 + }, + pickerCard: { + backgroundColor: colors.light.surfaceRoom, + borderColor: colors.light.strokeExtraLight, + borderRadius: 12, + borderWidth: 1, + overflow: 'hidden' + } +}); + +/** + * Renders the four action sheets that share the bottom safe-area spacing fix + * (ServersList, DirectoryView options, and the Media-auto-download & + * User-notification-preferences list pickers). Each trigger lives on the same + * screen so a single Owl build can drive every sheet; the test opens them one + * at a time and screenshots the presented native sheet. + */ +const Triggers = () => { + const { showActionSheet } = useActionSheet(); + + return ( + + Action sheet safe-area fixtures + + Each control below opens one of the action sheets affected by the bottom safe-area spacing change. + + +