on boarding tests

This commit is contained in:
Roman Volosovskyi 2016-07-18 16:22:32 +03:00
parent 1307e25de6
commit a0912230d4
21 changed files with 327 additions and 137 deletions

21
env/dev/env/android_test/main.cljs vendored Normal file
View File

@ -0,0 +1,21 @@
(ns ^:figwheel-no-load env.android-test.main
(:require [reagent.core :as r]
[status-im.android.core :as core]
[figwheel.client :as figwheel :include-macros true]
[status-im.test.handlers-stubs :refer [init-stubs]]))
(enable-console-print!)
(set! js/console.disableYellowBox true)
(def cnt (r/atom 0))
(defn reloader [] @cnt [core/app-root])
(def root-el (r/as-element [reloader]))
(figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws"
:heads-up-display false
:jsload-callback #(swap! cnt inc))
(core/init :test)
(init-stubs)

View File

@ -164,11 +164,17 @@ function loadApp(platform, devHost, onLoadCb) {
// callback when app is ready to get the reloadable component
var mainJs = '/env/' + platform + '/main.js';
var mainTestJs = '/env/' + platform + '_test/main.js';
evalListeners.push(function (url) {
if (url.indexOf(mainJs) > -1) {
onLoadCb(env[platform].main.root_el);
console.log('Done loading Clojure app');
}
if (url.indexOf(mainTestJs) > -1) {
onLoadCb(env[platform + "_test"].main.root_el);
console.log('Done loading Clojure app');
}
});
if (typeof goog === "undefined") {
@ -287,4 +293,4 @@ self = {
start: startApp
};
module.exports = self;
module.exports = self;

View File

@ -27,24 +27,30 @@
[io.appium/java-client "3.4.1"]]
:plugins [[lein-doo "0.1.6"]]
:source-paths ["src" "env/dev"]
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/ios/not-used.js"
:main "env.ios.main"
:output-dir "target/ios"
:optimizations :none}}
:android {:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/android/not-used.js"
:main "env.android.main"
:output-dir "target/android"
:optimizations :none}}
:test {:source-paths ["src" "test/cljs"]
:compiler
{:main status-im.test.runner
:output-to "target/test/test.js"
:optimizations :none
:target :nodejs}}}}
:cljsbuild {:builds {:ios {:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/ios/not-used.js"
:main "env.ios.main"
:output-dir "target/ios"
:optimizations :none}}
:android {:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/android/not-used.js"
:main "env.android.main"
:output-dir "target/android"
:optimizations :none}}
:android-test {:source-paths ["src" "env/dev"]
:figwheel true
:compiler {:output-to "target/android/not-used.js"
:main "env.android-test.main"
:output-dir "target/android"
:optimizations :none}}
:test {:source-paths ["src" "test/cljs"]
:compiler
{:main status-im.test.runner
:output-to "target/test/test.js"
:optimizations :none
:target :nodejs}}}}
:repl-options {:nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}}
:prod {:cljsbuild {:builds {:ios {:source-paths ["src" "env/prod"]
:compiler {:output-to "index.ios.js"

View File

@ -136,7 +136,7 @@ function phoneSuggestions(params) {
return {markup: view};
}
status.response({
var phoneConfig = {
name: "phone",
description: "Send phone number",
color: "#5fc48d",
@ -158,7 +158,9 @@ status.response({
params: [params.value]
};
}
});
};
status.response(phoneConfig);
status.command(phoneConfig);
status.command({
name: "help",
@ -193,6 +195,16 @@ status.response({
event: "confirm-sign-up",
params: [params.value]
};
},
validator: function(params){
if(!/^[\d]{4}$/.test(params.value)){
var error = status.components.validationMessage(
"Confirmation code",
"Wrong format"
);
return {errors: [error]}
}
}
});

View File

@ -56,7 +56,7 @@ function call(pathStr, paramsStr) {
_status_catalog
);
if(!fn) {
if (!fn) {
return null;
}
@ -94,6 +94,35 @@ function webView(url) {
}];
}
function validationMessage(titleText, descriptionText) {
var titleStyle = {
color: "white",
fontSize: 12,
fontFamily: "sans-serif"
};
var title = status.components.text(titleStyle, titleText);
var descriptionStyle = {
color: "white",
fontSize: 12,
fontFamily: "sans-serif",
opacity: 0.9
};
var description = status.components.text(descriptionStyle, descriptionText);
var message = status.components.view(
{
backgroundColor: "red",
height: 61,
paddingLeft: 16,
paddingTop: 14,
},
[title, description]
);
return message;
}
var status = {
command: function (h) {
var command = new Command();
@ -118,6 +147,7 @@ var status = {
image: image,
touchable: touchable,
scrollView: scrollView,
webView: webView
webView: webView,
validationMessage: validationMessage
}
};

View File

@ -37,6 +37,13 @@ else
device_type="genymotion"
fi
if [ ! -z $2 ]
then
cljs_build="$2"
else
cljs_build="android"
fi
if [ "$device_type" = "genymotion" ]
then
# Find Device based on Android version 6.0.0
@ -50,7 +57,7 @@ fi
lein voom build-deps && re-natal deps && re-natal use-android-device "${device_type}" && re-natal use-figwheel
# open figwheel in new tab
tab "lein figwheel android"
tab "lein figwheel ${cljs_build}"
# open react-native package in new tab
tab "react-native start"
@ -62,9 +69,9 @@ adb reverse tcp:8081 tcp:8081 && adb reverse tcp:3449 tcp:3449
react-native run-android
if [ ! -z $2 ]
if [ ! -z $3 ]
then
tab "appium"
lein test
lein doo node test once
fi
fi

View File

@ -96,7 +96,7 @@
:login [login]
:my-profile [my-profile])))})))
(defn init []
(defn init [& [env]]
(dispatch-sync [:reset-app])
(dispatch [:initialize-crypt])
(dispatch [:initialize-geth])

View File

@ -18,13 +18,14 @@
[status-im.persistence.realm.core :as r]
[status-im.handlers.server :as server]
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
[status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.phone-number :refer [format-phone-number
valid-mobile-number?]]
[status-im.utils.datetime :as time]
[status-im.components.react :refer [geth]]
[status-im.components.jail :as j]
[status-im.utils.types :refer [json->clj]]
[status-im.commands.utils :refer [generate-hiccup]]
status-im.chat.handlers.commands
[status-im.chat.handlers.commands :refer [command-prefix]]
status-im.chat.handlers.animation
status-im.chat.handlers.requests
status-im.chat.handlers.unviewed-messages))
@ -76,37 +77,28 @@
(when-let [message-input (:message-input db)]
(.blur message-input)))))
(defn update-text
[{:keys [current-chat-id] :as db} [_ text]]
(let [suggestions (get-in db [:command-suggestions current-chat-id])]
(if-not (= 1 (count suggestions))
(update-input-text db text)
(assoc db :disable-input true))))
(defn update-text [db [_ chat-id text]]
(assoc-in db [:chats chat-id :input-text] text))
(defn update-command [db [_ text]]
(if-not (commands/get-chat-command db)
(let [{:keys [command]} (suggestions/check-suggestion db text)]
(if command
(commands/set-chat-command db command)
(commands/set-command-input db :commands command)
db))
db))
(defn check-suggestions
[{:keys [current-chat-id] :as db} [_ text]]
[db [_ chat-id text]]
(let [suggestions (suggestions/get-suggestions db text)]
(assoc-in db [:command-suggestions current-chat-id] suggestions)))
(assoc-in db [:command-suggestions chat-id] suggestions)))
(defn select-suggestion!
[{:keys [current-chat-id] :as db} [_ text]]
(let [suggestions (get-in db [:command-suggestions current-chat-id])]
(when (= 1 (count suggestions))
(dispatch [:set-chat-command (ffirst suggestions)]))))
(register-handler :set-chat-input-text
[(enrich update-command)
(after select-suggestion!)
(after #(dispatch [:animate-command-suggestions]))]
((enrich update-text) check-suggestions))
[db [_ chat-id text]]
(let [suggestions (get-in db [:command-suggestions chat-id])]
(if (= 1 (count suggestions))
(dispatch [:set-chat-command (ffirst suggestions)])
(dispatch [::set-text chat-id text]))))
(defn console? [s]
(= "console" s))
@ -114,6 +106,43 @@
(def not-console?
(complement console?))
(register-handler :set-chat-input-text
(u/side-effect!
(fn [{:keys [current-chat-id]} [_ text]]
(if (console? current-chat-id)
(dispatch [::check-input-for-commands text])
(dispatch [::check-suggestions current-chat-id text])))))
(def possible-commands
{[:confirmation-code :responses] #(re-matches #"^[\d]{4}$" %)
[:phone :commands] valid-mobile-number?})
(defn check-text-for-commands [text]
(ffirst (filter (fn [[_ f]] (f text)) possible-commands)))
(register-handler ::check-input-for-commands
(u/side-effect!
(fn [_ [_ text]]
(if-let [[_ type :as command] (check-text-for-commands text)]
(let [text' (if (= :commands type)
(str command-prefix text)
text)]
(dispatch [::stage-command-with-content command text']))
(dispatch [::check-suggestions "console" text])))))
(register-handler ::stage-command-with-content
(u/side-effect!
(fn [_ [_ [command type] text]]
(dispatch [:set-chat-command command type])
(dispatch [:set-chat-command-content text]))))
(register-handler ::check-suggestions
[(after select-suggestion!)
(after #(dispatch [:animate-command-suggestions]))]
check-suggestions)
(register-handler ::set-text update-text)
(defn check-author-direction
[db chat-id {:keys [from outgoing] :as message}]
(let [previous-message (first (get-in db [:chats chat-id :messages]))]
@ -165,7 +194,7 @@
:outgoing true
:timestamp (time/now-ms)})]
(if command
(commands/set-chat-command db command)
(commands/set-command-input db :commands command)
(assoc db :new-message (when-not (str/blank? text) message)))))
(defn prepare-command
@ -344,7 +373,7 @@
(defn store-message!
[{:keys [new-message]} [_ {chat-id :from}]]
(messages/save-message chat-id new-message))
(messages/save-message chat-id new-message))
(defn dispatch-request!
[{:keys [new-message]} [_ {chat-id :from}]]
@ -448,16 +477,16 @@
(defn delete-messages!
[{:keys [current-chat-id]} _]
(r/write :account
(fn []
(r/delete :account (r/get-by-field :account :msgs :chat-id current-chat-id)))))
(fn []
(r/delete :account (r/get-by-field :account :msgs :chat-id current-chat-id)))))
(defn delete-chat!
[{:keys [current-chat-id]} _]
(r/write :account
(fn [] :account
(->> (r/get-by-field :account :chats :chat-id current-chat-id)
(r/single)
(r/delete :account)))))
(fn [] :account
(->> (r/get-by-field :account :chats :chat-id current-chat-id)
(r/single)
(r/delete :account)))))
(register-handler :leave-group-chat
;; todo oreder of operations tbd

View File

@ -139,9 +139,9 @@
(commands/unstage-command db staged-command)))
(defn set-chat-command
[{:keys [current-chat-id] :as db} [_ command-key]]
[{:keys [current-chat-id] :as db} [_ command-key type]]
(-> db
(commands/set-chat-command command-key)
(commands/set-command-input (or type :commands) command-key)
(assoc-in [:chats current-chat-id :command-input :content] command-prefix)
(assoc :disable-input true)))
@ -153,7 +153,7 @@
(defn set-response-command [db [_ to-msg-id command-key]]
(-> db
(commands/set-response-chat-command to-msg-id command-key)
(commands/set-command-input :responses to-msg-id command-key)
(assoc :canceled-command false)))
(register-handler :set-response-chat-command
@ -163,6 +163,7 @@
set-response-command)
(register-handler ::add-validation-errors
(after #(dispatch [:fix-response-height]))
(fn [db [_ chat-id errors]]
(assoc-in db [:custom-validation-errors chat-id]
(map cu/generate-hiccup errors))))

View File

@ -28,6 +28,37 @@
(s/put kv/kv-store :signed-up signed-up)
(assoc db :signed-up signed-up))
; todo fn name is not too smart, but...
(defn command-content
[command content]
{:command (name command)
:content content})
;; -- Send phone number ----------------------------------------
(defn on-sign-up-response [& [message]]
(let [msg-id (random/id)]
(dispatch [:received-msg
{:msg-id msg-id
:content (command-content
:confirmation-code
(or message (label :t/confirmation-code)))
:content-type content-type-command-request
:outgoing false
:from "console"
:to "me"}])))
(defn handle-sms [{body :body}]
(when-let [matches (re-matches #"(\d{4})" body)]
(dispatch [:sign-up-confirm (second matches)])))
(defn start-listening-confirmation-code-sms [db]
(when (not (:confirmation-code-sms-listener db))
(assoc db :confirmation-code-sms-listener (add-sms-listener handle-sms))))
(defn stop-listening-confirmation-code-sms [db]
(when-let [listener (:confirmation-code-sms-listener db)]
(remove-sms-listener listener)
(dissoc db :confirmation-code-sms-listener)))
;; -- Send confirmation code and synchronize contacts---------------------------
(defn on-sync-contacts []
@ -52,43 +83,15 @@
:outgoing false
:from "console"
:to "me"}])
(when (:confirmed body)
(dispatch [:stop-listening-confirmation-code-sms])
(sync-contacts)
;; TODO should be called after sync-contacts?
(dispatch [:set-signed-up true])))
; todo fn name is not too smart, but...
(defn command-content
[command content]
{:command (name command)
:content content})
;; -- Send phone number ----------------------------------------
(defn on-sign-up-response []
(let [msg-id (random/id)]
(dispatch [:received-msg
{:msg-id msg-id
:content (command-content
:confirmation-code
(label :t/confirmation-code))
:content-type content-type-command-request
:outgoing false
:from "console"
:to "me"}])))
(defn handle-sms [{body :body}]
(when-let [matches (re-matches #"(\d{4})" body)]
(dispatch [:sign-up-confirm (second matches)])))
(defn start-listening-confirmation-code-sms [db]
(when (not (:confirmation-code-sms-listener db))
(assoc db :confirmation-code-sms-listener (add-sms-listener handle-sms))))
(defn stop-listening-confirmation-code-sms [db]
(when-let [listener (:confirmation-code-sms-listener db)]
(remove-sms-listener listener)
(dissoc db :confirmation-code-sms-listener)))
(let [status (keyword (:status body))]
(when (= :confirmed status)
(do
(dispatch [:stop-listening-confirmation-code-sms])
(sync-contacts)
;; TODO should be called after sync-contacts?
(dispatch [:set-signed-up true])))
(when (= :failed status)
(on-sign-up-response (label :t/incorrect-code)))))
;; -- Saving password ----------------------------------------
(defn save-password [password]

View File

@ -76,10 +76,6 @@
(defn set-chat-command [msg-id command]
(dispatch [:set-response-chat-command msg-id (keyword (:name command))]))
(defn label [{:keys [command]}]
(->> (when command (name command))
(str "request-")))
(defn message-view
[message content]
[view (st/message-view message)

View File

@ -15,9 +15,10 @@
(defn set-chat-command [msg-id command]
(dispatch [:set-response-chat-command msg-id (keyword (:name command))]))
(defn label [{:keys [command]}]
(->> (name command)
(str "request-")))
(defn label [command]
(when command
(->> (name (:name command))
(str "request-"))))
(def min-scale 1)
(def max-scale 1.3)
@ -59,7 +60,8 @@
[touchable-highlight
{:on-press (when-not @answered?
#(set-chat-command msg-id command))
:style st/command-request-image-touchable}
:style st/command-request-image-touchable
:accessibility-label (label command)}
[animated-view {:style (st/command-request-image-view command scale-anim-val)}
[image {:source {:uri (:icon command)}
:style st/command-request-image}]]])})))

