Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrating hiccup to pure react component usage (First step) #18574

Closed
wants to merge 7 commits into from

Conversation

flexsurfer
Copy link
Member

@flexsurfer flexsurfer commented Jan 19, 2024

  1. The bottleneck in React Native is the JavaScript engine, as it is single-threaded and involves numerous calculations. If the JavaScript engine is heavily occupied, the application can experience slowdowns and lag. Therefore, we must strive to reduce the number of unnecessary computations.
  2. The combination of React states and reactive atoms does not work very well, resulting in code that is convoluted and inefficient. Therefore, it would be beneficial to rely solely on React states for functionality.

Thus, by transitioning to the exclusive use of React components and states, we will eliminate unnecessary computations of Hiccup markup by Reagent from the JavaScript engine, thereby freeing it up. This approach will also allow us to work solely with React states, removing any confusions.

In this PR new package was introduced

(ns react-native.pure

(defn get-create-element-fn
  [type]
  (fn [& children]
    (let [props (first children)]
      (if (map? props)
        (apply createElement type (reagent.template/convert-prop-value props) (rest children))
        (apply createElement type nil children)))))

(def view (get-create-element-fn View))
(def text (get-create-element-fn Text))

.
.
.

in this implementation, we keep Clojure data structures for props and styles, so the only overhead is converting cljs data to js, but this also was optimized by pre-initializing keys cache

good thing is that new components can be used in the hiccup, so we can migrate gradually

example of component migration

current

    [rn/view
     {:style (style/container circle-size customization-color neutral? theme)}
     [text/text
      {:accessibility-label :wallet-user-avatar
       :size                (:font-size (size properties))
       :weight              (if monospace? :monospace (:font-weight (size properties)))

new

    (rn.pure/view
     {:style (style/container circle-size customization-color neutral? theme)}
     (text/text
      {:accessibility-label :wallet-user-avatar
       :size                (:font-size (size properties))
       :weight              (if monospace? :monospace (:font-weight (size properties)))

so basically the only change is replacing [ with ( , but to remove confusion for now better to use also different namespace for rn components rn.pure

so the next thing is re-frame subscriptions, new functions was introduced in the re-frame utils namespace

(defn use-subscription
  [sub-vec]
  (let [[state set-state] (useState)]
    (useEffect (fn []
                 (let [track (reagent/track! #(set-state @(re-frame/subscribe sub-vec)))]
                   #(reagent/dispose! track)))
               #js [])
    state))

basically, it just updates state when subscriptions is changed

And reactive atoms should be replaced by react states

Example of migration

current implementation

(defn- settings-view-pure
  [_]
  (let [pressed-state? (reagent/atom false)]
  (fn [{:keys [theme]]
  (let [customization-color (rf/sub [:profile/customization-color])
    [rn/touchable-without-feedback
         {:on-press-in         (fn[] (reset! pressed-state? true)

new

(defn- settings-view-pure
  []
  (let [theme               (quo.theme/use-theme)
        customization-color (rf/use-subscription [:profile/customization-color])
        [pressed-state? set-pressed-state] (rn.pure/use-state false)]
    (rn.pure/touchable-without-feedback
     {:on-press-in         (fn [] (set-pressed-state true)

also, notice the theme context usage, now we're using it directly as react context in the components theme (quo.theme/use-theme) , there is a known limitation for now, because our parent components still hiccup we have to create functional component as element for now similar how :f> is used. for example, for settings-views it will look like

(defn view [props] (rn.pure/func settings-view-pure props))

also, one more confusion might be, that it's not possible to use hiccup inside new components, we might have these situations for now while we have a mixed approach, it won't be an issue later. For now most likely place to get this problem is the usage of text component when children are passed as parameters and its a hiccup

So in this PR i wanted to see how it works, and how difficult it will be to migrate our code, and was pretty smooth and simple, and i went pretty deep, but decided to stop, because it's already too many changes for one PR, so I'll continue work in another PR, but will start from migrating root components

One more thing is react native libraries, they also should be migrated, for now i just added pure versions for components in their namespaces for example blur
(def view-pure (rn.pure/get-create-element-fn (.-BlurView blur)))

reanimated (def view-pure (rn.pure/get-create-element-fn (.-View reanimated))) , btw we should look into reanimated separately , probably we could improve it because we don't have hiccup anymore etc

also one thing, svg was migrated and it should work faster now also because no sense to have it in hiccup

Summary: In fact, we are already trying to use react state instead of reagent atoms for local states, so when we discuss not using reagent, the only change for us is to use list instead of vector, is this really such a big deal? honestly i did a lot of work in this PR, and i didn't notice any difference in writing code, highlight is different because its a list now, but probably it's even better because it highlights a component name now

@@ -0,0 +1,29 @@
(ns react-native.pure
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pure components


(def settings-category (quo.theme/with-theme category-internal))
(defn settings-category
[{:keys [label data container-style blur?]}]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example of pure functional component with hooks

@status-im-auto
Copy link
Member

status-im-auto commented Jan 19, 2024

Jenkins Builds

Click to see older builds (46)
Commit #️⃣ Finished (UTC) Duration Platform Result
8835e05 #1 2024-01-19 14:32:46 ~1 min tests 📄log
✔️ 8835e05 #1 2024-01-19 14:37:15 ~6 min ios 📱ipa 📲
✔️ 8835e05 #1 2024-01-19 14:38:35 ~7 min android-e2e 🤖apk 📲
✔️ 8835e05 #1 2024-01-19 14:38:43 ~7 min android 🤖apk 📲
✔️ dba9baa #2 2024-01-23 14:36:53 ~7 min android-e2e 🤖apk 📲
✔️ dba9baa #2 2024-01-23 14:37:19 ~7 min android 🤖apk 📲
✔️ dba9baa #2 2024-01-23 14:37:48 ~8 min ios 📱ipa 📲
7e70401 #3 2024-01-23 14:40:17 ~1 min tests 📄log
✔️ 7e70401 #3 2024-01-23 14:46:36 ~7 min ios 📱ipa 📲
✔️ 7e70401 #3 2024-01-23 14:47:07 ~8 min android-e2e 🤖apk 📲
✔️ 7e70401 #3 2024-01-23 14:47:19 ~8 min android 🤖apk 📲
dd562c5 #4 2024-01-24 10:35:34 ~1 min tests 📄log
✔️ dd562c5 #4 2024-01-24 10:40:27 ~6 min ios 📱ipa 📲
✔️ dd562c5 #4 2024-01-24 10:42:16 ~8 min android 🤖apk 📲
✔️ dd562c5 #4 2024-01-24 10:42:22 ~8 min android-e2e 🤖apk 📲
e561216 #5 2024-01-24 13:14:40 ~5 min tests 📄log
✔️ e561216 #5 2024-01-24 13:16:25 ~6 min android 🤖apk 📲
✔️ e561216 #5 2024-01-24 13:18:26 ~8 min android-e2e 🤖apk 📲
✔️ e561216 #5 2024-01-24 13:18:42 ~9 min ios 📱ipa 📲
✔️ 0282404 #6 2024-01-25 12:32:35 ~6 min tests 📄log
✔️ 0282404 #6 2024-01-25 12:32:45 ~6 min ios 📱ipa 📲
✔️ 0282404 #6 2024-01-25 12:35:09 ~8 min android 🤖apk 📲
✔️ 0282404 #6 2024-01-25 12:35:10 ~8 min android-e2e 🤖apk 📲
✔️ 8e0b80a #7 2024-01-25 13:51:44 ~5 min tests 📄log
✔️ 8e0b80a #7 2024-01-25 13:53:24 ~7 min android-e2e 🤖apk 📲
✔️ 8e0b80a #7 2024-01-25 13:53:39 ~7 min ios 📱ipa 📲
✔️ 8e0b80a #7 2024-01-25 13:54:29 ~8 min android 🤖apk 📲
✔️ 52606eb #8 2024-01-26 12:56:08 ~5 min tests 📄log
✔️ 52606eb #8 2024-01-26 12:57:21 ~6 min ios 📱ipa 📲
✔️ 52606eb #8 2024-01-26 12:58:35 ~7 min android 🤖apk 📲
✔️ 52606eb #8 2024-01-26 13:00:50 ~10 min android-e2e 🤖apk 📲
4e5fc6c #9 2024-01-26 13:34:44 ~1 min tests 📄log
✔️ 4e5fc6c #9 2024-01-26 13:39:53 ~6 min ios 📱ipa 📲
✔️ 4e5fc6c #9 2024-01-26 13:40:22 ~7 min android 🤖apk 📲
✔️ e305612 #10 2024-01-26 13:48:39 ~5 min tests 📄log
✔️ e305612 #10 2024-01-26 13:49:16 ~6 min ios 📱ipa 📲
✔️ e305612 #10 2024-01-26 13:51:50 ~9 min android 🤖apk 📲
✔️ e305612 #10 2024-01-26 13:51:51 ~9 min android-e2e 🤖apk 📲
✔️ cab0f4a #11 2024-01-29 09:43:02 ~5 min tests 📄log
✔️ cab0f4a #11 2024-01-29 09:45:45 ~8 min android 🤖apk 📲
✔️ cab0f4a #11 2024-01-29 09:45:52 ~8 min android-e2e 🤖apk 📲
✔️ cab0f4a #11 2024-01-29 09:46:06 ~9 min ios 📱ipa 📲
✔️ 684e505 #12 2024-01-29 12:22:23 ~5 min tests 📄log
✔️ 684e505 #12 2024-01-29 12:23:24 ~6 min ios 📱ipa 📲
✔️ 684e505 #12 2024-01-29 12:24:53 ~7 min android-e2e 🤖apk 📲
✔️ 684e505 #12 2024-01-29 12:25:15 ~8 min android 🤖apk 📲
Commit #️⃣ Finished (UTC) Duration Platform Result
✔️ 3d8b72b #13 2024-01-29 13:43:50 ~5 min tests 📄log
✔️ 3d8b72b #13 2024-01-29 13:45:17 ~6 min android-e2e 🤖apk 📲
✔️ 3d8b72b #13 2024-01-29 13:45:34 ~7 min android 🤖apk 📲
✔️ 3d8b72b #13 2024-01-29 13:49:42 ~11 min ios 📱ipa 📲
✔️ c950d84 #14 2024-01-30 12:03:35 ~5 min tests 📄log
✔️ c950d84 #14 2024-01-30 12:05:26 ~7 min ios 📱ipa 📲
✔️ c950d84 #14 2024-01-30 12:05:41 ~7 min android-e2e 🤖apk 📲
✔️ c950d84 #14 2024-01-30 12:05:46 ~7 min android 🤖apk 📲

@flexsurfer flexsurfer self-assigned this Jan 19, 2024
@flexsurfer flexsurfer force-pushed the feature/pure-rn-experiment-2 branch 2 times, most recently from dd562c5 to e561216 Compare January 24, 2024 13:09
@flexsurfer flexsurfer changed the title [WIP] pure rn experiment 2 Migrating hiccup to pure react component usage (First step) Jan 25, 2024
@pavloburykh

This comment was marked as resolved.

@clauxx
Copy link
Member

clauxx commented Jan 25, 2024

💯 @flexsurfer! Looks really cool. I like the direction this is going in, specifically the moving away from reagent and using ratoms for local state. There's a few places I noticed where ratoms were passed down to (sometimes very nested) children and updated from there, making it hard to track what caused a state change. I wonder how difficult it might be to migrate such cases.

Also, are there any performance metrics that would show the benefits of the pure approach versus hiccup+reagent? I wonder how much performant it is and what are our current perfomance bottlenecks.

@ilmotta
Copy link
Contributor

ilmotta commented Jan 25, 2024

Thank you for working on this PR @flexsurfer!

I would like to review this PR and experiment with the abstractions you are proposing before judging. But before reviewing, I think this costly decision to migrate away from Reagent should be accompanied by a set of steps for other contributors to reproduce the performance improvements you have measured. The theory you are sharing makes sense, but we need numbers and a way to reproduce them ourselves :)

I think it's not just any % improvement that can justify the changes being proposed. Are we talking 10%, 20% lower times to render on average? Which % would justify abandoning Reagent?

There are other cards on the table IMO before we settle on a solution that can't be easily undone:

  • We could fork Reagent and see where that leads us in an experimental branch. Maybe our improvements could one day be pushed upstream. It was thought for the web, so perhaps there are some low hanging fruits there for us to pick.
  • UIx should still be in our cards. An experimental branch showing the perf improvements compared to Reagent would be perfect. I think I may not like UIx, but it may be actually good in some areas.

@ulisesmac
Copy link
Contributor

Very interesting work @flexsurfer ! I like that the API is similar to what we currently have.

I have a lot of thoughts about dropping Reagent.

Reagent is a very important library for the Clojure community, and we aren't the only ones having problems with it, so I want to share some ideas:

  • As @ilmotta said, we could experiment if we can improve Reagent in a fork. I think the Clojure community will also be too open improve it, so I guess we won't be alone - sometimes I think it's a matter of time until the community pays attention to Reagent again -.
  • In the same idea of improving Reagent, maybe Status can sponsor it throught Clojurists Together? I'm not sure if someone has presented Reagent improvements there.
  • There are some other libraries addressing the Reagent limitations, Helix and UIx are some of them, I don't think we'll enjoy using them but give them a try is important to have a wider perspective.
  • Is really Reagent a significant bottleneck for the performance of Status app? probably it's due to the complexity of the app, probably due to some practices. I wonder if just by dropping Reagent a user will notice the app is faster.

Related to the implementation in this PR:

I have to test it, but just by reading, I believe the Reagent's performance cost is mainly due to:

  1. Hiccup
  2. JS objects -> CLJS maps

We are still suffering by 2, since this implementation is still converting to CLJS maps. Maybe we could try using cljs.bean ( ->js and ->clj)? and also implement the cache of transfromed keys.

It'd be very helpful to check how similar is the performance of this implementation compared to Reagent. So as everyone said, some performance measurements to evaluate if this is the right path are needed.

@flexsurfer
Copy link
Member Author

thanks @pavloburykh , fixed and yes it will definitely will take some time to review this PR ;)

@status-im status-im deleted a comment from status-im-auto Jan 29, 2024
@status-im status-im deleted a comment from status-im-auto Jan 29, 2024
@status-im status-im deleted a comment from status-im-auto Jan 29, 2024
@status-im status-im deleted a comment from status-im-auto Jan 29, 2024
@J-Son89
Copy link
Contributor

J-Son89 commented Jan 29, 2024

and again, you all talking about dramatic significant changes, but they are not, we just replace one wrapper with another, it's not a significant change at all, we still work with react and react native, still clojure, still clojure data structures

For me, the significant changes I am referring is the sheer volume of work to make the proposed changes, not necessarily the type of changes.
This codebase is huge and we've seen numerous occasions where proposed "quick" updates to the codebase turn into migrations that are still incomplete 1 year later. It's just a reality that migrating code takes a long time, particularly in such a big team with demanding priorities. For that reason, it's nice if we can be very sure of the changes we want to make and further minimise the volume of changes made initially so that we can refine out our method before we adopt it in en masse.

@status-im-auto
Copy link
Member

29% of end-end tests have passed

Total executed tests: 48
Failed tests: 33
Expected to fail tests: 1
Passed tests: 14
IDs of failed tests: 702809,702782,702733,703194,702859,702813,703133,704613,702957,702840,703086,702948,702894,702745,702742,704615,702869,702936,702855,703391,702786,702839,702947,702838,702844,702843,702731,702845,702775,702958,703629,703382,702841 
IDs of expected to fail tests: 703503 

Failed tests (33)

Click to expand
  • Rerun failed tests

  • Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_markdown_support, id: 702809
    Test setup failed: critical/chats/test_public_chat_browsing.py:836: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    2. test_community_hashtag_links_to_community_channels, id: 702948

    Test setup failed: critical/chats/test_public_chat_browsing.py:836: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    3. test_community_mentions_push_notification, id: 702786

    # STEP: Send message to contact (need for blocking contact) test
    Device 2: Sending message 'hello'

    Test setup failed: critical/chats/test_public_chat_browsing.py:836: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    Device sessions

    4. test_community_leave, id: 702845

    Test setup failed: critical/chats/test_public_chat_browsing.py:836: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    5. test_community_join_when_node_owner_offline, id: 703629

    Test setup failed: critical/chats/test_public_chat_browsing.py:836: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element 
    

    [[Can't join a community if admin goes offline, https://github.com//issues/17678]]

    Class TestActivityMultipleDevicePRTwo:

    1. test_activity_center_mentions, id: 702957

    Device 2: Joining community
    Device 2: Looking for a message by text: https://status.app/c/

    Test setup failed: activity_center/test_activity_center.py:409: in prepare_devices
        self.community_2.join_community()
    ../views/chat_view.py:435: in join_community
        ChatView(self.driver).chat_element_by_text("https://status.app/c/").click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/')]` is not found on the screen after wait_for_visibility_of_element
    



    Device sessions

    2. test_activity_center_admin_notification_accept_swipe, id: 702958

    Test setup failed: activity_center/test_activity_center.py:409: in prepare_devices
        self.community_2.join_community()
    ../views/chat_view.py:435: in join_community
        ChatView(self.driver).chat_element_by_text("https://status.app/c/").click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/')]` is not found on the screen after wait_for_visibility_of_element
    



    Class TestDeepLinksOneDevice:

    1. test_links_open_universal_links_from_chat, id: 704613

    Device 1: Tap on found: SendMessageButton

    critical/test_deep_and_universal_links.py:39: in test_links_open_universal_links_from_chat
        self.channel.chat_element_by_text(url).click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 1: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/u/G10A4B0JdgwyRww90WXtnP1oNH1ZLQNM0yX0Ja9YyAMjrqSZIYINOHCbFhrnKRAcPGStPxCMJDSZlGCKzmZrJcimHY8BbcXlORrElv_BbQEegnMDPx1g9C5VVNl0fE4y#zQ3shwQPhRuDJSjVGVBnTjCdgXy5i9WQaeVPdGJD6yTarJQSj')]` is not found on the screen after wait_for_visibility_of_element; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    2. test_links_deep_links, id: 702775

    Device 1: Could not reach home view by pressing system back button
    Device 1: Find BrowserTab by accessibility id: browser-stack-tab

    critical/test_deep_and_universal_links.py:75: in test_links_deep_links
        self.home.browser_tab.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 1: BrowserTab by accessibility id: `browser-stack-tab` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    Class TestActivityMultipleDevicePR:

    1. test_navigation_jump_to, id: 702936

    Device 2: Joining community
    Device 2: Looking for a message by text: https://status.app/c/

    Test setup failed: activity_center/test_activity_center.py:270: in prepare_devices
        self.community_2.join_community()
    ../views/chat_view.py:435: in join_community
        ChatView(self.driver).chat_element_by_text("https://status.app/c/").click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/')]` is not found on the screen after wait_for_visibility_of_element
    



    Device sessions

    2. test_activity_center_reply_read_unread_delete_filter_swipe, id: 702947

    Test setup failed: activity_center/test_activity_center.py:270: in prepare_devices
        self.community_2.join_community()
    ../views/chat_view.py:435: in join_community
        ChatView(self.driver).chat_element_by_text("https://status.app/c/").click_on_link_inside_message_body()
    ../views/chat_view.py:193: in click_on_link_inside_message_body
        self.message_body.wait_for_visibility_of_element(30)
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 2: Text by xpath:`//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/')]` is not found on the screen after wait_for_visibility_of_element
    



    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_emoji_send_reply_and_open_link, id: 702782

    Device 1: Tap on found: SendMessageButton
    Device 2: Looking for a message by text: Test with link: https://status.im/ here should be nothing unusual.

    critical/chats/test_1_1_public_chats.py:148: in test_1_1_chat_emoji_send_reply_and_open_link
        self.chat_2.chat_element_by_text(url_message).wait_for_element(20)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatElementByText` by` xpath`: `//*[starts-with(@text,'Test with link: https://status.im/ here should be nothing unusual.')]/ancestor::android.view.ViewGroup[@content-desc='chat-item']` is not found on the screen after wait_for_element; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    2. test_1_1_chat_text_message_delete_push_disappear, id: 702733

    Device 2: Find Button by accessibility id: jump-to

    critical/chats/test_1_1_public_chats.py:458: in test_1_1_chat_text_message_delete_push_disappear
        self.chat_2.jump_to_card_by_text(self.username_1)
    ../views/base_view.py:658: in jump_to_card_by_text
        self.click_on_floating_jump_to()
    ../views/base_view.py:647: in click_on_floating_jump_to
        self.jump_to_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 2: Button by accessibility id: `jump-to` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    3. test_1_1_chat_push_emoji, id: 702813

    Device 2: Could not reach home view by pressing system back button
    Device 2: Find ChatsTab by accessibility id: chats-stack-tab

    critical/chats/test_1_1_public_chats.py:319: in test_1_1_chat_push_emoji
        self.home_2.profile_button.click()
    ../views/base_view.py:149: in click
        ChatsTab(self.driver).click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 2: ChatsTab by accessibility id: `chats-stack-tab` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    4. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745

    Device 1: Find Button by accessibility id: jump-to

    critical/chats/test_1_1_public_chats.py:268: in test_1_1_chat_non_latin_messages_stack_update_profile_photo
        self.home_1.jump_to_messages_home()
    ../views/base_view.py:650: in jump_to_messages_home
        self.click_on_floating_jump_to()
    ../views/base_view.py:647: in click_on_floating_jump_to
        self.jump_to_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 1: Button by accessibility id: `jump-to` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    5. test_1_1_chat_edit_message, id: 702855

    Device 2: Could not reach home view by pressing system back button
    Device 2: Find Button by accessibility id: jump-to

    critical/chats/test_1_1_public_chats.py:371: in test_1_1_chat_edit_message
        self.chat_2.jump_to_card_by_text(self.username_1)
    ../views/base_view.py:658: in jump_to_card_by_text
        self.click_on_floating_jump_to()
    ../views/base_view.py:647: in click_on_floating_jump_to
        self.jump_to_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 2: Button by accessibility id: `jump-to` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    6. test_1_1_chat_send_image_save_and_share, id: 703391

    Device 2: Find Button by accessibility id: jump-to

    critical/chats/test_1_1_public_chats.py:397: in test_1_1_chat_send_image_save_and_share
        self.chat_2.jump_to_card_by_text(self.username_1)
    ../views/base_view.py:658: in jump_to_card_by_text
        self.click_on_floating_jump_to()
    ../views/base_view.py:647: in click_on_floating_jump_to
        self.jump_to_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 2: Button by accessibility id: `jump-to` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    7. test_1_1_chat_pin_messages, id: 702731

    # STEP: Check that Device1 can pin own message in 1-1 chat
    Device 2: Find Button by accessibility id: jump-to

    critical/chats/test_1_1_public_chats.py:180: in test_1_1_chat_pin_messages
        self.chat_2.jump_to_card_by_text(self.username_1)
    ../views/base_view.py:658: in jump_to_card_by_text
        self.click_on_floating_jump_to()
    ../views/base_view.py:647: in click_on_floating_jump_to
        self.jump_to_button.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 2: Button by accessibility id: `jump-to` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    Class TestCommunityOneDeviceMerged:

    1. test_restore_multiaccount_with_waku_backup_remove_switch, id: 703133

    ## Signed in successfully!
    Device 1: Find CommunitiesTab by accessibility id: communities-stack-tab

    critical/chats/test_public_chat_browsing.py:256: in test_restore_multiaccount_with_waku_backup_remove_switch
        self.home.communities_tab.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 1: CommunitiesTab by accessibility id: `communities-stack-tab` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    2. test_community_copy_and_paste_message_in_chat_input, id: 702742

    Device 1: Copying 'https://status.im' message via long press
    Device 1: Looking for a message by text: https://status.im

    critical/chats/test_public_chat_browsing.py:95: in test_community_copy_and_paste_message_in_chat_input
        self.channel.copy_message_text(message)
    ../views/chat_view.py:1064: in copy_message_text
        self.chat_element_by_text(message_text).wait_for_visibility_of_element()
    ../views/base_element.py:139: in wait_for_visibility_of_element
        raise TimeoutException(
     Device 1: ChatElementByText by xpath:`//*[starts-with(@text,'https://status.im')]/ancestor::android.view.ViewGroup[@content-desc='chat-item']` is not found on the screen after wait_for_visibility_of_element; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    3. test_community_undo_delete_message, id: 702869

    Device 1: ChatMessageInput element not found
    Device 1: Sending message 'message to delete and undo'

    critical/chats/test_public_chat_browsing.py:109: in test_community_undo_delete_message
        self.channel.send_message(message_to_delete)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `1`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    4. test_community_mute_community_and_channel, id: 703382

    Device 1: Could not reach home view by pressing system back button
    Device 1: Find CommunitiesTab by accessibility id: communities-stack-tab

    critical/chats/test_public_chat_browsing.py:125: in test_community_mute_community_and_channel
        self.home.communities_tab.click()
    ../views/base_element.py:90: in click
        self.find_element().click()
    ../views/base_element.py:79: in find_element
        raise NoSuchElementException(
     Device 1: CommunitiesTab by accessibility id: `communities-stack-tab` is not found on the screen; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception; also Unexpected Alert is shown: 'Objects are not valid as a React child (found: object with keys {key, I, K, F, O}). If you meant to render a collection of children, use an array instead.'
    



    Device sessions

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_several_images_send_reply, id: 703194

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    2. test_community_one_image_send_reply, id: 702859

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    3. test_community_emoji_send_copy_paste_reply, id: 702840

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    4. test_community_mark_all_messages_as_read, id: 703086

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    5. test_community_contact_block_unblock_offline, id: 702894

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    6. test_community_edit_delete_message_when_offline, id: 704615

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    7. test_community_message_delete, id: 702839

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    8. test_community_message_send_check_timestamps_sender_username, id: 702838

    # STEP: Send message to contact (need for blocking contact) test
    Device 2: Sending message 'hello'

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    Device sessions

    9. test_community_links_with_previews_github_youtube_twitter_gif_send_enable, id: 702844

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    10. test_community_message_edit, id: 702843

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    11. test_community_unread_messages_badge, id: 702841

    Test setup failed: critical/chats/test_public_chat_browsing.py:321: in prepare_devices
        self.chat_2.send_message(self.text_message)
    ../views/chat_view.py:1012: in send_message
        self.chat_message_input.wait_for_element(wait_chat_input_sec)
    ../views/base_element.py:121: in wait_for_element
        raise TimeoutException(
     Device `2`: `ChatMessageInput` by` accessibility id`: `chat-message-input` is not found on the screen after wait_for_element
    



    Expected to fail tests (1)

    Click to expand

    Class TestCommunityOneDeviceMerged:

    1. test_community_discovery, id: 703503

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Curated communities not loading, https://github.com//issues/17852]]

    Passed tests (14)

    Click to expand

    Class TestActivityCenterContactRequestMultipleDevicePR:

    1. test_add_contact_field_validation, id: 702777
    Device sessions

    2. test_activity_center_contact_request_accept_swipe_mark_all_as_read, id: 702851
    Device sessions

    3. test_activity_center_contact_request_decline, id: 702850
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUiTwo:

    1. test_1_1_chat_delete_via_long_press_relogin, id: 702784
    Device sessions

    2. test_1_1_chat_is_shown_message_sent_delivered_from_offline, id: 702783
    Device sessions

    3. test_1_1_chat_mute_chat, id: 703496
    Device sessions

    Class TestCommunityOneDeviceMerged:

    1. test_community_navigate_to_channel_when_relaunch, id: 702846
    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_pin_messages, id: 702732
    Device sessions

    2. test_group_chat_mute_chat, id: 703495
    Device sessions

    3. test_group_chat_send_image_save_and_share, id: 703297
    Device sessions

    4. test_group_chat_reactions, id: 703202
    Device sessions

    5. test_group_chat_join_send_text_messages_push, id: 702807
    Device sessions

    6. test_group_chat_offline_pn, id: 702808
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_message_reaction, id: 702730
    Device sessions

    @ilmotta
    Copy link
    Contributor

    ilmotta commented Jan 29, 2024

    To reiterate @flexsurfer, just as I said in a private Google doc: Reagent has an overhead and we all know, but this doesn't mean I agree we should remove it, not without proof of perf gain to justify the effort and the architectural change.

    it's not theory, it started here https://discuss.status.app/t/application-performance-and-ux/1168 in Apr 19 since then lots of work has been done

    My comment is about this PR alone, not about past work, but thanks for sharing the links. Since you're proposing we rewrite a lot of code now and in follow-up PRs and abandon the Reagent way of life, I do believe you should back up your claims so we can all assess if it's worth or not to move forward with your proposal.

    btw basic components I've changed like text, icons, or buttons, give significant improvement for the entire app and for chat screen as well

    How significant? Could you share the steps you took to verify this and to reach this conclusion?

    so actually i don't see how it is costly and can't be easily undone

    To undo in the future, we would need to rewrite all files again to use Reagent, bring back all Reagent abstractions and update all guidelines, as well as align with all collaborators the effort to undo the changes. And probably fix a few bugs in the way due to the reverse migration. It's definitely costly to undo this tech stack decision in the future. That's one big reason why we are being more conservative while reviewing this PR.

    The combination of React states and reactive atoms does not work very well, resulting in code that is convoluted and inefficient.

    Hum, I think it's a stretch to say one is the result of the other. So far, it has been a joy to use Reagent in status-mobile, except a few places. Very seamless experience coming from Reagent on the web. The convoluted code you mention with reactive atoms is more the fault of poor code than that of Reagent itself, and also technical skills from developers. I believe we'll continue to have the same code complexity, on average.

    in fact, we are already trying to use react state instead of reagent atoms for local states

    I didn't know about this decision to move to React states over Reagent atoms? Is this written down somewhere?

    It seems to me that you are hoping that third-party libraries do some kind of magic

    Why do you think that? I'm not proposing using UIx, I'm proposing being open for other solutions and comparing them. UIx can bring other benefits for DX, such as compile-time linters when using use-subscribe, use-effect, and so on. But let's not obsess with it, although it surely got some things right IMO which we would need to reinvent the wheel to implement.

    uix and helix add macroses and changes API similar to react, we don't need this

    Macros are a unique advantage of Lisps. Clojure libs are exploring this realm mainly due to the ability to run compile-time transformations and compile-time checks/linting, something that can't be easily done with hiccup, or with just functions. We shouldn't dismiss macros as if they're generally bad. Other Lisps explore them a lot more.

    honestly i did a lot of work in this PR

    I understand how you feel, but abandoning Reagent is more than just changing vectors to lists. Generally, if the changes are controversial, I think it's best if we first agree on the approach and only then jump to the code.

    actually, quo should be migrated first, because it's a separate package and it doesn't rely on the global state and doesn't need a reagent, so we should ask ourselves why was it even developed with a reagent if it doesn't use it? so we just decided lets slowdown it a little bit, it's too fast :)

    This point is confusing to me. What do you mean by "doesn't need Reagent"? Quo components use Reagent for local state and for all the other niceties Reagent provides. It allows us to have a coherent code base, where the same practices are applied in components and in screens. This is important so that the developer only has to learn one way of doing things.

    Also, we like to refer to Quo as a library, but it's tightly coupled with the screens, so it's not really a component library to me. Hence, making decisions using this loose concept confuses me.

    we have to fight for every % where we can

    I disagree with this strategy. Do we have this goal as a team/org or is this your personal view?

    The product has yet to prove itself in the real world, so obsessing with UI performance will just slow us down and take away devs from doing something more important (including rewriting screens to be simpler and faster).

    The chat screen is primarily slow because of the way it's written, my gosh it's super convoluted and full of dynamic elements changing size and triggering re-renders. Devs should team up with designers to come up with a reasonable middle-ground in terms of functional & non-functional requirements.

    I worked in many React apps that were slow because of how badly they were written and/or how complex the UI was. It's the same thing for status-mobile. Also, we should seriously consider the fact that some screens just won't perform well with CLJS + RN, nor with just RN. Pushing for RN and CLJS everywhere in the app can lead to workarounds trying to fit a square in a circle.

    Currently, you're developing the app, and seems performant enough for you,

    Performance is bad while developing for Android under GNU/Linux. And on release builds on Android it has never been great since I touched the app on Aug 2022. I think Android's low performance is well established within the team.

    @status-im-auto
    Copy link
    Member

    73% of end-end tests have passed

    Total executed tests: 48
    Failed tests: 11
    Expected to fail tests: 2
    Passed tests: 35
    
    IDs of failed tests: 702733,702859,702813,704613,702894,702745,702855,703202,703391,702845,702775 
    
    IDs of expected to fail tests: 703503,703629 
    

    Failed tests (11)

    Click to expand
  • Rerun failed tests

  • Class TestCommunityMultipleDeviceMerged:

    1. test_community_one_image_send_reply, id: 702859
    Test setup failed: /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    <string>:3: in raise_from
        ???
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
    E   http.client.RemoteDisconnected: Remote end closed connection without response
    
    During handling of the above exception, another exception occurred:
    base_test_case.py:365: in setup_method
        driver.execute_script("sauce:context=Started %s" % method.__name__)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:405: in execute_script
        return self.execute(command, {"script": script, "args": converted_args})["value"]
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:343: in execute
        response = self.command_executor.execute(driver_command, params)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:291: in execute
        return self._request(command_info[0], url, body=data)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:312: in _request
        response = self._conn.request(method, url, body=body, headers=headers)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:78: in request
        return self.request_encode_body(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:170: in request_encode_body
        return self.urlopen(method, url, **extra_kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/poolmanager.py:376: in urlopen
        response = conn.urlopen(method, u.request_uri, **kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:787: in urlopen
        retries = retries.increment(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/util/retry.py:550: in increment
        raise six.reraise(type(error), error, _stacktrace)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/packages/six.py:769: in reraise
        raise value.with_traceback(tb)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
     ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
    



    2. test_community_contact_block_unblock_offline, id: 702894

    Device 1: Click until ChatMessageInput by accessibility id: chat-message-input will be presented
    Device 1: Looking for a message by text: Hurray! unblocked

    critical/chats/test_public_chat_browsing.py:705: in test_community_contact_block_unblock_offline
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Hurray! unblocked was not received in public chat after user unblock!
    



    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_leave, id: 702845

    Test setup failed: /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    <string>:3: in raise_from
        ???
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
    E   http.client.RemoteDisconnected: Remote end closed connection without response
    
    During handling of the above exception, another exception occurred:
    base_test_case.py:365: in setup_method
        driver.execute_script("sauce:context=Started %s" % method.__name__)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:405: in execute_script
        return self.execute(command, {"script": script, "args": converted_args})["value"]
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:343: in execute
        response = self.command_executor.execute(driver_command, params)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:291: in execute
        return self._request(command_info[0], url, body=data)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:312: in _request
        response = self._conn.request(method, url, body=body, headers=headers)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:78: in request
        return self.request_encode_body(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:170: in request_encode_body
        return self.urlopen(method, url, **extra_kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/poolmanager.py:376: in urlopen
        response = conn.urlopen(method, u.request_uri, **kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:787: in urlopen
        retries = retries.increment(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/util/retry.py:550: in increment
        raise six.reraise(type(error), error, _stacktrace)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/packages/six.py:769: in reraise
        raise value.with_traceback(tb)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
     ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
    



    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_text_message_delete_push_disappear, id: 702733

    critical/chats/test_1_1_public_chats.py:459: in test_1_1_chat_text_message_delete_push_disappear
        if not self.chat_1.chat_message_input.is_element_displayed():
    ../views/base_element.py:213: in is_element_displayed
        return self.wait_for_visibility_of_element(sec, ignored_exceptions=ignored_exceptions)
    ../views/base_element.py:137: in wait_for_visibility_of_element
        .until(expected_conditions.visibility_of_element_located((self.by, self.locator)))
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:86: in until
        value = method(self._driver)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:152: in _predicate
        return _element_if_visible(driver.find_element(*locator))
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/webdriver.py:409: in find_element
        return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:345: in execute
        self.error_handler.check_response(response)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/errorhandler.py:122: in check_response
        raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
     A session is either terminated or not started
    E   Stacktrace:
    E   NoSuchDriverError: A session is either terminated or not started
    E       at asyncHandler (/mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:315:15)
    E       at /mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:518:15
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:144:13)
    E       at Route.dispatch (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:114:3)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:284:15
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:365:14)
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:376:14)
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:421:3)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at logger (/mnt/sauce/appium/appium-v2.0.0/node_modules/morgan/index.js:144:5)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at trim_prefix (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:328:13)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:286:9
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:346:12)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/body-parser/lib/read.js:137:5
    E       at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    E       at invokeCallback (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:238:16)
    E       at done (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:227:7)
    E       at IncomingMessage.onEnd (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:287:7)
    E       at IncomingMessage.emit (node:events:513:28)
    E       at endReadableNT (node:internal/streams/readable:1359:12)
    E       at processTicksAndRejections (node:internal/process/task_queues:82:21)
    



    Device sessions

    2. test_1_1_chat_push_emoji, id: 702813

    critical/chats/test_1_1_public_chats.py:317: in test_1_1_chat_push_emoji
        self.home_1.navigate_back_to_home_view()
    ../views/base_view.py:407: in navigate_back_to_home_view
        while not self.chat_floating_screen.is_element_disappeared(1) \
    ../views/base_element.py:223: in is_element_disappeared
        return self.wait_for_invisibility_of_element(sec)
    ../views/base_element.py:146: in wait_for_invisibility_of_element
        .until(expected_conditions.invisibility_of_element_located((self.by, self.locator)))
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:86: in until
        value = method(self._driver)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:319: in _predicate
        target = driver.find_element(*target)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/webdriver.py:409: in find_element
        return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:345: in execute
        self.error_handler.check_response(response)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/errorhandler.py:122: in check_response
        raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
     A session is either terminated or not started
    E   Stacktrace:
    E   NoSuchDriverError: A session is either terminated or not started
    E       at asyncHandler (/mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:315:15)
    E       at /mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:518:15
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:144:13)
    E       at Route.dispatch (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:114:3)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:284:15
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:365:14)
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:376:14)
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:421:3)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at logger (/mnt/sauce/appium/appium-v2.0.0/node_modules/morgan/index.js:144:5)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at trim_prefix (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:328:13)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:286:9
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:346:12)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/body-parser/lib/read.js:137:5
    E       at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    E       at invokeCallback (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:238:16)
    E       at done (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:227:7)
    E       at IncomingMessage.onEnd (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:287:7)
    E       at IncomingMessage.emit (node:events:513:28)
    E       at endReadableNT (node:internal/streams/readable:1359:12)
    E       at processTicksAndRejections (node:internal/process/task_queues:82:21)
    



    Device sessions

    3. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745

    Test setup failed: /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    <string>:3: in raise_from
        ???
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
    E   http.client.RemoteDisconnected: Remote end closed connection without response
    
    During handling of the above exception, another exception occurred:
    base_test_case.py:365: in setup_method
        driver.execute_script("sauce:context=Started %s" % method.__name__)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:405: in execute_script
        return self.execute(command, {"script": script, "args": converted_args})["value"]
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:343: in execute
        response = self.command_executor.execute(driver_command, params)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:291: in execute
        return self._request(command_info[0], url, body=data)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/remote_connection.py:312: in _request
        response = self._conn.request(method, url, body=body, headers=headers)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:78: in request
        return self.request_encode_body(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/request.py:170: in request_encode_body
        return self.urlopen(method, url, **extra_kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/poolmanager.py:376: in urlopen
        response = conn.urlopen(method, u.request_uri, **kw)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:787: in urlopen
        retries = retries.increment(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/util/retry.py:550: in increment
        raise six.reraise(type(error), error, _stacktrace)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/packages/six.py:769: in reraise
        raise value.with_traceback(tb)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:703: in urlopen
        httplib_response = self._make_request(
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:449: in _make_request
        six.raise_from(e, None)
    /home/jenkins/.local/lib/python3.10/site-packages/urllib3/connectionpool.py:444: in _make_request
        httplib_response = conn.getresponse()
    /usr/lib/python3.10/http/client.py:1375: in getresponse
        response.begin()
    /usr/lib/python3.10/http/client.py:318: in begin
        version, status, reason = self._read_status()
    /usr/lib/python3.10/http/client.py:287: in _read_status
        raise RemoteDisconnected("Remote end closed connection without"
     ('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))
    



    4. test_1_1_chat_edit_message, id: 702855

    critical/chats/test_1_1_public_chats.py:369: in test_1_1_chat_edit_message
        self.home_1.navigate_back_to_home_view()
    ../views/base_view.py:407: in navigate_back_to_home_view
        while not self.chat_floating_screen.is_element_disappeared(1) \
    ../views/base_element.py:223: in is_element_disappeared
        return self.wait_for_invisibility_of_element(sec)
    ../views/base_element.py:146: in wait_for_invisibility_of_element
        .until(expected_conditions.invisibility_of_element_located((self.by, self.locator)))
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:86: in until
        value = method(self._driver)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:319: in _predicate
        target = driver.find_element(*target)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/webdriver.py:409: in find_element
        return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:345: in execute
        self.error_handler.check_response(response)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/errorhandler.py:122: in check_response
        raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
     A session is either terminated or not started
    E   Stacktrace:
    E   NoSuchDriverError: A session is either terminated or not started
    E       at asyncHandler (/mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:315:15)
    E       at /mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:518:15
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:144:13)
    E       at Route.dispatch (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:114:3)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:284:15
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:365:14)
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:376:14)
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:421:3)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at logger (/mnt/sauce/appium/appium-v2.0.0/node_modules/morgan/index.js:144:5)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at trim_prefix (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:328:13)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:286:9
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:346:12)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/body-parser/lib/read.js:137:5
    E       at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    E       at invokeCallback (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:238:16)
    E       at done (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:227:7)
    E       at IncomingMessage.onEnd (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:287:7)
    E       at IncomingMessage.emit (node:events:513:28)
    E       at endReadableNT (node:internal/streams/readable:1359:12)
    E       at processTicksAndRejections (node:internal/process/task_queues:82:21)
    



    Device sessions

    5. test_1_1_chat_send_image_save_and_share, id: 703391

    critical/chats/test_1_1_public_chats.py:398: in test_1_1_chat_send_image_save_and_share
        if not self.chat_1.chat_message_input.is_element_displayed():
    ../views/base_element.py:213: in is_element_displayed
        return self.wait_for_visibility_of_element(sec, ignored_exceptions=ignored_exceptions)
    ../views/base_element.py:137: in wait_for_visibility_of_element
        .until(expected_conditions.visibility_of_element_located((self.by, self.locator)))
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/wait.py:86: in until
        value = method(self._driver)
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/support/expected_conditions.py:152: in _predicate
        return _element_if_visible(driver.find_element(*locator))
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/webdriver.py:409: in find_element
        return self.execute(RemoteCommand.FIND_ELEMENT, {'using': by, 'value': value})['value']
    /home/jenkins/.local/lib/python3.10/site-packages/selenium/webdriver/remote/webdriver.py:345: in execute
        self.error_handler.check_response(response)
    /home/jenkins/.local/lib/python3.10/site-packages/appium/webdriver/errorhandler.py:122: in check_response
        raise exception_class(msg=message, stacktrace=format_stacktrace(stacktrace))
     A session is either terminated or not started
    E   Stacktrace:
    E   NoSuchDriverError: A session is either terminated or not started
    E       at asyncHandler (/mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:315:15)
    E       at /mnt/sauce/appium/appium-v2.0.0/packages/base-driver/lib/protocol/protocol.js:518:15
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:144:13)
    E       at Route.dispatch (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/route.js:114:3)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:284:15
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:365:14)
    E       at param (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:376:14)
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:421:3)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at logger (/mnt/sauce/appium/appium-v2.0.0/node_modules/morgan/index.js:144:5)
    E       at Layer.handle [as handle_request] (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/layer.js:95:5)
    E       at trim_prefix (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:328:13)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:286:9
    E       at Function.process_params (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:346:12)
    E       at next (/mnt/sauce/appium/appium-v2.0.0/node_modules/express/lib/router/index.js:280:10)
    E       at /mnt/sauce/appium/appium-v2.0.0/node_modules/body-parser/lib/read.js:137:5
    E       at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    E       at invokeCallback (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:238:16)
    E       at done (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:227:7)
    E       at IncomingMessage.onEnd (/mnt/sauce/appium/appium-v2.0.0/node_modules/raw-body/index.js:287:7)
    E       at IncomingMessage.emit (node:events:513:28)
    E       at endReadableNT (node:internal/streams/readable:1359:12)
    E       at processTicksAndRejections (node:internal/process/task_queues:82:21)
    



    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_reactions, id: 703202

    Device 1: Find Button by accessibility id: authors-for-reaction-5
    Device 1: Tap on found: Button

    None; 
     RemoteDisconnected; 
     RemoteDisconnected
    



    Device sessions

    Class TestDeepLinksOneDevice:

    1. test_links_open_universal_links_from_chat, id: 704613

    Device 1: Find Text by xpath: //android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK')]

    critical/test_deep_and_universal_links.py:70: in test_links_open_universal_links_from_chat
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the url https://status.app/c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the url https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    2. test_links_deep_links, id: 702775

    Device 1: Find BrowserTab by accessibility id: browser-stack-tab
    Device 1: Tap on found: BrowserTab

    critical/test_deep_and_universal_links.py:114: in test_links_deep_links
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the deep link status.app://c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the deep link status.app://c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    Expected to fail tests (2)

    Click to expand

    Class TestCommunityOneDeviceMerged:

    1. test_community_discovery, id: 703503

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Curated communities not loading, https://github.com//issues/17852]]

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_join_when_node_owner_offline, id: 703629

    Device 2: Tap on found: Button
    Device 2: Looking for community: 'open community'

    critical/chats/test_public_chat_browsing.py:1177: in test_community_join_when_node_owner_offline
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     open community is not listed inside Pending communities tab
    E    open community is not listed inside Joined communities tab 
    

    [[Can't join a community if admin goes offline, https://github.com//issues/17678]]

    Device sessions

    Passed tests (35)

    Click to expand

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_several_images_send_reply, id: 703194
    Device sessions

    2. test_community_emoji_send_copy_paste_reply, id: 702840
    Device sessions

    3. test_community_mark_all_messages_as_read, id: 703086
    Device sessions

    4. test_community_edit_delete_message_when_offline, id: 704615
    Device sessions

    5. test_community_message_delete, id: 702839
    Device sessions

    6. test_community_message_send_check_timestamps_sender_username, id: 702838
    Device sessions

    7. test_community_links_with_previews_github_youtube_twitter_gif_send_enable, id: 702844
    Device sessions

    8. test_community_message_edit, id: 702843
    Device sessions

    9. test_community_unread_messages_badge, id: 702841
    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_markdown_support, id: 702809
    Device sessions

    2. test_community_hashtag_links_to_community_channels, id: 702948
    Device sessions

    3. test_community_mentions_push_notification, id: 702786
    Device sessions

    Class TestActivityMultipleDevicePR:

    1. test_navigation_jump_to, id: 702936
    Device sessions

    2. test_activity_center_reply_read_unread_delete_filter_swipe, id: 702947
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_emoji_send_reply_and_open_link, id: 702782
    Device sessions

    2. test_1_1_chat_pin_messages, id: 702731
    Device sessions

    3. test_1_1_chat_message_reaction, id: 702730
    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_pin_messages, id: 702732
    Device sessions

    2. test_group_chat_mute_chat, id: 703495
    Device sessions

    3. test_group_chat_send_image_save_and_share, id: 703297
    Device sessions

    4. test_group_chat_join_send_text_messages_push, id: 702807
    Device sessions

    5. test_group_chat_offline_pn, id: 702808
    Device sessions

    Class TestCommunityOneDeviceMerged:

    1. test_restore_multiaccount_with_waku_backup_remove_switch, id: 703133
    Device sessions

    2. test_community_copy_and_paste_message_in_chat_input, id: 702742
    Device sessions

    3. test_community_undo_delete_message, id: 702869
    Device sessions

    4. test_community_navigate_to_channel_when_relaunch, id: 702846
    Device sessions

    5. test_community_mute_community_and_channel, id: 703382
    Device sessions

    Class TestActivityMultipleDevicePRTwo:

    1. test_activity_center_mentions, id: 702957
    Device sessions

    2. test_activity_center_admin_notification_accept_swipe, id: 702958
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUiTwo:

    1. test_1_1_chat_delete_via_long_press_relogin, id: 702784
    Device sessions

    2. test_1_1_chat_is_shown_message_sent_delivered_from_offline, id: 702783
    Device sessions

    3. test_1_1_chat_mute_chat, id: 703496
    Device sessions

    Class TestActivityCenterContactRequestMultipleDevicePR:

    1. test_add_contact_field_validation, id: 702777
    Device sessions

    2. test_activity_center_contact_request_accept_swipe_mark_all_as_read, id: 702851
    Device sessions

    3. test_activity_center_contact_request_decline, id: 702850
    Device sessions

    @flexsurfer
    Copy link
    Member Author

    thanks @ilmotta, @J-Son89 , the longer we wait, the more work will need to be done, changing brackets isn't that big of a job, it's more like changing formatting, i was trying to keep the approach and API as similar to the current as possible. Actually, it's not only about performance, and might be it even not the first reason, if we look at the reasons why big projects move away from reagent it is because it makes code more familiar to js (RN) devs.
    Most of our developers are experienced in RN and JS, also new version of the app is more complex and there are lots of animations and complex UI, and functional react components are used with mixed react hooks and reagent atoms, so it would be better to use only react hooks, because devs more familiar, and better to use only one approach, also @Parveshdhull has been working on replacing atoms, might add his thoughts

    React library is evolving (for example concurrent renderer) and it is better to use the latest versions and techniques, and the best way to do it is to use it directly without wrappers

    And regarding performance, setting screen changes in this PR shows visible improvements, it's visible for the user that the screen opens faster. and also measured in js profile, ~200ms vs ~300ms , but it's still hard to measure final numbers because we still have part of the app in hiccup with reagent atoms.

    From these points in the complex, it is obvious to me why we should move away from the reagent now and not wait until the code base becomes bigger and more complex. And it's not only about performance, but it's also about bad maintenance of library and devs experience

    @status-im-auto
    Copy link
    Member

    73% of end-end tests have passed

    Total executed tests: 11
    Failed tests: 3
    Expected to fail tests: 0
    Passed tests: 8
    
    IDs of failed tests: 702775,704613,703391 
    

    Failed tests (3)

    Click to expand
  • Rerun failed tests

  • Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_send_image_save_and_share, id: 703391

    Device 2: Find `Button` by `accessibility id`: `image-0`
    Device 2: Click system back button

    critical/chats/test_1_1_public_chats.py:453: in test_1_1_chat_send_image_save_and_share
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Message about saving a photo is not shown for receiver.
    



    Device sessions

    Class TestDeepLinksOneDevice:

    1. test_links_deep_links, id: 702775

    Device 1: Find BrowserTab by accessibility id: browser-stack-tab
    Device 1: Tap on found: BrowserTab

    critical/test_deep_and_universal_links.py:114: in test_links_deep_links
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the deep link status.app://c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the deep link status.app://c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    2. test_links_open_universal_links_from_chat, id: 704613

    Device 1: Find Text by xpath: //android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK')]

    critical/test_deep_and_universal_links.py:70: in test_links_open_universal_links_from_chat
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the url https://status.app/c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the url https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    Passed tests (8)

    Click to expand

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_contact_block_unblock_offline, id: 702894
    Device sessions

    2. test_community_one_image_send_reply, id: 702859
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_edit_message, id: 702855
    Device sessions

    2. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745
    Device sessions

    3. test_1_1_chat_text_message_delete_push_disappear, id: 702733
    Device sessions

    4. test_1_1_chat_push_emoji, id: 702813
    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_leave, id: 702845
    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_reactions, id: 703202
    Device sessions

    @@ -42,16 +42,15 @@
    (defn use-theme
    "A hook that returns the current theme context."
    []
    (utils.transforms/js->clj (rn/use-context theme-context)))
    (keyword (rn/use-context theme-context)))
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    btw we had initially made this return a map so that the api is easier to extend if we ever need to.
    use-theme-value would get the result directly and you could just use that here.

    @status-im-auto
    Copy link
    Member

    100% of end-end tests have passed

    Total executed tests: 1
    Failed tests: 0
    Expected to fail tests: 0
    Passed tests: 1
    

    Passed tests (1)

    Click to expand

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_send_image_save_and_share, id: 703391
    Device sessions

    @status-im-auto
    Copy link
    Member

    92% of end-end tests have passed

    Total executed tests: 48
    Failed tests: 2
    Expected to fail tests: 2
    Passed tests: 44
    
    IDs of failed tests: 704613,702775 
    
    IDs of expected to fail tests: 703503,703629 
    

    Failed tests (2)

    Click to expand
  • Rerun failed tests

  • Class TestDeepLinksOneDevice:

    1. test_links_open_universal_links_from_chat, id: 704613

    Device 1: Looking for a message by text: https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    Device 1: Find `Text` by `xpath`: `//android.view.ViewGroup[@content-desc='chat-item']//android.widget.TextView[contains(@text,'https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK')]`

    critical/test_deep_and_universal_links.py:70: in test_links_open_universal_links_from_chat
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the url https://status.app/c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the url https://status.app/c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    2. test_links_deep_links, id: 702775

    Device 1: Find BrowserTab by accessibility id: browser-stack-tab
    Device 1: Tap on found: BrowserTab

    critical/test_deep_and_universal_links.py:114: in test_links_deep_links
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     Closed community was not requested to join by the deep link status.app://c/G00AAGS9TbI9mSR-ZNmFrhRjNuEeXAAbcAIUaLLJyjMOG3ACJQ12oIHD78QhzO9s_T5bUeU7rnATWJg3mGgTUemrAg==#zQ3shspPKCZ1VPVQ9dLXGufUGvGphjxVwrcZ6rkZc7S39T4b3
    E    Closed community was not requested to join by the deep link status.app://c/G0UAAMTyNsn2QZDEG0EXftOl8pOEfwEBOOSA_YTfIk85xmADDgINGmxpUHAXzK36bN0fK42Xf4YD2yjPk1z2pbFwFw==#zQ3shgkDFQEnwxji7CvMTokMrShmC2UgxiJ549X5Aw746zQrK
    



    Device sessions

    Expected to fail tests (2)

    Click to expand

    Class TestCommunityOneDeviceMerged:

    1. test_community_discovery, id: 703503

    Test is not run, e2e blocker  
    

    [[reason: [NOTRUN] Curated communities not loading, https://github.com//issues/17852]]

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_join_when_node_owner_offline, id: 703629

    Device 2: Tap on found: Button
    Device 2: Looking for community: 'open community'

    critical/chats/test_public_chat_browsing.py:1177: in test_community_join_when_node_owner_offline
        self.errors.verify_no_errors()
    base_test_case.py:191: in verify_no_errors
        pytest.fail('\n '.join([self.errors.pop(0) for _ in range(len(self.errors))]))
     open community is not listed inside Pending communities tab
    E    Text "You joined “closed community”" in shown toast element doesn't match expected "You joined “open community”"
    E    open community is not listed inside Joined communities tab 
    

    [[Can't join a community if admin goes offline, https://github.com//issues/17678]]

    Device sessions

    Passed tests (44)

    Click to expand

    Class TestActivityMultipleDevicePR:

    1. test_navigation_jump_to, id: 702936
    Device sessions

    2. test_activity_center_reply_read_unread_delete_filter_swipe, id: 702947
    Device sessions

    Class TestCommunityMultipleDeviceMerged:

    1. test_community_several_images_send_reply, id: 703194
    Device sessions

    2. test_community_one_image_send_reply, id: 702859
    Device sessions

    3. test_community_emoji_send_copy_paste_reply, id: 702840
    Device sessions

    4. test_community_mark_all_messages_as_read, id: 703086
    Device sessions

    5. test_community_contact_block_unblock_offline, id: 702894
    Device sessions

    6. test_community_edit_delete_message_when_offline, id: 704615
    Device sessions

    7. test_community_message_delete, id: 702839
    Device sessions

    8. test_community_message_send_check_timestamps_sender_username, id: 702838
    Device sessions

    9. test_community_links_with_previews_github_youtube_twitter_gif_send_enable, id: 702844
    Device sessions

    10. test_community_message_edit, id: 702843
    Device sessions

    11. test_community_unread_messages_badge, id: 702841
    Device sessions

    Class TestActivityMultipleDevicePRTwo:

    1. test_activity_center_mentions, id: 702957
    Device sessions

    2. test_activity_center_admin_notification_accept_swipe, id: 702958
    Device sessions

    Class TestGroupChatMultipleDeviceMergedNewUI:

    1. test_group_chat_pin_messages, id: 702732
    Device sessions

    2. test_group_chat_mute_chat, id: 703495
    Device sessions

    3. test_group_chat_send_image_save_and_share, id: 703297
    Device sessions

    4. test_group_chat_reactions, id: 703202
    Device sessions

    5. test_group_chat_join_send_text_messages_push, id: 702807
    Device sessions

    6. test_group_chat_offline_pn, id: 702808
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUi:

    1. test_1_1_chat_emoji_send_reply_and_open_link, id: 702782
    Device sessions

    2. test_1_1_chat_text_message_delete_push_disappear, id: 702733
    Device sessions

    3. test_1_1_chat_push_emoji, id: 702813
    Device sessions

    4. test_1_1_chat_non_latin_messages_stack_update_profile_photo, id: 702745
    Device sessions

    5. test_1_1_chat_edit_message, id: 702855
    Device sessions

    6. test_1_1_chat_send_image_save_and_share, id: 703391
    Device sessions

    7. test_1_1_chat_pin_messages, id: 702731
    Device sessions

    8. test_1_1_chat_message_reaction, id: 702730
    Device sessions

    Class TestCommunityOneDeviceMerged:

    1. test_restore_multiaccount_with_waku_backup_remove_switch, id: 703133
    Device sessions

    2. test_community_copy_and_paste_message_in_chat_input, id: 702742
    Device sessions

    3. test_community_undo_delete_message, id: 702869
    Device sessions

    4. test_community_navigate_to_channel_when_relaunch, id: 702846
    Device sessions

    5. test_community_mute_community_and_channel, id: 703382
    Device sessions

    Class TestActivityCenterContactRequestMultipleDevicePR:

    1. test_add_contact_field_validation, id: 702777
    Device sessions

    2. test_activity_center_contact_request_accept_swipe_mark_all_as_read, id: 702851
    Device sessions

    3. test_activity_center_contact_request_decline, id: 702850
    Device sessions

    Class TestCommunityMultipleDeviceMergedTwo:

    1. test_community_markdown_support, id: 702809
    Device sessions

    2. test_community_hashtag_links_to_community_channels, id: 702948
    Device sessions

    3. test_community_mentions_push_notification, id: 702786
    Device sessions

    4. test_community_leave, id: 702845
    Device sessions

    Class TestOneToOneChatMultipleSharedDevicesNewUiTwo:

    1. test_1_1_chat_delete_via_long_press_relogin, id: 702784
    Device sessions

    2. test_1_1_chat_is_shown_message_sent_delivered_from_offline, id: 702783
    Device sessions

    3. test_1_1_chat_mute_chat, id: 703496
    Device sessions

    @ilmotta
    Copy link
    Contributor

    ilmotta commented Feb 1, 2024

    i was trying to keep the approach and API as similar to the current as possible.

    @flexsurfer I'll put some thought tomorrow and share. Thank you.

    The actual reason that makes me consider abandoning Reagent is the number of bugs our team produces due to incorrect usage of Reagent and our sub-optimal usage of it (perf wise), not really because it has a small(ish) overhead.

    My experience with React since the early days tells me it won't be much different with raw React, we'll kind of just switch the types of bugs... We just need to look at the parts of the app heavy on animation, the complexity isn't really due to Reagent, it's because of the animation code that infests everything. We take Reagent away from these places, the code will have the same degree of complexity on average (Composer for example, but many others).

    the longer we wait, the more work will need to be done, changing brackets isn't that big of a job, it's more like changing formatting

    This PR feels kind of stuck because of the lack of evidence to support performance claims to justify abandoning Reagent. When you suggest eliminating a basic library many people invested time learning and it's widely used, it's also natural to be questioned more.

    IMO, before this PR was opened, consensus in the team should have been reached without actual prod code. We don't need prod code to agree about removing Reagent and we don't need prod code to come up with a solution/API. Proposals are cheaper and we can do many.

    I also see you refactored a lot of code in this PR, which makes our job to review harder. It also creates this tension where, because you already invested too much time, you want to see them into develop asap. We don't need that much code in the first PR, we just need to agree on a solution and just a handful of examples in the code to showcase it. Then, follow-up PRs can do the fun job of refactoring things :) So please, consider a different approach for future work with widespread implications. It's really not about changing square brackets to parenthesis.

    Actually, it's not only about performance, and might be it even not the first reason

    I see. The main reason seems to be that Reagent feels outdated, requires convolutions to use hooks, confuses JS devs (most of the team), and so on. This is problematic, I agree.

    That's a bigger problem than Reagent's performance which could be in fact be improved considerably. We don't take advantage of its most basic performance feature that's based on diffing props. For instance, we pass anonymous functions down the entire component tree. No wonder Reagent has to do a ton of extra work.

    and also measured in js profile, ~200ms vs ~300ms , but it's still hard to measure final numbers because we still have part of the app in hiccup with reagent atoms.

    I appreciate the honesty about the difficulty to measure. I profiled the app using this PR as well with Hermes. I couldn't see a conclusive difference to justify eliminating Reagent, maybe because we have other parts using Reagent as you said. But some numbers could have been provided if the PR focused on refactoring a simpler screen. Even a single, heavy component in a preview screen could give interesting & reproducible results.

    if we look at the reasons why big projects move away from reagent it is because it makes code more familiar to js (RN) devs

    I'm curious. Would you mind sharing examples of companies or projects that moved away from Reagent?


    btw, I think we need more developers profiling the app and understanding the trade-offs. That might seem like a waste of time, but I think it will create a stronger team and it will pay off.

    @flexsurfer
    Copy link
    Member Author

    flexsurfer commented Feb 1, 2024

    @ilmotta @J-Son89 thank you very much for your very valuable feedback, now i understand that I acted a little recklessly by transferring this experimental PR into a merge-ready one, presented it as something just ready for review and then ready to be merged, in my head i see the big picture, i have 100% confidence it will work and we should move there, but probably as you correctly said, there should a plan and understanding of how and why we are going there, and this PR cannot be merged in this form.

    so at first, I was focusing on performance when I started looking into slow laggy settings screens, step by step I found out that the problem was in the number of elements on the screen, I knew that reagent adds some overhead to each component, so I decided to try to replace it, and at that moment I already had thoughts and knowledge that's it's better to use hooks, and actually reagent is not needed, so I moved fast, and decided to check this, and then on the halfway numbers showed 60% improvement I decided that's enough, and I can stop because I did already too many changes. And for that reason i decided to push it just as performance improvement.

    But now I think we should go the other way, I didn't notice that I had done the work of replacing reactive atoms with hooks because I considered it self-evident, and replacing [ with ( also might take some time for devs to get used to it.

    So now I think first we need to agree, that we use a lot of functional components, and mixed hooks and reagent atoms are not great, and for most js devs reactive atoms and reagent forms variants are not easy to understand and properly use. So it would be better to replace reagent atoms with hooks

    image

    this is work to be done ^

    and then, i think we could keep hiccup, and just use our custom compiler for reagent, where we will use only functional components without reactions, wdyt?

    PS: I'm currently writing an article with technical details that I will publish later

    @ilmotta
    Copy link
    Contributor

    ilmotta commented Feb 1, 2024

    and then, i think we could keep hiccup, and just use our custom compiler for reagent, where we will use only functional components without reactions, wdyt?

    PS: I'm currently writing an article with technical details that I will publish later

    Hey, this is rather interesting stuff @flexsurfer. Seems like a nice middleground if we can keep Reagent, but make it play nice with hooks and perform better. We should embrace hooks because they're not going anywhere. Do you believe you can eliminate or reduce the overhead of functional components with Reagent?

    Have you looked at this issue? Does it give you ideas? Provide a React hook for using ratoms/reactions as part of public API reagent-project/reagent#545 Or are you just inclined to eliminate reactions and period?

    just use our custom compiler

    When you mention "custom compiler" it confuses me a little bit, because Reagent does offer an API for a custom compiler since mid 2021. I have frequently wondered where this could lead us or if it could help us, but never played with it in status-mobile. I imagine the compiler could be optimized for our mobile constraints. Should probably be on our deck of cards too.

    So now I think first we need to agree, that we use a lot of functional components

    Correct, we do have many functional components and we'll eventually use more and more.

    for most js devs reactive atoms and reagent forms variants are not easy to understand and properly use

    Maybe others should jump in this conversation and answer this question, maybe it's actually fine for most.

    Based on my experience so far in this project, my impression is that most devs use Reagent atoms correctly after an initial learning curve of mistakes. The form-1, form-2 variant is a very simple concept based on closures, but mistakes are made every now and then. I see most also learn to do this effectively after a learning curve. But I can't speak for others on this matter.

    There are many mistakes made with Reagent that seem to be tied to devs's knowledge of CLJS, so we should be careful with any cause & effect analysis when we blame Reagent.

    I'm currently writing an article with technical details that I will publish later

    Super nice! Would love to read it Andrey.

    @J-Son89
    Copy link
    Contributor

    J-Son89 commented Feb 2, 2024

    @ilmotta @J-Son89 thank you very much for your very valuable feedback, now i understand that I acted a little recklessly by transferring this experimental PR into a merge-ready one, presented it as something just ready for review and then ready to be merged, in my head i see the big picture, i have 100% confidence it will work and we should move there, but probably as you correctly said, there should a plan and understanding of how and why we are going there, and this PR cannot be merged in this form.

    so at first, I was focusing on performance when I started looking into slow laggy settings screens, step by step I found out that the problem was in the number of elements on the screen, I knew that reagent adds some overhead to each component, so I decided to try to replace it, and at that moment I already had thoughts and knowledge that's it's better to use hooks, and actually reagent is not needed, so I moved fast, and decided to check this, and then on the halfway numbers showed 60% improvement I decided that's enough, and I can stop because I did already too many changes. And for that reason i decided to push it just as performance improvement.

    But now I think we should go the other way, I didn't notice that I had done the work of replacing reactive atoms with hooks because I considered it self-evident, and replacing [ with ( also might take some time for devs to get used to it.

    So now I think first we need to agree, that we use a lot of functional components, and mixed hooks and reagent atoms are not great, and for most js devs reactive atoms and reagent forms variants are not easy to understand and properly use. So it would be better to replace reagent atoms with hooks

    image this is work to be done ^

    and then, i think we could keep hiccup, and just use our custom compiler for reagent, where we will use only functional components without reactions, wdyt?

    PS: I'm currently writing an article with technical details that I will publish later

    Hey @flexsurfer, for sure I can definitely got on board if we take a more gradual approach and there's other developers working on some of this too. Who knows where our blind spots are on this!
    Looking forward to the article and I think will help other devs take on this strategy too.
    The offsite in April might also be a good opportunity to spread knowledge on it, either with a presentation or a workshop where we get some developers to refactor some components with this approach, or even both :)

    @@ -29,7 +29,7 @@
    {:height (:size opts)
    :width (:size opts)
    :borderRadius (style/get-border-radius (:size opts))
    :backgroundColor (colors/resolve-color (:customization-color opts) :dark)})
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hi @flexsurfer, why these values reversed here?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    idk , probably there was a bug before?

    [react-native.core :as rn]
    [react-native.pure :as rn.pure]))

    (defn view-pure
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    In other places are just replacing with pure version, why we are keeping both here? Is it WIP?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    yes, overwise i have to migrate all children for all overlay usage

    Comment on lines +18 to +23
    [^js data]
    (quo/category
    {:list-type :settings
    :container-style {:padding-bottom 0}
    :blur? true
    :data (.-item data)}))
    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    • Is ^js is necessary here?
    • Why data is changed here?

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    here not, in 18th line is enough, what do you mean by data changed? you mean why it's a js object now? it's a good question, somehow i missed these changes in the description of the PR, it should be a separate change, optimisation of flat-list

    Copy link
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    what do you mean by data changed?

    image

    In first case, we are passing data directly but in second we are using .-Item

    Copy link
    Member Author

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    we use flat list directly no wrappers anymore

    @flexsurfer flexsurfer closed this Feb 23, 2024
    @flexsurfer flexsurfer deleted the feature/pure-rn-experiment-2 branch August 30, 2024 11:29
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    Archived in project
    Archived in project
    Development

    Successfully merging this pull request may close these issues.

    9 participants