Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
Andrey Shovkoplyas 2018-02-14 17:49:01 +03:00
commit 6d0681f906
No known key found for this signature in database
GPG Key ID: EAAB7C8622D860A4
32 changed files with 676 additions and 329 deletions

View File

@ -70,7 +70,7 @@ node ('macos1'){
def filename = 'im.status.ethereum-' + shortCommit + '.apk' def filename = 'im.status.ethereum-' + shortCommit + '.apk'
def newArtifact = (artifact_dir + filename) def newArtifact = (artifact_dir + filename)
sh ('mv ' + artifact + ' ' + newArtifact) 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) def buildInfo = server.upload(uploadSpec)
apkUrl = 'http://artifacts.status.im:8081/artifactory/nightlies-local/' + filename apkUrl = 'http://artifacts.status.im:8081/artifactory/nightlies-local/' + filename

View File

@ -83,19 +83,14 @@
(async/go (async/>! realm-queue #(messages-store/save message))))) (async/go (async/>! realm-queue #(messages-store/save message)))))
(re-frame/reg-fx (re-frame/reg-fx
:delete-chat-messages :delete-messages
(fn [{:keys [chat-id group-chat debug?]}] (fn [chat-id]
(when (or group-chat debug?) (async/go (async/>! realm-queue #(messages-store/delete-by-chat-id chat-id)))))
(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)))))
(re-frame/reg-fx (re-frame/reg-fx
:update-message-overhead :delete-pending-messages
(fn [[chat-id network-status]] (fn [chat-id]
(let [update-fn (if (= network-status :offline) (async/go (async/>! realm-queue #(pending-messages-store/delete-all-by-chat-id chat-id)))))
chats-store/inc-message-overhead
chats-store/reset-message-overhead)]
(async/go (async/>! realm-queue #(update-fn chat-id))))))
(re-frame/reg-fx (re-frame/reg-fx
:save-chat :save-chat
@ -103,16 +98,14 @@
(async/go (async/>! realm-queue #(chats-store/save chat))))) (async/go (async/>! realm-queue #(chats-store/save chat)))))
(re-frame/reg-fx (re-frame/reg-fx
:delete-chat :deactivate-chat
(fn [{:keys [chat-id debug?]}] (fn [chat-id]
(if debug? (async/go (async/>! realm-queue #(chats-store/set-inactive chat-id)))))
(async/go (async/>! realm-queue #(chats-store/delete chat-id)))
(async/go (async/>! realm-queue #(chats-store/set-inactive chat-id))))))
(re-frame/reg-fx (re-frame/reg-fx
:save-all-contacts :delete-chat
(fn [contacts] (fn [chat-id]
(contacts-store/save-all contacts))) (async/go (async/>! realm-queue #(chats-store/delete chat-id)))))
(re-frame/reg-fx (re-frame/reg-fx
:protocol-send-seen :protocol-send-seen
@ -354,9 +347,14 @@
:remove-chat :remove-chat
[re-frame/trim-v] [re-frame/trim-v]
(fn [{:keys [db]} [chat-id]] (fn [{:keys [db]} [chat-id]]
(let [chat (get-in db [:chats chat-id])] (let [{:keys [chat-id group-chat debug?]} (get-in db [:chats chat-id])]
{:db (-> db (cond-> {:db (-> db
(update :chats dissoc chat-id) (update :chats dissoc chat-id)
(update :deleted-chats (fnil conj #{}) chat-id)) (update :deleted-chats (fnil conj #{}) chat-id))
:delete-chat chat :delete-pending-messages chat-id}
:delete-chat-messages chat}))) (or group-chat debug?)
(assoc :delete-messages chat-id)
debug?
(assoc :delete-chat chat-id)
(not debug?)
(assoc :deactivate-chat chat-id)))))

View File

@ -2,7 +2,7 @@
(:require [clojure.string :as string] (:require [clojure.string :as string]
[re-frame.core :as re-frame] [re-frame.core :as re-frame]
[taoensso.timbre :as log] [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 :as model]
[status-im.chat.models.input :as input-model] [status-im.chat.models.input :as input-model]
[status-im.chat.models.commands :as commands-model] [status-im.chat.models.commands :as commands-model]
@ -277,29 +277,36 @@
:proceed-event-creator (partial event-after-creator :proceed-event-creator (partial event-after-creator
command-message)}))) command-message)})))
;; TODO (janherich) request-command-data functions and event need to be refactored, they are needlessly complicated
(defn proceed-command (defn proceed-command
"Proceed with command processing by setting up and executing chain of events: "Proceed with command processing by setting up and executing chain of events:
1. Params validation 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] [{:keys [current-chat-id chats] :as db} {{:keys [bot]} :command :as content} message-id current-time]
(let [params-template {:content content (let [params-template {:content content
:chat-id current-chat-id :chat-id current-chat-id
:group-id (when (get-in chats [current-chat-id :group-chat]) :group-id (when (get-in chats [current-chat-id :group-chat])
current-chat-id) current-chat-id)
:jail-id (or bot current-chat-id) :jail-id (or bot current-chat-id)
:message-id message-id :message-id message-id
:current-time current-time} :current-time current-time}
preview-params (merge params-template preview-params (merge params-template
{:data-type :preview {:data-type :preview
:event-after-creator (fn [command-message jail-response] :event-after-creator (fn [command-message jail-response]
[::send-command [::send-command
(assoc-in command-message [:command :preview] jail-response)])}) (assoc-in command-message [:command :preview] jail-response)])})
validation-params (merge params-template short-preview-params (merge params-template
{:data-type :validator {:data-type :short-preview
:event-after-creator (fn [_ jail-response] :event-after-creator (fn [_ jail-response]
[::proceed-validation [::request-command-data
jail-response (assoc-in preview-params [:content :command :short-preview] jail-response)])})
[[::request-command-data preview-params]]])})] 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))) (request-command-data db validation-params)))
;;;; Handlers ;;;; Handlers
@ -443,7 +450,7 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:send-current-message :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 (fn [{{:keys [current-chat-id current-public-key] :as db} :db message-id :random-id current-time :now
:as cofx} _] :as cofx} _]
(when-not (get-in db [:chat-ui-props current-chat-id :sending-in-progress?]) (when-not (get-in db [:chat-ui-props current-chat-id :sending-in-progress?])

View File

@ -219,9 +219,8 @@
(let [chat (get-in db [:chats chat-id]) (let [chat (get-in db [:chats chat-id])
message (prepare-message params chat) message (prepare-message params chat)
params' (assoc params :message message) params' (assoc params :message message)
fx {:db (add-message-to-db db chat-id message true) fx {:db (add-message-to-db db chat-id message true)
:update-message-overhead [chat-id network-status] :save-message message}]
:save-message message}]
(-> (merge fx (chat-model/upsert-chat (assoc fx :now now) (-> (merge fx (chat-model/upsert-chat (assoc fx :now now)
{:chat-id chat-id})) {:chat-id chat-id}))
(as-> fx' (as-> fx'
@ -283,8 +282,7 @@
params' (assoc params :command command') params' (assoc params :command command')
fx {:db (-> (merge db (:db result)) fx {:db (-> (merge db (:db result))
(add-message-to-db chat-id command' true)) (add-message-to-db chat-id command' true))
:update-message-overhead [chat-id network-status]
:save-message (-> command' :save-message (-> command'
(assoc :chat-id chat-id) (assoc :chat-id chat-id)
(update-in [:content :params] (update-in [:content :params]

View File

@ -62,10 +62,6 @@
[chat-id] [chat-id]
(get-property chat-id :removed-at)) (get-property chat-id :removed-at))
(defn get-message-overhead
[chat-id]
(get-property chat-id :message-overhead))
(defn get-active-group-chats (defn get-active-group-chats
[] []
(data-store/get-active-group-chats)) (data-store/get-active-group-chats))
@ -74,14 +70,6 @@
[chat-id active?] [chat-id active?]
(save-property chat-id :is-active 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? (defn new-update?
[timestamp chat-id] [timestamp chat-id]
(let (let

View File

@ -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}}})

View File

@ -1,5 +1,5 @@
(ns status-im.data-store.realm.schemas.account.v21.core (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.v1.chat-contact :as chat-contact]
[status-im.data-store.realm.schemas.account.v19.contact :as contact] [status-im.data-store.realm.schemas.account.v19.contact :as contact]
[status-im.data-store.realm.schemas.account.v20.discover :as discover] [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] [status-im.data-store.realm.schemas.account.v21.browser :as browser]
[taoensso.timbre :as log] [taoensso.timbre :as log]
[cljs.reader :as reader] [cljs.reader :as reader]
[clojure.string :as str])) [clojure.string :as string]))
(def schema [chat/schema (def schema [chat/schema
chat-contact/schema chat-contact/schema
@ -45,7 +45,7 @@
content (aget message "content") content (aget message "content")
type (aget message "content-type")] type (aget message "content-type")]
(when (and (= type "command") (when (and (= type "command")
(> (str/index-of content "command=location") -1)) (string/includes? content "command=location"))
(aset message "show?" false)))))) (aset message "show?" false))))))
(defn remove-phone-messages! [old-realm new-realm] (defn remove-phone-messages! [old-realm new-realm]
@ -55,7 +55,7 @@
content (aget message "content") content (aget message "content")
type (aget message "content-type")] type (aget message "content-type")]
(when (and (= type "command") (when (and (= type "command")
(> (str/index-of content "command=phone") -1)) (string/includes? content "command=phone"))
(aset message "show?" false)))))) (aset message "show?" false))))))
(defn migration [old-realm new-realm] (defn migration [old-realm new-realm]

View File

@ -84,7 +84,7 @@
(contacts/save contact))) (contacts/save contact)))
(reg-fx (reg-fx
::save-contacts! :save-all-contacts
(fn [new-contacts] (fn [new-contacts]
(contacts/save-all new-contacts))) (contacts/save-all new-contacts)))
@ -223,8 +223,8 @@
;;(remove #(identities (:whisper-identity %))) ;;(remove #(identities (:whisper-identity %)))
(map #(vector (:whisper-identity %) %)) (map #(vector (:whisper-identity %) %))
(into {})) (into {}))
fx {:db (update db :contacts/contacts merge new-contacts') fx {:db (update db :contacts/contacts merge new-contacts')
::save-contacts! (vals new-contacts')}] :save-all-contacts (vals new-contacts')}]
(transduce (map second) (transduce (map second)
(completing (partial loading-events/load-commands (assoc cofx :db (:db fx)))) (completing (partial loading-events/load-commands (assoc cofx :db (:db fx))))
fx fx

View File

@ -3,7 +3,6 @@
(:require [cljs.spec.alpha :as spec] (:require [cljs.spec.alpha :as spec]
[status-im.constants :as constants] [status-im.constants :as constants]
[status-im.utils.platform :as platform] [status-im.utils.platform :as platform]
[status-im.utils.ethereum.core :as ethereum]
status-im.ui.screens.accounts.db status-im.ui.screens.accounts.db
status-im.ui.screens.contacts.db status-im.ui.screens.contacts.db
status-im.ui.screens.qr-scanner.db status-im.ui.screens.qr-scanner.db
@ -18,15 +17,6 @@
status-im.ui.screens.browser.db status-im.ui.screens.browser.db
status-im.ui.screens.add-new.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 ;; initial state of app-db
(def app-db {:current-public-key nil (def app-db {:current-public-key nil
:status-module-initialized? (or platform/ios? js/goog.DEBUG) :status-module-initialized? (or platform/ios? js/goog.DEBUG)
@ -46,7 +36,6 @@
:tags [] :tags []
:sync-state :done :sync-state :done
:wallet.transactions constants/default-wallet-transactions :wallet.transactions constants/default-wallet-transactions
:wallet {:send-transaction transaction-send-default}
:wallet-selected-asset {} :wallet-selected-asset {}
:prices {} :prices {}
:notifications {} :notifications {}

View File

@ -2,8 +2,7 @@
(:require [re-frame.core :refer [dispatch reg-fx]] (:require [re-frame.core :refer [dispatch reg-fx]]
[status-im.utils.handlers :refer [register-handler-fx]] [status-im.utils.handlers :refer [register-handler-fx]]
[status-im.protocol.core :as protocol] [status-im.protocol.core :as protocol]
[status-im.utils.random :as random] [status-im.utils.random :as random]
[status-im.chat.handlers :as chat-events]
[status-im.data-store.contacts :as contacts] [status-im.data-store.contacts :as contacts]
[status-im.data-store.messages :as messages] [status-im.data-store.messages :as messages]
[status-im.data-store.chats :as chats] [status-im.data-store.chats :as chats]
@ -173,4 +172,4 @@
:clear-history :clear-history
(fn [{{:keys [current-chat-id] :as db} :db} _] (fn [{{:keys [current-chat-id] :as db} :db} _]
{:db (assoc-in db [:chats current-chat-id :messages] {}) {:db (assoc-in db [:chats current-chat-id :messages] {})
::chat-events/delete-messages current-chat-id})) :delete-messages current-chat-id}))

View File

@ -16,42 +16,30 @@
[taoensso.timbre :as log] [taoensso.timbre :as log]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen])) [status-im.ui.components.chat-icon.screen :as chat-icon.screen]))
(defn message-content-text [{:keys [content] :as message}] (defn message-content-text [{:keys [content] :as message}]
(reagent/create-class [react/view styles/last-message-container
{:display-name "message-content-text" (cond
: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
(not message) (not message)
[react/text {:style styles/last-message-text} [react/text {:style styles/last-message-text}
(i18n/label :t/no-messages)] (i18n/label :t/no-messages)]
(str/blank? content) (str/blank? content)
[react/text {:style styles/last-message-text} [react/text {:style styles/last-message-text}
""] ""]
(:content content) (:content content)
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:number-of-lines 1} :number-of-lines 1}
(:content content)] (:content content)]
(and (:command content) (and (:command content) (-> content :short-preview :markup))
(-> content :short-preview :markup)) (commands-utils/generate-hiccup (-> content :short-preview :markup))
(commands-utils/generate-hiccup (-> content :short-preview :markup))
:else :else
[react/text {:style styles/last-message-text [react/text {:style styles/last-message-text
:number-of-lines 1} :number-of-lines 1}
content])])})) content])])
(defview message-status [{:keys [chat-id contacts]} (defview message-status [{:keys [chat-id contacts]}
{:keys [message-id user-statuses outgoing] :as msg}] {:keys [message-id user-statuses outgoing] :as msg}]

View File

@ -79,6 +79,11 @@
#(re-frame/dispatch [success-event %]) #(re-frame/dispatch [success-event %])
#(re-frame/dispatch [error-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
(handlers/register-handler-fx (handlers/register-handler-fx
@ -202,3 +207,15 @@
:content (i18n/label :t/transactions-delete-content) :content (i18n/label :t/transactions-delete-content)
:confirm-button-text (i18n/label :t/confirm) :confirm-button-text (i18n/label :t/confirm)
:on-accept #(re-frame/dispatch [:wallet/discard-unsigned-transaction transaction-id])}})) :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)))

View File

@ -1,6 +1,5 @@
(ns status-im.ui.screens.wallet.navigation (ns status-im.ui.screens.wallet.navigation
(:require [re-frame.core :as re-frame] (:require [re-frame.core :as re-frame]
[status-im.ui.screens.db :as db]
[status-im.ui.screens.navigation :as navigation] [status-im.ui.screens.navigation :as navigation]
[status-im.utils.ethereum.core :as ethereum] [status-im.utils.ethereum.core :as ethereum]
[status-im.utils.ethereum.tokens :as tokens])) [status-im.utils.ethereum.tokens :as tokens]))
@ -15,16 +14,23 @@
(re-frame/dispatch [:update-transactions]) (re-frame/dispatch [:update-transactions])
db) db)
(def transaction-send-default
(let [symbol :ETH]
{:gas (ethereum/estimate-gas symbol)
:symbol symbol}))
(defmethod navigation/preload-data! :wallet-request-transaction (defmethod navigation/preload-data! :wallet-request-transaction
[db [event]] [db [event]]
(if (= event :navigate-back) (if (= event :navigate-back)
db db
(-> db (-> db
(update :wallet dissoc :request-transaction) (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 (defmethod navigation/preload-data! :wallet-send-transaction
[db [event]] [db [event]]
(re-frame/dispatch [:wallet/update-gas-price])
(if (= event :navigate-back) (if (= event :navigate-back)
db db
(assoc-in db [:wallet :send-transaction] db/transaction-send-default))) (assoc-in db [:wallet :send-transaction] transaction-send-default)))

View File

@ -291,6 +291,7 @@
(handlers/register-handler-fx (handlers/register-handler-fx
:wallet.send/reset-gas-default :wallet.send/reset-gas-default
(fn [{:keys [db]}] (fn [{:keys [db]}]
{:db (update-in db [:wallet :edit] {:dispatch [:wallet/update-gas-price true]
merge :db (update-in db [:wallet :edit]
(db/gas-default (get-in db [:wallet :send-transaction :symbol])))})) assoc
:gas (ethereum/estimate-gas (get-in db [:wallet :send-transaction :symbol])))}))

View File

@ -83,10 +83,12 @@
(.sendTransaction (.-eth web3) (clj->js params) cb)) (.sendTransaction (.-eth web3) (clj->js params) cb))
(def default-transaction-gas (money/bignumber 21000)) (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] (defn estimate-gas [symbol]
(if (tokens/ethereum? symbol) (if (tokens/ethereum? symbol)
default-transaction-gas default-transaction-gas
;; TODO(jeluard) Rely on estimateGas call ;; TODO(jeluard) Rely on estimateGas call
(.times default-transaction-gas 5))) (.times default-transaction-gas 5)))

View File

@ -88,7 +88,7 @@ class AbstractTestCase:
@property @property
def implicitly_wait(self): def implicitly_wait(self):
return 10 return 8
def update_test_info_dict(self): def update_test_info_dict(self):
test_data.test_info[test_data.test_name] = dict() test_data.test_info[test_data.test_name] = dict()
@ -145,7 +145,8 @@ class SauceMultipleDeviceTestCase(AbstractTestCase):
@classmethod @classmethod
def setup_class(cls): 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): def setup_method(self, method):
self.update_test_info_dict() self.update_test_info_dict()

View File

@ -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'

View File

@ -47,7 +47,7 @@ class TestMultipleDevices(MultipleDeviceTestCase):
device_2_home.add_contact(device_1_public_key) device_2_home.add_contact(device_1_public_key)
device_2_chat = device_2_home.get_chat_view() device_2_chat = device_2_home.get_chat_view()
device_1_user_name = device_2_chat.user_name_text.text 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' chat_name = 'new_chat'
message_1 = 'first SOMETHING' message_1 = 'first SOMETHING'
message_2 = 'second SOMETHING' message_2 = 'second SOMETHING'
@ -83,64 +83,3 @@ class TestMultipleDevices(MultipleDeviceTestCase):
group_chat_d1.find_text_part("removed you from group chat") 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): 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.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()

View File

@ -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)

View File

@ -1,76 +1,99 @@
import pytest import pytest
import time import time
from views.console_view import ConsoleView from views.console_view import ConsoleView
from tests.base_test_case import SingleDeviceTestCase from tests.base_test_case import SingleDeviceTestCase, MultipleDeviceTestCase
from tests import transaction_users, api_requests, get_current_time from tests import transaction_users, api_requests, get_current_time, transaction_users_wallet
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException
@pytest.mark.all @pytest.mark.all
class TestTransactions(SingleDeviceTestCase): class TestTransaction(SingleDeviceTestCase):
@pytest.mark.transaction @pytest.mark.pr
@pytest.mark.parametrize("test, recipient", [('group_chat', 'A_USER'), def test_transaction_send_command_one_to_one_chat(self):
('one_to_one_chat', 'B_USER'), recipient = transaction_users['B_USER']
('wrong_password', 'A_USER')], console_view = ConsoleView(self.driver)
ids=['group_chat', console_view.create_user()
'one_to_one_chat', console_view.back_button.click()
'wrong_password']) home_view = console_view.get_home_view()
def test_transaction_send_command(self, test, recipient): 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 = ConsoleView(self.driver)
console_view.create_user() console_view.create_user()
console_view.back_button.click() console_view.back_button.click()
home_view = console_view.get_home_view() home_view = console_view.get_home_view()
recipient_address = transaction_users[recipient]['address']
recipient_key = transaction_users[recipient]['public_key']
transaction_amount = '0.001' transaction_amount = '0.001'
sender_public_key = home_view.get_public_key() sender_public_key = home_view.get_public_key()
sender_address = home_view.public_key_to_address(sender_public_key) sender_address = home_view.public_key_to_address(sender_public_key)
home_view.home_button.click() home_view.home_button.click()
api_requests.get_donate(sender_address) api_requests.get_donate(sender_address)
initial_balance_recipient = api_requests.get_balance(recipient_address) initial_balance_recipient = api_requests.get_balance(recipient['address'])
home_view.add_contact(recipient['public_key'])
home_view.add_contact(recipient_key) home_view.get_back_to_home_view()
if test == 'group_chat': home_view.create_group_chat([recipient['username']], 'trg_%s' % get_current_time())
home_view.back_button.click(times_to_click=2) chat_view = home_view.get_chat_view()
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()
chat_view.send_command.click() chat_view.send_command.click()
if test == 'group_chat': chat_view.first_recipient_button.click()
chat_view.first_recipient_button.click() chat_view.send_as_keyevent(transaction_amount)
chat_view.send_as_keyevent(transaction_amount)
else:
chat_view.send_as_keyevent(transaction_amount)
chat_view.send_message_button.click()
send_transaction_view = chat_view.get_send_transaction_view() send_transaction_view = chat_view.get_send_transaction_view()
send_transaction_view.sign_transaction_button.wait_for_element(5) chat_view.send_message_button.click_until_presence_of_element(send_transaction_view.sign_transaction_button)
send_transaction_view.sign_transaction_button.click() send_transaction_view.sign_transaction('qwerty1234')
if test == 'wrong_password': send_transaction_view.find_full_text(transaction_amount)
send_transaction_view.enter_password_input.send_keys('invalid') chat_view.find_full_text('to ' + recipient['username'], 10)
send_transaction_view.sign_transaction_button.click() api_requests.verify_balance_is_updated(initial_balance_recipient, recipient['address'])
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)
@pytest.mark.transaction @pytest.mark.pr
def test_send_transaction_from_daap(self): def test_send_transaction_from_daap(self):
console = ConsoleView(self.driver) console = ConsoleView(self.driver)
console.recover_access(transaction_users['B_USER']['passphrase'], sender = transaction_users['B_USER']
transaction_users['B_USER']['password'], console.recover_access(sender['passphrase'],
transaction_users['B_USER']['username']) sender['password'],
sender['username'])
home_view = console.get_home_view() home_view = console.get_home_view()
address = transaction_users['B_USER']['address'] address = transaction_users['B_USER']['address']
initial_balance = api_requests.get_balance(address) initial_balance = api_requests.get_balance(address)
@ -86,10 +109,203 @@ class TestTransactions(SingleDeviceTestCase):
auction_house.send_as_keyevent(auction_name) auction_house.send_as_keyevent(auction_name)
auction_house.register_name_button.click() auction_house.register_name_button.click()
send_transaction_view = home_view.get_send_transaction_view() send_transaction_view = home_view.get_send_transaction_view()
send_transaction_view.sign_transaction_button.wait_for_element(20) send_transaction_view.sign_transaction(sender['password'])
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()
auction_house.find_full_text('You are the proud owner of the name: ' + auction_name, 120) 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) 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'])

View File

@ -19,69 +19,6 @@ class TestWallet(SingleDeviceTestCase):
send_transaction.amount_edit_box.send_keys('0,1') send_transaction.amount_edit_box.send_keys('0,1')
send_transaction.find_full_text('Insufficient funds') 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 @pytest.mark.wallet
def test_eth_and_currency_balance(self): def test_eth_and_currency_balance(self):
errors = list() errors = list()

View File

@ -67,6 +67,7 @@ class BaseElement(object):
def is_element_present(self, sec=5): def is_element_present(self, sec=5):
try: try:
info('Wait for %s' % self.name)
self.wait_for_element(sec) self.wait_for_element(sec)
return True return True
except TimeoutException: except TimeoutException:
@ -120,3 +121,15 @@ class BaseButton(BaseElement):
self.find_element().click() self.find_element().click()
info('Tap on %s' % self.name) info('Tap on %s' % self.name)
return self.navigate() 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

View File

@ -81,6 +81,11 @@ class WalletButton(BaseButton):
super(WalletButton, self).__init__(driver) super(WalletButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Wallet']/..") 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): def navigate(self):
from views.wallet_view import WalletView from views.wallet_view import WalletView
return WalletView(self.driver) return WalletView(self.driver)
@ -135,8 +140,7 @@ class BaseView(object):
self.driver = driver self.driver = driver
self.home_button = HomeButton(self.driver) self.home_button = HomeButton(self.driver)
self.button = WalletButton(self.driver) self.wallet_button = WalletButton(self.driver)
self.wallet_button = self.button
self.profile_button = ProfileButton(self.driver) self.profile_button = ProfileButton(self.driver)
self.yes_button = YesButton(self.driver) self.yes_button = YesButton(self.driver)
@ -194,7 +198,7 @@ class BaseView(object):
element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]') element.locator = element.Locator.xpath_selector('//*[contains(@text, "' + text + '")]')
return element.wait_for_element(wait_time) 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) info("Looking for an element by text: '%s'" % text)
element = self.element_types[element_type](self.driver) element = self.element_types[element_type](self.driver)
element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]') element.locator = element.Locator.xpath_selector('//*[@text="' + text + '"]')
@ -222,6 +226,10 @@ class BaseView(object):
from views.send_transaction_view import SendTransactionView from views.send_transaction_view import SendTransactionView
return SendTransactionView(self.driver) 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): def get_unique_amount(self):
return '0.0%s' % datetime.now().strftime('%-m%-d%-H%-M%-S').strip('0') return '0.0%s' % datetime.now().strftime('%-m%-d%-H%-M%-S').strip('0')

View File

@ -1,4 +1,4 @@
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException, NoSuchElementException
from tests import info from tests import info
from views.base_element import BaseButton, BaseEditBox, BaseText from views.base_element import BaseButton, BaseEditBox, BaseText
from views.base_view import BaseView from views.base_view import BaseView
@ -34,11 +34,21 @@ class UserNameText(BaseText):
'//..//android.widget.TextView)[1]') '//..//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): class SendCommand(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(SendCommand, self).__init__(driver) super(SendCommand, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='/send']") 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): class RequestCommand(BaseButton):
def __init__(self, driver): def __init__(self, driver):
@ -98,6 +108,18 @@ class MoreUsersButton(BaseButton):
self.locator = self.Locator.xpath_selector("//android.widget.TextView[contains(@text, 'MORE')]") 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): class ChatView(BaseView):
def __init__(self, driver): def __init__(self, driver):
super(ChatView, self).__init__(driver) super(ChatView, self).__init__(driver)
@ -120,6 +142,10 @@ class ChatView(BaseView):
self.first_recipient_button = FirstRecipient(self.driver) 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): def wait_for_syncing_complete(self):
info('Waiting for syncing complete:') info('Waiting for syncing complete:')
while True: while True:
@ -131,3 +157,10 @@ class ChatView(BaseView):
def get_messages_sent_by_user(self, username): def get_messages_sent_by_user(self, username):
return MessageByUsername(self.driver, username).find_elements() 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)

View File

@ -73,4 +73,4 @@ class ConsoleView(BaseView):
recovered_user.click() recovered_user.click()
recover_access_view.password_input.send_keys(password) recover_access_view.password_input.send_keys(password)
recover_access_view.sign_in_button.click() recover_access_view.sign_in_button.click()
recover_access_view.find_full_text('Wallet', 30) recover_access_view.find_full_text('Wallet', 60)

View File

@ -1,7 +1,7 @@
from tests import info from tests import info
import time import time
from selenium.common.exceptions import TimeoutException from selenium.common.exceptions import TimeoutException, NoSuchElementException
from views.base_element import BaseButton from views.base_element import BaseButton, BaseText
from views.base_view import BaseView from views.base_view import BaseView
@ -12,8 +12,8 @@ class PlusButton(BaseButton):
"//android.view.ViewGroup/android.widget.TextView[@text='+']") "//android.view.ViewGroup/android.widget.TextView[@text='+']")
def navigate(self): def navigate(self):
from views.start_new_chat_view import StarNewChatView from views.start_new_chat_view import StartNewChatView
return StarNewChatView(self.driver) return StartNewChatView(self.driver)
class ConsoleButton(BaseButton): class ConsoleButton(BaseButton):
@ -33,12 +33,19 @@ class ChatElement(BaseButton):
return ChatView(self.driver) 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): class HomeView(BaseView):
def __init__(self, driver): def __init__(self, driver):
super(HomeView, self).__init__(driver) super(HomeView, self).__init__(driver)
self.plus_button = PlusButton(self.driver) self.plus_button = PlusButton(self.driver)
self.console_button = ConsoleButton(self.driver) self.console_button = ConsoleButton(self.driver)
self.first_chat_element_title = FirstChatElementTitle(self.driver)
def wait_for_syncing_complete(self): def wait_for_syncing_complete(self):
info('Waiting for syncing complete:') info('Waiting for syncing complete:')
@ -52,6 +59,16 @@ class HomeView(BaseView):
def get_chat_with_user(self, username): def get_chat_with_user(self, username):
return ChatElement(self.driver, 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): def add_contact(self, public_key):
start_new_chat = self.plus_button.click() start_new_chat = self.plus_button.click()
start_new_chat.add_new_contact.click() start_new_chat.add_new_contact.click()

View File

@ -1,4 +1,5 @@
import time import time
import pytest
from tests import info from tests import info
from views.base_element import BaseText, BaseButton, BaseEditBox from views.base_element import BaseText, BaseButton, BaseEditBox
from views.base_view import BaseView from views.base_view import BaseView
@ -8,7 +9,7 @@ class PublicKeyText(BaseText):
def __init__(self, driver): def __init__(self, driver):
super(PublicKeyText, self).__init__(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 @property
def text(self): def text(self):
@ -54,7 +55,7 @@ class NetworkSettingsButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
super(NetworkSettingsButton, self).__init__(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): class NetworkButton(BaseButton):
def __init__(self, driver, network): def __init__(self, driver, network):

View File

@ -59,6 +59,10 @@ class ChooseRecipientButton(BaseButton):
super(ChooseRecipientButton, self).__init__(driver) super(ChooseRecipientButton, self).__init__(driver)
self.locator = self.Locator.xpath_selector("//*[@text='Specify recipient...']") 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): class EnterContactCodeButton(BaseButton):
def __init__(self, driver): def __init__(self, driver):
@ -72,6 +76,24 @@ class EnterRecipientAddressInput(BaseEditBox):
self.locator = self.Locator.xpath_selector("//*[@text='Enter recipient address']") 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): class SendTransactionView(BaseView):
def __init__(self, driver): def __init__(self, driver):
super(SendTransactionView, self).__init__(driver) super(SendTransactionView, self).__init__(driver)
@ -80,6 +102,7 @@ class SendTransactionView(BaseView):
self.enter_contact_code_button = EnterContactCodeButton(self.driver) self.enter_contact_code_button = EnterContactCodeButton(self.driver)
self.enter_recipient_address_input = EnterRecipientAddressInput(self.driver) self.enter_recipient_address_input = EnterRecipientAddressInput(self.driver)
self.first_recipient_button = FirstRecipient(self.driver) self.first_recipient_button = FirstRecipient(self.driver)
self.recent_recipients_button = RecentRecipientsButton(self.driver)
self.amount_edit_box = AmountEditBox(self.driver) self.amount_edit_box = AmountEditBox(self.driver)
self.sign_transaction_button = SignTransactionButton(self.driver) self.sign_transaction_button = SignTransactionButton(self.driver)
@ -89,11 +112,11 @@ class SendTransactionView(BaseView):
self.enter_password_input = EnterPasswordInput(self.driver) self.enter_password_input = EnterPasswordInput(self.driver)
self.got_it_button = GotItButton(self.driver) self.got_it_button = GotItButton(self.driver)
def try_to_sing_transaction(self): self.select_asset_button = SelectAssetButton(self.driver)
for _ in range(4): self.stt_button = STTButton(self.driver)
try:
self.sign_transaction_button.click() def sign_transaction(self, sender_password):
self.enter_password_input.wait_for_element(5) self.sign_transaction_button.click_until_presence_of_element(self.enter_password_input)
return self.enter_password_input.send_keys(sender_password)
except (NoSuchElementException, TimeoutException): self.sign_transaction_button.click_until_presence_of_element(self.got_it_button)
pass self.got_it_button.click()

View File

@ -38,9 +38,15 @@ class OpenButton(BaseButton):
"//android.widget.TextView[@text='Open']") "//android.widget.TextView[@text='Open']")
class StarNewChatView(ContactsView): class EnterUrlEditbox(BaseEditBox):
def __init__(self, driver): 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.add_new_contact = AddNewContactButton(self.driver)
self.new_group_chat_button = NewGroupChatButton(self.driver) self.new_group_chat_button = NewGroupChatButton(self.driver)
@ -49,3 +55,4 @@ class StarNewChatView(ContactsView):
self.open_button = OpenButton(self.driver) self.open_button = OpenButton(self.driver)
self.name_edit_box = NameEditBox(self.driver) self.name_edit_box = NameEditBox(self.driver)
self.enter_url_editbox = EnterUrlEditbox(self.driver)

View File

@ -68,6 +68,36 @@ class UsdTotalValueText(BaseText):
self.locator = self.Locator.xpath_selector("//*[@text='USD']/../android.widget.TextView[1]") 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): class WalletView(BaseView):
def __init__(self, driver): def __init__(self, driver):
super(WalletView, self).__init__(driver) super(WalletView, self).__init__(driver)
@ -77,9 +107,15 @@ class WalletView(BaseView):
self.transactions_button = TransactionsButton(self.driver) self.transactions_button = TransactionsButton(self.driver)
self.eth_asset = EthAssetText(self.driver) self.eth_asset = EthAssetText(self.driver)
self.usd_total_value = UsdTotalValueText(self.driver) self.usd_total_value = UsdTotalValueText(self.driver)
self.send_transaction_request = SendTransactionRequestButton(self.driver)
self.request_button = RequestButton(self.driver) self.request_button = RequestButton(self.driver)
self.send_request_button = SendRequestButton(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): def get_usd_total_value(self):
return float(self.usd_total_value.text) return float(self.usd_total_value.text)

View File

@ -9,6 +9,19 @@ class ProgressBarIcon(BaseElement):
self.locator = self.Locator.xpath_selector("//android.widget.ProgressBar") 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): class BaseWebView(BaseView):
def __init__(self, driver): def __init__(self, driver):
@ -17,6 +30,9 @@ class BaseWebView(BaseView):
self.progress_bar_icon = ProgressBarIcon(self.driver) 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): def wait_for_d_aap_to_load(self, wait_time=35):
counter = 0 counter = 0
while self.progress_bar_icon.is_element_present(5): while self.progress_bar_icon.is_element_present(5):

View File

@ -64,7 +64,7 @@
(defn test-fixtures [] (defn test-fixtures []
(rf/reg-fx ::events/init-store #()) (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/save-contact #())
(rf/reg-fx ::contacts-events/watch-contact #()) (rf/reg-fx ::contacts-events/watch-contact #())
(rf/reg-fx ::contacts-events/stop-watching-contact #()) (rf/reg-fx ::contacts-events/stop-watching-contact #())