View File

@ -33,7 +33,8 @@
:alignItems :center
:justifyContent :center}
[image (:image nav-action)]]]
[touchable-highlight {:on-press #(dispatch [:navigate-back])}
[touchable-highlight {:on-press #(dispatch [:navigate-back])
:accessibility-label :navigate-back}
[view {:width 56
:height 56
:alignItems :center

View File

@ -16,4 +16,4 @@
(def response-input-hiding-duration 100)
(def response-suggesstion-resize-duration 100)
(def default-number-of-messages 5)
(def default-number-of-messages 20)

View File

@ -10,7 +10,6 @@
[status-im.utils.crypt :refer [gen-random-bytes]]
[status-im.components.react :refer [geth]]
[status-im.utils.handlers :refer [register-handler] :as u]
[status-im.models.protocol :as protocol]
status-im.chat.handlers
status-im.group-settings.handlers
status-im.navigation.handlers
@ -57,8 +56,7 @@
(register-handler :initialize-db
(fn [_ _]
(realm/reset-account)
(assoc app-db
:user-identity nil)))
(assoc app-db :user-identity nil)))
(register-handler :initialize-account-db
(fn [db _]

View File

@ -4,11 +4,9 @@
(defn get-commands [{:keys [current-chat-id] :as db}]
(or (get-in db [:chats current-chat-id :commands]) {}))
(defn get-command [{:keys [current-chat-id] :as db} command-key]
((or (->> (get-in db [:chats current-chat-id])
((juxt :commands :responses))
(apply merge))
{}) command-key))
(defn get-response-or-command
[type {:keys [current-chat-id] :as db} command-key]
((or (get-in db [:chats current-chat-id type]) {}) command-key))
(defn find-command [commands command-key]
(first (filter #(= command-key (:command %)) commands)))
@ -25,16 +23,15 @@
[{:keys [current-chat-id] :as db}]
(get-in db (db/chat-command-path current-chat-id)))
(defn set-response-chat-command
[{:keys [current-chat-id] :as db} msg-id command-key]
(update-in db [:chats current-chat-id :command-input] merge
{:content nil
:command (get-command db command-key)
:parameter-idx 0
:to-msg-id msg-id}))
(defn set-chat-command [db command-key]
(set-response-chat-command db nil command-key))
(defn set-command-input
([db type command-key]
(set-command-input db type nil command-key))
([{:keys [current-chat-id] :as db} type msg-id command-key]
(update-in db [:chats current-chat-id :command-input] merge
{:content nil
:command (get-response-or-command type db command-key)
:parameter-idx 0
:to-msg-id msg-id})))
(defn get-chat-command-to-msg-id
[{:keys [current-chat-id] :as db}]

View File

@ -10,10 +10,13 @@
r/collection->map))
(defn create-contact [{:keys [name photo-path whisper-identity] :as contact}]
(->> {:name (or name "")
:photo-path (or photo-path (identicon whisper-identity))}
(merge contact)
(r/create :account :contacts)))
(let [contact-from-db (r/get-one-by-field :account :contacts
:whisper-identity whisper-identity)]
(when-not contact-from-db
(->> {:name (or name "")
:photo-path (or photo-path (identicon whisper-identity))}
(merge contact)
(r/create :account :contacts)))))
(defn save-contacts [contacts]
(r/write :account #(mapv create-contact contacts)))

View File

@ -34,6 +34,7 @@
:contacts-syncronized "Your contacts have been synchronized"
:confirmation-code (str "Thanks! We've sent you a text message with a confirmation "
"code. Please provide that code to confirm your phone number")
:incorrect-code (str "Sorry the code was incorrect, please enter again")
:password-saved (str "OK great! Your password has been saved. Just to let you "
"know you can always change it in the Console by the way "
"it's me the Console nice to meet you!")
@ -127,7 +128,7 @@
:address-explication "Maybe here should be some text explaining what an address is and where to look for it"
:enter-valid-address "Please enter a valid address or scan a QR code"
:unknown-address "Unknown address"
;login
:recover-access "Recover access"

View File

@ -51,10 +51,18 @@
(defn xpath-by-text [text]
(str ".//*[@text='" text "']"))
(defn click-by-text [driver text]
(let [elements (->> (xpath-by-text text)
(elements-by-xpath driver))]
(when (pos? (.size elements))
(let [element (.get elements 0)]
(.click element)))))
(defn contains-text [driver text]
(is (= 1 (->> (xpath-by-text text)
(elements-by-xpath driver)
(.size)))))
(is (pos? (->> (xpath-by-text text)
(elements-by-xpath driver)
(.size)))
(format "Text \"%s\" was not found on screen." text)))
(defn quit [driver]
(.quit driver))
@ -81,6 +89,14 @@
(let [sym (gensym)]
`(deftest ~name
(let [~sym (init)]
(click-by-text ~sym "Continue")
~@(for [[f & rest] body]
`(~f ~sym ~@rest))
(quit ~sym)))))
(defmacro defaction
[name parameters & body]
(let [session (gensym)]
`(defn ~name [~@(concat [session] parameters)]
~@(for [[f & rest] body]
`(~f ~session ~@rest)))))

