diff --git a/Jenkinsfile.release b/Jenkinsfile.release index 8d83c98d78..c267cfa82c 100644 --- a/Jenkinsfile.release +++ b/Jenkinsfile.release @@ -70,7 +70,7 @@ node ('macos1'){ def filename = 'im.status.ethereum-' + shortCommit + '.apk' def newArtifact = (artifact_dir + filename) sh ('mv ' + artifact + ' ' + newArtifact) - def uploadSpec = '{ "files": [ { "pattern": "*apk/' + filename + '", "target": "nightlies-local" }]}' + def uploadSpec = '{ "files": [ { "pattern": "*apk/release/' + filename + '", "target": "nightlies-local" }]}' def buildInfo = server.upload(uploadSpec) apkUrl = 'http://artifacts.status.im:8081/artifactory/nightlies-local/' + filename diff --git a/src/status_im/chat/events.cljs b/src/status_im/chat/events.cljs index 20e31585fa..59351d8d12 100644 --- a/src/status_im/chat/events.cljs +++ b/src/status_im/chat/events.cljs @@ -83,19 +83,14 @@ (async/go (async/>! realm-queue #(messages-store/save message))))) (re-frame/reg-fx - :delete-chat-messages - (fn [{:keys [chat-id group-chat debug?]}] - (when (or group-chat debug?) - (async/go (async/>! realm-queue #(messages-store/delete-by-chat-id chat-id)))) - (async/go (async/>! realm-queue #(pending-messages-store/delete-all-by-chat-id chat-id))))) + :delete-messages + (fn [chat-id] + (async/go (async/>! realm-queue #(messages-store/delete-by-chat-id chat-id))))) (re-frame/reg-fx - :update-message-overhead - (fn [[chat-id network-status]] - (let [update-fn (if (= network-status :offline) - chats-store/inc-message-overhead - chats-store/reset-message-overhead)] - (async/go (async/>! realm-queue #(update-fn chat-id)))))) + :delete-pending-messages + (fn [chat-id] + (async/go (async/>! realm-queue #(pending-messages-store/delete-all-by-chat-id chat-id))))) (re-frame/reg-fx :save-chat @@ -103,16 +98,14 @@ (async/go (async/>! realm-queue #(chats-store/save chat))))) (re-frame/reg-fx - :delete-chat - (fn [{:keys [chat-id debug?]}] - (if debug? - (async/go (async/>! realm-queue #(chats-store/delete chat-id))) - (async/go (async/>! realm-queue #(chats-store/set-inactive chat-id)))))) + :deactivate-chat + (fn [chat-id] + (async/go (async/>! realm-queue #(chats-store/set-inactive chat-id))))) (re-frame/reg-fx - :save-all-contacts - (fn [contacts] - (contacts-store/save-all contacts))) + :delete-chat + (fn [chat-id] + (async/go (async/>! realm-queue #(chats-store/delete chat-id))))) (re-frame/reg-fx :protocol-send-seen @@ -354,9 +347,14 @@ :remove-chat [re-frame/trim-v] (fn [{:keys [db]} [chat-id]] - (let [chat (get-in db [:chats chat-id])] - {:db (-> db - (update :chats dissoc chat-id) - (update :deleted-chats (fnil conj #{}) chat-id)) - :delete-chat chat - :delete-chat-messages chat}))) + (let [{:keys [chat-id group-chat debug?]} (get-in db [:chats chat-id])] + (cond-> {:db (-> db + (update :chats dissoc chat-id) + (update :deleted-chats (fnil conj #{}) chat-id)) + :delete-pending-messages chat-id} + (or group-chat debug?) + (assoc :delete-messages chat-id) + debug? + (assoc :delete-chat chat-id) + (not debug?) + (assoc :deactivate-chat chat-id))))) diff --git a/src/status_im/chat/events/input.cljs b/src/status_im/chat/events/input.cljs index f33fc2e9f2..61a5e1e4cd 100644 --- a/src/status_im/chat/events/input.cljs +++ b/src/status_im/chat/events/input.cljs @@ -2,7 +2,7 @@ (:require [clojure.string :as string] [re-frame.core :as re-frame] [taoensso.timbre :as log] - [status-im.chat.constants :as constants] + [status-im.chat.constants :as constants] [status-im.chat.models :as model] [status-im.chat.models.input :as input-model] [status-im.chat.models.commands :as commands-model] @@ -277,29 +277,36 @@ :proceed-event-creator (partial event-after-creator command-message)}))) +;; TODO (janherich) request-command-data functions and event need to be refactored, they are needlessly complicated (defn proceed-command "Proceed with command processing by setting up and executing chain of events: 1. Params validation - 2. Preview fetching" + 2. Short preview fetching + 3. Preview fetching" [{:keys [current-chat-id chats] :as db} {{:keys [bot]} :command :as content} message-id current-time] - (let [params-template {:content content - :chat-id current-chat-id - :group-id (when (get-in chats [current-chat-id :group-chat]) - current-chat-id) - :jail-id (or bot current-chat-id) - :message-id message-id - :current-time current-time} - preview-params (merge params-template - {:data-type :preview - :event-after-creator (fn [command-message jail-response] - [::send-command - (assoc-in command-message [:command :preview] jail-response)])}) - validation-params (merge params-template - {:data-type :validator - :event-after-creator (fn [_ jail-response] - [::proceed-validation - jail-response - [[::request-command-data preview-params]]])})] + (let [params-template {:content content + :chat-id current-chat-id + :group-id (when (get-in chats [current-chat-id :group-chat]) + current-chat-id) + :jail-id (or bot current-chat-id) + :message-id message-id + :current-time current-time} + preview-params (merge params-template + {:data-type :preview + :event-after-creator (fn [command-message jail-response] + [::send-command + (assoc-in command-message [:command :preview] jail-response)])}) + short-preview-params (merge params-template + {:data-type :short-preview + :event-after-creator (fn [_ jail-response] + [::request-command-data + (assoc-in preview-params [:content :command :short-preview] jail-response)])}) + validation-params (merge params-template + {:data-type :validator + :event-after-creator (fn [_ jail-response] + [::proceed-validation + jail-response + [[::request-command-data short-preview-params]]])})] (request-command-data db validation-params))) ;;;; Handlers @@ -443,7 +450,7 @@ (handlers/register-handler-fx :send-current-message - message-model/send-interceptors + message-model/send-interceptors (fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now :as cofx} _] (when-not (get-in db [:chat-ui-props current-chat-id :sending-in-progress?]) diff --git a/src/status_im/chat/models/message.cljs b/src/status_im/chat/models/message.cljs index 38fc7bb8fa..5e0189f2eb 100644 --- a/src/status_im/chat/models/message.cljs +++ b/src/status_im/chat/models/message.cljs @@ -219,9 +219,8 @@ (let [chat (get-in db [:chats chat-id]) message (prepare-message params chat) params' (assoc params :message message) - fx {:db (add-message-to-db db chat-id message true) - :update-message-overhead [chat-id network-status] - :save-message message}] + fx {:db (add-message-to-db db chat-id message true) + :save-message message}] (-> (merge fx (chat-model/upsert-chat (assoc fx :now now) {:chat-id chat-id})) (as-> fx' @@ -283,8 +282,7 @@ params' (assoc params :command command') fx {:db (-> (merge db (:db result)) - (add-message-to-db chat-id command' true)) - :update-message-overhead [chat-id network-status] + (add-message-to-db chat-id command' true)) :save-message (-> command' (assoc :chat-id chat-id) (update-in [:content :params] diff --git a/src/status_im/data_store/chats.cljs b/src/status_im/data_store/chats.cljs index d81d3863f7..90605e0a44 100644 --- a/src/status_im/data_store/chats.cljs +++ b/src/status_im/data_store/chats.cljs @@ -62,10 +62,6 @@ [chat-id] (get-property chat-id :removed-at)) -(defn get-message-overhead - [chat-id] - (get-property chat-id :message-overhead)) - (defn get-active-group-chats [] (data-store/get-active-group-chats)) @@ -74,14 +70,6 @@ [chat-id active?] (save-property chat-id :is-active active?)) -(defn inc-message-overhead - [chat-id] - (save-property chat-id :message-overhead (inc (get-message-overhead chat-id)))) - -(defn reset-message-overhead - [chat-id] - (save-property chat-id :message-overhead 0)) - (defn new-update? [timestamp chat-id] (let diff --git a/src/status_im/data_store/realm/schemas/account/v21/chat.cljs b/src/status_im/data_store/realm/schemas/account/v21/chat.cljs new file mode 100644 index 0000000000..51e2ad1c1e --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v21/chat.cljs @@ -0,0 +1,37 @@ +(ns status-im.data-store.realm.schemas.account.v21.chat + (:require [status-im.ui.components.styles :refer [default-chat-color]])) + +(def schema {:name :chat + :primaryKey :chat-id + :properties {:chat-id :string + :name :string + :color {:type :string + :default default-chat-color} + :group-chat {:type :bool + :indexed true} + :group-admin {:type :string + :optional true} + :is-active :bool + :timestamp :int + :contacts {:type :list + :objectType :chat-contact} + :unremovable? {:type :bool + :default false} + :removed-at {:type :int + :optional true} + :removed-from-at {:type :int + :optional true} + :added-to-at {:type :int + :optional true} + :updated-at {:type :int + :optional true} + :public-key {:type :string + :optional true} + :private-key {:type :string + :optional true} + :contact-info {:type :string + :optional true} + :debug? {:type :bool + :default false} + :public? {:type :bool + :default false}}}) diff --git a/src/status_im/data_store/realm/schemas/account/v21/core.cljs b/src/status_im/data_store/realm/schemas/account/v21/core.cljs index 7baaa68101..321f7d57c1 100644 --- a/src/status_im/data_store/realm/schemas/account/v21/core.cljs +++ b/src/status_im/data_store/realm/schemas/account/v21/core.cljs @@ -1,5 +1,5 @@ (ns status-im.data-store.realm.schemas.account.v21.core - (:require [status-im.data-store.realm.schemas.account.v19.chat :as chat] + (:require [status-im.data-store.realm.schemas.account.v21.chat :as chat] [status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact] [status-im.data-store.realm.schemas.account.v19.contact :as contact] [status-im.data-store.realm.schemas.account.v20.discover :as discover] @@ -14,7 +14,7 @@ [status-im.data-store.realm.schemas.account.v21.browser :as browser] [taoensso.timbre :as log] [cljs.reader :as reader] - [clojure.string :as str])) + [clojure.string :as string])) (def schema [chat/schema chat-contact/schema @@ -45,7 +45,7 @@ content (aget message "content") type (aget message "content-type")] (when (and (= type "command") - (> (str/index-of content "command=location") -1)) + (string/includes? content "command=location")) (aset message "show?" false)))))) (defn remove-phone-messages! [old-realm new-realm] @@ -55,7 +55,7 @@ content (aget message "content") type (aget message "content-type")] (when (and (= type "command") - (> (str/index-of content "command=phone") -1)) + (string/includes? content "command=phone")) (aset message "show?" false)))))) (defn migration [old-realm new-realm] diff --git a/src/status_im/ui/screens/contacts/events.cljs b/src/status_im/ui/screens/contacts/events.cljs index f49a81a033..4a5e7569e3 100644 --- a/src/status_im/ui/screens/contacts/events.cljs +++ b/src/status_im/ui/screens/contacts/events.cljs @@ -84,7 +84,7 @@ (contacts/save contact))) (reg-fx - ::save-contacts! + :save-all-contacts (fn [new-contacts] (contacts/save-all new-contacts))) @@ -223,8 +223,8 @@ ;;(remove #(identities (:whisper-identity %))) (map #(vector (:whisper-identity %) %)) (into {})) - fx {:db (update db :contacts/contacts merge new-contacts') - ::save-contacts! (vals new-contacts')}] + fx {:db (update db :contacts/contacts merge new-contacts') + :save-all-contacts (vals new-contacts')}] (transduce (map second) (completing (partial loading-events/load-commands (assoc cofx :db (:db fx)))) fx diff --git a/src/status_im/ui/screens/db.cljs b/src/status_im/ui/screens/db.cljs index 0f74c35afc..881b7dd9b1 100644 --- a/src/status_im/ui/screens/db.cljs +++ b/src/status_im/ui/screens/db.cljs @@ -3,7 +3,6 @@ (:require [cljs.spec.alpha :as spec] [status-im.constants :as constants] [status-im.utils.platform :as platform] - [status-im.utils.ethereum.core :as ethereum] status-im.ui.screens.accounts.db status-im.ui.screens.contacts.db status-im.ui.screens.qr-scanner.db @@ -18,15 +17,6 @@ status-im.ui.screens.browser.db status-im.ui.screens.add-new.db)) -(defn gas-default [symbol] - {:gas (ethereum/estimate-gas symbol) - :gas-price ethereum/default-gas-price}) - -(def transaction-send-default - (let [symbol :ETH] - (merge (gas-default symbol) - {:symbol symbol}))) - ;; initial state of app-db (def app-db {:current-public-key nil :status-module-initialized? (or platform/ios? js/goog.DEBUG) @@ -46,7 +36,6 @@ :tags [] :sync-state :done :wallet.transactions constants/default-wallet-transactions - :wallet {:send-transaction transaction-send-default} :wallet-selected-asset {} :prices {} :notifications {} diff --git a/src/status_im/ui/screens/group/chat_settings/events.cljs b/src/status_im/ui/screens/group/chat_settings/events.cljs index fa6d9ad9e2..569e1a02ed 100644 --- a/src/status_im/ui/screens/group/chat_settings/events.cljs +++ b/src/status_im/ui/screens/group/chat_settings/events.cljs @@ -2,8 +2,7 @@ (:require [re-frame.core :refer [dispatch reg-fx]] [status-im.utils.handlers :refer [register-handler-fx]] [status-im.protocol.core :as protocol] - [status-im.utils.random :as random] - [status-im.chat.handlers :as chat-events] + [status-im.utils.random :as random] [status-im.data-store.contacts :as contacts] [status-im.data-store.messages :as messages] [status-im.data-store.chats :as chats] @@ -173,4 +172,4 @@ :clear-history (fn [{{:keys [current-chat-id] :as db} :db} _] {:db (assoc-in db [:chats current-chat-id :messages] {}) - ::chat-events/delete-messages current-chat-id})) + :delete-messages current-chat-id})) diff --git a/src/status_im/ui/screens/home/views/inner_item.cljs b/src/status_im/ui/screens/home/views/inner_item.cljs index 190ccef969..bb73836121 100644 --- a/src/status_im/ui/screens/home/views/inner_item.cljs +++ b/src/status_im/ui/screens/home/views/inner_item.cljs @@ -16,42 +16,30 @@ [taoensso.timbre :as log] [status-im.ui.components.chat-icon.screen :as chat-icon.screen])) -(defn message-content-text [{:keys [content] :as message}] - (reagent/create-class - {:display-name "message-content-text" - :component-will-mount - #(when (and (or (:command content) - (:content-command content)) - (not (:short-preview content))) - (re-frame/dispatch [:request-command-message-data message - {:data-type :short-preview - :cache-data? true}])) - :reagent-render - (fn [{:keys [content] :as message}] - [react/view styles/last-message-container - (cond +(defn message-content-text [{:keys [content] :as message}] + [react/view styles/last-message-container + (cond - (not message) - [react/text {:style styles/last-message-text} - (i18n/label :t/no-messages)] + (not message) + [react/text {:style styles/last-message-text} + (i18n/label :t/no-messages)] - (str/blank? content) - [react/text {:style styles/last-message-text} - ""] + (str/blank? content) + [react/text {:style styles/last-message-text} + ""] - (:content content) - [react/text {:style styles/last-message-text - :number-of-lines 1} - (:content content)] + (:content content) + [react/text {:style styles/last-message-text + :number-of-lines 1} + (:content content)] - (and (:command content) - (-> content :short-preview :markup)) - (commands-utils/generate-hiccup (-> content :short-preview :markup)) + (and (:command content) (-> content :short-preview :markup)) + (commands-utils/generate-hiccup (-> content :short-preview :markup)) - :else - [react/text {:style styles/last-message-text - :number-of-lines 1} - content])])})) + :else + [react/text {:style styles/last-message-text + :number-of-lines 1} + content])]) (defview message-status [{:keys [chat-id contacts]} {:keys [message-id user-statuses outgoing] :as msg}] diff --git a/src/status_im/ui/screens/wallet/events.cljs b/src/status_im/ui/screens/wallet/events.cljs index 35b90fe69d..92174e1fd9 100644 --- a/src/status_im/ui/screens/wallet/events.cljs +++ b/src/status_im/ui/screens/wallet/events.cljs @@ -79,6 +79,11 @@ #(re-frame/dispatch [success-event %]) #(re-frame/dispatch [error-event %])))) +(reg-fx + :update-gas-price + (fn [{:keys [web3 success-event edit?]}] + (ethereum/gas-price web3 #(re-frame/dispatch [success-event %2 edit?])))) + ;; Handlers (handlers/register-handler-fx @@ -202,3 +207,15 @@ :content (i18n/label :t/transactions-delete-content) :confirm-button-text (i18n/label :t/confirm) :on-accept #(re-frame/dispatch [:wallet/discard-unsigned-transaction transaction-id])}})) + +(handlers/register-handler-fx + :wallet/update-gas-price + (fn [{:keys [db]} [_ edit?]] + {:update-gas-price {:web3 (:web3 db) + :success-event :wallet/update-gas-price-success + :edit? edit?}})) + +(handlers/register-handler-db + :wallet/update-gas-price-success + (fn [db [_ price edit?]] + (assoc-in db [:wallet (if edit? :edit :send-transaction) :gas-price] price))) diff --git a/src/status_im/ui/screens/wallet/navigation.cljs b/src/status_im/ui/screens/wallet/navigation.cljs index 47ec962627..f39d28e461 100644 --- a/src/status_im/ui/screens/wallet/navigation.cljs +++ b/src/status_im/ui/screens/wallet/navigation.cljs @@ -1,6 +1,5 @@ (ns status-im.ui.screens.wallet.navigation (:require [re-frame.core :as re-frame] - [status-im.ui.screens.db :as db] [status-im.ui.screens.navigation :as navigation] [status-im.utils.ethereum.core :as ethereum] [status-im.utils.ethereum.tokens :as tokens])) @@ -15,16 +14,23 @@ (re-frame/dispatch [:update-transactions]) db) +(def transaction-send-default + (let [symbol :ETH] + {:gas (ethereum/estimate-gas symbol) + :symbol symbol})) + + (defmethod navigation/preload-data! :wallet-request-transaction [db [event]] (if (= event :navigate-back) db (-> db (update :wallet dissoc :request-transaction) - (assoc-in [:wallet :send-transaction] db/transaction-send-default)))) + (assoc-in [:wallet :send-transaction] transaction-send-default)))) (defmethod navigation/preload-data! :wallet-send-transaction [db [event]] + (re-frame/dispatch [:wallet/update-gas-price]) (if (= event :navigate-back) db - (assoc-in db [:wallet :send-transaction] db/transaction-send-default))) + (assoc-in db [:wallet :send-transaction] transaction-send-default))) diff --git a/src/status_im/ui/screens/wallet/send/events.cljs b/src/status_im/ui/screens/wallet/send/events.cljs index eda633a363..5cb06ac78d 100644 --- a/src/status_im/ui/screens/wallet/send/events.cljs +++ b/src/status_im/ui/screens/wallet/send/events.cljs @@ -291,6 +291,7 @@ (handlers/register-handler-fx :wallet.send/reset-gas-default (fn [{:keys [db]}] - {:db (update-in db [:wallet :edit] - merge - (db/gas-default (get-in db [:wallet :send-transaction :symbol])))})) + {:dispatch [:wallet/update-gas-price true] + :db (update-in db [:wallet :edit] + assoc + :gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))})) diff --git a/src/status_im/utils/ethereum/core.cljs b/src/status_im/utils/ethereum/core.cljs index cc628e8e74..855ebad80f 100644 --- a/src/status_im/utils/ethereum/core.cljs +++ b/src/status_im/utils/ethereum/core.cljs @@ -83,10 +83,12 @@ (.sendTransaction (.-eth web3) (clj->js params) cb)) (def default-transaction-gas (money/bignumber 21000)) -(def default-gas-price (money/->wei :gwei 21)) + +(defn gas-price [web3 cb] + (.getGasPrice (.-eth web3) cb)) (defn estimate-gas [symbol] (if (tokens/ethereum? symbol) default-transaction-gas ;; TODO(jeluard) Rely on estimateGas call - (.times default-transaction-gas 5))) \ No newline at end of file + (.times default-transaction-gas 5))) diff --git a/test/appium/tests/base_test_case.py b/test/appium/tests/base_test_case.py index 1e1339cf44..4674211ac9 100644 --- a/test/appium/tests/base_test_case.py +++ b/test/appium/tests/base_test_case.py @@ -88,7 +88,7 @@ class AbstractTestCase: @property def implicitly_wait(self): - return 10 + return 8 def update_test_info_dict(self): test_data.test_info[test_data.test_name] = dict() @@ -145,7 +145,8 @@ class SauceMultipleDeviceTestCase(AbstractTestCase): @classmethod def setup_class(cls): - cls.loop = asyncio.get_event_loop() + cls.loop = asyncio.new_event_loop() + asyncio.set_event_loop(cls.loop) def setup_method(self, method): self.update_test_info_dict() diff --git a/test/appium/tests/test_dapps_and_browsing.py b/test/appium/tests/test_dapps_and_browsing.py new file mode 100644 index 0000000000..e56416bf3b --- /dev/null +++ b/test/appium/tests/test_dapps_and_browsing.py @@ -0,0 +1,24 @@ +import pytest +from views.console_view import ConsoleView +from tests.base_test_case import SingleDeviceTestCase + + +@pytest.mark.all +class TestDappsAnsBrowsing(SingleDeviceTestCase): + + @pytest.mark.pr + def test_browse_link_entering_url_in_dapp_view(self): + console = ConsoleView(self.driver) + console.create_user() + console.back_button.click() + home_view = console.get_home_view() + start_new_chat = home_view.plus_button.click() + start_new_chat.open_d_app_button.click() + start_new_chat.enter_url_editbox.send_keys('status.im') + start_new_chat.confirm() + browsing_view = home_view.get_base_web_view() + browsing_view.wait_for_d_aap_to_load() + browsing_view.find_full_text('Status, the Ethereum discovery tool.') + browsing_view.back_to_home_button.click() + + assert home_view.first_chat_element_title.text == 'Status | The Mobile Ethereum Client' diff --git a/test/appium/tests/test_multiple_devices.py b/test/appium/tests/test_multiple_devices.py index ba0cd224d1..cd8ba19924 100644 --- a/test/appium/tests/test_multiple_devices.py +++ b/test/appium/tests/test_multiple_devices.py @@ -47,7 +47,7 @@ class TestMultipleDevices(MultipleDeviceTestCase): device_2_home.add_contact(device_1_public_key) device_2_chat = device_2_home.get_chat_view() device_1_user_name = device_2_chat.user_name_text.text - device_2_home.back_button.click(times_to_click=2) + device_2_home.get_back_to_home_view() chat_name = 'new_chat' message_1 = 'first SOMETHING' message_2 = 'second SOMETHING' @@ -83,64 +83,3 @@ class TestMultipleDevices(MultipleDeviceTestCase): group_chat_d1.find_text_part("removed you from group chat") if group_chat_d1.element_by_text(message_3, 'text').is_element_present(20): pytest.fail('Message is shown for the user which has been removed from the GroupChat', False) - - @pytest.mark.transaction - @pytest.mark.parametrize("test, recipient, sender", [('group_chat', - transaction_users['A_USER'], transaction_users['B_USER']), - ('one_to_one_chat', - transaction_users['B_USER'], transaction_users['A_USER']) - ], - ids=['group_chat', 'one_to_one_chat']) - def test_send_funds_via_request(self, test, recipient, sender): - self.create_drivers(2) - device_1, device_2 = \ - ConsoleView(self.drivers[0]), ConsoleView(self.drivers[1]) - device_1.recover_access(passphrase=recipient['passphrase'], - password=recipient['password'], - username=recipient['username']) - device_2.recover_access(passphrase=sender['passphrase'], - password=sender['password'], - username=sender['username']) - device_2_home = device_2.get_home_view() - device_1_home = device_1.get_home_view() - device_1_home.add_contact(sender['public_key']) - device_1_home.back_button.click(times_to_click=2) - if test == 'group_chat': - group_chat_name = 'gtr_%s' % get_current_time() - device_1_home.create_group_chat([sender['username']], group_chat_name) - device_2_home.element_by_text(group_chat_name, 'button').click() - else: - one_to_one_chat_device_1 = device_1_home.element_by_text_part(sender['username'][:25], 'button') - one_to_one_chat_device_1.scroll_to_element() - one_to_one_chat_device_1.click() - device_1_chat = device_1_home.get_chat_view() - device_2_chat = device_2_home.get_chat_view() - amount = device_1_chat.get_unique_amount() - if test == 'group_chat': - device_1_chat.request_command.click() - device_1_chat.first_recipient_button.click() - device_1_chat.send_as_keyevent(amount) - else: - one_to_one_chat_device_2 = device_2_chat.element_by_text_part(recipient['username'][:25], 'button') - one_to_one_chat_device_2.click() - device_1_chat.request_command.click() - device_1_chat.send_as_keyevent(amount) - device_1_chat.send_message_button.click() - initial_balance_recipient = api_requests.get_balance(recipient['address']) - if test == 'group_chat': - device_1_chat.find_full_text('from ' + sender['username'], 20) - device_2_chat.find_full_text('from ' + sender['username'], 20) - device_2_chat.element_by_text_part('Requesting %s ETH' % amount, 'button').click() - device_2_chat.send_message_button.click() - device_2_send_transaction = device_2_chat.get_send_transaction_view() - device_2_send_transaction.try_to_sing_transaction() - device_2_send_transaction.enter_password_input.send_keys(sender['password']) - device_2_send_transaction.sign_transaction_button.click() - device_2_send_transaction.got_it_button.click() - api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) - device_2_chat.back_button.click() - device_2_wallet = device_2_home.wallet_button.click() - transactions_view = device_2_wallet.transactions_button.click() - transaction_element = transactions_view.transactions_table.find_transaction(amount=amount) - transaction_details_view = transaction_element.click() - transaction_hash = transaction_details_view.get_transaction_hash() diff --git a/test/appium/tests/test_profile.py b/test/appium/tests/test_profile.py new file mode 100644 index 0000000000..1021ac7804 --- /dev/null +++ b/test/appium/tests/test_profile.py @@ -0,0 +1,46 @@ +import pytest +import time +from tests.base_test_case import SingleDeviceTestCase +from views.console_view import ConsoleView +from tests import basic_user + + +@pytest.mark.all +class TestProfileView(SingleDeviceTestCase): + + @pytest.mark.pr + def test_qr_code_and_its_value(self): + console_view = ConsoleView(self.driver) + console_view.create_user() + console_view.back_button.click() + profile_view = console_view.profile_button.click() + profile_view.share_my_contact_key_button.click() + key_value = profile_view.public_key_text.text + time.sleep(5) + key_value_from_qr = profile_view.get_text_from_qr() + assert key_value == key_value_from_qr + + @pytest.mark.pr + def test_contact_profile_view(self): + console_view = ConsoleView(self.driver) + console_view.create_user() + console_view.back_button.click() + home_view = console_view.get_home_view() + home_view.add_contact(basic_user['public_key']) + chat_view = home_view.get_chat_view() + chat_view.user_profile_icon_top_right.click() + chat_view.user_profile_details.click() + chat_view.find_full_text(basic_user['username']) + + @pytest.mark.pr + def test_network_switch(self): + console = ConsoleView(self.driver) + console.create_user() + console.back_button.click() + profile_view = console.profile_button.click() + sign_in_view = profile_view.switch_network('Rinkeby with upstream RPC') + sign_in_view.first_account_button.click() + sign_in_view.password_input.send_keys('qwerty1234') + sign_in_view.sign_in_button.click() + sign_in_view.profile_button.click() + sign_in_view.find_full_text('RINKEBY WITH UPSTREAM RPC', 20) diff --git a/test/appium/tests/test_transaction.py b/test/appium/tests/test_transaction.py index 9e0698ba0d..9853a4c44b 100644 --- a/test/appium/tests/test_transaction.py +++ b/test/appium/tests/test_transaction.py @@ -1,76 +1,99 @@ import pytest import time from views.console_view import ConsoleView -from tests.base_test_case import SingleDeviceTestCase -from tests import transaction_users, api_requests, get_current_time +from tests.base_test_case import SingleDeviceTestCase, MultipleDeviceTestCase +from tests import transaction_users, api_requests, get_current_time, transaction_users_wallet from selenium.common.exceptions import TimeoutException @pytest.mark.all -class TestTransactions(SingleDeviceTestCase): +class TestTransaction(SingleDeviceTestCase): - @pytest.mark.transaction - @pytest.mark.parametrize("test, recipient", [('group_chat', 'A_USER'), - ('one_to_one_chat', 'B_USER'), - ('wrong_password', 'A_USER')], - ids=['group_chat', - 'one_to_one_chat', - 'wrong_password']) - def test_transaction_send_command(self, test, recipient): + @pytest.mark.pr + def test_transaction_send_command_one_to_one_chat(self): + recipient = transaction_users['B_USER'] + console_view = ConsoleView(self.driver) + console_view.create_user() + console_view.back_button.click() + home_view = console_view.get_home_view() + transaction_amount = home_view.get_unique_amount() + sender_public_key = home_view.get_public_key() + sender_address = home_view.public_key_to_address(sender_public_key) + home_view.home_button.click() + api_requests.get_donate(sender_address) + initial_balance_recipient = api_requests.get_balance(recipient['address']) + home_view.add_contact(recipient['public_key']) + chat_view = home_view.get_chat_with_user(recipient['username']).click() + chat_view.send_command.click() + chat_view.send_as_keyevent(transaction_amount) + send_transaction_view = chat_view.get_send_transaction_view() + chat_view.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button) + send_transaction_view.sign_transaction('qwerty1234') + send_transaction_view.find_full_text(transaction_amount) + try: + chat_view.find_full_text('Sent', 10) + except TimeoutException: + chat_view.find_full_text('Delivered', 10) + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) + send_transaction_view.back_button.click() + wallet_view = home_view.wallet_button.click() + transactions_view = wallet_view.transactions_button.click() + transactions_view.transactions_table.find_transaction(amount=transaction_amount) + + @pytest.mark.pr + def test_transaction_send_command_wrong_password(self): + sender = transaction_users['A_USER'] + recipient = transaction_users['B_USER'] + console_view = ConsoleView(self.driver) + console_view.recover_access(sender['passphrase'], sender['password'], sender['username']) + home_view = console_view.get_home_view() + transaction_amount = '0.001' + home_view.add_contact(recipient['public_key']) + chat_view = home_view.get_chat_with_user(recipient['username']).click() + chat_view.send_command.click() + chat_view.send_as_keyevent(transaction_amount) + send_transaction_view = chat_view.get_send_transaction_view() + chat_view.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button) + send_transaction_view.sign_transaction_button.click_until_presence_of_element( + send_transaction_view.enter_password_input) + send_transaction_view.enter_password_input.send_keys('wrong_password') + send_transaction_view.sign_transaction_button.click() + send_transaction_view.find_full_text('Wrong password', 20) + + @pytest.mark.pr + def test_transaction_send_command_group_chat(self): + recipient = transaction_users['A_USER'] console_view = ConsoleView(self.driver) console_view.create_user() console_view.back_button.click() home_view = console_view.get_home_view() - recipient_address = transaction_users[recipient]['address'] - recipient_key = transaction_users[recipient]['public_key'] transaction_amount = '0.001' sender_public_key = home_view.get_public_key() sender_address = home_view.public_key_to_address(sender_public_key) home_view.home_button.click() api_requests.get_donate(sender_address) - initial_balance_recipient = api_requests.get_balance(recipient_address) - - home_view.add_contact(recipient_key) - if test == 'group_chat': - home_view.back_button.click(times_to_click=2) - home_view.create_group_chat([transaction_users[recipient]['username']], - 'trg_%s' % get_current_time()) - chat_view = home_view.get_chat_view() - else: - chat_view = home_view.get_chat_with_user(transaction_users[recipient]['username']).click() + initial_balance_recipient = api_requests.get_balance(recipient['address']) + home_view.add_contact(recipient['public_key']) + home_view.get_back_to_home_view() + home_view.create_group_chat([recipient['username']], 'trg_%s' % get_current_time()) + chat_view = home_view.get_chat_view() chat_view.send_command.click() - if test == 'group_chat': - chat_view.first_recipient_button.click() - chat_view.send_as_keyevent(transaction_amount) - else: - chat_view.send_as_keyevent(transaction_amount) - chat_view.send_message_button.click() + chat_view.first_recipient_button.click() + chat_view.send_as_keyevent(transaction_amount) send_transaction_view = chat_view.get_send_transaction_view() - send_transaction_view.sign_transaction_button.wait_for_element(5) - send_transaction_view.sign_transaction_button.click() - if test == 'wrong_password': - send_transaction_view.enter_password_input.send_keys('invalid') - send_transaction_view.sign_transaction_button.click() - send_transaction_view.find_full_text('Wrong password', 20) - else: - send_transaction_view.enter_password_input.send_keys('qwerty1234') - send_transaction_view.sign_transaction_button.click() - send_transaction_view.got_it_button.click() - send_transaction_view.find_full_text(transaction_amount) - try: - chat_view.find_full_text('Sent', 10) - except TimeoutException: - chat_view.find_full_text('Delivered', 10) - if test == 'group_chat': - chat_view.find_full_text('to ' + transaction_users[recipient]['username'], 60) - api_requests.verify_balance_is_updated(initial_balance_recipient, recipient_address) + chat_view.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button) + send_transaction_view.sign_transaction('qwerty1234') + send_transaction_view.find_full_text(transaction_amount) + chat_view.find_full_text('to ' + recipient['username'], 10) + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) - @pytest.mark.transaction + @pytest.mark.pr def test_send_transaction_from_daap(self): console = ConsoleView(self.driver) - console.recover_access(transaction_users['B_USER']['passphrase'], - transaction_users['B_USER']['password'], - transaction_users['B_USER']['username']) + sender = transaction_users['B_USER'] + console.recover_access(sender['passphrase'], + sender['password'], + sender['username']) home_view = console.get_home_view() address = transaction_users['B_USER']['address'] initial_balance = api_requests.get_balance(address) @@ -86,10 +109,203 @@ class TestTransactions(SingleDeviceTestCase): auction_house.send_as_keyevent(auction_name) auction_house.register_name_button.click() send_transaction_view = home_view.get_send_transaction_view() - send_transaction_view.sign_transaction_button.wait_for_element(20) - send_transaction_view.sign_transaction_button.click() - send_transaction_view.enter_password_input.send_keys(transaction_users['B_USER']['password']) - send_transaction_view.sign_transaction_button.click() - send_transaction_view.got_it_button.click() + send_transaction_view.sign_transaction(sender['password']) auction_house.find_full_text('You are the proud owner of the name: ' + auction_name, 120) api_requests.verify_balance_is_updated(initial_balance, address) + + @pytest.mark.pr + def test_send_eth_from_wallet_sign_later(self): + sender = transaction_users_wallet['B_USER'] + recipient = transaction_users_wallet['A_USER'] + console_view = ConsoleView(self.driver) + console_view.recover_access(sender['passphrase'], + sender['password'], + sender['username']) + home_view = console_view.get_home_view() + initial_balance_recipient = api_requests.get_balance(recipient['address']) + home_view.add_contact(recipient['public_key']) + home_view.get_back_to_home_view() + wallet_view = home_view.wallet_button.click() + send_transaction = wallet_view.send_button.click() + send_transaction.amount_edit_box.click() + amount = send_transaction.get_unique_amount() + send_transaction.amount_edit_box.set_value(amount) + send_transaction.confirm() + send_transaction.chose_recipient_button.click() + send_transaction.enter_contact_code_button.click() + send_transaction.enter_recipient_address_input.set_value(recipient['address']) + send_transaction.done_button.click() + send_transaction.sign_later_button.click() + send_transaction.yes_button.click() + send_transaction.ok_button_apk.click() + transactions_view = wallet_view.transactions_button.click() + transactions_view.unsigned_tab.click() + transactions_view.sign_button.click() + send_transaction.sign_transaction_button.click() + send_transaction.enter_password_input.send_keys(sender['password']) + send_transaction.sign_transaction_button.click() + send_transaction.got_it_button.click() + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) + transactions_view.history_tab.click() + transaction = transactions_view.transactions_table.find_transaction(amount=amount) + details_view = transaction.click() + details_view.get_transaction_hash() + + @pytest.mark.pr + def test_send_stt_from_wallet_via_enter_contact_code(self): + sender = transaction_users_wallet['A_USER'] + recipient = transaction_users_wallet['B_USER'] + console_view = ConsoleView(self.driver) + console_view.recover_access(sender['passphrase'], + sender['password'], + sender['username']) + home_view = console_view.get_home_view() + home_view.add_contact(recipient['public_key']) + home_view.get_back_to_home_view() + wallet_view = home_view.wallet_button.click() + wallet_view.options_button.click_until_presence_of_element(wallet_view.manage_assets_button) + wallet_view.manage_assets_button.click() + wallet_view.stt_check_box.click() + wallet_view.done_button.click() + send_transaction = wallet_view.send_button.click() + send_transaction.select_asset_button.click_until_presence_of_element(send_transaction.stt_button) + send_transaction.stt_button.click() + send_transaction.amount_edit_box.click() + send_transaction.amount_edit_box.set_value(send_transaction.get_unique_amount()) + send_transaction.confirm() + send_transaction.chose_recipient_button.click() + send_transaction.enter_contact_code_button.click() + send_transaction.enter_recipient_address_input.set_value(recipient['address']) + send_transaction.done_button.click() + send_transaction.sign_transaction_button.click() + send_transaction.enter_password_input.send_keys(sender['password']) + send_transaction.sign_transaction_button.click() + send_transaction.got_it_button.click() + + @pytest.mark.pr + def test_send_eth_from_wallet_sign_now(self): + sender = transaction_users_wallet['A_USER'] + console_view = ConsoleView(self.driver) + console_view.recover_access(sender['passphrase'], + sender['password'], + sender['username']) + home_view = console_view.get_home_view() + wallet_view = home_view.wallet_button.click() + send_transaction = wallet_view.send_button.click() + send_transaction.amount_edit_box.click() + send_transaction.amount_edit_box.set_value(send_transaction.get_unique_amount()) + send_transaction.confirm() + send_transaction.chose_recipient_button.click() + send_transaction.recent_recipients_button.click() + recent_recipient = send_transaction.element_by_text('Jarrad') + send_transaction.recent_recipients_button.click_until_presence_of_element(recent_recipient) + recent_recipient.click() + send_transaction.sign_transaction_button.click() + send_transaction.enter_password_input.send_keys(sender['password']) + send_transaction.sign_transaction_button.click() + send_transaction.got_it_button.click() + + +@pytest.mark.all +class TestTransactions(MultipleDeviceTestCase): + + @pytest.mark.pr + def test_send_eth_to_request_in_group_chat(self): + recipient = transaction_users['A_USER'] + sender = transaction_users['B_USER'] + self.create_drivers(2) + device_1, device_2 = \ + ConsoleView(self.drivers[0]), ConsoleView(self.drivers[1]) + for user_details in (recipient, device_1), (sender, device_2): + user_details[1].recover_access(passphrase=user_details[0]['passphrase'], + password=user_details[0]['password'], + username=user_details[0]['username']) + device_2_home = device_2.get_home_view() + device_1_home = device_1.get_home_view() + device_1_home.add_contact(sender['public_key']) + device_1_home.get_back_to_home_view() + group_chat_name = 'gtr_%s' % get_current_time() + device_1_home.create_group_chat([sender['username']], group_chat_name) + device_2_home.element_by_text(group_chat_name, 'button').click() + device_1_chat = device_1_home.get_chat_view() + device_2_chat = device_2_home.get_chat_view() + amount = device_1_chat.get_unique_amount() + device_1_chat.request_command.click() + device_1_chat.first_recipient_button.click() + device_1_chat.send_as_keyevent(amount) + device_1_chat.send_message_button.click() + initial_balance_recipient = api_requests.get_balance(recipient['address']) + request_button = device_2_chat.element_by_text_part('Requesting %s ETH' % amount, 'button') + device_2_chat.send_eth_to_request(request_button, sender['password']) + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) + + @pytest.mark.pr + def test_send_eth_to_request_in_one_to_one_chat(self): + recipient = transaction_users['B_USER'] + sender = transaction_users['A_USER'] + self.create_drivers(2) + device_1, device_2 = \ + ConsoleView(self.drivers[0]), ConsoleView(self.drivers[1]) + for user_details in (recipient, device_1), (sender, device_2): + user_details[1].recover_access(passphrase=user_details[0]['passphrase'], + password=user_details[0]['password'], + username=user_details[0]['username']) + device_2_home = device_2.get_home_view() + device_1_home = device_1.get_home_view() + device_1_home.add_contact(sender['public_key']) + device_1_home.get_back_to_home_view() + one_to_one_chat_device_1 = device_1_home.element_by_text_part(sender['username'][:25], 'button') + one_to_one_chat_device_1.scroll_to_element() + one_to_one_chat_device_1.click() + device_1_chat = device_1_home.get_chat_view() + device_2_chat = device_2_home.get_chat_view() + amount = device_1_chat.get_unique_amount() + one_to_one_chat_device_2 = device_2_chat.element_by_text_part(recipient['username'][:25], 'button') + one_to_one_chat_device_2.click() + device_1_chat.request_command.click() + device_1_chat.send_as_keyevent(amount) + device_1_chat.send_message_button.click() + initial_balance_recipient = api_requests.get_balance(recipient['address']) + request_button = device_2_chat.element_by_text_part('Requesting %s ETH' % amount, 'button') + device_2_chat.send_eth_to_request(request_button, sender['password']) + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) + device_2_chat.back_button.click() + device_2_wallet = device_2_home.wallet_button.click() + transactions_view = device_2_wallet.transactions_button.click() + transactions_view.transactions_table.find_transaction(amount=amount) + + @pytest.mark.pr + def test_send_eth_to_request_from_wallet(self): + recipient = transaction_users_wallet['B_USER'] + sender = transaction_users_wallet['A_USER'] + self.create_drivers(2) + device_1, device_2 = \ + ConsoleView(self.drivers[0]), ConsoleView(self.drivers[1]) + for user_details in (recipient, device_1), (sender, device_2): + user_details[1].recover_access(passphrase=user_details[0]['passphrase'], + password=user_details[0]['password'], + username=user_details[0]['username']) + device_2_home = device_2.get_home_view() + device_1_home = device_1.get_home_view() + device_1_home.add_contact(sender['public_key']) + device_1_home.get_back_to_home_view() + wallet_view_device_1 = device_1_home.wallet_button.click() + send_transaction_device_1 = wallet_view_device_1.request_button.click_until_presence_of_element( + wallet_view_device_1.send_transaction_request) + wallet_view_device_1.send_transaction_request.click() + send_transaction_device_1.amount_edit_box.scroll_to_element() + amount = device_1_home.get_unique_amount() + send_transaction_device_1.amount_edit_box.set_value(amount) + send_transaction_device_1.confirm() + send_transaction_device_1.chose_recipient_button.click() + sender_button = send_transaction_device_1.element_by_text(sender['username']) + send_transaction_device_1.recent_recipients_button.click_until_presence_of_element(sender_button) + sender_button.click() + wallet_view_device_1.send_request_button.click() + device_2_chat = device_2_home.get_chat_view() + one_to_one_chat_device_2 = device_2_chat.element_by_text_part(recipient['username'][:25], 'button') + one_to_one_chat_device_2.click() + initial_balance_recipient = api_requests.get_balance(recipient['address']) + request_button = device_2_chat.element_by_text_part('Requesting %s ETH' % amount, 'button') + device_2_chat.send_eth_to_request(request_button, sender['password']) + api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address']) diff --git a/test/appium/tests/test_wallet.py b/test/appium/tests/test_wallet.py index 1d7dfb1acf..7eeb6c701d 100644 --- a/test/appium/tests/test_wallet.py +++ b/test/appium/tests/test_wallet.py @@ -19,69 +19,6 @@ class TestWallet(SingleDeviceTestCase): send_transaction.amount_edit_box.send_keys('0,1') send_transaction.find_full_text('Insufficient funds') - @pytest.mark.wallet - def test_request_transaction_from_wallet(self): - console_view = ConsoleView(self.driver) - console_view.recover_access(transaction_users_wallet['A_USER']['passphrase'], - transaction_users_wallet['A_USER']['password'], - transaction_users_wallet['A_USER']['username']) - home_view = console_view.get_home_view() - recipient_key = transaction_users_wallet['B_USER']['public_key'] - home_view.add_contact(recipient_key) - home_view.back_button.click(times_to_click=2) - wallet_view = home_view.wallet_button.click() - send_transaction_view = wallet_view.request_button.click() - send_transaction_view.amount_edit_box.scroll_to_element() - send_transaction_view.amount_edit_box.send_keys('0.1') - wallet_view.send_request_button.click() - user_chat = home_view.get_chat_with_user(transaction_users_wallet['B_USER']['username']).click() - user_chat.find_text_part('Requesting 0.1 ETH') - - @pytest.mark.parametrize("test, recipient, sender", [('sign_now', 'A_USER', 'B_USER'), - ('sign_later', 'B_USER', 'A_USER')], - ids=['sign_now','sign_later']) - def test_send_transaction_from_wallet(self, test, recipient, sender): - console_view = ConsoleView(self.driver) - console_view.recover_access(transaction_users_wallet[sender]['passphrase'], - transaction_users_wallet[sender]['password'], - transaction_users_wallet[sender]['username']) - home_view = console_view.get_home_view() - recipient_key = transaction_users_wallet[recipient]['public_key'] - recipient_address = transaction_users_wallet[recipient]['address'] - initial_balance_recipient = api_requests.get_balance(recipient_address) - home_view.add_contact(recipient_key) - home_view.back_button.click(times_to_click=2) - wallet_view = home_view.wallet_button.click() - send_transaction = wallet_view.send_button.click() - send_transaction.amount_edit_box.click() - amount = send_transaction.get_unique_amount() - send_transaction.send_as_keyevent(amount) - send_transaction.confirm() - send_transaction.chose_recipient_button.click() - send_transaction.enter_contact_code_button.click() - send_transaction.enter_recipient_address_input.set_value(recipient_address) - send_transaction.done_button.click() - if test == 'sign_later': - send_transaction.sign_later_button.click() - send_transaction.yes_button.click() - send_transaction.ok_button_apk.click() - transactions_view = wallet_view.transactions_button.click() - transactions_view.unsigned_tab.click() - transactions_view.sign_button.click() - send_transaction.sign_transaction_button.click() - send_transaction.enter_password_input.send_keys(transaction_users_wallet[sender]['password']) - send_transaction.sign_transaction_button.click() - send_transaction.got_it_button.click() - api_requests.verify_balance_is_updated(initial_balance_recipient, recipient_address) - if test == 'sign_later': - transactions_view.history_tab.click() - else: - home_view.wallet_button.click() - transactions_view = wallet_view.transactions_button.click() - transaction = transactions_view.transactions_table.find_transaction(amount=amount) - details_view = transaction.click() - details_view.get_transaction_hash() - @pytest.mark.wallet def test_eth_and_currency_balance(self): errors = list() diff --git a/test/appium/views/base_element.py b/test/appium/views/base_element.py index fee7260720..6a3784f851 100644 --- a/test/appium/views/base_element.py +++ b/test/appium/views/base_element.py @@ -67,6 +67,7 @@ class BaseElement(object): def is_element_present(self, sec=5): try: + info('Wait for %s' % self.name) self.wait_for_element(sec) return True except TimeoutException: @@ -120,3 +121,15 @@ class BaseButton(BaseElement): self.find_element().click() info('Tap on %s' % self.name) return self.navigate() + + def click_until_presence_of_element(self, desired_element, attempts=5): + counter = 0 + while not desired_element.is_element_present() and counter <= attempts: + try: + info('Tap on %s' % self.name) + self.find_element().click() + info('Wait for %s' % desired_element.name) + desired_element.wait_for_element(5) + return self.navigate() + except (NoSuchElementException, TimeoutException): + counter += 1 diff --git a/test/appium/views/base_view.py b/test/appium/views/base_view.py index db84b5bf41..5bbbf55443 100644 --- a/test/appium/views/base_view.py +++ b/test/appium/views/base_view.py @@ -81,6 +81,11 @@ class WalletButton(BaseButton): super(WalletButton, self).__init__(driver) self.locator = self.Locator.xpath_selector("//*[@text='Wallet']/..") + def click(self): + from views.wallet_view import TransactionsButton + self.click_until_presence_of_element(desired_element=TransactionsButton(self.driver), attempts=3) + return self.navigate() + def navigate(self): from views.wallet_view import WalletView return WalletView(self.driver) @@ -135,8 +140,7 @@ class BaseView(object): self.driver = driver self.home_button = HomeButton(self.driver) - self.button = WalletButton(self.driver) - self.wallet_button = self.button + self.wallet_button = WalletButton(self.driver) self.profile_button = ProfileButton(self.driver) self.yes_button = YesButton(self.driver) @@ -194,7 +198,7 @@ class BaseView(object): element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]') return element.wait_for_element(wait_time) - def element_by_text(self, text, element_type='base'): + def element_by_text(self, text, element_type='button'): info("Looking for an element by text: '%s'" % text) element = self.element_types[element_type](self.driver) element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]') @@ -222,6 +226,10 @@ class BaseView(object): from views.send_transaction_view import SendTransactionView return SendTransactionView(self.driver) + def get_base_web_view(self): + from views.web_views.base_web_view import BaseWebView + return BaseWebView(self.driver) + def get_unique_amount(self): return '0.0%s' % datetime.now().strftime('%-m%-d%-H%-M%-S').strip('0') diff --git a/test/appium/views/chat_view.py b/test/appium/views/chat_view.py index 3c3e912004..a64f372ed6 100644 --- a/test/appium/views/chat_view.py +++ b/test/appium/views/chat_view.py @@ -1,4 +1,4 @@ -from selenium.common.exceptions import TimeoutException +from selenium.common.exceptions import TimeoutException, NoSuchElementException from tests import info from views.base_element import BaseButton, BaseEditBox, BaseText from views.base_view import BaseView @@ -34,11 +34,21 @@ class UserNameText(BaseText): '//..//android.widget.TextView)[1]') +class TransactionPopupText(BaseText): + def __init__(self, driver): + super(TransactionPopupText, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Send transaction']") + + class SendCommand(BaseButton): def __init__(self, driver): super(SendCommand, self).__init__(driver) self.locator = self.Locator.xpath_selector("//*[@text='/send']") + def click(self): + desired_element = TransactionPopupText(self.driver) + self.click_until_presence_of_element(desired_element=desired_element) + class RequestCommand(BaseButton): def __init__(self, driver): @@ -98,6 +108,18 @@ class MoreUsersButton(BaseButton): self.locator = self.Locator.xpath_selector("//android.widget.TextView[contains(@text, 'MORE')]") +class UserProfileIconTopRight(BaseButton): + def __init__(self, driver): + super(UserProfileIconTopRight, self).__init__(driver) + self.locator = self.Locator.accessibility_id('chat-icon') + + +class UserProfileDetails(BaseButton): + def __init__(self, driver): + super(UserProfileDetails, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Profile']") + + class ChatView(BaseView): def __init__(self, driver): super(ChatView, self).__init__(driver) @@ -120,6 +142,10 @@ class ChatView(BaseView): self.first_recipient_button = FirstRecipient(self.driver) + self.user_profile_icon_top_right = UserProfileIconTopRight(self.driver) + self.user_profile_details = UserProfileDetails(self.driver) + + def wait_for_syncing_complete(self): info('Waiting for syncing complete:') while True: @@ -131,3 +157,10 @@ class ChatView(BaseView): def get_messages_sent_by_user(self, username): return MessageByUsername(self.driver, username).find_elements() + + def send_eth_to_request(self, request, sender_password): + gas_popup = self.element_by_text_part('Send transaction') + request.click_until_presence_of_element(gas_popup) + send_transaction = self.get_send_transaction_view() + self.send_message_button.click_until_presence_of_element(send_transaction.sign_transaction_button) + send_transaction.sign_transaction(sender_password) diff --git a/test/appium/views/console_view.py b/test/appium/views/console_view.py index 394034e119..61e64c10e0 100644 --- a/test/appium/views/console_view.py +++ b/test/appium/views/console_view.py @@ -73,4 +73,4 @@ class ConsoleView(BaseView): recovered_user.click() recover_access_view.password_input.send_keys(password) recover_access_view.sign_in_button.click() - recover_access_view.find_full_text('Wallet', 30) + recover_access_view.find_full_text('Wallet', 60) diff --git a/test/appium/views/home_view.py b/test/appium/views/home_view.py index d466b09452..f462c3f148 100644 --- a/test/appium/views/home_view.py +++ b/test/appium/views/home_view.py @@ -1,7 +1,7 @@ from tests import info import time -from selenium.common.exceptions import TimeoutException -from views.base_element import BaseButton +from selenium.common.exceptions import TimeoutException, NoSuchElementException +from views.base_element import BaseButton, BaseText from views.base_view import BaseView @@ -12,8 +12,8 @@ class PlusButton(BaseButton): "//android.view.ViewGroup/android.widget.TextView[@text='+']") def navigate(self): - from views.start_new_chat_view import StarNewChatView - return StarNewChatView(self.driver) + from views.start_new_chat_view import StartNewChatView + return StartNewChatView(self.driver) class ConsoleButton(BaseButton): @@ -33,12 +33,19 @@ class ChatElement(BaseButton): return ChatView(self.driver) +class FirstChatElementTitle(BaseText): + def __init__(self, driver): + super(FirstChatElementTitle, self).__init__(driver) + self.locator = self.Locator.xpath_selector('(//android.widget.ScrollView//android.widget.TextView)[1]') + + class HomeView(BaseView): def __init__(self, driver): super(HomeView, self).__init__(driver) self.plus_button = PlusButton(self.driver) self.console_button = ConsoleButton(self.driver) + self.first_chat_element_title = FirstChatElementTitle(self.driver) def wait_for_syncing_complete(self): info('Waiting for syncing complete:') @@ -52,6 +59,16 @@ class HomeView(BaseView): def get_chat_with_user(self, username): return ChatElement(self.driver, username) + def get_back_to_home_view(self): + counter = 0 + while not self.home_button.is_element_present(): + try: + if counter >= 5: + return + self.back_button.click() + except (NoSuchElementException, TimeoutException): + counter += 1 + def add_contact(self, public_key): start_new_chat = self.plus_button.click() start_new_chat.add_new_contact.click() diff --git a/test/appium/views/profile_view.py b/test/appium/views/profile_view.py index 54bfa0c49d..c8f8963e13 100644 --- a/test/appium/views/profile_view.py +++ b/test/appium/views/profile_view.py @@ -1,4 +1,5 @@ import time +import pytest from tests import info from views.base_element import BaseText, BaseButton, BaseEditBox from views.base_view import BaseView @@ -8,7 +9,7 @@ class PublicKeyText(BaseText): def __init__(self, driver): super(PublicKeyText, self).__init__(driver) - self.locator = self.Locator.accessibility_id('profile-public-key') + self.locator = self.Locator.xpath_selector('//*[contains(@text, "0x04")]') @property def text(self): @@ -54,7 +55,7 @@ class NetworkSettingsButton(BaseButton): def __init__(self, driver): super(NetworkSettingsButton, self).__init__(driver) - self.locator = self.Locator.xpath_selector('//*[@text="Network settings"]') + self.locator = self.Locator.xpath_selector('//*[@text="Network"]') class NetworkButton(BaseButton): def __init__(self, driver, network): diff --git a/test/appium/views/send_transaction_view.py b/test/appium/views/send_transaction_view.py index 556d092d95..248238d1f4 100644 --- a/test/appium/views/send_transaction_view.py +++ b/test/appium/views/send_transaction_view.py @@ -59,6 +59,10 @@ class ChooseRecipientButton(BaseButton): super(ChooseRecipientButton, self).__init__(driver) self.locator = self.Locator.xpath_selector("//*[@text='Specify recipient...']") + def click(self): + desired_element = EnterContactCodeButton(self.driver) + self.click_until_presence_of_element(desired_element=desired_element) + class EnterContactCodeButton(BaseButton): def __init__(self, driver): @@ -72,6 +76,24 @@ class EnterRecipientAddressInput(BaseEditBox): self.locator = self.Locator.xpath_selector("//*[@text='Enter recipient address']") +class RecentRecipientsButton(BaseButton): + def __init__(self, driver): + super(RecentRecipientsButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Recent recipients']") + + +class SelectAssetButton(BaseButton): + def __init__(self, driver): + super(SelectAssetButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[4]/..') + + +class STTButton(BaseButton): + def __init__(self, driver): + super(STTButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Status Test Token']") + + class SendTransactionView(BaseView): def __init__(self, driver): super(SendTransactionView, self).__init__(driver) @@ -80,6 +102,7 @@ class SendTransactionView(BaseView): self.enter_contact_code_button = EnterContactCodeButton(self.driver) self.enter_recipient_address_input = EnterRecipientAddressInput(self.driver) self.first_recipient_button = FirstRecipient(self.driver) + self.recent_recipients_button = RecentRecipientsButton(self.driver) self.amount_edit_box = AmountEditBox(self.driver) self.sign_transaction_button = SignTransactionButton(self.driver) @@ -89,11 +112,11 @@ class SendTransactionView(BaseView): self.enter_password_input = EnterPasswordInput(self.driver) self.got_it_button = GotItButton(self.driver) - def try_to_sing_transaction(self): - for _ in range(4): - try: - self.sign_transaction_button.click() - self.enter_password_input.wait_for_element(5) - return - except (NoSuchElementException, TimeoutException): - pass + self.select_asset_button = SelectAssetButton(self.driver) + self.stt_button = STTButton(self.driver) + + def sign_transaction(self, sender_password): + self.sign_transaction_button.click_until_presence_of_element(self.enter_password_input) + self.enter_password_input.send_keys(sender_password) + self.sign_transaction_button.click_until_presence_of_element(self.got_it_button) + self.got_it_button.click() diff --git a/test/appium/views/start_new_chat_view.py b/test/appium/views/start_new_chat_view.py index fe9c1838b5..fb6bb70219 100644 --- a/test/appium/views/start_new_chat_view.py +++ b/test/appium/views/start_new_chat_view.py @@ -38,9 +38,15 @@ class OpenButton(BaseButton): "//android.widget.TextView[@text='Open']") -class StarNewChatView(ContactsView): +class EnterUrlEditbox(BaseEditBox): def __init__(self, driver): - super(StarNewChatView, self).__init__(driver) + super(EnterUrlEditbox, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//android.widget.EditText") + + +class StartNewChatView(ContactsView): + def __init__(self, driver): + super(StartNewChatView, self).__init__(driver) self.add_new_contact = AddNewContactButton(self.driver) self.new_group_chat_button = NewGroupChatButton(self.driver) @@ -49,3 +55,4 @@ class StarNewChatView(ContactsView): self.open_button = OpenButton(self.driver) self.name_edit_box = NameEditBox(self.driver) + self.enter_url_editbox = EnterUrlEditbox(self.driver) diff --git a/test/appium/views/wallet_view.py b/test/appium/views/wallet_view.py index 719662137c..30d389c35e 100644 --- a/test/appium/views/wallet_view.py +++ b/test/appium/views/wallet_view.py @@ -68,6 +68,36 @@ class UsdTotalValueText(BaseText): self.locator = self.Locator.xpath_selector("//*[@text='USD']/../android.widget.TextView[1]") +class SendTransactionRequestButton(BaseButton): + def __init__(self, driver): + super(SendTransactionRequestButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='SEND A TRANSACTION REQUEST']") + + +class OptionsButton(BaseButton): + def __init__(self, driver): + super(OptionsButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[1]') + + +class ManageAssetsButton(BaseButton): + def __init__(self, driver): + super(ManageAssetsButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Manage Assets']") + + +class STTCheckBox(BaseButton): + def __init__(self, driver): + super(STTCheckBox, self).__init__(driver) + self.locator = self.Locator.xpath_selector("(//*[@text='STT']//..//android.view.ViewGroup)[1]") + + +class DoneButton(BaseButton): + def __init__(self, driver): + super(DoneButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//*[@text='Done']") + + class WalletView(BaseView): def __init__(self, driver): super(WalletView, self).__init__(driver) @@ -77,9 +107,15 @@ class WalletView(BaseView): self.transactions_button = TransactionsButton(self.driver) self.eth_asset = EthAssetText(self.driver) self.usd_total_value = UsdTotalValueText(self.driver) + + self.send_transaction_request = SendTransactionRequestButton(self.driver) self.request_button = RequestButton(self.driver) self.send_request_button = SendRequestButton(self.driver) + self.options_button = OptionsButton(self.driver) + self.manage_assets_button = ManageAssetsButton(self.driver) + self.stt_check_box = STTCheckBox(self.driver) + self.done_button = DoneButton(self.driver) def get_usd_total_value(self): return float(self.usd_total_value.text) diff --git a/test/appium/views/web_views/base_web_view.py b/test/appium/views/web_views/base_web_view.py index 12887610ad..824ceb9d37 100644 --- a/test/appium/views/web_views/base_web_view.py +++ b/test/appium/views/web_views/base_web_view.py @@ -9,6 +9,19 @@ class ProgressBarIcon(BaseElement): self.locator = self.Locator.xpath_selector("//android.widget.ProgressBar") +class WebLinkEditBox(BaseEditBox): + + def __init__(self, driver): + super(WebLinkEditBox, self).__init__(driver) + self.locator = self.Locator.xpath_selector("//android.widget.EditText") + + +class BackToHomeButton(BaseButton): + def __init__(self, driver): + super(BackToHomeButton, self).__init__(driver) + self.locator = self.Locator.xpath_selector('(//android.view.ViewGroup[@content-desc="icon"])[1]') + + class BaseWebView(BaseView): def __init__(self, driver): @@ -17,6 +30,9 @@ class BaseWebView(BaseView): self.progress_bar_icon = ProgressBarIcon(self.driver) + self.web_link_edit_box = WebLinkEditBox(self.driver) + self.back_to_home_button = BackToHomeButton(self.driver) + def wait_for_d_aap_to_load(self, wait_time=35): counter = 0 while self.progress_bar_icon.is_element_present(5): diff --git a/test/cljs/status_im/test/contacts/events.cljs b/test/cljs/status_im/test/contacts/events.cljs index 47e8c5e1b2..fbbbcb5e69 100644 --- a/test/cljs/status_im/test/contacts/events.cljs +++ b/test/cljs/status_im/test/contacts/events.cljs @@ -64,7 +64,7 @@ (defn test-fixtures [] (rf/reg-fx ::events/init-store #()) - (rf/reg-fx ::contacts-events/save-contacts! #()) + (rf/reg-fx :save-all-contacts #()) (rf/reg-fx ::contacts-events/save-contact #()) (rf/reg-fx ::contacts-events/watch-contact #()) (rf/reg-fx ::contacts-events/stop-watching-contact #())