Compare commits

..
Author SHA1 Message Date
Volodymyr Kozieiev d2eb401a16 wip 2025-01-26 16:36:48 +00:00
Volodymyr Kozieiev c568a51c60 Before modifying signing order 2025-01-24 16:55:15 +00:00
55 changed files with 766 additions and 973 deletions
+2 -4
View File
@@ -1,4 +1,4 @@
{ callPackage, lib, buildGoPackage, pkgs
{ callPackage, lib, buildGoPackage
, androidPkgs, openjdk, gomobile, xcodeWrapper, removeReferencesTo
, go-bindata, mockgen, protobuf3_20, protoc-gen-go
, meta
@@ -15,8 +15,6 @@ let
isIOS = platform == "ios";
isAndroid = platform == "android";
enforceXCodeAvailable = callPackage ./enforceXCodeAvailable.nix { };
# Fixes fatal: not a git repository (or any of the parent directories): .git
fakeGit = pkgs.writeScriptBin "git" "echo ${source.version}";
in buildGoPackage rec {
pname = source.repo;
@@ -31,7 +29,7 @@ in buildGoPackage rec {
extraSrcPaths = [ gomobile ];
nativeBuildInputs = [
gomobile removeReferencesTo go-bindata mockgen protoc-gen-go protobuf3_20 fakeGit
gomobile removeReferencesTo go-bindata mockgen protoc-gen-go protobuf3_20
] ++ optional isAndroid openjdk
++ optional isIOS xcodeWrapper;
+6 -10
View File
@@ -253,19 +253,15 @@
(defn hash-typed-data
"used for keycard"
([data]
(native-utils/promisify-native-module-call hash-typed-data data))
([data callback]
(log/debug "[native-module] hash-typed-data")
(.hashTypedData ^js (encryption) data callback)))
[data callback]
(log/debug "[native-module] hash-typed-data")
(.hashTypedData ^js (encryption) data callback))
(defn hash-typed-data-v4
"used for keycard"
([data]
(native-utils/promisify-native-module-call hash-typed-data-v4 data))
([data callback]
(log/debug "[native-module] hash-typed-data-v4")
(.hashTypedDataV4 ^js (encryption) data callback)))
[data callback]
(log/debug "[native-module] hash-typed-data-v4")
(.hashTypedDataV4 ^js (encryption) data callback))
(defn send-transaction-with-signature
"used for keycard"
+2 -3
View File
@@ -21,13 +21,13 @@
[{:keys [type on-press on-check disabled? checked? child]} customization-color theme]
(if (= type :custom)
child
[rn/touchable-opacity {:on-press on-press}
[rn/touchable-opacity
{:on-press on-press}
(case type
:options
[icons/icon :i/options
{:size 20
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]
:checkbox
[selectors/view
{:type :checkbox
@@ -36,7 +36,6 @@
:accessibility-label :user-list-toggle-check
:disabled? disabled?
:on-change (when on-check on-check)}]
:close
[text/text "not implemented"]
[rn/view])]))
@@ -66,8 +66,7 @@
button-label]])
(defn small-option-card
[{:keys [variant title subtitle button-label image max-height on-press accessibility-label
button-type container-style]
[{:keys [variant title subtitle button-label image max-height on-press accessibility-label button-type]
:or {variant :main accessibility-label :small-option-card}}]
(let [main-variant? (= variant :main)
card-component (if main-variant? main-variant icon-variant)
@@ -75,7 +74,7 @@
(not main-variant?) style/icon-variant-height
max-height (min max-height style/main-variant-height)
:else style/main-variant-height)]
[rn/view {:style (merge (style/card card-height) container-style)}
[rn/view {:style (style/card card-height)}
[card-component
{:title title
:subtitle subtitle
@@ -15,8 +15,7 @@
:border-color (colors/theme-colors colors/neutral-20 dark-border theme)}))
(def text
{:flex 1
:margin-left 8})
{:margin-left 8})
(def icon-container
{:align-items :flex-end
+6 -1
View File
@@ -265,11 +265,16 @@
:sub-label nil
:chevron? false}))
;; TODO(OmarBasem): Requires design input.
(defn show-qr-entry
[public-key]
(entry {:icon :i/qr-code
:label (i18n/label :t/show-qr)
:on-press #(rf/dispatch [:contacts/show-qr-code public-key])
:on-press (fn []
(rf/dispatch [:universal-links/generate-profile-url
{:public-key public-key
:on-success #(rf/dispatch [:open-modal
:share-contact])}]))
:danger? false
:accessibility-label :show-qr-code
:sub-label nil
@@ -11,28 +11,28 @@
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
auth-button-icon-left size blur? container-style disabled? dependencies on-complete]
:or {container-style {:flex 1}}}]
(let [theme (quo.theme/use-theme)
auth-method (rf/sub [:auth-method])
biometric-auth? (= auth-method constants/auth-method-biometric)
on-complete-callback (rn/use-callback
(fn []
(rf/dispatch [:standard-auth/authorize
{:auth-button-icon-left auth-button-icon-left
:theme theme
:blur? blur?
:biometric-auth? biometric-auth?
:on-auth-success on-auth-success
:on-auth-fail on-auth-fail
:auth-button-label auth-button-label}]))
(vec (conj dependencies on-auth-success on-auth-fail)))
on-slider-complete (rn/use-callback
(fn [reset-slider-fn]
(js/setTimeout #(reset-slider-fn false) 500)
(if (fn? on-complete)
(on-complete)
(on-complete-callback)))
[on-complete on-complete-callback])
biometric-type (rf/sub [:biometrics/supported-type])]
(let [theme (quo.theme/use-theme)
auth-method (rf/sub [:auth-method])
biometric-auth? (= auth-method constants/auth-method-biometric)
authorization-callback (rn/use-callback
(fn []
(rf/dispatch [:standard-auth/authorize
{:auth-button-icon-left auth-button-icon-left
:theme theme
:blur? blur?
:biometric-auth? biometric-auth?
:on-auth-success on-auth-success
:on-auth-fail on-auth-fail
:auth-button-label auth-button-label}]))
(vec (conj dependencies on-auth-success on-auth-fail)))
on-slider-complete (rn/use-callback
(fn [reset-slider-fn]
(js/setTimeout #(reset-slider-fn false) 500)
(if (fn? on-complete)
(on-complete)
(authorization-callback)))
[on-complete authorization-callback])
biometric-type (rf/sub [:biometrics/supported-type])]
[quo/slide-button
{:container-style container-style
:size size
+7 -9
View File
@@ -213,15 +213,13 @@
(defn save-profile-url
[{:keys [db]} [public-key url]]
(let [contact-from-key (get-in db [:contacts/contacts public-key])
profile-public-key? (= public-key (get-in db [:profile/profile :public-key]))]
(when url
{:db (cond-> db
contact-from-key
(assoc-in [:contacts/contacts public-key :universal-profile-url] url)
profile-public-key?
(assoc-in [:profile/profile :universal-profile-url] url))})))
(when url
{:db
(cond-> db
(get-in db [:contacts/contacts public-key])
(assoc-in [:contacts/contacts public-key :universal-profile-url] url)
(= public-key (get-in db [:profile/profile :public-key]))
(assoc-in [:profile/profile :universal-profile-url] url))}))
(schema/=> save-profile-url
[:=>
+9 -1
View File
@@ -221,7 +221,10 @@
(def ^:const wallet-connect-eth-sign-typed-v4-method "eth_signTypedData_v4")
(def ^:const wallet-connect-supported-methods
#{wallet-connect-personal-sign-method
wallet-connect-eth-sign-method
wallet-connect-eth-send-transaction-method
;; NOTE: disabled, as we have no clear use cases for it and other wallets don't support it
;; wallet-connect-eth-sign-transaction-method
wallet-connect-eth-sign-typed-method
wallet-connect-eth-sign-typed-v4-method})
(def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"})
@@ -234,9 +237,11 @@
(def ^:const wallet-connect-message-signing-methods
#{wallet-connect-personal-sign-method
wallet-connect-eth-sign-typed-method
wallet-connect-eth-sign-method
wallet-connect-eth-sign-typed-v4-method})
(def ^:const wallet-connect-transaction-methods
#{wallet-connect-eth-send-transaction-method})
#{wallet-connect-eth-send-transaction-method
wallet-connect-eth-sign-transaction-method})
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
@@ -443,7 +448,10 @@
(def ^:const wallet-account-name-max-length 20)
(def ^:const gas-rate-low 0)
(def ^:const gas-rate-medium 1)
(def ^:const gas-rate-high 2)
(def ^:const gas-rate-custom 3)
(def ^:const send-type-transfer 0)
(def ^:const send-type-bridge 5)
(def ^:const send-type-erc-721-transfer 6)
@@ -151,12 +151,3 @@
error]]]})
(rf/reg-event-fx :contacts/update-nickname-error update-nickname-error)
(rf/reg-event-fx
:contacts/show-qr-code
(fn [{db :db} [public-key]]
{:db (assoc db :contacts/identity public-key)
:fx [[:dispatch
[:universal-links/generate-profile-url
{:public-key public-key
:on-success #(rf/dispatch [:open-modal :share-contact])}]]]}))
@@ -159,9 +159,7 @@
[content]
(reduce (fn [acc e]
(conj acc (resolve-group-system-message e)))
[rn/view
{:style {:flex-direction :row
:flex-wrap :wrap}}]
[quo/text]
(:parsed-text content)))
(defn group-system-message
+2 -25
View File
@@ -3,39 +3,16 @@
[react-native.core :as rn]
[status-im.common.events-helper :as events-helper]
[status-im.common.resources :as resources]
[status-im.constants :as constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- keycard-documentation
[]
[quo/documentation-drawers
{:title (i18n/label :t/keycard)
:shell? true}
[rn/view
[quo/text {:size :paragraph-2}
(i18n/label :t/keycard-documentation)]
[quo/button
{:size 40
:type :primary
:container-style {:margin-top 24 :margin-bottom 12}
:background :blur
:icon-right :i/external
:on-press #(rf/dispatch [:browser.ui/open-url constants/get-keycard-url])
:accessibility-label :get-keycard}
(i18n/label :t/buy-keycard)]]])
(defn view
[]
(let [{:keys [on-press]} (rf/sub [:get-screen-params])]
[:<>
[quo/page-nav
{:icon-name :i/arrow-left
:on-press events-helper/navigate-back
:right-side [{:icon-name :i/info
:on-press #(rf/dispatch [:show-bottom-sheet
{:content keycard-documentation
:shell? true}])}]}]
{:icon-name :i/arrow-left
:on-press events-helper/navigate-back}]
[quo/page-top
{:title (i18n/label :t/check-keycard)
:description :text
@@ -106,10 +106,3 @@
{:pin pin
:on-success #(rf/dispatch [:keycard.login/recover-profile-and-login %])
:on-failure #(rf/dispatch [:keycard/on-action-with-pin-error %])}]]}))))
(rf/reg-event-fx :keycard/create.seed-phrase-entered
(fn [{:keys [db]} [key-uid masked-seed-phrase]]
(if (contains? (:profile/profiles-overview db) key-uid)
{:fx [[:dispatch [:onboarding/multiaccount-already-exists key-uid]]]}
{:db (assoc-in db [:keycard :create :masked-phrase] masked-seed-phrase)
:fx [[:dispatch [:keycard/create.create-or-enter-pin]]]})))
+14 -21
View File
@@ -17,27 +17,20 @@
{:title (i18n/label :t/keycard-empty)
:description :text
:description-text (i18n/label :t/what-to-do)}]
[quo/small-option-card
{:variant :main
:title (i18n/label :t/create-new-profile)
:subtitle (i18n/label :t/new-key-pair-keycard)
:button-label (i18n/label :t/lets-go)
:accessibility-label :create-new-profile-keycard
:container-style {:margin-horizontal 20 :margin-top 8}
:image (resources/get-image :keycard-buy)
:button-type :primary
:on-press #(rf/dispatch [:keycard/create.get-phrase])}]
[quo/small-option-card
{:variant :icon
:title (i18n/label :t/import-recovery-phrase-to-keycard)
:subtitle (i18n/label :t/store-key-pair-on-keycard)
:accessibility-label :import-recovery-phrase-to-keycard
:container-style {:margin 20}
:image (resources/get-image :use-keycard)
:on-press #(rf/dispatch [:open-modal :screen/use-recovery-phrase-dark
{:on-success (fn [{:keys [key-uid phrase]}]
(rf/dispatch [:keycard/create.seed-phrase-entered
key-uid phrase]))}])}]])
[rn/view {:style {:padding-horizontal 28 :padding-top 20}}
[quo/small-option-card
{:variant :main
:title (i18n/label :t/create-new-profile)
:subtitle (i18n/label :t/new-key-pair-keycard)
:button-label (i18n/label :t/lets-go)
:accessibility-label :create-new-profile-keycard
:image (resources/get-image :keycard-buy)
:button-type :primary
:on-press #(rf/dispatch [:keycard/create.get-phrase])}]]
[quo/information-box
{:type :default
:style {:margin-top 32 :margin-horizontal 28}}
(i18n/label :t/add-key-pair-desktop)]])
(defn view
[]
-13
View File
@@ -76,16 +76,3 @@
args
:on-success (get-on-success args)
:on-failure (get-on-failure args)))
(defn keycard-address?
[keypairs address]
(let [find-keycard-keypair (fn [kps] (some #(when-not (empty? (:keycards %)) %) kps))
keypair-addresses (fn [kp]
(->> (:accounts kp)
(map :address)
set))]
(-> keypairs
vals
find-keycard-keypair
keypair-addresses
(contains? (string/lower-case address)))))
+8 -14
View File
@@ -107,19 +107,6 @@
[:navigate-to-within-stack [:screen/onboarding.enable-biometrics from-screen]]
[:onboarding/create-account-and-login])]]})))
(rf/reg-event-fx
:onboarding/multiaccount-already-exists
(fn [_ [key-uid]]
{:fx [[:effects.utils/show-confirmation
{:title (i18n/label :t/multiaccount-exists-title)
:content (i18n/label :t/multiaccount-exists-content)
:confirm-button-text (i18n/label :t/unlock)
:on-accept (fn []
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
;; Note - Profile selection is not working
(re-frame/dispatch [:profile/profile-selected key-uid]))
:on-cancel #(re-frame/dispatch [:pop-to-root :screen/profile.profiles])}]]}))
(rf/reg-event-fx
:onboarding/seed-phrase-validated
(fn [{:keys [db]} [seed-phrase key-uid]]
@@ -128,7 +115,14 @@
:onboarding/navigated-to-enter-seed-phrase-from-screen
:screen/onboarding.create-profile)]
(if (contains? (:profile/profiles-overview db) key-uid)
{:fx [[:dispatch [:onboarding/multiaccount-already-exists key-uid]]]}
{:fx [[:effects.utils/show-confirmation
{:title (i18n/label :t/multiaccount-exists-title)
:content (i18n/label :t/multiaccount-exists-content)
:confirm-button-text (i18n/label :t/unlock)
:on-accept (fn []
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
(re-frame/dispatch [:profile/profile-selected key-uid]))
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}]]}
{:db (-> db
(assoc-in [:onboarding/profile :seed-phrase] seed-phrase)
(assoc-in [:onboarding/profile :key-uid] key-uid)
@@ -52,9 +52,7 @@
[quo/drawer-top
{:type :context-tag
:context-tag-type :default
:title (if has-nickname?
(i18n/label :t/edit-nickname)
(i18n/label :t/add-nickname-title))
:title (i18n/label :t/add-nickname-title)
:full-name full-name
:profile-picture profile-picture
:customization-color customization-color}]
@@ -2,7 +2,6 @@
(:require [quo.core :as quo]
[react-native.core :as rn]
[react-native.safe-area :as safe-area]
[status-im.common.events-helper :as events-helper]
[status-im.common.qr-codes.view :as qr-codes]
[status-im.contexts.profile.contact.share.style :as style]
[status-im.contexts.profile.utils :as profile.utils]
@@ -10,32 +9,32 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn navigation-back [] (rf/dispatch [:navigate-back]))
(defn view
[]
(let [{:keys [universal-profile-url customization-color]
:as profile} (rf/sub [:contacts/current-contact])
abbreviated-url (rn/use-memo
(fn []
(address/get-abbreviated-profile-url universal-profile-url))
[universal-profile-url])
on-share-press (rn/use-callback
#(rf/dispatch [:open-share
{:options {:message universal-profile-url}}])
[universal-profile-url])
on-copy-press (rn/use-callback
(fn []
(rf/dispatch
[:share/copy-text-and-show-toast
{:text-to-copy universal-profile-url
:post-copy-message (i18n/label :t/link-to-profile-copied)}]))
[universal-profile-url])]
abbreviated-url (rn/use-memo (fn []
(address/get-abbreviated-profile-url universal-profile-url))
[universal-profile-url])
on-share-press (rn/use-callback #(rf/dispatch [:open-share
{:options {:message universal-profile-url}}])
[universal-profile-url])
on-copy-press (rn/use-callback (fn []
(rf/dispatch [:share/copy-text-and-show-toast
{:text-to-copy universal-profile-url
:post-copy-message
(i18n/label
:t/link-to-profile-copied)}]))
[universal-profile-url])]
[quo/overlay {:type :shell}
[rn/view
{:style {:padding-top (safe-area/get-top)}
:key :share-community}
[quo/page-nav
{:icon-name :i/close
:on-press events-helper/navigate-back
:on-press navigation-back
:background :blur
:accessibility-label :top-bar}]
[quo/page-top
+5 -5
View File
@@ -24,11 +24,11 @@
(defn- reduce-profiles
[profiles]
(reduce (fn [acc {:keys [key-uid] :as profile}]
(def --x profile)
(assoc acc key-uid (profile.rpc/rpc->profiles-overview profile)))
{}
profiles))
(reduce
(fn [acc {:keys [key-uid] :as profile}]
(assoc acc key-uid (profile.rpc/rpc->profiles-overview profile)))
{}
profiles))
(rf/reg-fx
:profile/get-profiles-overview
@@ -40,15 +40,11 @@
;; login phase 1: we want to load and show chats faster, so we split login into 2 phases
(rf/reg-event-fx :profile.login/login-existing-profile
(fn [{:keys [db]} [settings-data account]]
(let [_ (def --sd settings-data)
settings (data-store.settings/rpc->settings settings-data)
_ (def --s settings)
(let [settings (data-store.settings/rpc->settings settings-data)
profile-overview (profile.rpc/rpc->profiles-overview account)
_ (def --xx profile-overview)
log-level (or (:log-level settings) config/log-level)
pairing-completed? (= (get-in db [:syncing :pairing-status]) :completed)
biometric-supported-type (get-in db [:biometrics :supported-type])
_ (def --db db)
new-db (-> db
(assoc :profile/profile
(merge profile-overview
@@ -56,13 +52,7 @@
{:log-level log-level}))
(assoc-in [:activity-center :loading?] true)
(dissoc :centralized-metrics/onboarding-enabled?))
_ (def --ndb new-db)
keycard? (get-in new-db [:profile/profile :keycard-pairing])]
(comment
(:compressed-key (:profile/profile --ndb))
(keys --s)
)
{:db (cond-> new-db
pairing-completed? (dissoc :syncing))
:fx (into [[:json-rpc/call
+1 -5
View File
@@ -16,9 +16,5 @@
(dissoc :customizationColor)
(assoc :customization-color (keyword customizationColor))
(assoc :ens-name? (utils.ens/is-valid-eth-name? (:name profile)))
(assoc :keycard-pairing (when-not (string/blank? keycard-pairing) keycard-pairing))
(update :name #(if (empty? %)
(:name profile)
;(:alias profile)
(:name profile))))
(assoc :keycard-pairing (when-not (string/blank? keycard-pairing) keycard-pairing)))
profile))
@@ -30,7 +30,8 @@
type :no-title}}]
(let [{:keys [color emoji watch-only?]} (rf/sub [:wallet/current-viewing-account])
networks (rf/sub [:wallet/selected-network-details])
sending-collectible? (rf/sub [:wallet/sending-collectible?])]
sending-collectible? (rf/sub [:wallet/sending-collectible?])
keycard? (rf/sub [:wallet/selected-keypair-keycard?])]
[quo/page-nav
{:type type
:icon-name icon-name
@@ -45,7 +46,11 @@
(not watch-only?)
show-dapps-button?)
{:icon-name :i/dapps
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
:on-press #(rf/dispatch
(if keycard?
[:keycard/feature-unavailable-show
{:feature-name :wallet.show-connected-dapps}]
[:navigate-to :screen/wallet.connected-dapps]))})
(when-not sending-collectible?
{:content-type :account-switcher
:customization-color color
@@ -279,7 +279,8 @@
:to (:to-chain new-path)
:approval-amount-required (:approval-amount-required new-path)
;; :cost () ;; tbd not used on desktop
:gas-amount (:tx-gas-amount new-path)}))
:gas-amount (:tx-gas-amount new-path)
:router-input-params-uuid (:router-input-params-uuid new-path)}))
(defn tokens-never-loaded?
[db]
+3 -7
View File
@@ -120,13 +120,9 @@
(rf/reg-fx
:effects.wallet/sign-transaction-hashes
(fn [{:keys [hashes address password on-success on-error]}]
(tap> {:in :effects.wallet/sign-transaction-hashes
:hashes hashes
:password password})
(-> (sign-transaction-hashes hashes address password)
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet/sign-message
(fn [{:keys [message address password on-success on-error]}]
(-> (wallet-rpc/sign-message message address (security/safe-unmask-data password))
(promesa/then on-success)
(promesa/catch on-error))))
@@ -762,6 +762,8 @@
(rf/reg-event-fx
:wallet/sign-transactions-signal-received
(fn [{:keys [db]} [{send-details :sendDetails :as data}]]
(tap> {:in :wallet/sign-transactions-signal-received
:data data})
(let [type (if (or (= (:fromToken send-details)
(:toToken send-details))
(string/blank? (:toToken send-details)))
@@ -781,6 +783,7 @@
(fn [{:keys [db]}
[{sent-transactions :sentTransactions
send-details :sendDetails}]]
(tap> {:in :wallet/transactions-sent-signal-received})
(let [swap? (get-in db [:wallet :ui :swap])]
{:fx [[:dispatch
(if-let [error-response (:errorResponse send-details)]
+1 -1
View File
@@ -47,7 +47,7 @@
chain-id
constants/transaction-pending-type-wallet-connect-transfer
(transforms/js-stringify tx-args 0)
(utils.hex/normalize-hex signature)))
signature))
(defn sign-message
[message address password]
+37 -2
View File
@@ -4,6 +4,7 @@
[status-im.constants :as constants]
[status-im.contexts.wallet.collectible.utils :as collectible.utils]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.send.utils :as send-utils]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[status-im.contexts.wallet.data-store :as data-store]
[status-im.contexts.wallet.send.utils :as send-utils]
@@ -12,7 +13,8 @@
[utils.money :as utils.money]
[utils.number]
[utils.re-frame :as rf]
[utils.security.core :as security]))
[utils.security.core :as security]
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]))
(rf/reg-event-fx :wallet/clean-send-data
(fn [{:keys [db]}]
@@ -386,7 +388,7 @@
{:db (-> db
(assoc-in [:wallet :ui :send :amount] amount)
(update-in [:wallet :ui :send] dissoc :transaction-for-signing))
:fx [[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
:fx [#_[:dispatch [:wallet/build-transactions-from-route {:request-uuid last-request-uuid}]]
[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen stack-id
@@ -651,6 +653,8 @@
(rf/reg-event-fx
:wallet/build-transactions-from-route
(fn [_ [{:keys [request-uuid slippage] :or {slippage constants/default-slippage}}]]
(tap> {:in :wallet/build-transactions-from-route
:request-uuid request-uuid})
{:json-rpc/call [{:method "wallet_buildTransactionsFromRoute"
:params [{:uuid request-uuid
:slippagePercentage slippage}]
@@ -666,6 +670,9 @@
(rf/reg-event-fx
:wallet/prepare-signatures-for-transactions
(fn [{:keys [db]} [type sha3-pwd]]
(tap> {:in :wallet/prepare-signatures-for-transactions
:type type
:sha3-pwd sha3-pwd})
(let [{:keys [hashes address signOnKeycard]} (get-in db
[:wallet :ui type :transaction-for-signing
:signingDetails])
@@ -702,6 +709,9 @@
(rf/reg-event-fx
:wallet/send-router-transactions-with-signatures
(fn [{:keys [db]} [type signatures]]
(tap> {:in :wallet/send-router-transactions-with-signatures
:type type
:signatures signatures})
(let [transaction-for-signing (get-in db [:wallet :ui type :transaction-for-signing])
signatures-map (reduce (fn [acc {:keys [message signature]}]
(assoc acc
@@ -842,3 +852,28 @@
:wallet/set-nonce
(fn [{db :db} [value]]
{:db (assoc-in db [:wallet :ui :send :tx-settings :nonce :current] value)}))
(rf/reg-event-fx :wallet/quick-transaction-settings-confirmed
(fn [_cofx [path-tx-identity fee-mode]]
(let [params [path-tx-identity fee-mode]]
{:json-rpc/call [{:method "wallet_setFeeMode"
:params params
:on-error (fn [error]
(log/error "failed to get suggested routes (async)"
{:event :wallet/start-get-suggested-routes
:error (:message error)
:params params}))}]})))
#_(rf/reg-event-fx :wallet/quick-transaction-settings-confirmed
(fn [_cofx [path-tx-identity fee-mode]]
(let [params [path-tx-identity fee-mode]]
{:json-rpc/call [{:method "wallet_setCustomTxDetails"
:params params
:on-error (fn [error]
(tap> {:in :wallet/quick-transaction-settings-confirmed
:error error})
(log/error "failed to get suggested routes (async)"
{:event :wallet/start-get-suggested-routes
:error (:message error)
:params params}))}]})))
@@ -8,6 +8,7 @@
[status-im.common.events-helper :as events-helper]
[status-im.common.floating-button-page.view :as floating-button-page]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.send.transaction-confirmation.style :as style]
[status-im.contexts.wallet.send.transaction-settings.view :as transaction-settings]
@@ -167,11 +168,19 @@
:title title
:subtitle subtitle}])
(defn quick-transaction-settings-confirmed
[path-identity setting]
(let [gas-rate (case setting
:normal constants/gas-rate-low
:fast constants/gas-rate-medium
:urgent constants/gas-rate-high
constants/gas-rate-low)]
(rf/dispatch [:wallet/quick-transaction-settings-confirmed path-identity gas-rate])))
(defn- transaction-details
[{:keys [estimated-time-min max-fees to-network route
transaction-type]}]
(let [route-loaded? (and route (seq route))
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
[{:keys [estimated-time-min max-fees to-network
transaction-type path-identity route-loaded?]}]
(let [loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
amount (rf/sub [:wallet/send-total-amount-formatted])]
[rn/view
{:style (style/details-container
@@ -190,9 +199,14 @@
:inner-style {:opacity 1}
:accessibility-label :advanced-button
:container-style {:margin-right 8}
:on-press #(rf/dispatch
[:show-bottom-sheet
{:content transaction-settings/settings-sheet}])}
:on-press (fn []
(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[transaction-settings/settings-sheet
#(quick-transaction-settings-confirmed
path-identity
%)])}]))}
:i/advanced])
[data-item
{:title (i18n/label :t/est-time)
@@ -217,6 +231,7 @@
{:keys [token-display-name collectible amount
route
to-address bridge-to-chain-id type
last-request-uuid
recipient]} send-transaction-data
collectible? (some? collectible)
image-url (when collectible
@@ -248,9 +263,7 @@
account))}
user-props {:full-name to-address
:address (utils/get-shortened-address
to-address)}
sign-on-keycard? (get-in transaction-for-signing
[:signingDetails :signOnKeycard])]
to-address)}]
(hot-reload/use-safe-unmount #(rf/dispatch [:wallet/clean-route-data-for-collectible-tx]))
;; In token send flow we already have transaction built when
;; we reach confirmation screen. But in send collectible flow
@@ -283,7 +296,9 @@
:to-network bridge-to-network
:theme theme
:route route
:transaction-type transaction-type}]
:transaction-type transaction-type
:path-identity (send-utils/path-identity first-route)
:route-loaded? (and route (seq route))}]
(when (and (not loading-suggested-routes?) route (seq route))
[standard-auth/slide-button
{:size :size-48
@@ -291,10 +306,11 @@
(i18n/label :t/slide-to-bridge)
(i18n/label :t/slide-to-send))
:container-style {:z-index 2}
:disabled? (not transaction-for-signing)
;; :disabled? (not transaction-for-signing)
:customization-color account-color
:auth-button-label (i18n/label :t/confirm)
:on-complete (when sign-on-keycard?
:on-complete (when (get-in transaction-for-signing
[:signingDetails :signOnKeycard])
#(rf/dispatch
[:wallet/prepare-signatures-for-transactions
:send
@@ -66,7 +66,7 @@
:button-one-label (i18n/label :t/confirm)}]]))
(defn settings-sheet
[_]
[on-quick-settings-confirmed]
(let [[selected-id set-selected-id] (rn/use-state :normal)]
[rn/view
[quo/drawer-top
@@ -119,7 +119,11 @@
:preview-size :size-32}]}]
[quo/bottom-actions
{:actions :one-action
:button-one-props {:on-press #(rf/dispatch [:hide-bottom-sheet])}
:button-one-props {:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(when on-quick-settings-confirmed
(on-quick-settings-confirmed selected-id))
)}
:button-one-label (i18n/label :t/confirm)}]]))
(defn- hint
@@ -224,3 +224,10 @@
{:r (subs signature 0 64)
:s (subs signature 64 128)
:v (subs signature 128 130)})
(defn path-identity
[path]
{:routerInputParamsUuid (:router-input-params-uuid path)
:pathName (:bridge-name path)
:chainID (get-in path [:to :chain-id])
:isApprovalTx (:approval-required path)})
@@ -7,7 +7,7 @@
[utils.re-frame :as rf]))
(defn- crypto-on-ramp-item
[{:keys [name fees logo-url site-url recurrent-site-url urls-need-parameters]
[{:keys [name description fees logo-url site-url recurrent-site-url urls-need-parameters]
:as provider}
_
_
@@ -22,16 +22,18 @@
(rn/open-url (if (= tab :recurrent) recurrent-site-url site-url))))
[site-url recurrent-site-url tab])]
[quo/settings-item
{:title name
:tag :context
:tag-props {:icon :i/fees
:context fees}
:action :arrow
:action-props {:alignment :flex-start
:icon :i/external}
:image :icon-avatar
:image-props {:icon logo-url}
:on-press open-url}]))
{:title name
:description :text
:description-props {:text description}
:tag :context
:tag-props {:icon :i/fees
:context fees}
:action :arrow
:action-props {:alignment :flex-start
:icon :i/external}
:image :icon-avatar
:image-props {:icon logo-url}
:on-press open-url}]))
(def ^:private tabs
[{:id :one-time
@@ -1,16 +1,16 @@
(ns status-im.contexts.wallet.wallet-connect.events.effects
(:require
[native-module.core :as native-module]
[promesa.core :as promesa]
[react-native.wallet-connect :as wallet-connect]
[status-im.config :as config]
[status-im.constants :as constants]
[status-im.contexts.wallet.rpc :as wallet-rpc]
[status-im.contexts.wallet.wallet-connect.utils.sessions :as sessions]
[status-im.contexts.wallet.wallet-connect.utils.signing :as signing]
[status-im.contexts.wallet.wallet-connect.utils.transactions :as transactions]
[status-im.contexts.wallet.wallet-connect.utils.typed-data :as typed-data]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.transforms :as transforms]))
[utils.security.core :as security]))
(rf/reg-fx
:effects.wallet-connect/init
@@ -69,21 +69,20 @@
(promesa/catch (partial rf/call-continuation on-fail)))))
(rf/reg-fx
:effects.wallet-connect/hash-message
(fn [{:keys [message on-success on-fail]}]
(-> (wallet-rpc/hash-message-eip-191 message)
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-fail)))))
:effects.wallet-connect/sign-message
(fn [{:keys [password address data rpc-method on-success on-error]}]
(let [password (security/safe-unmask-data password)]
(-> (condp =
rpc-method
:personal-sign
(signing/personal-sign password address data)
(rf/reg-fx
:effects.wallet-connect/hash-typed-data
(fn [{:keys [message legacy? on-success on-fail]}]
(-> (if legacy?
(native-module/hash-typed-data message)
(native-module/hash-typed-data-v4 message))
(promesa/then (fn [response] (-> response transforms/json->clj :result)))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-fail)))))
:eth-sign
(signing/eth-sign password address data)
(signing/personal-sign password address data))
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error))))))
(rf/reg-fx
:effects.wallet-connect/prepare-transaction
@@ -94,12 +93,36 @@
(promesa/then on-success)
(promesa/catch on-error))))
(rf/reg-fx
:effects.wallet-connect/sign-transaction
(fn [{:keys [password address chain-id tx-hash tx-args on-success on-error]}]
(-> (transactions/sign-transaction (security/safe-unmask-data password)
address
tx-hash
tx-args
chain-id)
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
(rf/reg-fx
:effects.wallet-connect/send-transaction
(fn [{:keys [chain-id signature tx-args on-success on-error]}]
(-> (wallet-rpc/send-transaction-with-signature chain-id
tx-args
signature)
(fn [{:keys [password address chain-id tx-hash tx-args on-success on-error]}]
(-> (transactions/send-transaction (security/safe-unmask-data password)
address
tx-hash
tx-args
chain-id)
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
(rf/reg-fx
:effects.wallet-connect/sign-typed-data
(fn [{:keys [password address data version chain-id on-success on-error]}]
(-> (typed-data/sign (security/safe-unmask-data password)
address
data
chain-id
version)
(promesa/then (partial rf/call-continuation on-success))
(promesa/catch (partial rf/call-continuation on-error)))))
@@ -2,6 +2,7 @@
(:require [clojure.string :as string]
[re-frame.core :as rf]
[react-native.wallet-connect :as wallet-connect]
[status-im.contexts.wallet.data-store :as wallet-data-store]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store]
[status-im.contexts.wallet.wallet-connect.utils.networks :as networks]
@@ -45,8 +46,15 @@
expired? (-> parsed-uri
:expiryTimestamp
uri/timestamp-expired?)
version-supported? (uri/version-supported? version)]
version-supported? (uri/version-supported? version)
keycard? (wallet-data-store/selected-keypair-keycard? db)]
(cond
keycard?
{:fx [[:dispatch
[:keycard/feature-unavailable-show
{:feature-name :wallet.scan-dapp-connection}]]]}
(or (not valid-wc-uri?)
(not version-supported?)
(= network-status :offline)
@@ -41,6 +41,12 @@
[:wallet-connect/process-eth-send-transaction
{:on-success (fn [] (rf/dispatch [:wallet-connect/show-request-modal]))}]]
constants/wallet-connect-eth-sign-method
[:dispatch [:wallet-connect/process-eth-sign]]
constants/wallet-connect-eth-sign-transaction-method
[:dispatch [:wallet-connect/process-eth-sign-transaction]]
constants/wallet-connect-eth-sign-typed-method
[:dispatch [:wallet-connect/process-sign-typed]]
@@ -50,13 +56,6 @@
constants/wallet-connect-personal-sign-method
[:dispatch [:wallet-connect/process-personal-sign]])]}))))
(rf/reg-event-fx
:wallet-connect/store-prepared-hash
(fn [{:keys [db]} [prepared-hash]]
{:db (assoc-in db
[:wallet-connect/current-request :prepared-hash]
prepared-hash)}))
(rf/reg-event-fx
:wallet-connect/process-personal-sign
(fn [{:keys [db]}]
@@ -66,20 +65,30 @@
[:wallet-connect/current-request]
assoc
:address (string/lower-case address)
:raw-data raw-data
:display-data (or parsed-data raw-data))
:fx [[:effects.wallet-connect/hash-message
{:message raw-data
:on-success #(rf/dispatch [:wallet-connect/store-prepared-hash %])
:on-fail #(rf/dispatch [:wallet-connect/on-processing-error %])}]
[:dispatch [:wallet-connect/show-request-modal]]]})))
:fx [[:dispatch [:wallet-connect/show-request-modal]]]})))
(rf/reg-event-fx
:wallet-connect/process-eth-sign
(fn [{:keys [db]}]
(let [[address raw-data] (data-store/get-db-current-request-params db)
parsed-data (native-module/hex-to-utf8 raw-data)]
{:db (update-in db
[:wallet-connect/current-request]
assoc
:address (string/lower-case address)
:raw-data raw-data
:display-data (or parsed-data raw-data))
:fx [[:dispatch [:wallet-connect/show-request-modal]]]})))
(rf/reg-event-fx
:wallet-connect/prepare-transaction-success
(fn [{:keys [db]} [prepared-tx chain-id]]
(let [{:keys [tx-args tx-hash]} prepared-tx
tx (bean/->clj tx-args)
address (-> tx :from string/lower-case)
display-data (transactions/beautify-transaction tx)]
(let [{:keys [tx-args]} prepared-tx
tx (bean/->clj tx-args)
address (-> tx :from string/lower-case)
display-data (transactions/beautify-transaction tx)]
{:db (update-in db
[:wallet-connect/current-request]
assoc
@@ -87,8 +96,7 @@
:raw-data prepared-tx
:transaction tx
:chain-id chain-id
:display-data display-data)
:fx [[:dispatch [:wallet-connect/store-prepared-hash tx-hash]]]})))
:display-data display-data)})))
(rf/reg-event-fx
:wallet-connect/process-eth-send-transaction
@@ -108,14 +116,25 @@
(rf/call-continuation on-success)))
:on-error #(rf/dispatch [:wallet-connect/on-processing-error %])}]]}))))
(rf/reg-event-fx
:wallet-connect/process-eth-sign-transaction
(fn [{:keys [db]}]
(let [event (data-store/get-db-current-request-event db)
tx (-> event data-store/get-request-params first)
chain-id (-> event
(get-in [:params :chainId])
networks/eip155->chain-id)]
{:fx [[:effects.wallet-connect/prepare-transaction
{:tx tx
:chain-id chain-id
:on-success #(rf/dispatch [:wallet-connect/prepare-transaction-success % chain-id])
:on-error #(rf/dispatch [:wallet-connect/on-processing-error %])}]]})))
(rf/reg-event-fx
:wallet-connect/process-sign-typed
(fn [{:keys [db]}]
(try
(let [[address raw-data] (data-store/get-db-current-request-params db)
method (-> db
data-store/get-db-current-request-event
data-store/get-request-method)
session-chain-id (-> (data-store/get-db-current-request-event db)
(get-in [:params :chainId])
networks/eip155->chain-id)
@@ -135,13 +154,7 @@
:address (string/lower-case address)
:display-data (typed-data/flatten-typed-data typed-data)
:raw-data raw-data)
:fx [[:effects.wallet-connect/hash-typed-data
{:message raw-data
:legacy? (not= constants/wallet-connect-eth-sign-typed-v4-method
method)
:on-success #(rf/dispatch [:wallet-connect/store-prepared-hash %])
:on-fail #(rf/dispatch [:wallet-connect/on-processing-error %])}]
[:dispatch [:wallet-connect/show-request-modal]]]}))
:fx [[:dispatch [:wallet-connect/show-request-modal]]]}))
(catch js/Error err
{:fx [[:dispatch
[:wallet-connect/on-processing-error
@@ -2,47 +2,16 @@
(:require [re-frame.core :as rf]
[react-native.wallet-connect :as wallet-connect]
[status-im.constants :as constants]
[status-im.contexts.keycard.utils :as keycard]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store]
[status-im.contexts.wallet.wallet-connect.utils.uri :as uri]
[taoensso.timbre :as log]
[utils.hex :as hex]
[utils.i18n :as i18n]
[utils.transforms :as transforms]))
(rf/reg-event-fx
:wallet-connect/authorized-signing
:wallet-connect/respond-current-session
(fn [{:keys [db]} [password]]
(let [prepared-hash (get-in db [:wallet-connect/current-request :prepared-hash])
address (get-in db [:wallet-connect/current-request :address])
keycard-sign? (-> (get-in db [:wallet :keypairs])
(keycard/keycard-address? address))
on-success #(rf/dispatch [:wallet-connect/respond (hex/prefix-hex %)])
on-fail #(rf/dispatch [:wallet-connect/on-sign-error %])]
(if keycard-sign?
{:fx [[:dispatch
[:standard-auth/authorize-with-keycard
{:on-complete (fn [pin]
(rf/dispatch [:keycard/connect-and-sign-hashes
{:keycard-pin pin
:address address
:hashes [prepared-hash]
:on-success (fn [signatures]
(rf/dispatch [:hide-bottom-sheet])
(on-success (:signature (first
signatures))))
:on-failure on-fail}]))}]]]}
{:fx [[:effects.wallet/sign-message
{:message prepared-hash
:address address
:password password
:on-success on-success
:on-error on-fail}]]}))))
(rf/reg-event-fx
:wallet-connect/respond
(fn [{:keys [db]} [signature]]
(let [event (get-in db [:wallet-connect/current-request :event])
method (data-store/get-request-method event)
screen (data-store/method-to-screen method)
@@ -50,30 +19,83 @@
(if (uri/timestamp-expired? expiry)
{:fx [[:dispatch
[:toasts/upsert
{:type :negative
{:id :new-wallet-account-created
:type :negative
:text (i18n/label :t/wallet-connect-request-expired)}]]
[:dispatch [:dismiss-modal screen]]]}
{:fx [(condp contains? method
#{constants/wallet-connect-personal-sign-method
constants/wallet-connect-eth-sign-typed-method
constants/wallet-connect-eth-sign-typed-v4-method}
[:dispatch [:wallet-connect/finish-session-request signature]]
{:fx [(condp = method
constants/wallet-connect-personal-sign-method
[:dispatch [:wallet-connect/respond-sign-message password :personal-sign]]
#{constants/wallet-connect-eth-send-transaction-method}
[:dispatch [:wallet-connect/respond-send-transaction-data signature]])]}))))
constants/wallet-connect-eth-sign-method
[:dispatch [:wallet-connect/respond-sign-message password :eth-sign]]
constants/wallet-connect-eth-send-transaction-method
[:dispatch [:wallet-connect/respond-send-transaction-data password]]
constants/wallet-connect-eth-sign-transaction-method
[:dispatch [:wallet-connect/respond-sign-transaction-data password]]
constants/wallet-connect-eth-sign-typed-method
[:dispatch [:wallet-connect/respond-sign-typed-data password :v1]]
constants/wallet-connect-eth-sign-typed-v4-method
[:dispatch [:wallet-connect/respond-sign-typed-data password :v4]])]}))))
(rf/reg-event-fx
:wallet-connect/respond-sign-message
(fn [{:keys [db]} [password rpc-method]]
(let [{:keys [address raw-data]} (get db :wallet-connect/current-request)]
{:fx [[:effects.wallet-connect/sign-message
{:password password
:address address
:data raw-data
:rpc-method rpc-method
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/finish-session-request]}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-typed-data
(fn [{:keys [db]} [password typed-data-version]]
(let [{:keys [address raw-data event]} (get db :wallet-connect/current-request)
chain-id (get-in event [:params :chainId])]
{:fx [[:effects.wallet-connect/sign-typed-data
{:password password
:address address
:data raw-data
:chain-id chain-id
:version typed-data-version
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/finish-session-request]}]]})))
(rf/reg-event-fx
:wallet-connect/respond-send-transaction-data
(fn [{:keys [db]} [signature]]
(let [{:keys [chain-id raw-data]} (get db :wallet-connect/current-request)
{:keys [tx-args]} raw-data]
(fn [{:keys [db]} [password]]
(let [{:keys [chain-id raw-data address]} (get db :wallet-connect/current-request)
{:keys [tx-hash tx-args]} raw-data]
{:fx [[:effects.wallet-connect/send-transaction
{:signature signature
{:password password
:address address
:chain-id chain-id
:tx-hash tx-hash
:tx-args tx-args
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/finish-session-request]}]]})))
(rf/reg-event-fx
:wallet-connect/respond-sign-transaction-data
(fn [{:keys [db]} [password]]
(let [{:keys [chain-id raw-data address]} (get db :wallet-connect/current-request)
{:keys [tx-hash tx-args]} raw-data]
{:fx [[:effects.wallet-connect/sign-transaction
{:password password
:address address
:chain-id chain-id
:tx-hash tx-hash
:tx-params tx-args
:on-error [:wallet-connect/on-sign-error]
:on-success [:wallet-connect/finish-session-request]}]]})))
(rf/reg-event-fx
:wallet-connect/on-sign-error
(fn [{:keys [db]} [error]]
@@ -12,14 +12,13 @@
(defn- on-auth-success
[password]
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:wallet-connect/authorized-signing password]))
(rf/dispatch [:wallet-connect/respond-current-session password]))
(defn view
[{:keys [warning-label slide-button-text error-state]} & children]
(let [{:keys [customization-color]} (rf/sub [:wallet-connect/current-request-account-details])
offline? (rf/sub [:network/offline?])
theme (quo.theme/use-theme)
sign-on-keycard? (rf/sub [:wallet-connect/sign-on-keycard?])]
theme (quo.theme/use-theme)]
[:<>
(when (or offline? error-state)
[quo/alert-banner
@@ -49,8 +48,6 @@
:disabled? (or offline? error-state)
:customization-color customization-color
:on-auth-success on-auth-success
:on-complete (when sign-on-keycard?
#(on-auth-success ""))
:auth-button-label (i18n/label :t/confirm)}]]
[rn/view {:style style/warning-container}
[quo/text
@@ -30,8 +30,10 @@
(def method-to-screen
{constants/wallet-connect-personal-sign-method :screen/wallet-connect.sign-message
constants/wallet-connect-eth-sign-typed-method :screen/wallet-connect.sign-message
constants/wallet-connect-eth-sign-method :screen/wallet-connect.sign-message
constants/wallet-connect-eth-sign-typed-v4-method :screen/wallet-connect.sign-message
constants/wallet-connect-eth-send-transaction-method :screen/wallet-connect.send-transaction})
constants/wallet-connect-eth-send-transaction-method :screen/wallet-connect.send-transaction
constants/wallet-connect-eth-sign-transaction-method :screen/wallet-connect.sign-transaction})
(defn extract-native-call-signature
[data]
@@ -57,11 +59,11 @@
(defn get-current-request-dapp
[request sessions]
(let [request-topic (get-in request [:event :topic])]
(let [dapp-url (get-in request [:event :verifyContext :verified :origin])]
(->> sessions
(filter (fn [session]
(= (:topic session)
request-topic)))
(= (utils.string/remove-trailing-slash dapp-url)
(utils.string/remove-trailing-slash (get session :url)))))
first)))
(defn get-dapp-redirect-url
@@ -8,15 +8,15 @@
(deftest get-current-request-dapp-test
(testing "returns the correct dapp based on the request's origin"
(let [request {:event {:topic "123"}}
sessions [{:topic "123"}
{:topic "456"}]]
(is (= {:topic "123"}
(let [request {:event {:verifyContext {:verified {:origin "https://dapp.com"}}}}
sessions [{:url "https://dapp.com"}
{:url "https://anotherdapp.com"}]]
(is (= {:url "https://dapp.com"}
(sut/get-current-request-dapp request sessions)))))
(testing "returns nil if no matching dapp is found"
(let [request {:event {:topic "123"}}
sessions [{:topic "456"}]]
(let [request {:event {:verifyContext {:verified {:origin "https://dapp.com"}}}}
sessions [{:url "https://anotherdapp.com"}]]
(is (nil? (sut/get-current-request-dapp request sessions))))))
(deftest get-dapp-redirect-url-test
@@ -0,0 +1,24 @@
(ns status-im.contexts.wallet.wallet-connect.utils.signing
(:require
[native-module.core :as native-module]
[promesa.core :as promesa]
[status-im.contexts.wallet.rpc :as wallet-rpc]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store]
[utils.hex :as hex]
[utils.transforms :as transforms]))
(defn eth-sign
[password address data]
(-> {:data data
:account address
:password password}
transforms/clj->json
native-module/sign-message
(promesa/then data-store/extract-native-call-signature)))
(defn personal-sign
[password address data]
(-> (wallet-rpc/hash-message-eip-191 data)
(promesa/then #(wallet-rpc/sign-message % address password))
(promesa/then hex/prefix-hex)))
@@ -14,7 +14,8 @@
(defn transaction-request?
[event]
(->> (data-store/get-request-method event)
(contains? constants/wallet-connect-transaction-methods)))
(contains? #{constants/wallet-connect-eth-send-transaction-method
constants/wallet-connect-eth-sign-transaction-method})))
;; NOTE: Currently we don't allow the user to configure the tx priority as we don't
;; show the estimated time, but when we implement it, we should allow to change it
@@ -135,6 +136,22 @@
:suggested-fees suggested-fees
:estimated-time estimated-time}))
(defn sign-transaction
[password address tx-hash tx-args chain-id]
(promesa/let
[signature (wallet-rpc/sign-message tx-hash address password)
raw-tx (wallet-rpc/build-raw-transaction chain-id tx-args signature)]
raw-tx))
(defn send-transaction
[password address tx-hash tx-args chain-id]
(promesa/let
[signature (wallet-rpc/sign-message tx-hash address password)
tx (wallet-rpc/send-transaction-with-signature chain-id
tx-args
signature)]
tx))
(defn transactions->display-array
[data]
(remove (fn [[k v]]
@@ -6,7 +6,7 @@
{:server-enabled? (config/enabled? config/STATUS_BACKEND_SERVER_ENABLED)
:status-go-endpoint (str "http://" config/STATUS_BACKEND_SERVER_HOST "/statusgo/")
:signal-endpoint (str "ws://" config/STATUS_BACKEND_SERVER_HOST "/signals")
:root-data-dir "/home/ulises/p/status-backend-data-dir/"})
:root-data-dir config/STATUS_BACKEND_SERVER_ROOT_DATA_DIR})
(defn set-config!
[{:keys [server-enabled? status-go-endpoint signal-endpoint root-data-dir]}]
@@ -1,6 +1,5 @@
(ns status-im.subs.wallet.dapps.requests
(:require [re-frame.core :as rf]
[status-im.contexts.keycard.utils :as keycard]
[status-im.contexts.wallet.common.utils :as wallet-utils]
[status-im.contexts.wallet.wallet-connect.utils.data-store :as
data-store]
@@ -60,10 +59,3 @@
:wallet-connect/typed-data-request?
:<- [:wallet-connect/current-request-method]
typed-data/typed-data-request?)
(rf/reg-sub
:wallet-connect/sign-on-keycard?
:<- [:wallet/keypairs]
:<- [:wallet-connect/current-request-address]
(fn [[keypairs address]]
(keycard/keycard-address? keypairs address)))
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v9.3.0",
"commit-sha1": "bec0c3733eb9629153bc3df3d6294cec6a23af09",
"src-sha256": "0vj9vhmlf8csnpy8b0xiny425yzpl4wj1z873igb5av5hqllabf3"
"version": "v9.1.0",
"commit-sha1": "4ec885a91f2857a30d1838213000f0a5a91fd52a",
"src-sha256": "1fkvhazv7v2vyqpffx3r4p3aii5ai464nx2pdfgn6b6gmb24bxdq"
}
@@ -40,10 +40,9 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
if text_name != self.username_1 and text_name != "%s...%s" % (
self.public_key_1[:3], self.public_key_1[-6:]):
self.errors.append(
self.home_2,
"Neither username nor public key is shown on 'Add contact' page after entering valid public key")
else:
self.errors.append(self.home_2, "User is not found on 'Add contact' page after entering valid public key")
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
chat = self.home_2.get_chat_view()
chat.view_profile_new_contact_button.click_until_presence_of_element(chat.profile_send_contact_request_button)
@@ -56,8 +55,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
self.device_1.just_fyi("Device 1: check there is no PN when receiving new message to activity centre")
self.device_1.open_notification_bar()
if self.home_1.element_by_text_part("Please add me to your contacts").is_element_displayed():
self.errors.append(self.home_1,
"Push notification with text was received for new message in activity centre")
self.errors.append("Push notification with text was received for new message in activity centre")
self.device_1.click_system_back_button()
self.device_1.driver.activate_app(app_package)
self.device_1.wait_for_application_to_be_running(app_package)
@@ -67,9 +65,9 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
for indicator in (self.home_1.notifications_unread_badge, self.home_1.contact_new_badge):
if not indicator.is_element_displayed():
self.errors.append(
self.home_1, "Unread indicator on contacts tab or on activity center is not shown for incoming CR!")
"Unread indicator on contacts tab or on activity center is not shown for incoming CR!")
if self.home_1.pending_contact_request_text.text != '1':
self.errors.append(self.home_1, "The amount of contact requests is not shown for incoming CR!")
self.errors.append("The amount of contact requests is not shown for incoming CR!")
self.device_1.just_fyi('Device1 declines pending contact request')
self.home_1.handle_contact_request(username=self.username_2, action='decline')
@@ -77,7 +75,6 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
self.home_1.pending_contact_request_text):
if indicator.is_element_displayed():
self.errors.append(
self.home_1,
"Unread indicator on contacts tab or on activity center is shown after declining contact request!")
self.device_1.just_fyi("Check that it is still pending contact after declining on sender device")
@@ -88,7 +85,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
if element.title.text != 'Contact request' or element.context_tag_text != self.username_1 \
or not element.pending_status_tag.is_element_displayed():
self.errors.append(
self.home_2, "Pending contact request is not shown on unread notification element on Activity center!")
"Pending contact request is not shown on unread notification element on Activity center!")
self.home_2.close_activity_centre.click()
self.errors.verify_no_errors()
@@ -126,8 +123,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
self.home_1.more_options_activity_button.click()
self.home_1.mark_all_read_activity_button.click()
if cr_element.is_element_displayed():
self.errors.append(
self.home_1, "Contact request is still shown in activity centre after marking all messages as read!")
self.errors.append("Contact request is still shown in activity centre after marking all messages as read!")
self.home_1.just_fyi("Check that can accept contact request from read notifications")
self.home_1.activity_unread_filter_button.click()
@@ -136,16 +132,14 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
self.home_1.close_activity_centre.click()
self.home_1.contacts_tab.click()
if not self.home_1.contact_details_row(username=new_username).is_element_displayed(20):
self.errors.append(self.home_1,
"Contact was not added to contact list after accepting contact request (as receiver)")
self.errors.append("Contact was not added to contact list after accepting contact request (as receiver)")
self.device_2.just_fyi('Device1 check that contact appeared in contact list mutually')
self.home_2.navigate_back_to_home_view()
self.home_2.chats_tab.click()
self.home_2.contacts_tab.click()
if not self.home_2.contact_details_row(username=self.username_1).is_element_displayed(20):
self.errors.append(self.home_2,
"Contact was not added to contact list after accepting contact request (as sender)")
self.errors.append("Contact was not added to contact list after accepting contact request (as sender)")
self.errors.verify_no_errors()
@@ -178,10 +172,9 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
text_name = self.home_1.user_name_text.text
if text_name != self.username_2 and text_name != "%s...%s" % (public_key_2[:3], public_key_2[-6:]):
self.errors.append(
self.home_1,
"Neither username nor public key is shown on 'Add contact' page after entering valid profile link")
else:
self.errors.append(self.home_1, "User is not found on 'Add contact' page after entering valid public key")
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
chat_1 = self.home_1.get_chat_view()
chat_1.view_profile_new_contact_button.click_until_presence_of_element(
chat_1.profile_send_contact_request_button)
@@ -204,10 +197,9 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
text_name = self.home_1.user_name_text.text
if text_name != self.username_2 and text_name != "%s...%s" % (public_key_2[:3], public_key_2[-6:]):
self.errors.append(
self.home_1,
"Neither username nor public key is shown on 'Add contact' page after entering valid public key")
else:
self.errors.append(self.home_1, "User is not found on 'Add contact' page after entering valid public key")
self.errors.append("User is not found on 'Add contact' page after entering valid public key")
self.home_2.just_fyi("Device 2 gets sync code")
self.home_2.navigate_back_to_home_view()
@@ -225,7 +217,7 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
try:
self.home_1.element_by_translation_id("invalid-ens-or-key").wait_for_visibility_of_element()
except TimeoutException:
self.errors.append(self.home_1, "Error message is not shown for value \"%s\"" % value)
self.errors.append("Error message is not shown for value \"%s\"" % value)
self.errors.verify_no_errors()
@@ -274,16 +266,15 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
self.community_1.click_on_floating_jump_to()
for card in (self.community_name, self.username_2):
if not self.community_1.element_by_text_part(card).is_element_displayed(20):
self.errors.append(self.community_1, "Card %s is not shown on Jump to screen!" % card)
self.errors.append("Card %s is not shown on Jump to screen!" % card)
self.community_1.element_by_translation_id("community-channel").click()
if not self.channel_1.chat_element_by_text(self.text_message).is_element_displayed(20):
self.errors.append(self.channel_1,
"User was not redirected to community channel after tapping on community channel card!")
self.errors.append("User was not redirected to community channel after tapping on community channel card!")
self.channel_1.click_system_back_button()
self.community_1.click_on_floating_jump_to()
self.community_1.element_by_text_part(self.username_2).click()
if not self.chat_1.chat_element_by_text(self.one_to_one_message).is_element_displayed(20):
self.errors.append(self.chat_1, "User was not redirected to 1-1 chat after tapping card!")
self.errors.append("User was not redirected to 1-1 chat after tapping card!")
self.errors.verify_no_errors()
@@ -307,29 +298,29 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
community_element_1 = self.home_1.get_chat(self.community_name, community=True)
for unread_counter in community_element_1.new_messages_counter, self.home_1.communities_tab.counter:
if not unread_counter.is_element_displayed(60):
self.errors.append(self.home_1, 'New message counter badge is not shown!')
self.errors.append('New message counter badge is not shown!')
if int(unread_counter.text) != 1:
self.errors.append(self.home_1, 'New message counter badge is not 1, it is %s!' % unread_counter.text)
self.errors.append('New message counter badge is not 1, it is %s!' % unread_counter.text)
self.home_1.just_fyi("Checking reply attributes in activity center")
self.home_1.open_activity_center_button.click()
reply_element = self.home_1.get_element_from_activity_center_view(reply_to_message_from_sender)
if reply_element.title.text != 'Reply':
self.errors.append(self.home_1, "Expected title is not shown, '%s' is instead!" % reply_element.title)
self.errors.append("Expected title is not shown, '%s' is instead!" % reply_element.title)
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append(self.home_1, "No unread dot is shown on activity center element!")
self.errors.append("No unread dot is shown on activity center element!")
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
self.home_1.just_fyi("Swiping to 'Replies' on activity center and check unread there")
self.home_1.mention_activity_tab_button.click()
if reply_element.is_element_displayed(2):
self.errors.append(self.home_1, "Filter on mentions is not working in Activity centre!")
self.errors.append("Filter on mentions is not working in Activity centre!")
self.home_1.reply_activity_tab_button.click()
if not self.home_1.reply_activity_tab_button.counter.is_element_displayed(2):
self.errors.append(self.home_1, "No unread dot is shown on activity center tab element!")
self.errors.append("No unread dot is shown on activity center tab element!")
if not reply_element.is_element_displayed():
self.errors.append(self.home_1, "Filter on replies tab is not working in Activity centre!")
self.errors.append("Filter on replies tab is not working in Activity centre!")
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
@@ -337,10 +328,10 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
reply_element.title.swipe_right_on_element(width_percentage=6)
self.home_1.activity_notification_swipe_button.click()
if reply_element.is_element_displayed(2):
self.errors.append(self.home_1, "Message is not marked as read!")
self.errors.append("Message is not marked as read!")
self.home_1.activity_unread_filter_button.click()
if not reply_element.is_element_displayed(2):
self.errors.append(self.home_1, "Read filter is not displayed read message!")
self.errors.append("Read filter is not displayed read message!")
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
@@ -348,18 +339,16 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
reply_element.title.swipe_right_on_element(width_percentage=6)
self.home_1.activity_notification_swipe_button.click()
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append(self.home_1,
"No unread dot is shown on activity center element after marking it as unread!")
self.errors.append("No unread dot is shown on activity center element after marking it as unread!")
self.home_1.just_fyi("Tap on it and check it marked as read")
reply_element.click()
if not self.channel_1.chat_element_by_text(reply_to_message_from_sender).is_element_displayed():
self.errors.append(self.home_1, "Was not redirected to chat after tapping on reply!")
self.errors.append("Was not redirected to chat after tapping on reply!")
self.home_1.navigate_back_to_home_view()
self.home_1.communities_tab.click()
if self.home_1.notifications_unread_badge.is_element_displayed():
self.errors.append(self.home_1,
"Notification was not marked as read after opening it in community channel!")
self.errors.append("Notification was not marked as read after opening it in community channel!")
self.home_2.chats_tab.is_element_displayed() # just saving device 2 session from expiration
@@ -368,7 +357,7 @@ class TestActivityMultipleDevicePR(MultipleSharedDeviceTestCase):
reply_element.swipe_left_on_element()
self.home_1.activity_notification_swipe_button.click()
if reply_element.is_element_displayed():
self.errors.append(self.home_1, "Reply is still shown after removing from activity centre!")
self.errors.append("Reply is still shown after removing from activity centre!")
self.errors.verify_no_errors()
@@ -425,26 +414,25 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
community_element_1 = self.home_1.get_chat(self.community_name, community=True)
for unread_counter in community_element_1.new_messages_counter, self.home_1.communities_tab.counter:
if not unread_counter.is_element_displayed(60):
self.errors.append(self.home_1, 'New message counter badge is not shown while mentioned!')
self.errors.append('New message counter badge is not shown while mentioned!')
if int(unread_counter.text) != 1:
self.errors.append(self.home_1, 'New message counter badge is not 1, it is %s!' % unread_counter.text)
self.errors.append('New message counter badge is not 1, it is %s!' % unread_counter.text)
self.home_1.just_fyi("Checking mention attributes in activity center")
self.home_1.open_activity_center_button.click()
mention_element = self.home_1.get_element_from_activity_center_view('@%s' % self.username_1)
if mention_element.title.text != 'Mention':
self.errors.append(self.home_1, "Expected title is not shown, '%s' is instead!" % mention_element.title)
self.errors.append("Expected title is not shown, '%s' is instead!" % mention_element.title)
if not mention_element.unread_indicator.is_element_displayed():
self.errors.append(self.home_1, "No unread dot is shown on activity center element (mention)!")
self.errors.append("No unread dot is shown on activity center element (mention)!")
if mention_element.message_body.text != '@%s' % self.username_1:
self.errors.append(
self.home_1, "Mention body in activity center does not match expected, it is %s!"
% mention_element.message_body.text)
"Mention body in activity center does not match expected, it is %s!" % mention_element.message_body.text)
self.home_1.just_fyi("Tap on it and check redirect to channel")
mention_element.click()
if not self.channel_1.chat_element_by_text(self.username_1).is_element_displayed():
self.errors.append(self.home_1, "Was not redirected to chat after tapping on mention!")
self.errors.append("Was not redirected to chat after tapping on mention!")
self.errors.verify_no_errors()
@marks.testrail_id(702958)
@@ -477,13 +465,13 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
try:
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(120)
except TimeoutException:
self.errors.append(self.home_1, "Unread indicator is not shown in notifications")
self.errors.append("Unread indicator is not shown in notifications")
self.home_1.open_activity_center_button.click()
reply_element = self.home_1.get_element_from_activity_center_view(self.username_2)
if reply_element.title.text != 'Join request':
self.errors.append(self.home_1, "Expected title is not shown, '%s' is instead!" % reply_element.title)
self.errors.append("Expected title is not shown, '%s' is instead!" % reply_element.title)
if not reply_element.unread_indicator.is_element_displayed():
self.errors.append(self.home_1, "No unread dot is shown on activity center element!")
self.errors.append("No unread dot is shown on activity center element!")
reply_element.title.swipe_right_on_element(width_percentage=2.5)
self.home_1.activity_notification_swipe_button.click()
self.home_1.close_activity_centre.click()
@@ -491,5 +479,5 @@ class TestActivityMultipleDevicePRTwo(MultipleSharedDeviceTestCase):
self.home_2.just_fyi("Checking that community appeared on the list")
if not self.home_2.element_by_text_part(community_name).is_element_displayed(30):
self.errors.append(
self.home_2, "Community is not appeared in the list after accepting admin request from activity centre")
"Community is not appeared in the list after accepting admin request from activity centre")
self.errors.verify_no_errors()
+3 -6
View File
@@ -18,7 +18,6 @@ from urllib3.exceptions import MaxRetryError, ProtocolError
from support.api.network_api import NetworkApi
from tests import test_suite_data, start_threads, pytest_config_global, transl
from tests.conftest import github_report, run_name, lambda_test_username, lambda_test_access_key
from views.base_view import BaseView
executor_lambda_test = 'https://%s:%s@mobile-hub.lambdatest.com/wd/hub' % (lambda_test_username, lambda_test_access_key)
@@ -165,14 +164,12 @@ class Driver(webdriver.Remote):
self.execute_script("lambda-hook: %s" % str(data).replace("'", "\""))
class Errors:
class Errors(object):
def __init__(self):
self.errors = list()
def append(self, view: BaseView, text: str):
error_text = "Device %s: %s" % (view.driver.number, text)
self.errors.append(error_text)
view.driver.log_event("appium", error_text)
def append(self, text=str()):
self.errors.append(text)
def verify_no_errors(self):
if self.errors:
@@ -89,13 +89,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
if not self.chat_1.user_list_element_by_name(
self.username_1).is_element_displayed() or not self.chat_1.user_list_element_by_name(
self.username_2).is_element_displayed():
self.errors.append(self.chat_1, "Incorrect users are shown for 'love' reaction.")
self.errors.append("Incorrect users are shown for 'love' reaction.")
self.chat_1.authors_for_reaction(emoji="thumbs-up").double_click()
if not self.chat_1.user_list_element_by_name(
self.username_1).is_element_displayed() or self.chat_1.user_list_element_by_name(
self.username_2).is_element_displayed():
self.errors.append(self.chat_1, "Incorrect users are shown for 'thumbs-up' reaction.")
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction.")
self.chat_1.driver.press_keycode(4)
self.errors.verify_no_errors()
@@ -111,18 +111,17 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.send_message(emoji.emojize(emoji_name))
for chat in self.chat_1, self.chat_2:
if not chat.chat_element_by_text(emoji_unicode).is_element_displayed():
self.errors.append(chat, 'Message with emoji was not sent or received in 1-1 chat')
self.errors.append('Message with emoji was not sent or received in 1-1 chat')
self.chat_1.quote_message(emoji_unicode)
actual_text = self.chat_1.quote_username_in_message_input.text
if actual_text != "You":
self.errors.append(
self.chat_1,
"'You' is not displayed in reply quote snippet replying to own message, '%s' instead" % actual_text)
self.chat_1.just_fyi("Clear quote and check there is not snippet anymore")
self.chat_1.cancel_reply_button.click()
if self.chat_1.cancel_reply_button.is_element_displayed():
self.errors.append(self.chat_1, "Message quote kept in public chat input after it was cancelled")
self.errors.append("Message quote kept in public chat input after it was cancelled")
self.chat_1.just_fyi("Send reply")
self.chat_1.quote_message(emoji_unicode)
@@ -131,7 +130,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.just_fyi("Receiver verifies received reply...")
if self.chat_2.chat_element_by_text(reply_to_message_from_sender).replied_message_text != emoji_unicode:
self.errors.append(self.chat_2, "No reply received in 1-1 chat")
self.errors.append("No reply received in 1-1 chat")
else:
self.chat_2.just_fyi("Device 2 sets a reaction on the message reply. Device 1 checks the reaction")
self.chat_1.set_reaction(reply_to_message_from_sender)
@@ -139,7 +138,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.chat_element_by_text(
reply_to_message_from_sender).emojis_below_message().wait_for_element_text(1)
except Failed:
self.errors.append(self.chat_1, "Reply message reaction is not shown for the sender")
self.errors.append("Reply message reaction is not shown for the sender")
self.home_1.just_fyi("Check that link can be opened and replied from 1-1 chat")
reply = 'reply to link'
@@ -150,15 +149,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_2.send_message(reply)
replied_message = self.chat_1.chat_element_by_text(reply)
if replied_message.replied_message_text != url_message:
self.errors.append(self.chat_1,
"Reply for '%s' not present in message received in public chat" % url_message)
self.errors.append("Reply for '%s' not present in message received in public chat" % url_message)
self.chat_2.just_fyi("Device 2 sets a reaction on the message with a link. Device 1 checks the reaction")
self.chat_2.set_reaction(url_message)
try:
self.chat_1.chat_element_by_text(url_message).emojis_below_message().wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.chat_1, "Link message reaction is not shown for the sender")
self.errors.append("Link message reaction is not shown for the sender")
self.home_2.just_fyi("Check 'Open in Status' option")
# url_to_open = 'http://status.app'
@@ -171,15 +169,15 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
try:
self.chat_2.wait_for_current_package_to_be('com.android.chrome')
except TimeoutException:
self.errors.append(self.chat_2, 'URL was not opened from 1-1 chat')
self.errors.append('URL was not opened from 1-1 chat')
else:
self.chat_2.element_by_text("No thanks").click_if_shown()
text_element = self.chat_2.element_by_text("a free (libre) open source, mobile OS for Ethereum")
sign_in_button = Button(self.chat_2.driver, xpath="//android.view.View[@content-desc='Sign in']")
if not text_element.is_element_displayed() or not sign_in_button.is_element_displayed():
self.errors.append(self.chat_2, 'URL was not opened from 1-1 chat')
self.errors.append('URL was not opened from 1-1 chat')
else:
self.errors.append(self.chat_2, "Message with URL was not received")
self.errors.append("Message with URL was not received")
self.errors.verify_no_errors()
@@ -214,15 +212,14 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
else:
expected_text = "You" if message == self.message_2 else self.username_1
if text != expected_text:
self.errors.append(chat,
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, chat_number + 1)
)
self.errors.append(
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, chat_number + 1)
)
else:
self.errors.append(chat,
"Message '%s' is missed on Pinned messages list for user %s" % (
message, chat_number + 1)
)
self.errors.append(
"Message '%s' is missed on Pinned messages list for user %s" % (message, chat_number + 1)
)
chat.click_system_back_button()
self.home_1.just_fyi("Check that Device1 can not pin more than 3 messages and 'Unpin' dialog appears")
@@ -235,23 +232,22 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.view_pinned_messages_button.click_until_presence_of_element(self.chat_1.pinned_messages_list)
if self.chat_1.pinned_messages_list.get_pinned_messages_number() > 3 \
or self.chat_1.pinned_messages_list.message_element_by_text(self.message_4).is_element_displayed():
self.errors.append(self.chat_1, "Can pin more than 3 messages in chat")
self.errors.append("Can pin more than 3 messages in chat")
else:
unpin_element = self.chat_1.element_by_translation_id('unpin-from-chat')
self.chat_1.pinned_messages_list.message_element_by_text(self.message_2).long_press_without_release()
self.home_1.just_fyi("Unpin one message so that another could be pinned")
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
self.chat_1.pin_message(self.message_4, 'pin-to-chat')
for chat in self.chat_1, self.chat_2:
if chat.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30):
self.errors.append(chat, "Message 4 is not pinned in chat after unpinning previous one")
if not (self.chat_1.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30) and
self.chat_2.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 4 is not pinned in chat after unpinning previous one")
self.home_1.just_fyi("Check pinned messages are visible in Pinned panel for both users")
for chat_number, chat in enumerate([self.chat_1, self.chat_2]):
count = chat.pinned_messages_count.text
if count != '3':
self.errors.append(chat,
"Pinned messages count is %s but should be 3 for user %s" % (count, chat_number + 1))
self.errors.append("Pinned messages count is %s but should be 3 for user %s" % (count, chat_number + 1))
self.home_1.just_fyi("Unpin one message and check it's unpinned for another user")
self.chat_2.tap_by_coordinates(500, 100)
@@ -272,7 +268,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
chat.pinned_messages_count.wait_for_element_text(text='2', wait_time=20)
except Failed:
self.errors.append(
chat, "Pinned messages count is not 2 after unpinning the last pinned message for user %s" % (
"Pinned messages count is not 2 after unpinning the last pinned message for user %s" % (
chat_number + 1)
)
self.errors.verify_no_errors()
@@ -297,7 +293,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
for message in messages:
self.chat_2.send_message(message)
if not self.chat_1.chat_element_by_text(message).is_element_displayed(30):
self.errors.append(self.chat_1, "Message with text '%s' was not received" % message)
self.errors.append("Message with text '%s' was not received" % message)
self.chat_2.just_fyi("Checking updated member photo, timestamp and username on message")
self.chat_2.hide_keyboard_if_shown()
@@ -305,15 +301,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
timestamp = self.chat_2.chat_element_by_text(messages[0]).timestamp
sent_time_variants = self.chat_2.convert_device_time_to_chat_timestamp()
if timestamp not in sent_time_variants:
self.errors.append(self.chat_2,
'Timestamp on message %s does not correspond expected %s' % (
timestamp, sent_time_variants))
self.errors.append(
'Timestamp on message %s does not correspond expected %s' % (timestamp, sent_time_variants))
except NoSuchElementException:
self.errors.append(self.chat_2, "No timestamp on message %s" % messages[0])
self.errors.append("No timestamp on message %s" % messages[0])
for message in [messages[1], messages[2]]:
if self.chat_2.chat_element_by_text(message).member_photo.is_element_displayed():
self.errors.append(self.chat_2,
'%s is not stack to 1st(they are sent in less than 5 minutes)!' % message)
self.errors.append('%s is not stack to 1st(they are sent in less than 5 minutes)!' % message)
self.chat_1.just_fyi("Sending message")
message = 'profile_photo'
@@ -325,7 +319,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.home_2.get_chat(self.username_1).click()
if self.chat_2.chat_element_by_text(message).member_photo.is_element_differs_from_template(
"profile_image_in_1_1_chat.png", diff=7):
self.errors.append(self.chat_2, "Image of user in 1-1 chat is too different from template!")
self.errors.append("Image of user in 1-1 chat is too different from template!")
self.errors.verify_no_errors()
@marks.testrail_id(702813)
@@ -377,10 +371,9 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.device_1.just_fyi("Checks there are no PN after message was seen")
[home.open_notification_bar() for home in self.homes]
if self.device_2.element_by_text_part(message).is_element_displayed():
self.errors.append(self.chat_2, "PN are keep staying after message '%s' was seen by user" % message)
if self.device_1.element_by_text_part(emoji_unicode).is_element_displayed():
self.errors.append(self.chat_1, "PN are keep staying after message '%s' was seen by user" % emoji_unicode)
if (self.device_2.element_by_text_part(message).is_element_displayed()
or self.device_1.element_by_text_part(emoji_unicode).is_element_displayed()):
self.errors.append("PN are keep staying after message was seen by user")
self.errors.verify_no_errors()
@marks.testrail_id(702855)
@@ -400,7 +393,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
message_text_after_edit = message_after_edit_1_1 + ' (Edited)'
chat_element = self.chat_1.chat_element_by_text(message_text_after_edit)
if not chat_element.is_element_displayed(30):
self.errors.append(self.chat_1, 'No edited message in 1-1 chat displayed')
self.errors.append('No edited message in 1-1 chat displayed')
else:
self.device_1.just_fyi("Device 1 sets a reaction on the edited message. Device 2 checks the reaction")
self.chat_1.set_reaction(message_text_after_edit)
@@ -408,7 +401,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_1.chat_element_by_text(
message_text_after_edit).emojis_below_message().wait_for_element_text(1)
except Failed:
self.errors.append(self.chat_1, "Message reaction is not shown for the sender")
self.errors.append("Message reaction is not shown for the sender")
self.errors.verify_no_errors()
@marks.testrail_id(703391)
@@ -432,7 +425,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_2.chat_element_by_text(image_description).wait_for_visibility_of_element(30)
if not self.chat_2.chat_element_by_text(
image_description).image_in_message.is_element_image_similar_to_template('image_1_chat_view.png'):
self.errors.append(self.chat_2, "Not expected image is shown to the receiver.")
self.errors.append("Not expected image is shown to the receiver.")
for chat in self.chat_1, self.chat_2:
chat.just_fyi("Open the image and share it")
@@ -444,9 +437,8 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
try:
chat.wait_for_current_package_to_be('com.google.android.apps.docs')
except TimeoutException:
self.errors.append(chat,
"%s can't share an image via Gmail." % (
"Sender" if chat is self.chat_1 else "Receiver"))
self.errors.append(
"%s can't share an image via Gmail." % ("Sender" if chat is self.chat_1 else "Receiver"))
chat.navigate_back_to_chat_view()
for chat in self.chat_1, self.chat_2:
@@ -460,10 +452,10 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
toast_element_text = toast_element.text
if toast_element_text != chat.get_translation_by_key("photo-saved"):
self.errors.append(
chat, "Shown message '%s' doesn't match expected '%s' after saving an image for %s." % (
"Shown message '%s' doesn't match expected '%s' after saving an image for %s." % (
toast_element_text, chat.get_translation_by_key("photo-saved"), device_name))
else:
self.errors.append(chat, "Message about saving a photo is not shown for %s." % device_name)
self.errors.append("Message about saving a photo is not shown for %s." % device_name)
chat.navigate_back_to_chat_view()
for chat in self.chat_1, self.chat_2:
@@ -471,9 +463,8 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
chat.show_images_button.click()
chat.allow_all_button.click_if_shown()
if not chat.get_image_by_index(0).is_element_image_similar_to_template("image_1_gallery_view.png"):
self.errors.append(chat,
"Image is not saved to gallery for %s." % (
"sender" if chat is self.chat_1 else "receiver"))
self.errors.append(
"Image is not saved to gallery for %s." % ("sender" if chat is self.chat_1 else "receiver"))
chat.click_system_back_button()
self.errors.verify_no_errors()
@@ -499,7 +490,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
chat_1_element.long_press_without_release()
for action in ("edit", "delete-for-everyone"):
if self.chat_1.element_by_translation_id(action).is_element_displayed():
self.errors.append(self.chat_1, 'Option to %s someone else message available!' % action)
self.errors.append('Option to %s someone else message available!' % action)
self.home_1.tap_by_coordinates(500, 100)
self.device_2.just_fyi("Delete message for me and check it is only deleted for the author")
@@ -509,23 +500,23 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
self.chat_2.chat_element_by_text(message_to_delete_for_me).wait_for_status_to_be("Delivered", timeout)
self.chat_2.delete_message_in_chat(message_to_delete_for_me, everyone=False)
except TimeoutException:
self.errors.append(self.chat_2, "Message status was not changed to 'Delivered' after %s s" % timeout)
self.errors.append("Message status was not changed to 'Delivered' after %s s" % timeout)
else:
if not self.chat_2.chat_element_by_text(message_to_delete_for_me).is_element_disappeared(20):
self.errors.append(self.chat_2, "Deleted for me message is shown in chat for the author of message")
self.errors.append("Deleted for me message is shown in chat for the author of message")
if not self.chat_2.element_by_translation_id('message-deleted-for-you').is_element_displayed(20):
self.errors.append(self.chat_2, "System message about deletion for you is not displayed")
self.errors.append("System message about deletion for you is not displayed")
if not self.chat_1.chat_element_by_text(message_to_delete_for_me).is_element_displayed(20):
self.errors.append(self.chat_1, "Deleted for me message is deleted for both users")
self.errors.append("Deleted for me message is deleted for both users")
self.device_2.just_fyi("Delete message for everyone and check it is not shown in chat preview on home")
self.chat_2.delete_message_in_chat(message_after_edit_1_1)
for chat in (self.chat_2, self.chat_1):
if chat.chat_element_by_text(message_after_edit_1_1).is_element_displayed(30):
self.errors.append(chat, "Deleted message is shown in chat view for 1-1 chat")
self.errors.append("Deleted message is shown in chat view for 1-1 chat")
self.chat_1.navigate_back_to_home_view()
if self.home_1.element_by_text(message_after_edit_1_1).is_element_displayed(30):
self.errors.append(self.home_1, "Deleted message is shown on chat element on home screen")
self.errors.append("Deleted message is shown on chat element on home screen")
self.device_2.just_fyi("Send one more message and check that PN will be deleted with message deletion")
message_to_delete = 'DELETE ME'
@@ -536,12 +527,12 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
if not self.home_1.get_pn(message_to_delete):
self.home_1.click_system_back_button()
self.device_2.driver.activate_app(app_package)
self.errors.append(self.home_1, "Push notification doesn't appear")
self.errors.append("Push notification doesn't appear")
self.chat_2.delete_message_in_chat(message_to_delete)
pn_to_disappear = self.home_1.get_pn(message_to_delete)
if pn_to_disappear:
if not pn_to_disappear.is_element_disappeared(90):
self.errors.append(self.home_1, "Push notification was not removed after initial message deletion")
self.errors.append("Push notification was not removed after initial message deletion")
self.errors.verify_no_errors()
@@ -589,9 +580,9 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
chat_element = chat.chat_element_by_text(image_description)
if chat_element.is_element_displayed(30):
if not chat_element.image_in_message.is_element_image_similar_to_template('saucelabs_camera_image.png'):
self.errors.append(chat, "Not expected image is shown to the %s." % chat_name)
self.errors.append("Not expected image is shown to the %s." % chat_name)
else:
self.errors.append(chat, "Message with camera image is not shown in chat for %s" % chat_name)
self.errors.append("Message with camera image is not shown in chat for %s" % chat_name)
self.errors.verify_no_errors()
@marks.testrail_id(702783)
@@ -617,7 +608,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
self.chat_2.send_message(message_1)
status = self.chat_2.chat_element_by_text(message_1).status
if not (status == 'Sending' or status == 'Sent'):
self.errors.append(self.chat_2, 'Message status is not "Sending", it is "%s"!' % status)
self.errors.append('Message status is not "Sending", it is "%s"!' % status)
self.home_2.just_fyi('Device2 goes back online and checks that status of the message is changed to "delivered"')
for home in self.homes:
@@ -625,13 +616,13 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
self.home_1.just_fyi('Device1 goes back online and checks that 1-1 chat will be fetched')
if not self.chat_1.chat_element_by_text(message_1).is_element_displayed(120):
self.errors.append(self.chat_1, "Message was not delivered after resending from offline")
self.errors.append("Message was not delivered after resending from offline")
self.home_2.just_fyi('Device1 goes back online and checks that 1-1 chat will be fetched')
try:
self.chat_2.chat_element_by_text(message_1).wait_for_status_to_be(expected_status='Delivered', timeout=120)
except TimeoutException as e:
self.errors.append(self.chat_2, '%s after back up online!' % e.msg)
self.errors.append('%s after back up online!' % e.msg)
self.errors.verify_no_errors()
@marks.testrail_id(703496)
@@ -645,35 +636,33 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
self.chat_2.send_message(muted_message)
chat = self.home_1.get_chat(self.username_2)
if chat.new_messages_counter.is_element_displayed(30) or self.home_1.chats_tab.counter.is_element_displayed(10):
self.errors.append(self.home_1, "New messages counter is shown after mute")
self.errors.append("New messages counter is shown after mute")
if not chat.chat_preview.text.startswith(muted_message):
self.errors.append(self.home_1, "Message text '%s' is not shown in chat preview after mute" % muted_message)
self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message)
chat.click()
if not self.chat_1.chat_element_by_text(muted_message).is_element_displayed(30):
self.errors.append(self.chat_1, "Message '%s' is not shown in chat for receiver after mute" % muted_message)
self.errors.append("Message '%s' is not shown in chat for receiver after mute" % muted_message)
self.chat_1.just_fyi("Unmute chat")
self.chat_1.navigate_back_to_home_view()
chat.long_press_without_release()
if self.home_1.mute_chat_button.text != transl["unmute-chat"]:
self.errors.append(self.home_1, "Chat is not muted")
self.errors.append("Chat is not muted")
expected_text = "Muted until you turn it back on"
if not self.home_1.element_by_text(expected_text).is_element_displayed():
self.errors.append(self.home_1, "Text '%s' is not shown for muted chat" % expected_text)
self.errors.append("Text '%s' is not shown for muted chat" % expected_text)
self.home_1.mute_chat_button.double_click()
unmuted_message = "after unmute"
self.chat_2.send_message(unmuted_message)
if not chat.new_messages_counter.is_element_displayed(
30) or not self.home_1.chats_tab.counter.is_element_displayed(10):
self.errors.append(self.home_1, "New messages counter is not shown after unmute")
self.errors.append("New messages counter is not shown after unmute")
if not chat.chat_preview.text.startswith(unmuted_message):
self.errors.append(self.home_1,
"Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
chat.click()
if not self.chat_1.chat_element_by_text(unmuted_message).is_element_displayed(30):
self.errors.append(self.chat_1,
"Message '%s' is not shown in chat for receiver after unmute" % unmuted_message)
self.errors.append("Message '%s' is not shown in chat for receiver after unmute" % unmuted_message)
self.errors.verify_no_errors()
@@ -688,7 +677,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
for element in self.chat_2.chat_element_by_text(text='').message_text_content.find_elements():
chat_history.append(element.text)
if not chat_history:
self.errors.append(self.chat_2, "No chat history was loaded")
self.errors.append("No chat history was loaded")
self.home_2.just_fyi("Deleting chat via delete button and check it will not reappear after relaunching app")
self.home_2.navigate_back_to_home_view()
@@ -696,12 +685,10 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
self.home_2.delete_chat_long_press(username=self.username_1)
chat = self.home_2.get_chat_from_home_view(self.username_1)
if chat.is_element_displayed():
self.errors.append(self.chat_2,
"Deleted '%s' chat is shown, but the chat has been deleted" % self.username_1)
self.errors.append("Deleted '%s' chat is shown, but the chat has been deleted" % self.username_1)
self.home_2.reopen_app(user_name=self.username_2)
if chat.is_element_displayed(15):
self.errors.append(
self.chat_2,
"Deleted chat '%s' is shown after re-login, but the chat has been deleted" % self.username_1)
chat.click()
else:
@@ -714,6 +701,5 @@ class TestOneToOneChatMultipleSharedDevicesNewUiTwo(MultipleSharedDeviceTestCase
if not self.chat_2.chat_element_by_text(message_text).is_element_displayed():
lost_messages.append(message_text)
if lost_messages:
self.errors.append(self.chat_2,
"Message(s) missed in 1-1 chat after deleting the chat and relogin: %s" % lost_messages)
self.errors.append("Message(s) missed in 1-1 chat after deleting the chat and relogin: %s" % lost_messages)
self.errors.verify_no_errors()
@@ -95,14 +95,14 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if pn:
pn.click()
else:
self.errors.append(self.homes[0], "No PN was received on new message for message in group chat")
self.errors.append("No PN was received on new message for message in group chat")
self.homes[0].click_system_back_button()
self.homes[0].get_chat(self.chat_name).click()
self.chats[1].just_fyi('Check message status and message delivery')
self.chats[1].chat_element_by_text(message_to_admin).wait_for_status_to_be('Delivered', timeout=120)
if not self.chats[0].chat_element_by_text(message_to_admin).is_element_displayed(30):
self.errors.append(self.chats[0], 'Message %s was not received by admin' % message_to_admin)
self.errors.append('Message %s was not received by admin' % message_to_admin)
self.errors.verify_no_errors()
@marks.testrail_id(703202)
@@ -139,19 +139,19 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if not self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'thumbs-up' reaction.")
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction.")
self.chats[0].authors_for_reaction(emoji="love").double_click()
if not self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'love' reaction.")
self.errors.append("Incorrect users are shown for 'love' reaction.")
self.chats[0].authors_for_reaction(emoji="laugh").click()
if self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'laugh' reaction.")
self.errors.append("Incorrect users are shown for 'laugh' reaction.")
self.chats[0].just_fyi("Admin opens member_2 profile")
self.chats[0].user_list_element_by_name(self.usernames[2]).click()
@@ -159,12 +159,11 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
username_shown = self.chats[0].get_profile_view().contact_name_text.text
if username_shown != self.usernames[2]:
self.errors.append(
self.chats[0],
"Incorrect profile is opened from the list of reactions, username is %s but expected to be %s" % (
username_shown, self.usernames[2])
)
except NoSuchElementException:
self.errors.append(self.chats[0], "User profile was not opened from the list of reactions")
self.errors.append("User profile was not opened from the list of reactions")
self.chats[0].navigate_back_to_chat_view()
self.chats[1].just_fyi("Member_1 removes 'thumbs-up' reaction and adds 'sad' one")
@@ -184,9 +183,8 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
chat_element.emojis_below_message(emoji="love").wait_for_element_text(1)
chat_element.emojis_below_message(emoji="sad").wait_for_element_text(2)
except (Failed, NoSuchElementException):
self.errors.append(self.chats[chat_view_index],
"Incorrect reactions count for %s after changing the reactions" % self.usernames[
chat_view_index])
self.errors.append(
"Incorrect reactions count for %s after changing the reactions" % self.usernames[chat_view_index])
self.loop.run_until_complete(run_in_parallel((
(_check_reactions_count_after_change, {'chat_view_index': 0}),
@@ -206,7 +204,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
message_element.emojis_below_message(emoji="love").wait_for_element_text(1)
message_element.emojis_below_message(emoji="sad").wait_for_element_text(2)
except (Failed, NoSuchElementException):
self.errors.append(self.chats[0], "Incorrect reactions count after relogin")
self.errors.append("Incorrect reactions count after relogin")
for chat in self.chats[1], self.chats[2]:
chat.just_fyi("Just making the session not to quit")
@@ -217,19 +215,19 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'thumbs-up' reaction after relogin.")
self.errors.append("Incorrect users are shown for 'thumbs-up' reaction after relogin.")
self.chats[0].authors_for_reaction(emoji="love").double_click()
if not self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'love' reaction after relogin.")
self.errors.append("Incorrect users are shown for 'love' reaction after relogin.")
self.chats[0].authors_for_reaction(emoji="sad").click()
if not self.chats[0].user_list_element_by_name(
self.usernames[1]).is_element_displayed() or not self.chats[0].user_list_element_by_name(
self.usernames[2]).is_element_displayed():
self.errors.append(self.chats[0], "Incorrect users are shown for 'laugh' reaction after relogin.")
self.errors.append("Incorrect users are shown for 'laugh' reaction after relogin.")
self.errors.verify_no_errors()
@@ -247,13 +245,13 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
chat_element = self.chats[0].chat_element_by_text(image_description)
chat_element.wait_for_visibility_of_element(60)
if not chat_element.image_in_message.is_element_image_similar_to_template('image_2_chat_view.png'):
self.errors.append(self.chats[0], "Not expected image is shown to the admin.")
self.errors.append("Not expected image is shown to the admin.")
self.chats[2].just_fyi("Member_2 checks image message")
chat_element = self.chats[2].chat_element_by_text(image_description)
chat_element.wait_for_visibility_of_element(60)
if not chat_element.image_in_message.is_element_image_similar_to_template('image_2_chat_view.png'):
self.errors.append(self.chats[2], "Not expected image is shown to the member_2.")
self.errors.append("Not expected image is shown to the member_2.")
self.chats[0].just_fyi("Admin opens the image and shares it")
self.chats[0].chat_element_by_text(image_description).image_in_message.click()
@@ -262,7 +260,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
try:
self.chats[0].wait_for_current_package_to_be('com.google.android.apps.docs')
except TimeoutException:
self.errors.append(self.chats[0], "Admin can't share an image via Gmail.")
self.errors.append("Admin can't share an image via Gmail.")
self.chats[0].navigate_back_to_chat_view()
self.chats[1].navigate_back_to_home_view()
@@ -277,11 +275,10 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
toast_element_text = toast_element.wait_for_visibility_of_element().text
if toast_element_text != self.chats[2].get_translation_by_key("photo-saved"):
self.errors.append(
self.chats[2],
"Shown message '%s' doesn't match expected '%s' after saving an image for member_2." % (
toast_element_text, self.chats[2].get_translation_by_key("photo-saved")))
except TimeoutException:
self.errors.append(self.chats[2], "Message about saving a photo is not shown for member_2.")
self.errors.append("Message about saving a photo is not shown for member_2.")
self.chats[2].navigate_back_to_chat_view()
# workaround for app closed after navigating back from gallery
@@ -295,7 +292,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[2].show_images_button.click()
self.chats[2].allow_all_button.click_if_shown()
if not self.chats[2].get_image_by_index(0).is_element_image_similar_to_template("image_2_gallery_view.png"):
self.errors.append(self.chats[2], "Image is not saved to gallery for member_2.")
self.errors.append("Image is not saved to gallery for member_2.")
self.chats[2].navigate_back_to_home_view()
# workaround for app closed after navigating back from gallery
@@ -336,7 +333,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
if self.homes[0].element_by_text(message).is_element_displayed(30):
break
else:
self.errors.append(self.homes[0], 'Messages PN was not fetched from offline')
self.errors.append('Messages PN was not fetched from offline')
self.homes[0].click_system_back_button()
# workaround for app closed after opening notifications
if not self.homes[0].chats_tab.is_element_displayed():
@@ -349,7 +346,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[index].just_fyi("Check that messages are shown for user %s" % self.usernames[index])
for message_text in (message_1, message_2):
if not self.chats[index].chat_element_by_text(message_text).is_element_displayed(30):
self.errors.append(self.chats[index], '%s if not shown for device %s' % (message_text, index))
self.errors.append('%s if not shown for device %s' % (message_text, index))
self.loop.run_until_complete(run_in_parallel((
(_check_messages, {'index': 0}),
@@ -370,14 +367,14 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[0].send_message(self.message_1)
self.chats[0].pin_message(self.message_1, "pin-to-chat")
for chat in self.chats[0], self.chats[1]:
if not chat.chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30):
self.errors.append(chat, "Message 1 is not pinned in group chat!")
if not (self.chats[0].chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30) and
self.chats[1].chat_element_by_text(self.message_1).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 1 is not pinned in group chat!")
self.chats[0].just_fyi("Check that non admin user can not unpin messages")
self.chats[1].chat_element_by_text(self.message_1).long_press_without_release()
if self.chats[1].element_by_translation_id("unpin-from-chat").is_element_displayed():
self.errors.append(self.chats[1], "Unpin option is available for non-admin user")
self.errors.append("Unpin option is available for non-admin user")
self.chats[1].tap_by_coordinates(500, 100)
self.chats[1].tap_by_coordinates(500, 100)
@@ -399,9 +396,9 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
# here group_chat_1 should be changed to group_chat_2 after enabling the previous block
self.chats[0].send_message(message)
self.chats[0].pin_message(message, 'pin-to-chat')
for chat in self.chats[0], self.chats[1]:
if not chat.chat_element_by_text(message).pinned_by_label.is_element_displayed(30):
self.errors.append(chat, "%s is not pinned in group chat!" % message)
if not (self.chats[0].chat_element_by_text(message).pinned_by_label.is_element_displayed(30) and
self.chats[1].chat_element_by_text(message).pinned_by_label.is_element_displayed(30)):
self.errors.append("%s is not pinned in group chat!" % message)
self.chats[0].just_fyi("Check that a user can not pin more than 3 messages")
self.chats[0].send_message(self.message_4)
@@ -412,17 +409,16 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
unpin_element.click_until_absense_of_element(desired_element=unpin_element)
self.chats[0].chat_element_by_text(self.message_4).click()
self.chats[0].pin_message(self.message_4, 'pin-to-chat')
for chat in self.chats[0], self.chats[1]:
if not chat.chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30):
self.errors.append(chat, "Message 4 is not pinned in group chat after unpinning previous one")
if not (self.chats[0].chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30) and
self.chats[1].chat_element_by_text(self.message_4).pinned_by_label.is_element_displayed(30)):
self.errors.append("Message 4 is not pinned in group chat after unpinning previous one")
def _check_pinned_messages(index):
self.chats[index].just_fyi("Check pinned messages count and content for user %s" % self.usernames[index])
count = self.chats[index].pinned_messages_count.text
if count != '3':
self.errors.append(self.chats[index],
"Pinned messages count %s doesn't match expected 3 for user %s" % (
count, self.usernames[index]))
self.errors.append(
"Pinned messages count %s doesn't match expected 3 for user %s" % (count, self.usernames[index]))
self.chats[index].pinned_messages_count.click()
for message_text in self.message_1, self.message_3, self.message_4:
pinned_by = self.chats[index].pinned_messages_list.get_message_pinned_by_text(message_text)
@@ -430,15 +426,14 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
text = pinned_by.text.strip()
expected_text = "You" if index == 0 else self.usernames[0]
if text != expected_text:
self.errors.append(self.chats[index],
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, self.usernames[index])
)
self.errors.append(
"Pinned by '%s' doesn't match expected '%s' for user %s" % (
text, expected_text, self.usernames[index])
)
else:
self.errors.append(self.chats[index],
"Message '%s' is missed on Pinned messages list for user %s" % (
message, self.usernames[index])
)
self.errors.append(
"Message '%s' is missed on Pinned messages list for user %s" % (message, self.usernames[index])
)
self.loop.run_until_complete(run_in_parallel((
(_check_pinned_messages, {'index': 0}),
@@ -465,7 +460,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
pytest.fail("Chat is not muted")
current_text = self.homes[1].mute_chat_button.unmute_caption_text
if current_text not in expected_texts:
self.errors.append(self.homes[1], "Text '%s' is not shown for muted chat" % expected_texts[1])
self.errors.append("Text '%s' is not shown for muted chat" % expected_texts[1])
self.homes[1].click_system_back_button()
try:
initial_counter = int(self.homes[1].chats_tab.counter.text)
@@ -479,23 +474,20 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.homes[1].just_fyi("Member 1 checks that chat is muted and message is received")
if chat.new_messages_grey_dot.is_element_displayed(30):
self.errors.append(self.homes[1], "New messages grey dot near chat name is shown after mute")
self.errors.append("New messages grey dot near chat name is shown after mute")
try:
after_mute_counter = int(self.homes[1].chats_tab.counter.text)
except NoSuchElementException:
after_mute_counter = 0
if after_mute_counter > initial_counter:
self.errors.append(self.homes[1],
"New messages counter near chats tab button is %s after mute, but should be %s" % (
after_mute_counter, initial_counter))
self.errors.append("New messages counter near chats tab button is %s after mute, but should be %s" % (
after_mute_counter, initial_counter))
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[0], muted_message[:25])):
self.errors.append(self.homes[1],
"Message text '%s' is not shown in chat preview after mute" % muted_message)
self.errors.append("Message text '%s' is not shown in chat preview after mute" % muted_message)
chat.click()
if not self.chats[1].chat_element_by_text(muted_message).is_element_displayed(30):
self.errors.append(self.chats[1],
"Message '%s' is not shown in chat for %s (Member 1) after mute" % (
muted_message, self.usernames[1]))
self.errors.append(
"Message '%s' is not shown in chat for %s (Member 1) after mute" % (muted_message, self.usernames[1]))
self.chats[1].navigate_back_to_home_view()
self.chats[1].just_fyi("Member 1 unmutes the chat")
@@ -503,7 +495,7 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.homes[1].mute_chat_button.double_click()
chat.long_press_without_release()
if self.homes[1].element_starts_with_text("Muted until").is_element_displayed():
self.errors.append(self.homes[1], "Chat is still muted after being unmuted")
self.errors.append("Chat is still muted after being unmuted")
self.errors.verify_no_errors()
if self.homes[1].mute_chat_button.is_element_displayed():
self.homes[1].click_system_back_button()
@@ -518,22 +510,20 @@ class TestGroupChatMultipleDeviceMergedNewUI(MultipleSharedDeviceTestCase):
self.chats[2].send_message(unmuted_message)
self.homes[1].just_fyi("Member 1 checks that chat is unmuted and message is received")
if not chat.new_messages_grey_dot.is_element_displayed(30):
self.errors.append(self.homes[1], "New messages counter near chat name is not shown after unmute")
self.errors.append("New messages counter near chat name is not shown after unmute")
try:
after_mute_counter = int(self.homes[1].chats_tab.counter.text)
except NoSuchElementException:
after_mute_counter = 0
if after_mute_counter != initial_counter:
self.errors.append(self.homes[1],
"New messages counter near chats tab button is %s after unmute, but should be %s" % (
after_mute_counter, initial_counter + 1))
self.errors.append("New messages counter near chats tab button is %s after unmute, but should be %s" % (
after_mute_counter, initial_counter + 1))
if not chat.chat_preview.text.startswith("%s: %s" % (self.usernames[2], unmuted_message)):
self.errors.append(self.homes[1],
"Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
self.errors.append("Message text '%s' is not shown in chat preview after unmute" % unmuted_message)
chat.click()
if not self.chats[1].chat_element_by_text(unmuted_message).is_element_displayed(30):
self.errors.append(self.chats[1],
"Message '%s' is not shown in chat for %s (Member 1) after unmute" % (
unmuted_message, self.usernames[1]))
self.errors.append(
"Message '%s' is not shown in chat for %s (Member 1) after unmute" % (
unmuted_message, self.usernames[1]))
self.errors.verify_no_errors()
@@ -10,7 +10,7 @@ from selenium.common.exceptions import NoSuchElementException, TimeoutException,
from tests import marks, run_in_parallel, pytest_config_global, transl
from tests.base_test_case import create_shared_drivers, MultipleSharedDeviceTestCase
from views.chat_view import CommunityView
from views.chat_view import CommunityView, ChatView
from views.dbs.waku_backup import user as waku_user
from views.sign_in_view import SignInView
@@ -61,7 +61,6 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
actual_copied_text = self.channel.driver.get_clipboard_text()
if actual_copied_text != message:
self.errors.append(
self.channel,
'Message %s text was not copied in community channel, text in clipboard %s' % actual_copied_text)
self.errors.verify_no_errors()
@@ -104,9 +103,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
try:
current_text = self.home.unmute_community_button.unmute_caption_text
if current_text not in expected_texts:
self.errors.append(self.home, "Text '%s' is not shown for muted community" % expected_texts[1])
self.errors.append("Text '%s' is not shown for muted community" % expected_texts[1])
except NoSuchElementException:
self.errors.append(self.home, "Caption with text 'Muted until...' is not shown for muted community")
self.errors.append("Caption with text 'Muted until...' is not shown for muted community")
self.home.click_system_back_button()
self.home.get_chat(self.community_name, community=True).click()
@@ -115,11 +114,9 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
try:
current_text = self.home.mute_channel_button.unmute_caption_text
if current_text not in expected_texts:
self.errors.append(self.home,
"Text '%s' is not shown for a channel in muted community" % expected_texts[1])
self.errors.append("Text '%s' is not shown for a channel in muted community" % expected_texts[1])
except NoSuchElementException:
self.errors.append(self.home,
"Caption with text 'Muted until...' is not shown for a channel in muted community")
self.errors.append("Caption with text 'Muted until...' is not shown for a channel in muted community")
self.home.just_fyi("Unmute channel and check that the community is also unmuted")
self.home.mute_channel_button.click()
@@ -127,7 +124,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.communities_tab.click()
self.home.get_chat(self.community_name, community=True).long_press_element()
if not self.home.element_by_text("Mute community").is_element_displayed():
self.errors.append(self.home, "Community is not unmuted when channel is unmuted")
self.errors.append("Community is not unmuted when channel is unmuted")
self.home.click_system_back_button()
self.home.just_fyi("Mute channel and check that community is not muted")
@@ -143,18 +140,16 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
try:
current_text = self.home.mute_channel_button.unmute_caption_text
if current_text not in expected_texts:
self.errors.append(self.home,
"Text '%s' is not shown for a muted community channel" % expected_texts[1])
self.errors.append("Text '%s' is not shown for a muted community channel" % expected_texts[1])
except NoSuchElementException:
self.errors.append(self.home,
"Caption with text '%s' is not shown for a muted community channel" % expected_texts[1])
self.errors.append("Caption with text '%s' is not shown for a muted community channel" % expected_texts[1])
self.home.click_system_back_button()
self.home.navigate_back_to_home_view()
self.home.communities_tab.click()
self.home.get_chat(self.community_name, community=True).long_press_element()
if self.home.element_by_text_part("Muted until").is_element_displayed() or \
self.home.mute_community_button.text != transl["mute-community"]:
self.errors.append(self.home, "Community is muted when channel is muted")
self.errors.append("Community is muted when channel is muted")
self.home.click_system_back_button()
self.errors.verify_no_errors()
@@ -177,7 +172,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
# "Incorrect contacts number restored: %s instead of %s" % (contacts_number, len(waku_user.contacts)))
for contact in waku_user.contacts:
if not self.home.element_by_text(contact).is_element_displayed(30):
self.errors.append(self.home, '%s was not restored as a contact from waku backup!' % contact)
self.errors.append('%s was not restored as a contact from waku backup!' % contact)
# Disabled for simple check as sometimes from waku-backup users restored with 3-random names
# self.home.click_system_back_button_until_element_is_shown()
# contact_row = self.home.contact_details_row(index=i + 1)
@@ -206,7 +201,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.communities_tab.click()
for key in ['admin_open', 'member_open', 'admin_closed', 'member_closed']:
if not self.home.element_by_text(waku_user.communities[key]).is_element_displayed(30):
self.errors.append(self.home, "%s was not restored from waku-backup!!" % key)
self.errors.append("%s was not restored from waku-backup!!" % key)
# TODO: there is a bug when pending community sometimes restored as joined; needs investigation
# self.home.opened_communities_tab.click()
# if not self.home.element_by_text(waku_user.communities['member_pending']).is_element_displayed(30):
@@ -227,7 +222,7 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
self.home.navigate_back_to_home_view()
self.home.communities_tab.click()
if self.home.element_by_text(waku_user.communities['admin_open']).is_element_displayed(30):
self.errors.append(self.home, "Community of previous user is shown!")
self.errors.append("Community of previous user is shown!")
self.home.just_fyi("Check that can remove user from logged out state")
self.home.reopen_app(sign_in=False)
@@ -235,13 +230,13 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
user_card.open_user_options()
self.sign_in.remove_profile_button.click()
if not self.sign_in.element_by_translation_id("remove-profile-confirm-message").is_element_displayed(30):
self.errors.append(self.home, "Warning is not shown on removing profile!")
self.errors.append("Warning is not shown on removing profile!")
self.sign_in.element_by_translation_id("remove").click()
self.home.just_fyi("Check that removed user is not shown in the list anymore")
self.home.reopen_app(sign_in=False)
if self.sign_in.element_by_text(recover_user_name).is_element_displayed():
self.errors.append(self.home, "Removed user is re-appeared after relogin!")
self.errors.append("Removed user is re-appeared after relogin!")
self.errors.verify_no_errors()
@@ -284,23 +279,21 @@ class TestCommunityOneDeviceMerged(MultipleSharedDeviceTestCase):
except TimeoutException:
missing_tags.append(text)
if missing_tags:
self.errors.append(self.home,
"Community '%s' is missing tag(s) %s." % (community_name, ','.join(tags)))
self.errors.append("Community '%s' is missing tag(s) %s." % (community_name, ','.join(tags)))
# if community_name == 'Status':
self.home.just_fyi("Check Status community screen")
card.click()
if self.community_view.join_button.is_element_differs_from_template(
'status_community_join_button.png'):
self.errors.append(self.home, "Status community Join button is different from expected template.")
self.errors.append("Status community Join button is different from expected template.")
if self.community_view.community_logo.is_element_differs_from_template('status_community_logo.png'):
self.errors.append(self.home, "Status community logo is different from expected template.")
self.errors.append("Status community logo is different from expected template.")
# self.community_view.close_community_view_button.click()
# self.home.swipe_up()
except TimeoutException:
self.errors.append(self.home,
"Community '%s' is not in the Discover Communities list." % community_name)
self.errors.append("Community '%s' is not in the Discover Communities list." % community_name)
self.errors.verify_no_errors()
# Note: this test should always be the LAST ONE in the group because it turns on mainnet in the app!
@@ -357,7 +350,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
timestamp = self.channel_1.chat_element_by_text(message).timestamp
if sent_time_variants and timestamp:
if timestamp not in sent_time_variants:
self.errors.append(self.channel_1, "Timestamp is not shown, expected: '%s', in fact: '%s'" %
self.errors.append("Timestamp is not shown, expected: '%s', in fact: '%s'" %
(", ".join(sent_time_variants), timestamp))
self.channel_1.verify_message_is_under_today_text(message, self.errors)
self.channel_2.send_message("one more message")
@@ -365,8 +358,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.send_message(new_message)
self.channel_2.verify_message_is_under_today_text(new_message, self.errors, 60)
if self.channel_2.chat_element_by_text(new_message).username.text != self.username_1:
self.errors.append(self.channel_2,
"Default username '%s' is not shown next to the received message" % self.username_1)
self.errors.append("Default username '%s' is not shown next to the received message" % self.username_1)
self.errors.verify_no_errors()
@marks.smoke
@@ -378,13 +370,13 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.edit_message_in_chat(message_before_edit, message_after_edit)
for channel in (self.channel_1, self.channel_2):
if not channel.element_by_text_part(message_after_edit).is_element_displayed(60):
self.errors.append(channel, 'Message is not edited')
self.errors.append('Message is not edited')
message_text_after_edit = message_after_edit + ' (Edited)'
self.channel_2.set_reaction(message_text_after_edit)
try:
self.channel_1.chat_element_by_text(message_text_after_edit).emojis_below_message().wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.channel_1, "Message reaction is not shown for the sender")
self.errors.append("Message reaction is not shown for the sender")
self.errors.verify_no_errors()
@marks.testrail_id(702839)
@@ -397,9 +389,9 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.delete_message_in_chat(message_to_delete_everyone)
for channel in (self.channel_1, self.channel_2):
if not channel.chat_element_by_text(message_to_delete_everyone).is_element_disappeared(30):
self.errors.append(channel, "Deleted message is shown in channel")
self.errors.append("Deleted message is shown in channel")
if not self.channel_2.element_by_translation_id('message-deleted-for-everyone').is_element_displayed(30):
self.errors.append(self.channel_2, "System message about deletion for everyone is not displayed")
self.errors.append("System message about deletion for everyone is not displayed")
self.home_2.just_fyi(
'Deleting message for me. Checking that message is deleted only for the author of the message')
@@ -407,11 +399,11 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.chat_element_by_text(message_to_delete_for_me).wait_for_element(120)
self.channel_2.delete_message_in_chat(message_to_delete_for_me, everyone=False)
if not self.channel_2.chat_element_by_text(message_to_delete_for_me).is_element_disappeared(30):
self.errors.append(self.channel_2, "Deleted for me message is shown in channel for the author of message")
self.errors.append("Deleted for me message is shown in channel for the author of message")
if not self.channel_2.element_by_translation_id('message-deleted-for-you').is_element_displayed(30):
self.errors.append(self.channel_2, "System message about deletion for you is not displayed")
self.errors.append("System message about deletion for you is not displayed")
if not self.channel_1.chat_element_by_text(message_to_delete_for_me).is_element_displayed(30):
self.errors.append(self.channel_1, "Deleted for me message is deleted all channel members")
self.errors.append("Deleted for me message is deleted all channel members")
self.errors.verify_no_errors()
@marks.testrail_id(703194)
@@ -431,22 +423,22 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
image = chat_element.image_container_in_message
if (image.is_element_differs_from_template("images_gallery.png", 5) and
image.is_element_differs_from_template("images_gallery_inverted.png", 5)):
self.errors.append(self.channel_2, "Gallery message does not match the template!")
self.errors.append("Gallery message does not match the template!")
except TimeoutException:
self.errors.append(self.channel_2, "Gallery message was not received")
self.errors.append("Gallery message was not received")
received = False
if received:
self.channel_2.just_fyi("Checking an ability to save and share an image from gallery")
chat_element.image_container_in_message.image_by_index(1).click()
if not self.channel_2.share_image_icon_button.is_element_displayed():
self.errors.append(self.channel_2, "Can't share an image from gallery.")
self.errors.append("Can't share an image from gallery.")
if self.channel_2.view_image_options_button.is_element_displayed():
self.channel_2.view_image_options_button.click()
if not self.channel_2.save_image_icon_button.is_element_displayed():
self.errors.append(self.channel_2, "Can't save an image from gallery.")
self.errors.append("Can't save an image from gallery.")
else:
self.errors.append(self.channel_2, "Image options button is not shown for an image from gallery.")
self.errors.append("Image options button is not shown for an image from gallery.")
self.channel_2.navigate_back_to_chat_view()
@@ -458,7 +450,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
chat_element_1 = self.channel_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(
sec=60) or chat_element_1.replied_message_text != image_description:
self.errors.append(self.channel_1, 'Reply message was not received by the sender')
self.errors.append('Reply message was not received by the sender')
self.errors.verify_no_errors()
@marks.testrail_id(702859)
@@ -473,7 +465,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.chat_element_by_text(image_description).wait_for_visibility_of_element(10)
if not self.channel_2.chat_element_by_text(
image_description).image_in_message.is_element_image_similar_to_template('image_1_chat_view.png'):
self.errors.append(self.channel_2, "Not expected image is shown to the receiver")
self.errors.append("Not expected image is shown to the receiver")
if not self.channel_1.chat_element_by_text(image_description).is_element_displayed(60):
self.channel_1.hide_keyboard_if_shown()
@@ -485,11 +477,11 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
if toast_element.is_element_displayed():
toast_element_text = toast_element.text
if toast_element_text != self.channel_1.get_translation_by_key("photo-saved"):
self.errors.append(self.channel_1,
"Shown message '%s' doesn't match expected '%s' after saving an image." % (
toast_element_text, self.channel_1.get_translation_by_key("photo-saved")))
self.errors.append(
"Shown message '%s' doesn't match expected '%s' after saving an image." % (
toast_element_text, self.channel_1.get_translation_by_key("photo-saved")))
else:
self.errors.append(self.channel_1, "Message about saving a photo is not shown.")
self.errors.append("Message about saving a photo is not shown.")
self.channel_1.navigate_back_to_chat_view()
self.channel_1.just_fyi("Check that image is saved in gallery")
@@ -497,7 +489,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.allow_all_button.click_if_shown()
if not self.channel_1.get_image_by_index(0).is_element_image_similar_to_template(
"image_1_gallery_view.png"):
self.errors.append(self.channel_1, 'Saved image is not shown in Recent')
self.errors.append('Saved image is not shown in Recent')
self.channel_1.click_system_back_button()
self.home_2.just_fyi('Check share option on opened image')
@@ -507,7 +499,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
try:
self.channel_2.wait_for_current_package_to_be('com.google.android.apps.docs')
except TimeoutException:
self.errors.append(self.channel_2, "Can't share image")
self.errors.append("Can't share image")
self.channel_2.navigate_back_to_chat_view()
self.channel_2.just_fyi("Can reply to images")
@@ -519,20 +511,20 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.send_message_button.click()
chat_element_1 = self.channel_1.chat_element_by_text(message_text)
if not chat_element_1.is_element_displayed(sec=60) or chat_element_1.replied_message_text != image_description:
self.errors.append(self.channel_1, 'Reply message was not received by the sender')
self.errors.append('Reply message was not received by the sender')
self.channel_2.just_fyi("Set a reaction for the image message")
self.channel_2.set_reaction(message=image_description)
try:
self.channel_1.chat_element_by_text(image_description).emojis_below_message().wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.channel_1, "Image message reaction is not shown for the sender")
self.errors.append("Image message reaction is not shown for the sender")
self.channel_1.just_fyi("Set a reaction for the message reply")
self.channel_2.set_reaction(message=image_description, emoji="love")
try:
self.channel_2.chat_element_by_text(message_text).emojis_below_message(
emoji="love").wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.channel_2, "Reply message reaction is not shown for the reply sender")
self.errors.append("Reply message reaction is not shown for the reply sender")
self.errors.verify_no_errors()
@@ -545,14 +537,13 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.send_message(emoji_message)
for channel in self.channel_1, self.channel_2:
if not channel.chat_element_by_text(emoji_unicode).is_element_displayed(30):
self.errors.append(channel, 'Message with emoji was not sent or received in community channel')
self.errors.append('Message with emoji was not sent or received in community channel')
self.channel_1.just_fyi("Can copy and paste emojis")
self.channel_1.copy_message_text(emoji_unicode)
actual_copied_text = self.channel_1.driver.get_clipboard_text()
if actual_copied_text != emoji_unicode:
self.errors.append(self.channel_1,
'Emoji message was not copied, text in clipboard is %s' % actual_copied_text)
self.errors.append('Emoji message was not copied, text in clipboard is %s' % actual_copied_text)
self.channel_1.just_fyi("Can reply to emojis")
if not self.channel_2.chat_message_input.is_element_displayed():
@@ -566,7 +557,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
chat_element_1 = self.channel_1.chat_element_by_text(message_text)
chat_element_1.wait_for_element(60)
if chat_element_1.replied_message_text != emoji_unicode:
self.errors.append(self.channel_1, 'Reply message is not reply to original message!')
self.errors.append('Reply message is not reply to original message!')
self.errors.verify_no_errors()
@marks.testrail_id(702844)
@@ -622,30 +613,27 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
try:
self.channel_2.url_preview_composer.wait_for_element(20)
except TimeoutException:
self.errors.append(self.channel_1, "No preview is loaded for url %s" % url)
self.errors.append("No preview is loaded for url %s" % url)
self.channel_2.send_message_button.click()
continue
shown_title = self.channel_2.url_preview_composer_text.text
if shown_title != data['title']:
self.errors.append(self.channel_2, "Preview text is not expected, it is '%s'" % shown_title)
self.errors.append("Preview text is not expected, it is '%s'" % shown_title)
self.channel_2.send_message_button.click()
message = self.channel_1.get_preview_message_by_text(url)
message.wait_for_element(60)
if not message.preview_image:
self.errors.append(self.channel_1, "No preview image is shown for %s" % url)
self.errors.append("No preview image is shown for %s" % url)
shown_title = message.preview_title.text
if shown_title != data['title']:
self.errors.append(self.channel_1,
"Title is not equal expected for '%s', actual is '%s'" % (url, shown_title))
self.errors.append("Title is not equal expected for '%s', actual is '%s'" % (url, shown_title))
shown_description = message.preview_subtitle.text
if shown_description != data['description']:
self.errors.append(self.channel_1,
"Description is not equal expected for '%s', actual is '%s'" % (
url, shown_description))
self.errors.append(
"Description is not equal expected for '%s', actual is '%s'" % (url, shown_description))
shown_link = message.preview_link.text
if shown_link != data['link']:
self.errors.append(self.channel_1,
"Link is not equal expected for '%s', actual is '%s'" % (url, shown_link))
self.errors.append("Link is not equal expected for '%s', actual is '%s'" % (url, shown_link))
self.channel_1.just_fyi("Set reaction and check it")
message_with_reaction = list(preview_urls.values())[-1]['url']
@@ -657,7 +645,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.chat_element_by_text(message_with_reaction).emojis_below_message(
emoji="laugh").wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.channel_2, "Link message reaction is not shown for the sender")
self.errors.append("Link message reaction is not shown for the sender")
self.errors.verify_no_errors()
@@ -674,14 +662,14 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.just_fyi('Check new messages badge is shown for community')
community_element_1 = self.home_1.get_chat(self.community_name, community=True)
if not community_element_1.new_messages_grey_dot.is_element_displayed(sec=30):
self.errors.append(self.home_1, 'New message community badge is not shown')
self.errors.append('New message community badge is not shown')
community_1 = community_element_1.click()
channel_1_element = community_1.get_channel(self.channel_name)
self.home_1.just_fyi('Check new messages badge is shown for channel')
if not channel_1_element.new_messages_grey_dot.is_element_displayed():
self.errors.append(self.channel_1, 'New messages channel badge is not shown on channel')
self.errors.append('New messages channel badge is not shown on channel')
channel_1_element.click()
self.errors.verify_no_errors()
@@ -708,7 +696,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.chat_1.just_fyi('Check that messages from blocked user are hidden in public chat and close app')
if not self.chat_1.chat_element_by_text(message_to_disappear).is_element_disappeared(30):
self.errors.append(self.chat_1, "Messages from blocked user is not cleared in public chat ")
self.errors.append("Messages from blocked user is not cleared in public chat ")
self.chat_1.navigate_back_to_home_view()
# ToDo: enable when https://github.com/status-im/status-mobile/issues/19334 is fixed
# self.home_1.chats_tab.click()
@@ -727,8 +715,8 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.get_chat(self.channel_name, community_channel=True).click()
for message in message_to_disappear, message_blocked:
if self.chat_1.chat_element_by_text(message).is_element_displayed(30):
self.errors.append(self.chat_1,
"'%s' from blocked user is fetched from offline in community channel" % message)
self.errors.append(
"'%s' from blocked user is fetched from offline in community channel" % message)
self.chat_1.just_fyi('Unblock user and check that can see further messages')
# TODO: still no blocked users in new UI
@@ -748,8 +736,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.home_1.get_chat(self.channel_name, community_channel=True).click()
self.chat_1.hide_keyboard_if_shown()
if not self.chat_1.chat_element_by_text(message_unblocked).is_element_displayed(120):
self.errors.append(self.chat_1,
"%s was not received in public chat after user unblock!" % message_unblocked)
self.errors.append("%s was not received in public chat after user unblock!" % message_unblocked)
self.errors.verify_no_errors()
self.home_1.just_fyi("Add blocked user to contacts again after removing(removed automatically when blocked)")
@@ -769,7 +756,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
unblocked = True
except TimeoutException:
unblocked = False
self.errors.append(self.chat_1, "Chat with unblocked user was not enabled after 1 minute")
self.errors.append("Chat with unblocked user was not enabled after 1 minute")
if unblocked:
self.home_2.just_fyi("Check message in 1-1 chat after unblock")
@@ -780,9 +767,9 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.chat_2.chat_element_by_text(message_unblocked).wait_for_status_to_be(expected_status='Delivered',
timeout=120)
if not self.chat_1.chat_element_by_text(message_unblocked).is_element_displayed(30):
self.errors.append(self.chat_1, "Message was not received in 1-1 chat after user unblock!")
self.errors.append("Message was not received in 1-1 chat after user unblock!")
except TimeoutException:
self.errors.append(self.chat_2, 'Message was not delivered after back up online.')
self.errors.append('Message was not delivered after back up online.')
self.errors.verify_no_errors()
@@ -796,23 +783,22 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_2.send_message(self.text_message)
community_1_element = self.community_1.get_chat(self.community_name, community=True)
if not community_1_element.new_messages_grey_dot.is_element_displayed(90):
self.errors.append(self.community_1, 'New messages counter is not shown in home > Community element')
self.errors.append('New messages counter is not shown in home > Community element')
community_1_element.click()
channel_1_element = self.community_1.get_chat(self.channel_name, community_channel=True)
if not channel_1_element.new_messages_grey_dot.is_element_displayed():
self.errors.append(self.community_1, "New messages counter is not shown in community channel element")
self.errors.append("New messages counter is not shown in community channel element")
self.community_1.click_system_back_button()
mark_as_read_button = self.community_1.mark_all_messages_as_read_button
self.home_1.community_floating_screen.wait_for_invisibility_of_element()
community_1_element.long_press_until_element_is_shown(mark_as_read_button)
mark_as_read_button.click()
if community_1_element.new_messages_grey_dot.is_element_displayed():
self.errors.append(self.community_1,
'Unread messages badge is shown in community element while there are no unread messages')
self.errors.append(
'Unread messages badge is shown in community element while there are no unread messages')
community_1_element.click()
if channel_1_element.new_messages_grey_dot.is_element_displayed():
self.errors.append(
self.community_1,
"New messages badge is shown in community channel element while there are no unread messages")
self.errors.verify_no_errors()
@@ -841,10 +827,9 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.channel_1.just_fyi("Receiver is checking if messages were updated and deleted")
if not self.channel_1.chat_element_by_text(message_after_edit).is_element_displayed(30):
self.errors.append(self.channel_1,
"Updated message '%s' is not delivered to the receiver" % message_after_edit)
self.errors.append("Updated message '%s' is not delivered to the receiver" % message_after_edit)
if not self.channel_1.chat_element_by_text(message_to_delete).is_element_disappeared():
self.errors.append(self.channel_1, "Message '%s' was not deleted for the receiver" % message_to_delete)
self.errors.append("Message '%s' was not deleted for the receiver" % message_to_delete)
self.errors.verify_no_errors()
@@ -905,13 +890,12 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
message_received = True
if not self.channel_1.chat_element_by_text(self.username_1).is_element_displayed():
if self.channel_1.chat_message_input.is_element_displayed():
self.errors.append(self.channel_1,
"Message with the mention is not shown in the chat for the admin")
self.errors.append("Message with the mention is not shown in the chat for the admin")
else:
self.errors.append(self.channel_1,
"Channel did not open by clicking on a notification with the mention for admin")
self.errors.append(
"Channel did not open by clicking on a notification with the mention for admin")
else:
self.errors.append(self.channel_1, "Push notification with the mention was not received by admin")
self.errors.append("Push notification with the mention was not received by admin")
if not self.channel_1.chat_message_input.is_element_displayed():
self.channel_1.navigate_back_to_home_view()
@@ -941,20 +925,20 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.channel_2.send_message_button.click()
edit_done = True
if chat_element.message_body_with_mention.text != expected_message:
self.errors.append(self.channel_2, "Edited message is not shown correctly for the sender")
self.errors.append("Edited message is not shown correctly for the sender")
except NoSuchElementException:
self.errors.append(self.channel_2, "Can not edit a message with a mention")
self.errors.append("Can not edit a message with a mention")
if edit_done:
element = self.channel_1.chat_element_by_text(self.username_1).message_body_with_mention
if not element.is_element_displayed(10) or element.text != expected_message:
self.errors.append(self.channel_1, "Edited message is not shown correctly for the (receiver) admin")
self.errors.append("Edited message is not shown correctly for the (receiver) admin")
self.device_2.just_fyi("Sender checks the reaction for a message with a mention")
try:
self.channel_2.chat_element_by_text(self.username_1).emojis_below_message(
emoji="sad").wait_for_element_text(1)
except (Failed, NoSuchElementException):
self.errors.append(self.channel_2, "Message reaction is not shown for the sender")
self.errors.append("Message reaction is not shown for the sender")
self.home_2.navigate_back_to_home_view()
if not self.channel_1.chat_message_input.is_element_displayed():
@@ -973,15 +957,12 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
push_notification_element.click()
if not self.channel_2.chat_element_by_text(self.username_2).is_element_displayed():
if self.channel_2.chat_message_input.is_element_displayed():
self.errors.append(self.channel_2,
"Message with the mention is not shown in the chat for the invited member")
self.errors.append("Message with the mention is not shown in the chat for the invited member")
else:
self.errors.append(
self.channel_2,
"Channel did not open by clicking on a notification with the mention for the invited member")
else:
self.errors.append(self.channel_2,
"Push notification with the mention was not received by the invited member")
self.errors.append("Push notification with the mention was not received by the invited member")
self.errors.verify_no_errors()
@marks.testrail_id(702809)
@@ -1008,13 +989,11 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.channel_2.send_message(message_to_send)
if not self.channel_2.chat_element_by_text(message).is_element_displayed():
self.errors.append(
self.channel_2,
'%s is not displayed with markdown in community channel for the sender \n' % message)
'%s is not displayed with markdown in community channel for the sender (device 2) \n' % message)
if not self.channel_1.chat_element_by_text(message).is_element_displayed():
self.errors.append(
self.channel_1,
'%s is not displayed with markdown in community channel for the recipient \n' % message)
'%s is not displayed with markdown in community channel for the recipient (device 1) \n' % message)
for home in self.homes:
home.navigate_back_to_home_view()
@@ -1030,11 +1009,10 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.chat_1.send_message(message_to_send)
if not self.chat_1.chat_element_by_text(message).is_element_displayed(30):
self.errors.append(
self.chat_1, '%s is not displayed with markdown in 1-1 chat for the sender (device 1) \n' % message)
'%s is not displayed with markdown in 1-1 chat for the sender (device 1) \n' % message)
if not self.chat_2.chat_element_by_text(message).is_element_displayed(30):
self.errors.append(
self.chat_2,
'%s is not displayed with markdown in 1-1 chat for the recipient (device 2) \n' % message)
self.errors.verify_no_errors()
@@ -1049,7 +1027,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
community_to_leave.leave_community_button.click()
community_to_leave.leave_community_button.click()
if not community.is_element_disappeared():
self.errors.append(self.home_2, 'Community is still shown in the list after leave')
self.errors.append('Community is still shown in the list after leave')
self.errors.verify_no_errors()
@marks.xfail(reason="Can't navigate to a community channel before joining the community, "
@@ -1080,13 +1058,12 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
if not self.community_2.get_channel(chan_name).is_element_displayed():
not_shown.append(chan_name)
if not_shown:
self.errors.append(self.community_2,
"Not all channels are shown in community before joining: %s" % not_shown)
self.errors.append("Not all channels are shown in community before joining: %s" % not_shown)
chan = self.community_2.get_channel("general")
if chan.is_element_displayed():
chan.find_element().click()
if not self.channel_2.chat_element_by_text(control_message_general_chat).is_element_displayed(20):
self.errors.append(self.channel_2, "Message in community channel is not visible for user before join")
self.errors.append("Message in community channel is not visible for user before join")
else:
not_shown.append("general")
@@ -1101,7 +1078,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
try:
self.home_1.notifications_unread_badge.wait_for_visibility_of_element(120)
except TimeoutException:
self.errors.append(self.home_1, "Unread indicator is not shown in notifications on membership request")
self.errors.append("Unread indicator is not shown in notifications on membership request")
self.home_1.open_activity_center_button.click()
reply_element = self.home_1.get_element_from_activity_center_view(self.username_2)
reply_element.title.swipe_right_on_element(width_percentage=2.5)
@@ -1127,12 +1104,12 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.home_2.get_to_community_channel_from_home(community_name, dogs_channel)
self.channel_2.chat_element_by_text(message_with_hashtag).click_on_link_inside_message_body()
if not self.channel_2.chat_element_by_text(cats_message).is_element_displayed(30):
self.errors.append(self.channel_2, "Receiver was not navigated to the cats channel")
self.errors.append("Receiver was not navigated to the cats channel")
self.home_1.just_fyi("Device 1 clicks on the message with hashtag in the community channel")
self.channel_1.chat_element_by_text(message_with_hashtag).click_on_link_inside_message_body()
if not self.channel_1.chat_element_by_text(cats_message).is_element_displayed(30):
self.errors.append(self.channel_1, "Sender was not navigated to the cats channel")
self.errors.append("Sender was not navigated to the cats channel")
for home in self.homes:
home.navigate_back_to_home_view()
@@ -1146,12 +1123,12 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
self.home_1.get_chat(self.username_2).click()
self.chat_1.chat_element_by_text(message_with_hashtag).click_on_link_inside_message_body()
if self.chat_1.chat_element_by_text(control_message_1_1_chat).is_element_disappeared():
self.errors.append(self.chat_1, "Receiver was navigated out of 1-1 chat")
self.errors.append("Receiver was navigated out of 1-1 chat")
self.home_2.just_fyi("Device 2 clicks on the message with hashtag in 1-1 chat")
self.chat_2.chat_element_by_text(message_with_hashtag).click_on_link_inside_message_body()
if self.chat_2.chat_element_by_text(control_message_1_1_chat).is_element_disappeared():
self.errors.append(self.chat_2, "Sender was navigated out of 1-1 chat")
self.errors.append("Sender was navigated out of 1-1 chat")
self.errors.verify_no_errors()
@@ -1192,23 +1169,21 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
if self.community_2.toast_content_element.is_element_displayed(10):
cur_text = self.community_2.toast_content_element.text
if cur_text != exp_text:
self.errors.append(self.community_2,
"Text \"%s\" in shown toast element doesn't match expected \"%s\"" % (
cur_text, exp_text))
self.errors.append(
"Text \"%s\" in shown toast element doesn't match expected \"%s\"" % (cur_text, exp_text))
else:
self.errors.append(self.community_2, "Toast element with the text \"%s\" doesn't appear" % exp_text)
self.errors.append("Toast element with the text \"%s\" doesn't appear" % exp_text)
if not self.community_2.community_status_pending.is_element_displayed():
self.errors.append(self.community_2, "Pending status is not displayed")
self.errors.append("Pending status is not displayed")
general_channel = self.community_2.get_channel("general")
if general_channel.is_element_displayed():
general_channel.find_element().click()
if not self.channel_2.chat_element_by_text(control_message_general_chat).is_element_displayed(30):
self.errors.append(
self.community_2,
"Message in community channel is not visible for user before join, it was indicated as " \
"%s sent for the sender before he went offline" % ("" if message_sent else "not"))
else:
self.errors.append(self.community_2, "Community channel is not displayed for user before join")
self.errors.append("Community channel is not displayed for user before join")
self.community_2.toast_content_element.wait_for_invisibility_of_element(30)
self.home_2.navigate_back_to_home_view()
self.home_2.communities_tab.click()
@@ -1216,7 +1191,7 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
if self.home_2.get_chat(community_name, community=True).is_element_displayed():
self.home_2.get_chat(community_name, community=True).click()
else:
self.errors.append(self.home_2, "%s is not listed inside Pending communities tab" % community_name)
self.errors.append("%s is not listed inside Pending communities tab" % community_name)
self.home_1.just_fyi("Device 1 goes back online")
self.home_1.driver.activate_app(app_package)
@@ -1227,14 +1202,13 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
if self.community_2.toast_content_element.is_element_displayed(60):
cur_text = self.community_2.toast_content_element.text
if cur_text != exp_text:
self.errors.append(self.community_2,
"Text \"%s\" in shown toast element doesn't match expected \"%s\"" % (
cur_text, exp_text))
self.errors.append(
"Text \"%s\" in shown toast element doesn't match expected \"%s\"" % (cur_text, exp_text))
# else:
# self.errors.append("Toast element with the text \"%s\" doesn't appear" % exp_text)
# ToDo: add verification when toast is fixed
if not self.community_2.community_status_joined.is_element_displayed():
self.errors.append(self.community_2, "Joined status is not displayed")
self.errors.append("Joined status is not displayed")
self.community_2.close_community_view_button.click_until_absense_of_element(
self.community_2.close_community_view_button)
self.home_2.joined_communities_tab.click()
@@ -1242,6 +1216,6 @@ class TestCommunityMultipleDeviceMergedTwo(MultipleSharedDeviceTestCase):
if chat_element.is_element_displayed(30):
chat_element.click()
else:
self.errors.append(self.home_2, "%s is not listed inside Joined communities tab" % community_name)
self.errors.append("%s is not listed inside Joined communities tab" % community_name)
self.errors.verify_no_errors()
@@ -42,9 +42,9 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
if self.channel.profile_send_contact_request_button.is_element_displayed(10):
username_text = self.profile_view.contact_name_text.text
if not (username_text.endswith(url[-6:]) or username_text == text):
self.errors.append(self.channel, "Incorrect username is shown for profile url %s" % url)
self.errors.append("Incorrect username is shown for profile url %s" % url)
else:
self.errors.append(self.channel, "Profile was not opened by the profile url %s" % url)
self.errors.append("Profile was not opened by the profile url %s" % url)
self.profile_view.close_button.click()
self.errors.verify_no_errors()
@@ -69,7 +69,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
else:
name_is_shown = shown_name_text.endswith(link[-6:])
if not self.channel.profile_send_contact_request_button.is_element_displayed(10) or not name_is_shown:
self.errors.append(self.channel, "Profile was not opened by the profile deep link %s" % link)
self.errors.append("Profile was not opened by the profile deep link %s" % link)
self.browser_view.click_system_back_button()
self.errors.verify_no_errors()
@@ -103,13 +103,11 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
self.browser_view.open_url(link)
if text == snt_community_name:
if self.community_view.community_title.text != text:
self.errors.append(self.community_view,
"Community '%s' was not requested to join by the deep link %s" % (text, link))
self.errors.append("Community '%s' was not requested to join by the deep link %s" % (text, link))
else:
if not self.community_view.join_button.is_element_displayed(
10) or self.community_view.community_title.text != text:
self.errors.append(self.community_view,
"Community '%s' was not requested to join by the deep link %s" % (text, link))
self.errors.append("Community '%s' was not requested to join by the deep link %s" % (text, link))
if text != closed_community_name: # the last one
self.home.navigate_back_to_home_view()
self.home.browser_tab.click()
@@ -125,8 +123,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
self.home.open_link_from_google_search_app(profile_url, app_package)
if not self.channel.profile_add_to_contacts_button.is_element_displayed(
10) or not self.profile_view.default_username_text.text.endswith(profile_url[-6:]):
self.errors.append(self.profile_view,
"Profile was not opened by the url %s when user is logged in" % profile_url)
self.errors.append("Profile was not opened by the url %s when user is logged in" % profile_url)
self.home.just_fyi("Opening a community URL from google search bar when user is logged out")
self.driver.terminate_app(app_package)
@@ -134,8 +131,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
self.home.open_link_from_google_search_app(community_url, app_package)
self.sign_in.sign_in(user_name=self.username)
if not self.community_view.join_button.is_element_displayed(10):
self.errors.append(self.community_view,
"Closed community was not requested to join by the url %s" % community_url)
self.errors.append("Closed community was not requested to join by the url %s" % community_url)
# ToDo: enable when https://github.com/status-im/status-mobile/issues/18074 is fixed
# self.home.just_fyi("Opening a community channel URL from google search bar with no account created")
+30 -50
View File
@@ -72,11 +72,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
if device_element.is_element_displayed():
if not device_element.get_pair_button.is_element_displayed():
self.errors.append(
self.profile_1,
"Pair button is absent for the device 2 inside Paired devices list of profile 1 before pairing")
else:
self.errors.append(self.profile_1,
"Device 2 is not shown in Paired devices list for device 1 before pairing")
self.errors.append("Device 2 is not shown in Paired devices list for device 1 before pairing")
self.profile_1.click_system_back_button(times=3)
for home in self.home_1, self.home_2:
@@ -86,10 +84,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.home_1.just_fyi("Checking pairing request on device 1")
a_c_element = self.home_1.get_activity_center_element_by_text(transl['review-pairing-request'])
if a_c_element.title.text != transl['new-device-detected']:
self.errors.append(self.home_1,
"Notification with title '%s' is not shown in the activity center for the device 1" %
transl[
'new-device-detected'])
self.errors.append(
"Notification with title '%s' is not shown in the activity center for the device 1" % transl[
'new-device-detected'])
a_c_element.review_pairing_request_button.click()
device_id_1 = self.home_1.get_new_device_installation_id()
@@ -98,15 +95,14 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.home_2.just_fyi("Checking sync profile on device 2")
a_c_element = self.home_2.get_activity_center_element_by_text(transl['more-details'])
if a_c_element.title.text != transl['sync-your-profile']:
self.errors.append(self.home_2,
"Notification with title '%s' is not shown in the activity center for the device 2" %
transl[
'sync-your-profile'])
self.errors.append(
"Notification with title '%s' is not shown in the activity center for the device 2" % transl[
'sync-your-profile'])
a_c_element.more_details_button.click()
device_id_2 = self.home_2.get_new_device_installation_id()
if device_id_1 != device_id_2:
self.errors.append(self.home_2, "Device ids don't match on the activity center notifications")
self.errors.append("Device ids don't match on the activity center notifications")
self.home_1.just_fyi("Confirm pairing request on device 1")
self.home_1.element_by_translation_id('pair-and-sync').click()
@@ -125,11 +121,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
if device_element.is_element_displayed():
if not device_element.get_unpair_button.is_element_displayed():
self.errors.append(
self.profile_1,
"Unpair button is absent for the device 2 inside Paired devices list of profile 1 after pairing")
else:
self.errors.append(self.profile_1,
"Device 2 is not shown in Paired devices list for device 1 after pairing")
self.errors.append("Device 2 is not shown in Paired devices list for device 1 after pairing")
self.home_2.just_fyi("Device 2: Check that the device 1 is shown paired devices list")
self.home_2.profile_button.click()
@@ -139,11 +133,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
if device_element.is_element_displayed():
if not device_element.get_unpair_button.is_element_displayed():
self.errors.append(
self.profile_2,
"Unpair button is absent for the device 1 inside Paired devices list of profile 2 after pairing")
else:
self.errors.append(self.profile_2,
"Device 1 is not shown in Paired devices list for device 2 after pairing")
self.errors.append("Device 1 is not shown in Paired devices list for device 2 after pairing")
self.home_3.just_fyi("Device 3: send a message to user 1")
self.home_3.chats_tab.click()
@@ -161,7 +153,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
chat_view = chat_element.click()
chat_view.chat_element_by_text(message).wait_for_visibility_of_element(60)
except TimeoutException:
self.errors.append(home_view, "Message is not received by the user %s" % index)
self.errors.append("Message is not received by the user %s" % index)
self.loop.run_until_complete(
run_in_parallel(((_check_message, {'home_view': self.home_1, 'index': 1}),
@@ -186,12 +178,11 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
wallet_1.close_account_button.click_until_presence_of_element(account_element)
if regular_account_address != expected_addresses[1]:
self.errors.append(wallet_1, "Newly added regular account address %s doesn't match expected %s" % (
self.errors.append("Newly added regular account address %s doesn't match expected %s" % (
regular_account_address, expected_addresses[1]))
if regular_account_address not in expected_addresses:
self.errors.append(wallet_1,
"Newly added regular account address %s is not in the list of expected addresses %s" % (
regular_account_address, expected_addresses))
self.errors.append("Newly added regular account address %s is not in the list of expected addresses %s" % (
regular_account_address, expected_addresses))
wallet_1.just_fyi("Device 1: add a new key pair account by importing recovery phrase")
account_element.swipe_left_on_element()
@@ -219,7 +210,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
]
for text in expected_texts_regular:
if not wallet_1.default_key_pair_container.get_child_element_by_text_part(text).is_element_displayed():
self.errors.append(wallet_1, "Newly added regular account is not shown in default key pair list")
self.errors.append("Newly added regular account is not shown in default key pair list")
break
expected_texts_key_pair = [
imported_key_pair_account_name, imported_key_pair_name,
@@ -227,7 +218,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
]
for text in expected_texts_key_pair:
if not wallet_1.added_key_pair_container.get_child_element_by_text_part(text).is_element_displayed():
self.errors.append(wallet_1, "Newly added regular account is not shown in default key pair list")
self.errors.append("Newly added regular account is not shown in default key pair list")
break
wallet_1.just_fyi("Device 1: add a new key pair account by generating a new key pair")
@@ -241,30 +232,27 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
expected_addresses = generate_wallet_address(passphrase=generated_passphrase, number=4)
if generated_key_pair_account_address != expected_addresses[0]:
self.errors.append(wallet_1, "Generated key pair account address %s doesn't match expected %s" % (
self.errors.append("Generated key pair account address %s doesn't match expected %s" % (
generated_key_pair_account_address, expected_addresses[0]))
if generated_key_pair_account_address not in expected_addresses:
self.errors.append(wallet_1,
"Generated key pair account address %s is not in the list of expected addresses %s" % (
generated_key_pair_account_address, expected_addresses))
self.errors.append("Generated key pair account address %s is not in the list of expected addresses %s" % (
generated_key_pair_account_address, expected_addresses))
self.home_2.just_fyi("Device 2: check imported accounts are shown before importing key pair")
self.home_2.profile_button.click()
self.profile_2.profile_wallet_button.click()
self.profile_2.key_pairs_and_accounts_button.click()
if not self.profile_2.get_missing_key_pair_by_name(key_pair_name=imported_key_pair_name).is_element_displayed():
self.errors.append(self.profile_2,
"New imported key pair is not shown in profile as missing before importing")
self.errors.append("New imported key pair is not shown in profile as missing before importing")
if not self.profile_2.get_missing_key_pair_by_name(
key_pair_name=generated_key_pair_name).is_element_displayed():
self.errors.append(self.profile_2, "Generated key pair is not shown in profile as missing before importing")
self.errors.append("Generated key pair is not shown in profile as missing before importing")
if not self.profile_2.get_key_pair_account_by_name(account_name=regular_account_name).is_element_displayed():
self.errors.append(
self.profile_2,
"Newly added regular account is not shown in profile as on device before importing key pair")
self.profile_2.options_button.click()
if not self.profile_2.import_by_entering_recovery_phrase_button.is_element_displayed():
self.errors.append(self.profile_2, "Can not import key pair account from profile")
self.errors.append("Can not import key pair account from profile")
self.profile_2.click_system_back_button(times=4)
wallet_2.just_fyi("Device 2: import key pair")
@@ -282,11 +270,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
address_text = self.profile_2.get_key_pair_account_by_name(account_name=regular_account_name).address.text
if address_text != '...'.join((regular_account_address[:5], regular_account_address[-3:])):
self.errors.append(
self.profile_2,
"Incorrect wallet address if shown for regular account after importing: " + address_text)
else:
self.errors.append(self.profile_2,
"Newly added regular account is not shown in profile after importing key pair")
self.errors.append("Newly added regular account is not shown in profile after importing key pair")
account_element = self.profile_2.get_key_pair_account_by_name(
account_name=imported_key_pair_account_name)
@@ -295,17 +281,14 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
if address_text != '...'.join(
(imported_key_pair_account_address[:5], imported_key_pair_account_address[-3:])):
self.errors.append(
self.profile_2,
"Incorrect wallet address if shown for imported key pair account after importing: " + address_text)
else:
self.errors.append(
self.profile_2,
"Imported key pair account is not shown in profile as on device after importing key pair")
if not self.profile_2.get_missing_key_pair_by_name(
key_pair_name=generated_key_pair_name).is_element_displayed():
self.errors.append(
self.profile_2,
"Generated key pair account is not shown in profile as missing after importing the first key pair")
self.profile_2.click_system_back_button(times=3)
@@ -323,15 +306,14 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
wallet_2.about_tab.click()
der_path = wallet_2.account_about_derivation_path_text.text
if der_path != regular_derivation_path:
self.errors.append(wallet_2, "Incorrect derivation path %s is shown for the regular account" % der_path)
self.errors.append("Incorrect derivation path %s is shown for the regular account" % der_path)
wallet_2.close_account_button.click_until_presence_of_element(account_element)
account_element.swipe_left_on_element()
wallet_2.get_account_element(account_name=imported_key_pair_account_name).click()
wallet_2.about_tab.click()
der_path = wallet_2.account_about_derivation_path_text.text
if der_path != imported_key_pair_derivation_path:
self.errors.append(wallet_2,
"Incorrect derivation path %s is shown for the imported key pair account" % der_path)
self.errors.append("Incorrect derivation path %s is shown for the imported key pair account" % der_path)
wallet_2.close_account_button.click_until_presence_of_element(account_element)
account_element.swipe_left_on_element()
wallet_2.get_account_element(account_name=generated_key_pair_account_name).click()
@@ -342,8 +324,7 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
wallet_2.about_tab.click()
der_path = wallet_2.account_about_derivation_path_text.text
if der_path != generated_key_pair_derivation_path:
self.errors.append(wallet_2,
"Incorrect derivation path %s is shown for the generated key pair account" % der_path)
self.errors.append("Incorrect derivation path %s is shown for the generated key pair account" % der_path)
if not wallet_2.element_by_text_part(generated_key_pair_account_address).is_element_displayed():
self.errors.append(
"Generated key pair address %s is absent in About tab" % generated_key_pair_account_address)
@@ -364,14 +345,14 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.sign_in_2.passphrase_edit_box.send_keys(' '.join(['asset'] * 12))
self.sign_in_2.continue_button.click()
if not self.sign_in_2.element_by_translation_id('seed-phrase-invalid').is_element_displayed():
self.errors.append(self.sign_in_2, "Error message is not displayed for invalid recovery phrase")
self.errors.append("Error message is not displayed for invalid recovery phrase")
self.sign_in_2.just_fyi("Device 2: try creating an account with another valid passphrase")
self.sign_in_2.passphrase_edit_box.clear()
self.sign_in_2.passphrase_edit_box.send_keys(transaction_senders['A']['passphrase'])
self.sign_in_2.continue_button.click()
if not self.sign_in_2.password_input.is_element_displayed():
self.errors.append(self.sign_in_2, "Can't recover an access with a valid passphrase")
self.errors.append("Can't recover an access with a valid passphrase")
self.sign_in_2.click_system_back_button(times=2)
self.sign_in_2.just_fyi("Device 2: try recovering an account which is already synced")
@@ -382,10 +363,9 @@ class TestFallbackMultipleDevice(MultipleSharedDeviceTestCase):
self.sign_in_2.native_alert_title.wait_for_element()
shown_text = self.sign_in_2.native_alert_title.text
if shown_text != "Keys for this account already exist":
self.errors.append(self.sign_in_2,
"Incorrect error message '%s' is shown for already synced account" % shown_text)
self.errors.append("Incorrect error message '%s' is shown for already synced account" % shown_text)
self.sign_in_2.cancel_button.click()
except TimeoutException:
self.errors.append(self.sign_in_2, "Error is not shown for already synced account")
self.errors.append("Error is not shown for already synced account")
self.errors.verify_no_errors()
+25 -194
View File
@@ -1,10 +1,9 @@
import datetime
import re
import time
import pytest
from _pytest.outcomes import Failed
from selenium.common import NoSuchElementException, TimeoutException
from selenium.common import TimeoutException, NoSuchElementException
from base_test_case import MultipleSharedDeviceTestCase, create_shared_drivers
from support.api.network_api import NetworkApi
@@ -76,9 +75,8 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
return
if user_name == self.receiver_username and new_eth_amount >= exp_amount:
return
self.errors.append(wallet_view,
"Eth amount in the %s's wallet is %s but should be %s" % (
user_name, new_eth_amount, exp_amount))
self.errors.append(
"Eth amount in the %s's wallet is %s but should be %s" % (user_name, new_eth_amount, exp_amount))
# ToDo: disable relogin when autoupdate feature is ready
self.home_1.just_fyi("Relogin for getting an updated balance")
@@ -121,12 +119,10 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
activity_element.from_text == sender_address_short,
activity_element.to_text == receiver_address_short)):
self.errors.append(
wallet_view,
"The last transaction is not listed in activity for the %s, expected timestamp is %s" %
('sender' if sender else 'receiver', expected_time))
except NoSuchElementException:
self.errors.append(wallet_view,
"Can't find the last transaction for the %s" % ('sender' if sender else 'receiver'))
self.errors.append("Can't find the last transaction for the %s" % ('sender' if sender else 'receiver'))
finally:
wallet_view.close_account_button.click_until_presence_of_element(wallet_view.show_qr_code_button)
@@ -145,7 +141,7 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
device_time_before_sending = self.wallet_1.driver.device_time
self.wallet_1.send_asset(address='arb1:' + self.receiver['wallet_address'],
asset_name='Ether',
amount=f"{amount_to_send:.4f}",
amount=amount_to_send,
network_name=self.network)
# ToDo: Arbiscan API is down, looking for analogue
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
@@ -181,7 +177,7 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
device_time_before_sending = self.wallet_1.driver.device_time
self.wallet_1.send_asset_from_drawer(address='arb1:' + self.receiver['wallet_address'],
asset_name='Ether',
amount=f"{amount_to_send:.4f}",
amount=amount_to_send,
network_name=self.network)
# ToDo: Arbiscan API is down, looking for analogue
# self.network_api.wait_for_confirmation_of_transaction(address=self.sender['wallet_address'],
@@ -211,12 +207,13 @@ class TestWalletMultipleDevice(MultipleSharedDeviceTestCase):
class TestWalletOneDevice(MultipleSharedDeviceTestCase):
def prepare_devices(self):
self.network_api = NetworkApi()
self.drivers, self.loop = create_shared_drivers(1)
self.sign_in_view = SignInView(self.drivers[0])
self.sender, self.receiver = transaction_senders['ETH_1'], transaction_senders['ETH_2']
self.total_balance = {'Ether': 0.0062, 'USDCoin': 5.0, 'Status': 13.0, 'Uniswap': 0.627, 'Dai Stablecoin': 0.0}
self.total_balance = {'Ether': 0.0052, 'USDCoin': 5.0, 'Status': 10.0, 'Uniswap': 0.627, 'Dai Stablecoin': 0.0}
self.mainnet_balance = {'Ether': 0.005, 'USDCoin': 0.0, 'Status': 10.0, 'Uniswap': 0.127, 'Dai Stablecoin': 0.0}
self.optimism_balance = {'Ether': 0.0011, 'USDCoin': 5.0, 'Status': 3.0, 'Uniswap': 0, 'Dai Stablecoin': 0.0}
self.optimizm_balance = {'Ether': 0.0001, 'USDCoin': 5.0, 'Status': 0, 'Uniswap': 0, 'Dai Stablecoin': 0.0}
self.arb_balance = {'Ether': 0.0001, 'USDCoin': 0.0, 'Status': 0.0, 'Uniswap': 0.5, 'Dai Stablecoin': 0.0}
self.sender['wallet_address'] = '0x' + self.sender['address']
self.receiver['wallet_address'] = '0x' + self.receiver['address']
@@ -224,13 +221,15 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
self.home_view = self.sign_in_view.get_home_view()
self.sender_username = self.home_view.get_username()
self.profile_view = self.home_view.profile_button.click()
self.profile_view.switch_network()
self.sign_in_view.sign_in(user_name=self.sender_username)
self.wallet_view = self.home_view.wallet_tab.click()
@marks.testrail_id(740490)
def test_wallet_balance_mainnet(self):
self.profile_view = self.home_view.profile_button.click()
self.profile_view.switch_network()
self.sign_in_view.sign_in(user_name=self.sender_username)
self.sign_in_view.wallet_tab.click()
self.wallet_view.just_fyi("Checking total balance")
real_balance = {}
for asset in self.total_balance:
@@ -238,12 +237,12 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
for asset in self.total_balance:
if real_balance[asset] != self.total_balance[asset]:
self.errors.append(self.wallet_view, "For the %s the wrong value %s is shown, expected %s in total" %
self.errors.append("For the %s the wrong value %s is shown, expected %s in total" %
(asset, real_balance[asset], self.total_balance[asset]))
expected_balances = {
'Mainnet': self.mainnet_balance,
'Arbitrum': self.arb_balance,
'Optimism': self.optimism_balance
'Optimism': self.optimizm_balance
}
for network in expected_balances:
@@ -254,181 +253,14 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
real_balance[asset] = self.wallet_view.get_asset(asset).get_amount()
for asset in expected_balances[network]:
if real_balance[asset] != expected_balances[network][asset]:
self.errors.append(self.wallet_view, "For the %s the wrong value %s is shown, expected %s on %s" %
self.errors.append("For the %s the wrong value %s is shown, expected %s on %s" %
(asset, real_balance[asset], expected_balances[network][asset], network))
self.wallet_view.set_network_in_wallet(network)
self.errors.verify_no_errors()
@marks.testrail_id(741554)
def test_wallet_send_flow_mainnet(self):
self.wallet_view.get_account_element().click()
self.wallet_view.send_button.click()
self.wallet_view.address_text_input.send_keys(self.receiver['wallet_address'])
self.wallet_view.continue_button.click()
asset_data = {
'Ether': {'networks': ['Mainnet', 'Arbitrum'], 'amount': '0.00001'},
'Status': {'networks': ['Mainnet', 'Optimism'], 'amount': '1'}
}
for asset, data in asset_data.items():
for network in data['networks']:
self.wallet_view.just_fyi("Checking the send flow for %s on %s" % (asset, network))
self.wallet_view.select_asset(asset)
self.wallet_view.select_network(network)
self.wallet_view.set_amount(data['amount'])
try:
max_fees_text = self.wallet_view.get_data_item_element_text(data_item_name='Max fees')
if not re.findall(r"[$]\d+.\d+", max_fees_text):
self.errors.append(self.wallet_view,
"%s on %s: max fee is not a number - %s" % (asset, network, max_fees_text))
except TimeoutException:
self.errors.append(
self.wallet_view,
"%s on %s: max fees is not shown before Review Send button is clicked" % (asset, network))
self.wallet_view.confirm_button.click()
self.wallet_view.just_fyi("Checking Review Send page for %s on %s" % (asset, network))
expected_amount = "%s %s" % (data['amount'], 'ETH' if asset == 'Ether' else 'SNT')
sender_short_address = self.sender['wallet_address'].replace(self.sender['wallet_address'][6:-3],
'').lower()
receiver_short_address = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][6:-3],
'').lower()
for text in ['Account 1', sender_short_address, expected_amount]:
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: text %s is not shown in 'From' container on the Review Send page" % (
asset, network, text))
for text in [receiver_short_address, expected_amount]:
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: text %s is not shown in 'To' container on the Review Send page" % (
asset, network, text))
data_to_check = {
'Est. time': ' min',
'Max fees': r"[$]\d+.\d+",
'Recipient gets': expected_amount
}
for key, expected_value in data_to_check.items():
try:
text = self.wallet_view.get_data_item_element_text(data_item_name=key)
if key == 'Max fees':
if not re.findall(expected_value, text):
self.errors.append(self.wallet_view,
"%s on %s: max fee is not a number - %s on the Review Send page" % (
asset, network, text))
else:
if text != expected_value:
self.errors.append(
self.wallet_view,
"%s on %s: %s text %s doesn't match expected %s on the Review Send page" % (
asset, network, key, text, expected_value))
except TimeoutException:
self.errors.append(self.wallet_view,
"%s on %s: %s is not shown on the Review Send page" % (asset, network, key))
self.wallet_view.slide_button_track.slide()
if not self.wallet_view.password_input.is_element_displayed():
self.errors.append("%s on %s: can't confirm transaction" % (asset, network))
self.wallet_view.click_system_back_button_until_presence_of_element(
element=self.wallet_view.element_by_text('Select token'), attempts=4)
self.wallet_view.click_system_back_button_until_presence_of_element(
element=self.wallet_view.add_account_button, attempts=6)
self.errors.verify_no_errors()
@marks.testrail_id(741555)
def test_wallet_swap_flow_mainnet(self):
self.wallet_view.navigate_back_to_wallet_view()
self.wallet_view.get_account_element().click()
self.wallet_view.swap_button.click()
for network in ['Mainnet', 'Optimism']:
self.wallet_view.just_fyi("Checking the Swap flow for SNT on %s" % network)
self.wallet_view.select_asset('Status')
self.wallet_view.select_network(network)
self.wallet_view.set_amount('1')
data_to_check = {
'Max fees': r"[$]\d+.\d+",
'Max slippage': r"\d+.\d+[%]"
}
for key, expected_value in data_to_check.items():
try:
text = self.wallet_view.get_data_item_element_text(data_item_name=key)
if not re.findall(expected_value, text):
self.errors.append(self.wallet_view,
"%s: %s is not a number - %s before pressing Review Swap button" % (
network, key, text))
except TimeoutException:
self.errors.append(self.wallet_view,
"%s: %s is not shown before pressing Review Swap button" % (network, key))
try:
self.wallet_view.wait_for_swap_input_to_be_shown()
except TimeoutException:
self.errors.append(self.wallet_view, "%s: ETH amount is not displayed")
continue
self.wallet_view.approve_swap_button.click()
self.wallet_view.just_fyi("Checking 'Set Spending Cap' screen for %s" % network)
if not self.wallet_view.spending_cap_approval_info_container.get_child_element_by_text(
'1 SNT').is_element_displayed():
self.errors.append(self.wallet_view,
"%s: Spending cap is not shown on the 'Set Spending Cap' screen" % network)
for text in ['Account 1',
self.sender['wallet_address'].replace(self.sender['wallet_address'][5:-3], '...').lower()]:
if not self.wallet_view.account_approval_info_container.get_child_element_by_text(
text).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s: Text %s is not shown for the account on the 'Set Spending Cap' screen" % (network, text))
if not self.wallet_view.token_approval_info_container.get_child_element_by_text(
'SNT').is_element_displayed():
self.errors.append(self.wallet_view,
"%s: Token is not shown on the 'Set Spending Cap' screen" % network)
if not self.wallet_view.spender_contract_approval_info_container.is_element_displayed():
self.errors.append(self.wallet_view,
"%s: Spender contract info is missing on the 'Set Spending Cap' screen" % network)
data_to_check = {
'Network': network,
# 'Max fees': r"[$]\d+.\d+", # ToDO: enable when https://github.com/status-im/status-mobile/issues/21948 is fixed
# 'Est. time': ' min',
}
for key, expected_value in data_to_check.items():
try:
text = self.wallet_view.get_data_item_element_text(data_item_name=key)
if key == 'Max fees':
if not re.findall(expected_value, text):
self.errors.append(self.wallet_view,
"%s: max fee is not a number - %s on the 'Set Spending Cap' screen" % (
network, text))
else:
if text != expected_value:
self.errors.append(
self.wallet_view,
"%s: %s text %s doesn't match expected %s on the 'Set Spending Cap' screen" % (
network, key, text, expected_value))
except (TimeoutException, NoSuchElementException):
self.errors.append(self.wallet_view,
"%s: %s is not shown on the 'Set Spending Cap' screen" % (network, key))
try:
self.wallet_view.slide_button_track.slide()
if not self.wallet_view.password_input.is_element_displayed():
self.errors.append(self.wallet_view, "%s: can't sign swap" % network)
except NoSuchElementException:
self.errors.append(self.wallet_view, "%s: can't sign swap" % network)
self.wallet_view.click_system_back_button_until_presence_of_element(
element=self.wallet_view.element_by_text('Select asset to pay'), attempts=4)
self.wallet_view.click_system_back_button_until_presence_of_element(
element=self.wallet_view.add_account_button, attempts=6)
self.errors.verify_no_errors()
@marks.testrail_id(727231)
def test_wallet_add_remove_regular_account(self):
self.wallet_view.navigate_back_to_wallet_view()
self.wallet_view.just_fyi("Adding new regular account")
new_account_name = "New Account"
self.wallet_view.add_regular_account(account_name=new_account_name)
@@ -442,17 +274,16 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
self.home_view.show_qr_code_button.click()
self.home_view.share_wallet_tab_button.click()
if self.home_view.account_name_text.text != 'Account 1':
self.errors.append(self.home_view, "Incorrect first account is shown on Share QR Code menu")
self.errors.append("Incorrect first account is shown on Share QR Code menu")
self.home_view.qr_code_image_element.swipe_left_on_element()
try:
self.home_view.account_name_text.wait_for_element_text(text=new_account_name, wait_time=3)
except Failed:
self.errors.append(self.home_view, "Can't swipe between accounts, newly added account is not shown")
self.errors.append("Can't swipe between accounts, newly added account is not shown")
else:
shown_address = self.home_view.copy_wallet_address()
if set(shown_address.split(':')) != set(new_wallet_address.split(':')):
self.errors.append(
self.home_view,
"Incorrect address '%s' is shown when swiping between accounts, expected one is '%s'" % (
shown_address, new_wallet_address))
self.home_view.click_system_back_button()
@@ -461,9 +292,9 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
if self.wallet_view.get_account_element(account_name=new_account_name).is_element_displayed():
self.wallet_view.remove_account(account_name=new_account_name)
if self.wallet_view.get_account_element(account_name=new_account_name).is_element_displayed():
self.errors.append(self.wallet_view, "Account was not removed from wallet")
self.errors.append("Account was not removed from wallet")
else:
self.errors.append(self.wallet_view, "Newly added account is not shown in the accounts list")
self.errors.append("Newly added account is not shown in the accounts list")
self.errors.verify_no_errors()
@@ -485,12 +316,12 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
self.home_view.show_qr_code_button.click()
self.home_view.share_wallet_tab_button.click()
if self.home_view.account_name_text.text != 'Account 1':
self.errors.append(self.home_view, "Incorrect first account is shown on Share QR Code menu")
self.errors.append("Incorrect first account is shown on Share QR Code menu")
self.home_view.qr_code_image_element.swipe_left_on_element()
try:
self.home_view.account_name_text.wait_for_element_text(text=new_account_name, wait_time=3)
except Failed:
self.errors.append(self.home_view, "Can't swipe between accounts, account to watch is not shown")
self.errors.append("Can't swipe between accounts, account to watch is not shown")
else:
shown_address = self.home_view.copy_wallet_address()
if set(shown_address.split(':')) != {'eth', 'arb1', 'oeth', address_to_watch}:
@@ -503,8 +334,8 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
if self.wallet_view.get_account_element(account_name=new_account_name).is_element_displayed():
self.wallet_view.remove_account(account_name=new_account_name, watch_only=True)
if self.wallet_view.get_account_element(account_name=new_account_name).is_element_displayed():
self.errors.append(self.wallet_view, "Account was not removed from wallet")
self.errors.append("Account was not removed from wallet")
else:
self.errors.append(self.wallet_view, "Watch only account is not shown in the accounts list")
self.errors.append("Watch only account is not shown in the accounts list")
self.errors.verify_no_errors()
+4 -4
View File
@@ -201,7 +201,7 @@ class BaseView(object):
for _ in range(times):
self.driver.press_keycode(4)
def click_system_back_button_until_presence_of_element(self, element, attempts=3):
def _navigate_back_to_view(self, element, attempts=3):
counter = 0
while not element.is_element_displayed(1) and counter <= attempts:
self.driver.press_keycode(4)
@@ -218,14 +218,14 @@ class BaseView(object):
or not self.community_floating_screen.is_element_disappeared(1) \
or not self.discover_communities_floating_screen.is_element_disappeared(1):
self.driver.press_keycode(4)
self.click_system_back_button_until_presence_of_element(self.chats_tab)
self._navigate_back_to_view(self.chats_tab)
def navigate_back_to_chat_view(self):
self.click_system_back_button_until_presence_of_element(self.get_chat_view().chat_message_input)
self._navigate_back_to_view(self.get_chat_view().chat_message_input)
def navigate_back_to_wallet_view(self, attempts=3):
element = self.get_wallet_view().network_drop_down
self.click_system_back_button_until_presence_of_element(element)
self._navigate_back_to_view(element)
def click_system_home_button(self):
self.driver.info('Press system Home button')
+1 -1
View File
@@ -377,7 +377,7 @@ class HomeView(BaseView):
if self.toast_content_element.is_element_displayed(10):
self.toast_content_element.wait_for_invisibility_of_element()
try:
self.notifications_unread_badge.wait_for_visibility_of_element(120)
self.notifications_unread_badge.wait_for_visibility_of_element(60)
except TimeoutException:
pass
self.open_activity_center_button.click_until_presence_of_element(self.close_activity_centre)
+4 -36
View File
@@ -84,7 +84,6 @@ class WalletView(BaseView):
self.driver, xpath="//*[@content-desc='account-avatar']/../following-sibling::android.widget.TextView[1]")
self.account_emoji_button = Button(self.driver, accessibility_id='account-emoji')
self.send_button = Button(self.driver, accessibility_id='send')
self.swap_button = Button(self.driver, accessibility_id='swap')
self.send_from_drawer_button = Button(
self.driver, xpath="//*[@content-desc='send']/*[@content-desc='left-icon-for-action']")
self.copy_address_button = Button(self.driver, accessibility_id='copy-address')
@@ -105,27 +104,6 @@ class WalletView(BaseView):
self.confirm_button = Button(self.driver, accessibility_id='button-one')
self.done_button = Button(self.driver, accessibility_id='done')
# Review Send page
self.from_data_container = BaseElement(
self.driver, xpath="//*[@content-desc='summary-from-label']/following-sibling::android.view.ViewGroup[1]")
self.to_data_container = BaseElement(
self.driver, xpath="//*[@content-desc='summary-to-label']/following-sibling::android.view.ViewGroup[1]")
# Swap flow
self.approve_swap_button = Button(self.driver, accessibility_id='Approve')
self.spending_cap_approval_info_container = BaseElement(
self.driver,
xpath="//*[@content-desc='spending-cap-label']/following-sibling::*[@content-desc='approval-info'][1]")
self.account_approval_info_container = BaseElement(
self.driver,
xpath="//*[@content-desc='account-label']/following-sibling::*[@content-desc='approval-info'][1]")
self.token_approval_info_container = BaseElement(
self.driver,
xpath="//*[@content-desc='token-label']/following-sibling::*[@content-desc='approval-info'][1]")
self.spender_contract_approval_info_container = BaseElement(
self.driver,
xpath="//*[@content-desc='spender-contract-label']/following-sibling::*[@content-desc='approval-info'][1]")
# Edit key pair
self.edit_key_pair_button = Button(self.driver, accessibility_id="Edit")
self.key_pairs_plus_button = Button(self.driver, accessibility_id="standard-title-action")
@@ -178,11 +156,11 @@ class WalletView(BaseView):
self.confirm_button.click()
self.slide_and_confirm_with_password()
def set_amount(self, amount: str):
for i in amount:
def set_amount(self, amount: float):
for i in '{:f}'.format(amount).rstrip('0'):
Button(self.driver, accessibility_id='keyboard-key-%s' % i).click()
def send_asset(self, address: str, asset_name: str, amount: str, network_name: str):
def send_asset(self, address: str, asset_name: str, amount: float, network_name: str):
self.send_button.click()
self.address_text_input.send_keys(address)
self.continue_button.click()
@@ -191,7 +169,7 @@ class WalletView(BaseView):
self.set_amount(amount)
self.confirm_transaction()
def send_asset_from_drawer(self, address: str, asset_name: str, amount: str, network_name: str):
def send_asset_from_drawer(self, address: str, asset_name: str, amount: float, network_name: str):
asset_element = self.get_asset(asset_name)
asset_element.long_press_without_release()
self.send_from_drawer_button.double_click()
@@ -272,13 +250,3 @@ class WalletView(BaseView):
wallet_address = self.sharing_text_native.text
self.click_system_back_button()
return wallet_address
def get_data_item_element_text(self, data_item_name: str):
element = Text(self.driver, xpath="//*[@text='%s']/following-sibling::android.widget.TextView" % data_item_name)
element.wait_for_element(15)
return element.text
def wait_for_swap_input_to_be_shown(self):
locator = "//*[@content-desc='swap-input'][2]//*[@content-desc='token-avatar']" \
"/following-sibling::*//*[starts-with(@text,'0.000')]"
BaseElement(self.driver, xpath=locator).wait_for_visibility_of_element()
+1 -3
View File
@@ -61,6 +61,7 @@
"add-custom-token": "Add custom token",
"add-eth": "Add ETH",
"add-favourite": "Add favourite",
"add-key-pair-desktop": "To add existing key pair to the Keycard please use Status Desktop. If you'd like this feature on mobile, feel free to upvote them.",
"add-mailserver": "Add Status node",
"add-me-to-your-contacts": "Please add me to your contacts",
"add-members": "Add members",
@@ -1226,7 +1227,6 @@
"import-private-key": "Import private key",
"import-private-key-info": "New addresses cannot be derived from an account imported from a private key. Import using a seed phrase if you wish to derive addresses.",
"import-profile-key-pair": "Import profile key pair",
"import-recovery-phrase-to-keycard": "Import recovery phrase to Keycard",
"import-to-use-derived-accounts": "Import to use derived accounts",
"import-using-phrase": "Import using recovery phrase",
"in": "in",
@@ -1381,7 +1381,6 @@
"keycard-connected-title": "Connected",
"keycard-contains-key-pair": "Keycard contains your profile key pair",
"keycard-desc": "Own a Keycard? Store your keys on it; youll need it for transactions",
"keycard-documentation": "Keycard is a hardware wallet in a credit-card sized smartcard that works with the Status app. You can store your Status keys and sign transactions securely with it.\n\nKeycard is designed to be mobile-friendly and uses contactless NFC technology to communicate with your phone, so you can sign transactions with just a tap of the card. It is lightweight, convenient, and can fit in your wallet, pocket, or phone case.\n\nProtect your assets and accounts with the Keycard, a cold storage hardware wallet that provides a contactless and convenient experience.",
"keycard-dont-ask-card": "Don't ask for card to sign in",
"keycard-empty": "Keycard is empty",
"keycard-empty-ready": "Keycard is empty and ready to be used",
@@ -2520,7 +2519,6 @@
"sticker-market": "Sticker market",
"storage": "Storage",
"store-confirmations": "Store confirmations",
"store-key-pair-on-keycard": "Store your existing key pair on Keycard",
"store-your-asets-on-keycard": "Store your assets on Keycard",
"strength-divider-okay-label": "Okay",
"strength-divider-strong-label": "Strong",