View File

@ -7,9 +7,45 @@
" the exclamation mark or hit the icon to open the command "
"list and choose the !phone command"))
(appium-test console-test
(click :request-keypair-password)
(write :command-input "123")
(click :stage-command)
(defaction send-sommand []
(click :send-message)
(contains-text message-text))
(click :send-message))
(defaction respond-to-request
[request value]
(click (keyword (str "request-" (name request))))
(write :input value)
(send-sommand))
(appium-test happy-case
(click :create-account)
(respond-to-request :keypair "123")
(contains-text message-text)
(respond-to-request :phone "+380671111111")
(respond-to-request :confirmation-code "1234")
(click :navigate-back)
(contains-text "Switch users"))
(appium-test wrong-confirmation-code
(click :create-account)
(respond-to-request :keypair "123")
(respond-to-request :phone "+380671111111")
(respond-to-request :confirmation-code "432")
(contains-text "Wrong format")
(respond-to-request :confirmation-code "4321")
(contains-text "Wrong code!")
(write :input "1234")
(send-sommand)
(click :navigate-back)
(contains-text "Switch users"))
(appium-test wrong-phone-number
(click :create-account)
(respond-to-request :keypair "123")
(respond-to-request :phone "+380671111111")
(write :input "+380671111112")
(send-sommand)
(write :input "1234")
(send-sommand)
(click :navigate-back)
(contains-text "Switch users"))

View File

@ -0,0 +1,25 @@
(ns status-im.test.handlers-stubs
(:require [re-frame.core :refer [subscribe dispatch after]]
[status-im.utils.handlers :refer [register-handler]]
[status-im.utils.handlers :as u]
[status-im.chat.sign-up :as sign-up-service]
status-im.handlers))
(defn init-stubs []
(register-handler :sign-up
(fn []
(println :ohh)
;; todo save phone number to db
(sign-up-service/on-sign-up-response)))
(register-handler :sign-up-confirm
(u/side-effect!
(fn [_ [_ confirmation-code]]
(sign-up-service/on-send-code-response
(if (= "1234" confirmation-code)
{:message "Done!"
:status :confirmed
:confirmed true}
{:message "Wrong code!"
:status :failed
:confirmed false}))))))