Compare commits

..
Author SHA1 Message Date
jo-mut 7e54c6802d blur header height and line category fix 2023-12-28 13:27:14 +01:00
Ulises Manuel 107d1a80c9 Fix token images not being displayed (#18288)
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-12-27 12:43:47 -03:00
Omar Basem 01e8c7e480 Wallet: about tab fixes (#18298)
* wallet: about tab fixes
2023-12-27 19:14:09 +04:00
Siddarth Kumar 0a1152bcc6 chore: bump react-native-webview to 13.6.3 (#18295)
We need to upgrade `react-native-webview` as a pre-requisite for upgrading `react-native` to `0.73.x`
else we face this issue while building iOS : https://github.com/react-native-webview/react-native-webview/issues/3233
2023-12-27 09:13:29 +05:30
Yevheniia Berdnyk 734abc221c e2e: tests fixes 2023-12-27 00:50:01 +02:00
Ajay Sivan bec51b7d0e Add :wallet/accounts-with-customization-color subscription (#18302) 2023-12-26 08:12:20 -08:00
Icaro Motta 0b4a1545ae Fix component tests, upgrade Jest & friends, and a few other goodies (#18276)
Fix all component tests after the latest RN upgrade.

Fixes https://github.com/status-im/status-mobile/issues/18157
Closes https://github.com/status-im/status-mobile/pull/18235

Dependency changes

- Upgraded Jest: from 26.6.3 to latest 29.7.0.
- Upgraded @testing-library/jest-native: from 5.3.0 to latest 5.4.3
- Upgraded @testing-library/react-native: from 11.5.4 to 12.4.2
- Removed explicit dependency on jest-circus, this is now the default test
  runner.
- Removed explicit dependency on jest-environment-node. This is handled by the
  package manager.
- Added jest-silent-reporter at version 0.5.0.

### Why component tests were failing?

Many tests were failing because we were using RN Testing Library (RNTL) in an
unreliable fashion. With the recent library upgrades, the unreliability was
excerbated. Other times, the tests were incorrectly arranging data.

### with-redefs does not work with async code

Generally speaking, with-redefs should not be used with async code, assume the
worst. The scope of the macro will cease to exist by the time the async code
runs. In many tests we were using with-redefs, then calling render, but for some
components that use use-effect, JS timers, animations, etc it's unreliable and
were the reason for failures.

It's easy to reproduce too:

```clojure
(defn foo []
  :foo)

(foo)
;; => :foo

(with-redefs [foo (constantly :bar)]
  (foo))
;; => :bar

(js/setTimeout
 (fn []
   (tap> [:calling-foo (foo)]))
 100)
;; Taps [:calling-foo :foo]
;; As you would expect, when running without with-redefs, it prints :foo.

;; So far so good, but whatch what happens with async code:

(with-redefs [foo (constantly :bar)]
  (js/setTimeout
   (fn []
     (tap> [:calling-foo (foo)]))
   100))
;; Taps [:calling-foo :foo]
;; ====> PROBLEM: Taps :foo, not :bar as one might expect
```

### Not waiting on wait-for

When test-helpers.component/wait-for is used, subsequent assertions/etc should
be done after the promise returned by wait-for is resolved. But remember to not
perform side-effects inside the wait-for callback (check out the docs
https://callstack.github.io/react-native-testing-library/docs/api#waitfor).
Most, if not all of our usages of wait-for were not waiting.

#### Improvement 1 - Silence Jest on demand

If you need to re-run component tests frequently, you may want to reduce the
output verbosity. By passing JEST_USE_SILENT_REPORTER=true to make
component-test or make component-test-watch you will see a lot less noise and be
able to focus on what really matters to you.

#### Improvement 2 - Selectively focus/disable tests

Because of our need to first compile CLJS to JS before running tests via Jest,
we couldn't easily skip or focus on specific tests. From this commit onwards, we
should never again have to change the list of requires in files core_spec.cljs.
Commenting out required namespaces gives a bad DX because it causes constant
rebasing issues.

#### Improvement 3 - Translations now work as in prod code (but only English)

Translations performed by *-by-translation-text can be done now without any
workaround under the hood. The query functions are now linted just like
i18n/label, which means static translation keywords must be qualified with :t/,
which is good for consistency.
2023-12-26 11:58:23 -03:00
Siddarth Kumar 46c5f42fad chore: add form-data package for DIWAI uploads (#18299) 2023-12-26 16:08:46 +05:30
Yevheniia Berdnyk 5d21b1f5ae e2e: fix for getting public key 2023-12-24 01:47:16 +02:00
Siddarth Kumar 49c6a44824 chore: update status-go version (#18253) 2023-12-23 10:08:49 +05:30
flexsurfer 31acb8e9c4 improve profile screen performance (#18281) 2023-12-22 16:59:12 +01:00
Jamie CapraniandPaul Fitzgerald eda8c0ccb0 fix(quo): truncation on wallet account card long name (#18259)
---------

Co-authored-by: Paul Fitzgerald <paulfitz99@gmail.com>
2023-12-22 15:48:57 +00:00
64 changed files with 1391 additions and 2559 deletions
+7 -1
View File
@@ -1,2 +1,8 @@
{:hooks {:analyze-call {utils.i18n/label utils.i18n/label}}
{:hooks
{:analyze-call
{utils.i18n/label utils.i18n/label
test-helpers.component/get-all-by-translation-text utils.i18n/label
test-helpers.component/get-by-translation-text utils.i18n/label
test-helpers.component/query-all-by-translation-text utils.i18n/label
test-helpers.component/query-by-translation-text utils.i18n/label}}
:linters {:status-im.linter/invalid-translation-keyword {:level :error}}}
+5 -1
View File
@@ -18,13 +18,17 @@
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
:respect-bl
;; hang multiline left-hand-thing
;; hang multiline left-hand-thing
;; https://github.com/kkinnear/zprint/issues/273
:multi-lhs-hang]
:fn-map
{"reg-sub" :arg1-pair
"h/describe" :arg1-body
"h/describe-skip" :arg1-body
"h/describe-only" :arg1-body
"h/test" :arg1-body
"h/test-skip" :arg1-body
"h/test-only" :arg1-body
"global.describe" :arg1-body
"global.test" :arg1-body
"list-comp" :binding
+3 -1
View File
@@ -327,7 +327,7 @@ lint-fix: ##@test Run code style checks and fix issues
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
clojure-lsp --ns-exclude-regex ".*/src/status_im/core\.cljs$$" clean-ns && \
clojure-lsp --ns-exclude-regex ".*/src/status_im/core\.cljs|.*/src/test_helpers/component_tests_preload\.cljs$$" clean-ns && \
sh scripts/lint/trailing-newline.sh --fix && \
node_modules/.bin/prettier --write .
@@ -364,6 +364,7 @@ android-test:
component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
component-test-watch: export BABEL_ENV := test
component-test-watch: export JEST_USE_SILENT_REPORTER := false
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
@@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
@@ -373,6 +374,7 @@ component-test-watch: ##@ Watch tests and re-run no changes to cljs files
component-test: export TARGET := clojure
component-test: export COMPONENT_TEST := true
component-test: export BABEL_ENV := test
component-test: export JEST_USE_SILENT_REPORTER := false
component-test: ##@test Run component tests once in NodeJS
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
+2 -2
View File
@@ -340,7 +340,7 @@ PODS:
- React
- react-native-transparent-video (0.1.0):
- React-Core
- react-native-webview (13.3.1):
- react-native-webview (13.6.3):
- React-Core
- React-NativeModulesApple (0.72.5):
- React-callinvoker
@@ -838,7 +838,7 @@ SPEC CHECKSUMS:
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
react-native-status-keycard: f1c1227b2d5984c10fb44db68e4bfd2937f31e98
react-native-transparent-video: e484ad11ace8e5f62516e2c5e15efd3cb4df24b0
react-native-webview: c2b70afb1d910cdd8810375aecc6c2894e2ba061
react-native-webview: 88293a0f23eca8465c0433c023ec632930e644d0
React-NativeModulesApple: c6529c637f2e886aab44c48d66cabef2d4fd1138
React-perflogger: cd8886513f68e1c135a1e79d20575c6489641597
React-RCTActionSheet: 726d2615ca62a77ce3e2c13d87f65379cdc73498
+1 -9
View File
@@ -12,8 +12,7 @@ stdenv.mkDerivation {
"patchBuildIdPhase"
"patchKeyChainPhase"
"patchGlogPhase"
"patchJestPhase"
"installPhase"
"installPhase"
];
# First symlink all modules as is
@@ -56,13 +55,6 @@ stdenv.mkDerivation {
'-Wl,--build-id=none'
'';
# Remove when we upgrade jest to 29
patchJestPhase = ''
substituteInPlace ./node_modules/react-native/jest/setup.js --replace \
'jest.now()' \
'Date.now'
'';
installPhase = ''
mkdir -p $out
cp -R node_modules $out/
+6 -6
View File
@@ -26,6 +26,7 @@
"create-react-class": "^15.6.2",
"emojilib": "^2.4.0",
"eth-phishing-detect": "^1.2.0",
"form-data": "^4.0.0",
"functional-red-black-tree": "^1.0.1",
"i18n-js": "^3.3.0",
"jsc-android": "^250231.0.0",
@@ -66,7 +67,7 @@
"react-native-svg": "13.10.0",
"react-native-touch-id": "^4.4.1",
"react-native-transparent-video": "git+https://github.com/status-im/react-native-transparent-video.git#refs/tags/0.1.1",
"react-native-webview": "13.3.1",
"react-native-webview": "13.6.3",
"react-syntax-highlighter": "^15.5.0",
"rn-emoji-keyboard": "0.7.0",
"tdigest": "^0.1.1"
@@ -81,18 +82,17 @@
"@babel/register": "7.0.0",
"@jest/globals": "^25.1.0",
"@mapbox/node-pre-gyp": "^1.0.9",
"@testing-library/jest-native": "^5.0.0",
"@testing-library/react-native": "^11.2.0",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^12.4.2",
"@tsconfig/react-native": "^3.0.0",
"@types/jest": "^28.1.6",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"babel-jest": "^29.7.0",
"concurrently": "^7.6.0",
"jest": "^26.6.3",
"jest-circus": "^26.0.0",
"jest-environment-node": "^26.6.2",
"jest": "^29.7.0",
"jest-image-snapshot": "^5.1.0",
"jest-silent-reporter": "^0.5.0",
"metro-react-native-babel-preset": "0.76.8",
"nodemon": "^2.0.16",
"nyc": "^14.1.1",
+1 -1
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env sh
if rg --quiet --multiline '^\(ns.*\n^\s*\(:require\n(^\s*(;|#_).*\n)*(^\s*\[status-im\.setup\.i18n-resources\W)' src/status_im/core.cljs; then
if rg --quiet --multiline '^\(ns.*\n^\s*\(:require\n(^\s*(;|#_).*\n)*(^\s*\[status-im\.setup\.i18n-resources\W)' src/status_im/core.cljs src/test_helpers/component_tests_preload.cljs; then
exit 0
elif [ $? -eq 1 ]; then
echo "status-im.setup.i18n-resources must be loaded first (be the first one in ns :require form) in status-im.core"
+5 -3
View File
@@ -150,9 +150,10 @@
:source-map false}}
:component-test {:target :npm-module
:entries [;; We need to tell shadow-cljs to compile
;; the preloads namespace because it will
;; be used directly by Jest in the option
;; setupFilesAfterEnv.
;; the preloads namespaces because they
;; will be used directly by Jest in the
;; option setupFilesAfterEnv.
test-helpers.component-tests-preload
status-im.setup.schema-preload
quo.core-spec
@@ -161,5 +162,6 @@
:output-dir "component-spec"
:closure-defines {schema.core/throw-on-error? true}
:compiler-options {:warnings-as-errors false
:warnings {:fn-deprecated false}
:static-fns false
:infer-externs true}}}}
@@ -63,14 +63,7 @@
:track-icon :face-id})
(h/describe "slide-button"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/setup-fake-timers)
(h/test "render the correct text"
(h/render [slide-button/view default-props])
@@ -17,5 +17,3 @@
(h/fire-event :press (get (h/get-all-by-label-text :color-picker-item) 0))
(-> (h/expect @selected)
(.toStrictEqual :blue)))))
@@ -27,14 +27,18 @@
(let [selected (reagent/atom default-selected)
{window-width :width} (rn/get-window)
ref (atom nil)]
(rn/use-effect #(js/setTimeout (fn []
(.scrollToIndex ^js @ref
#js
{:animated true
:index (.indexOf colors/account-colors
default-selected)
:viewPosition 0.5}))
50))
(rn/use-effect
(fn []
(js/setTimeout
(fn []
(let [index (.indexOf colors/account-colors default-selected)]
(when (and @ref (>= index 0))
(some-> ^js @ref
(.scrollToIndex #js
{:animated true
:index index
:viewPosition 0.5})))))
50)))
[rn/flat-list
{:ref #(reset! ref %)
;; TODO: using :feng-shui? temporarily while b & w is being developed.
@@ -6,34 +6,25 @@
(h/describe "select-profile component"
(h/test "render component"
(h/render [strength-divider/view {:type :okay}])
(-> (h/expect (h/get-by-label-text :strength-divider))
(.toBeTruthy)))
(h/is-truthy (h/get-by-label-text :strength-divider)))
(h/test "render component with :type :very-weak"
(h/render [strength-divider/view {:type :very-weak}])
(-> (h/expect (h/get-by-translation-text :strength-divider-very-weak-label))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/strength-divider-very-weak-label)))
(h/test "render component with :type :weak"
(h/render [strength-divider/view {:type :weak}])
(-> (h/expect (h/get-by-translation-text :strength-divider-weak-label))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/strength-divider-weak-label)))
(h/test "render component with :type :okay"
(h/render [strength-divider/view {:type :okay}])
(-> (h/expect (h/get-by-translation-text :strength-divider-okay-label))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/strength-divider-okay-label)))
(h/test "render component with :type :strong"
(h/render [strength-divider/view {:type :strong}])
(-> (h/expect (h/get-by-translation-text :strength-divider-strong-label))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/strength-divider-strong-label)))
(h/test "render component with :type :very-strong"
(h/render [strength-divider/view {:type :very-strong}])
(-> (h/expect (h/get-by-translation-text :strength-divider-very-strong-label))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/strength-divider-very-strong-label)))
(h/test "render component with :type :alert"
(h/render [strength-divider/view {:type :alert} "Text message"])
(-> (h/expect (h/get-by-text "Text message"))
(.toBeTruthy)))
(h/is-truthy (h/get-by-text "Text message")))
(h/test "render component with :type :info"
(h/render [strength-divider/view {:type :info} "Text Info"])
(-> (h/expect (h/get-by-text "Text Info"))
(.toBeTruthy))))
(h/is-truthy (h/get-by-text "Text Info"))))
@@ -6,14 +6,7 @@
[test-helpers.component :as h]))
(h/describe "drawer-buttons"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/setup-fake-timers)
(h/test "the top heading and subheading render"
(h/render [drawer-buttons/view
@@ -37,7 +30,6 @@
(-> (js/expect (h/get-by-text "bottom-sub-heading"))
(.toBeTruthy)))
(h/test "it clicks the top card"
(let [event (h/mock-fn)]
(with-redefs [safe-area/get-top (fn [] 10)]
@@ -71,7 +71,7 @@
:icon-avatar :i/placeholder
:type :keypair}])
(h/is-truthy (h/get-by-text "Title"))
(-> (h/expect (h/get-by-translation-text :on-device))
(-> (h/expect (h/get-by-translation-text :t/on-device))
(.toBeTruthy)))
(h/test "component renders in keypair type when keycard? is true"
@@ -81,7 +81,7 @@
:icon-avatar :i/placeholder
:type :keypair}])
(h/is-truthy (h/get-by-text "Title"))
(-> (h/expect (h/get-by-translation-text :on-keycard))
(-> (h/expect (h/get-by-translation-text :t/on-keycard))
(.toBeTruthy)))
(h/test "component renders in default-keypair type"
@@ -13,7 +13,10 @@
{:time-frame :empty}])
(h/is-truthy (h/get-by-label-text :illustration)))
(h/test "render 1 week wallet graph"
;; NOTE: Throws error:
;; _reactNative.Animated.timing(widthValue2, {
;; Cannot read properties of undefined (reading 'timing')
(h/test-skip "render 1 week wallet graph"
(h/render [wallet-graph/view
{:time-frame :1-week
:data (data 7)}])
@@ -18,7 +18,9 @@
(with-redefs [clipboard/get-string #(% "")]
(h/render [address-input/address-input {:ens-regex ens-regex}])
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input) :placeholder-text-color colors/neutral-40)))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-40)))
(h/test "on focus with blur? true"
(with-redefs [clipboard/get-string #(% "")]
@@ -38,27 +40,33 @@
{:scanned-value scanned-value
:on-change-text on-change-text
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))
(h/was-called-with on-change-text scanned-value)
(h/has-prop (h/get-by-label-text :address-text-input) :default-value scanned-value))))
(-> (h/wait-for #(h/get-by-label-text :clear-button))
(.then (fn []
(h/was-called-with on-change-text scanned-value)
(h/has-prop (h/get-by-label-text :address-text-input)
:default-value
scanned-value)))))))
(h/test "clear icon is shown when input has text"
(with-redefs [clipboard/get-string #(% "")]
(h/render [address-input/address-input
{:scanned-value "scanned value"
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button-container)))
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))))
(-> (h/wait-for #(h/get-by-label-text :clear-button-container))
(.then #(h/is-truthy (h/get-by-label-text :clear-button))))))
(h/test "on blur with text and blur? false"
(with-redefs [clipboard/get-string #(% "")]
(h/render [address-input/address-input
{:scanned-value "scanned value"
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input) :placeholder-text-color colors/neutral-30)))
(-> (h/wait-for #(h/get-by-label-text :clear-button))
(.then (fn []
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-30))))))
(h/test "on blur with text blur? true"
(with-redefs [clipboard/get-string #(% "")]
@@ -66,19 +74,22 @@
{:scanned-value "scanned value"
:blur? true
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-80-opa-20)))
(-> (h/wait-for #(h/get-by-label-text :clear-button))
(.then (fn []
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-80-opa-20))))))
(h/test "on blur with no text and blur? false"
(with-redefs [clipboard/get-string #(% "")]
(h/render [address-input/address-input {:ens-regex ens-regex}])
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input) :placeholder-text-color colors/neutral-40)))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-40)))
(h/test "on blur with no text blur? true"
(with-redefs [clipboard/get-string #(% "")]
@@ -98,9 +109,10 @@
{:scanned-value "scanned value"
:on-clear on-clear
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))
(h/fire-event :press (h/get-by-label-text :clear-button))
(h/was-called on-clear))))
(-> (h/wait-for #(h/get-by-label-text :clear-button))
(.then (fn []
(h/fire-event :press (h/get-by-label-text :clear-button))
(h/was-called on-clear)))))))
(h/test "on-focus is called"
(let [on-focus (h/mock-fn)]
@@ -122,18 +134,22 @@
(let [on-scan (h/mock-fn)]
(with-redefs [clipboard/get-string #(% "")]
(h/render [address-input/address-input {:on-scan on-scan}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :scan-button)))
(h/fire-event :press (h/get-by-label-text :scan-button))
(h/was-called on-scan))))
(-> (h/wait-for #(h/get-by-label-text :scan-button))
(.then (fn []
(h/fire-event :press (h/get-by-label-text :scan-button))
(h/was-called on-scan)))))))
(h/test "paste from clipboard"
(let [clipboard "clipboard"]
(with-redefs [clipboard/get-string #(% clipboard)]
(h/render [address-input/address-input {:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :paste-button)))
(h/is-truthy (h/query-by-label-text :paste-button))
(h/fire-event :press (h/get-by-label-text :paste-button))
(h/wait-for #(h/is-truthy (h/get-by-label-text :clear-button)))
(h/has-prop (h/get-by-label-text :address-text-input) :default-value clipboard))))
(-> (h/wait-for #(h/get-by-label-text :clear-button))
(.then (fn []
(h/has-prop (h/get-by-label-text :address-text-input)
:default-value
clipboard)))))))
(h/test "ENS loading state and call on-detect-ens"
(let [clipboard "test.eth"
@@ -142,11 +158,12 @@
(h/render [address-input/address-input
{:on-detect-ens on-detect-ens
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :paste-button)))
(h/is-truthy (h/query-by-label-text :paste-button))
(h/fire-event :press (h/get-by-label-text :paste-button))
(h/wait-for #(h/is-falsy (h/get-by-label-text :clear-button)))
(h/wait-for #(h/is-truthy (h/get-by-label-text :loading-button-container)))
(h/was-called on-detect-ens))))
(-> (h/wait-for #(h/is-falsy (h/query-by-label-text :clear-button)))
(.then (fn []
(h/wait-for #(h/get-by-label-text :loading-button-container))))
(.then #(h/was-called on-detect-ens))))))
(h/test "ENS valid state and call on-detect-ens"
(let [clipboard "test.eth"
@@ -156,11 +173,12 @@
{:on-detect-ens on-detect-ens
:valid-ens-or-address? true
:ens-regex ens-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :paste-button)))
(h/is-truthy (h/query-by-label-text :paste-button))
(h/fire-event :press (h/get-by-label-text :paste-button))
(h/wait-for #(h/is-falsy (h/get-by-label-text :clear-button)))
(h/wait-for #(h/is-truthy (h/get-by-label-text :positive-button-container)))
(h/was-called on-detect-ens))))
(-> (h/wait-for #(h/is-falsy (h/query-by-label-text :clear-button)))
(.then (fn []
(h/wait-for #(h/get-by-label-text :positive-button-container))))
(.then #(h/was-called on-detect-ens))))))
(h/test "address loading state and call on-detect-address"
(let [clipboard "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
@@ -169,21 +187,24 @@
(h/render [address-input/address-input
{:on-detect-address on-detect-address
:address-regex address-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :paste-button)))
(h/is-truthy (h/query-by-label-text :paste-button))
(h/fire-event :press (h/get-by-label-text :paste-button))
(h/wait-for #(h/is-falsy (h/get-by-label-text :clear-button)))
(h/wait-for #(h/is-truthy (h/get-by-label-text :loading-button-container)))
(h/was-called on-detect-address))))
(-> (h/wait-for #(h/is-falsy (h/query-by-label-text :clear-button)))
(.then (fn []
(h/wait-for #(h/get-by-label-text :loading-button-container))))
(.then #(h/was-called on-detect-address))))))
(h/test "address valid state and call on-detect-address"
(let [clipboard "0x2f88d65f3cb52605a54a833ae118fb1363acccd2"
on-detect-address (h/mock-fn)]
(with-redefs [clipboard/get-string #(% clipboard)]
(h/render [address-input/address-input
{:on-detect-address on-detect-address
:address-regex address-regex}])
(h/wait-for #(h/is-truthy (h/get-by-label-text :paste-button)))
{:on-detect-address on-detect-address
:address-regex address-regex
:valid-ens-or-address? true}])
(h/is-truthy (h/query-by-label-text :paste-button))
(h/fire-event :press (h/get-by-label-text :paste-button))
(h/wait-for #(h/is-falsy (h/get-by-label-text :clear-button)))
(h/wait-for #(h/is-truthy (h/get-by-label-text :positive-button-container)))
(h/was-called on-detect-address)))))
(-> (h/wait-for #(h/is-falsy (h/query-by-label-text :clear-button)))
(.then (fn []
(h/wait-for #(h/get-by-label-text :positive-button-container))))
(.then #(h/was-called on-detect-address)))))))
@@ -13,16 +13,17 @@
{:value ""
:max-length 24}])
(h/fire-event :on-focus (h/query-by-label-text :profile-title-input))
(h/wait-for #(h/is-truthy (h/query-by-text "00")))
(h/is-truthy (h/query-by-text "/24")))
(-> (h/wait-for #(h/get-by-text "00"))
(.then #(h/is-truthy (h/query-by-text "/24")))))
(h/test "renders with max length digits and character count"
(h/render [title-input/view
{:default-value "abc"
:max-length 24} "abc"])
:max-length 24}
"abc"])
(h/fire-event :on-focus (h/query-by-label-text :profile-title-input))
(h/wait-for #(h/is-truthy (h/query-by-text "03")))
(h/is-truthy (h/query-by-text "/24")))
(-> (h/wait-for #(h/get-by-text "03"))
(.then #(h/is-truthy (h/query-by-text "/24")))))
(h/test "text updates on change"
(let [on-change-text (h/mock-fn)]
@@ -6,7 +6,9 @@
(h/describe "keycard component"
(h/test "Render of keycard component when: holder-name prop is not set"
(h/render [keycard/keycard])
(h/is-truthy (h/get-by-translation-text :empty-keycard)))
(h/is-truthy (h/get-by-translation-text :t/empty-keycard)))
(h/test "Render of keycard component when: holder-name prop is set"
(h/render [keycard/keycard {:holder-name "Alisha"}])
(h/is-truthy (h/get-by-translation-text :user-keycard))))
(let [holder-name "Alisha"]
(h/render [keycard/keycard {:holder-name holder-name}])
(h/is-truthy (h/get-by-translation-text :t/user-keycard {:name holder-name})))))
@@ -47,11 +47,11 @@
(h/render [account/view {:type :tag}])
(h/is-truthy (h/query-by-label-text :tag-container)))
(h/test "renders keycard icon if title-icon? is true"
(h/render [account/view {:title-icon? true}])
(h/test "renders keycard icon if title-icon is present"
(h/render [account/view {:title-icon :i/placeholder}])
(h/is-truthy (h/query-by-label-text :title-icon)))
(h/test "doesn't render keycard icon if title-icon? is false"
(h/test "doesn't render keycard icon if title-icon is missing"
(h/render [account/view])
(h/is-falsy (h/query-by-label-text :title-icon)))
@@ -22,14 +22,14 @@
{:backgroundColor colors/white-opa-5})))
(h/test "on-press-out changes state to :active"
(h/render [address/view])
(h/render [address/view {:active-state? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [address/view {:blur? true}])
(h/render [address/view {:active-state? true :blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
@@ -7,14 +7,7 @@
[utils.datetime :as datetime]))
(h/describe "record audio component"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/setup-fake-timers)
(h/test "renders record-audio"
(h/render [record-audio/record-audio])
@@ -6,14 +6,7 @@
[test-helpers.component :as h]))
(h/describe "soundtrack component"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/setup-fake-timers)
(h/test "renders soundtrack"
(with-redefs [audio/get-player-duration (fn [] 2000)]
@@ -15,10 +15,12 @@
:size :paragraph-2
:style (style/label props)}
label])
[rn/flat-list
{:data data
:style (style/settings-items props)
:render-fn settings-item/view
:separator [rn/view {:style (style/settings-separator props)}]}]])
[rn/view {:style (style/settings-items props)}
(for [item data]
^{:key item}
[:<>
[settings-item/view item]
(when-not (= item (last data))
[rn/view {:style (style/settings-separator props)}])])]])
(def settings-category (quo.theme/with-theme category-internal))
+2 -2
View File
@@ -74,8 +74,8 @@
[rn/view
{:flex-direction :row
:align-items :center}
(for [{:keys [token-icon]} selected-tokens]
^{:key token-icon}
(for [{:keys [token-icon id]} selected-tokens]
^{:key id}
[rn/view {:flex-direction :row}
[rn/view (outer-resource-container size background-color)
[rn/image
@@ -3,12 +3,13 @@
(:require [clojure.string :as string]))
(def ^:private tokens (loader/resolve-tokens))
(def ^:private safe-lower-case (comp string/lower-case str))
(defn- get-token-image*
[token]
(let [token-symbol (cond-> token
(keyword? token) name
:always (comp string/lower-case str))]
:always safe-lower-case)]
(get tokens token-symbol)))
(def get-token-image (memoize get-token-image*))
@@ -126,9 +126,13 @@
[text/text {:style style/emoji} emoji]]
[rn/view {:style style/watch-only-container}
[text/text
{:size :paragraph-2
:weight :medium
:style (style/account-name type theme)}
{:size :paragraph-2
:weight :medium
:number-of-lines 1
:max-width 110
:margin-right 4
:ellipis-mode :tail
:style (style/account-name type theme)}
name]
(when watch-only? [icon/icon :i/reveal {:color colors/neutral-50 :size 12}])
(when missing-keypair?
@@ -10,7 +10,7 @@
:stored :on-keycard
:derivation-path "m / 44 / 60 / 0 / 0 / 2"
:user-name "Test Name"}])
(-> (h/expect (h/get-by-translation-text :origin))
(-> (h/expect (h/get-by-translation-text :t/origin))
(.toBeTruthy)))
(h/test "recovery phrase icon is visible when :type is :recovery-phrase"
@@ -59,7 +59,7 @@
:stored :on-device
:derivation-path "m / 44 / 60 / 0 / 0 / 2"
:user-name "Test Name"}])
(-> (h/expect (h/get-by-translation-text :on-device))
(-> (h/expect (h/get-by-translation-text :t/on-device))
(.toBeTruthy)))
(h/test "on-keycard text is visible when :stored is :on-keycard"
@@ -68,7 +68,7 @@
:stored :on-keycard
:derivation-path "m / 44 / 60 / 0 / 0 / 2"
:user-name "Test Name"}])
(-> (h/expect (h/get-by-translation-text :on-keycard))
(-> (h/expect (h/get-by-translation-text :t/on-keycard))
(.toBeTruthy)))
(h/test "on-press is called when :type is :recovery-phrase"
@@ -9,48 +9,52 @@
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn network-bridge-add
[{:keys [network state theme]}]
[rn/view {:style (merge (style/container network state theme) (style/add-container theme))}
[icon/icon :i/add-circle {:size 12 :no-color true}]])
(defn- network->text
[network]
(cond (not network) ""
(= network :ethereum) "Mainnet"
:else (string/capitalize (name network))))
(defn view-internal
[{:keys [theme network status amount container-style] :as args}]
(let [network-text (if (= network :ethereum) "Mainnet" (string/capitalize (name network)))]
(if (= status :add)
[network-bridge-add args]
[rn/view
{:style (merge (style/container network status theme) container-style)
:accessible true
:accessibility-label :container}
(if (= status :loading)
[rn/view
{:style (style/loading-skeleton theme)
:accessible true
:accessibility-label :loading}]
[rn/view
{:style {:flex-direction :row
:justify-content :space-between}}
[text/text
{:size :paragraph-2
:weight :medium} amount]
(when (= status :locked)
[icon/icon :i/locked
{:size 12
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:accessible true
:accessibility-label :lock}])])
(if (= status :add)
[network-bridge-add args]
[rn/view
{:style (merge (style/container network status theme) container-style)
:accessible true
:accessibility-label :container}
(if (= status :loading)
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[rn/image
{:source (resources/get-network network)
:style style/network-icon}]
{:style (style/loading-skeleton theme)
:accessible true
:accessibility-label :loading}]
[rn/view
{:style {:flex-direction :row
:justify-content :space-between}}
[text/text
{:size :label
:weight :medium
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
network-text]]])))
{:size :paragraph-2
:weight :medium} amount]
(when (= status :locked)
[icon/icon :i/locked
{:size 12
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:accessible true
:accessibility-label :lock}])])
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[rn/image
{:source (resources/get-network network)
:style style/network-icon}]
[text/text
{:size :label
:weight :medium
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(network->text network)]]]))
(def view (quo.theme/with-theme view-internal))
@@ -86,10 +86,10 @@
(defn- dashed-line
[network-name]
[rn/view {:style style/dashed-line}
(take 19
(interleave (repeat [rn/view {:style (style/dashed-line-line network-name)}])
(repeat [rn/view {:style style/dashed-line-space}])))])
(into [rn/view {:style style/dashed-line}]
(take 19
(interleave (repeat [rn/view {:style (style/dashed-line-line network-name)}])
(repeat [rn/view {:style style/dashed-line-space}])))))
(defn f-network-routing-bars
[_]
@@ -180,8 +180,8 @@
:networks networks}]
[tag-internal tag-photo tag-name tag-number theme]
(for [network networks]
^{:key (:network network)}
(let [assoc-props #(get-network networks %)]
^{:key (:network network)}
[view-network (assoc-props (:network network))]))]])
(def view (quo.theme/with-theme view-internal))
+100 -106
View File
@@ -1,107 +1,101 @@
(ns quo.core-spec
(:require ;; [quo.components.list-items.account.component-spec]
;; [quo.components.list-items.address.component-spec]
;; [quo.components.list-items.saved-address.component-spec]
;; [quo.components.list-items.saved-contact-address.component-spec]
;; [quo.components.list-items.saved-contact-address.component-spec]
;; [quo.components.list-items.token-network.component-spec]
[quo.components.avatars.account-avatar.component-spec]
[quo.components.avatars.user-avatar.component-spec]
[quo.components.banners.banner.component-spec]
[quo.components.browser.browser-input.component-spec]
[quo.components.buttons.button.component-spec]
[quo.components.buttons.composer-button.component-spec]
[quo.components.buttons.logout-button.component-spec]
[quo.components.buttons.predictive-keyboard.component-spec]
[quo.components.buttons.slide-button.component-spec]
[quo.components.buttons.wallet-button.component-spec]
[quo.components.buttons.wallet-ctas.component-spec]
[quo.components.calendar.calendar-day.component-spec]
[quo.components.calendar.calendar-year.component-spec]
[quo.components.calendar.calendar.component-spec]
[quo.components.calendar.calendar.month-picker.component-spec]
[quo.components.colors.color-picker.component-spec]
[quo.components.community.community-stat.component-spec]
[quo.components.counter.counter.component-spec]
[quo.components.counter.step.component-spec]
[quo.components.dividers.divider-label.component-spec]
[quo.components.dividers.strength-divider.component-spec]
[quo.components.drawers.action-drawers.component-spec]
[quo.components.drawers.bottom-actions.component-spec]
[quo.components.drawers.documentation-drawers.component-spec]
[quo.components.drawers.drawer-buttons.component-spec]
[quo.components.drawers.drawer-top.component-spec]
[quo.components.drawers.permission-context.component-spec]
[quo.components.dropdowns.dropdown-input.component-spec]
[quo.components.dropdowns.dropdown.component-spec]
[quo.components.dropdowns.network-dropdown.component-spec]
[quo.components.gradient.gradient-cover.component-spec]
[quo.components.graph.wallet-graph.component-spec]
[quo.components.inputs.input.component-spec]
[quo.components.inputs.locked-input.component-spec]
[quo.components.inputs.profile-input.component-spec]
[quo.components.inputs.recovery-phrase.component-spec]
[quo.components.keycard.component-spec]
[quo.components.links.link-preview.component-spec]
[quo.components.links.url-preview-list.component-spec]
[quo.components.links.url-preview.component-spec]
[quo.components.list-items.channel.component-spec]
[quo.components.list-items.community.component-spec]
[quo.components.list-items.dapp.component-spec]
[quo.components.list-items.token-value.component-spec]
[quo.components.loaders.skeleton-list.component-spec]
[quo.components.markdown.list.component-spec]
[quo.components.markdown.text-component-spec]
[quo.components.navigation.top-nav.component-spec]
[quo.components.notifications.notification.component-spec]
[quo.components.numbered-keyboard.keyboard-key.component-spec]
[quo.components.onboarding.small-option-card.component-spec]
[quo.components.password.tips.component-spec]
[quo.components.profile.link-card.component-spec]
[quo.components.profile.select-profile.component-spec]
[quo.components.profile.showcase-nav.component-spec]
[quo.components.record-audio.record-audio.component-spec]
[quo.components.record-audio.soundtrack.component-spec]
[quo.components.selectors.disclaimer.component-spec]
[quo.components.selectors.filter.component-spec]
[quo.components.selectors.reactions-selector.component-spec]
[quo.components.selectors.selectors.component-spec]
[quo.components.settings.category.component-spec]
[quo.components.settings.data-item.component-spec]
[quo.components.settings.reorder-item.component-spec]
[quo.components.settings.settings-item.component-spec]
[quo.components.share.share-qr-code.component-spec]
[quo.components.switchers.base-card.component-spec]
[quo.components.switchers.group-messaging-card.component-spec]
[quo.components.tags.network-tags.component-spec]
[quo.components.tags.status-tags-component-spec]
[quo.components.tags.summary-tag.component-spec]
[quo.components.tags.tiny-tag.component-spec]
[quo.components.text-combinations.channel-name.component-spec]
[quo.components.text-combinations.page-top.component-spec]
[quo.components.text-combinations.username.component-spec]
[quo.components.wallet.account-card.component-spec]
[quo.components.wallet.account-origin.component-spec]
[quo.components.wallet.account-overview.component-spec]
[quo.components.wallet.account-permissions.component-spec]
[quo.components.wallet.confirmation-progress.component-spec]
[quo.components.wallet.keypair.component-spec]
[quo.components.wallet.network-amount.component-spec]
[quo.components.wallet.network-bridge.component-spec]
[quo.components.wallet.network-routing.component-spec]
[quo.components.wallet.progress-bar.component-spec]
[quo.components.wallet.required-tokens.component-spec]
[quo.components.wallet.summary-info.component-spec]
[quo.components.wallet.token-input.component-spec]
[quo.components.wallet.transaction-progress.component-spec]
[quo.components.wallet.transaction-summary.component-spec]
[quo.components.wallet.wallet-activity.component-spec]
[quo.components.wallet.wallet-overview.component-spec]))
;; [quo.components.inputs.address-input.component-spec]
;; [quo.components.inputs.title-input.component-spec]
;; [quo.components.list-items.account.component-spec]
;; [quo.components.list-items.address.component-spec]
;; [quo.components.list-items.saved-address.component-spec]
;; [quo.components.list-items.saved-contact-address.component-spec]
;; [quo.components.list-items.token-network.component-spec]
(:require
quo.components.avatars.account-avatar.component-spec
quo.components.avatars.user-avatar.component-spec
quo.components.banners.banner.component-spec
quo.components.browser.browser-input.component-spec
quo.components.buttons.button.component-spec
quo.components.buttons.composer-button.component-spec
quo.components.buttons.logout-button.component-spec
quo.components.buttons.predictive-keyboard.component-spec
quo.components.buttons.slide-button.component-spec
quo.components.buttons.wallet-button.component-spec
quo.components.buttons.wallet-ctas.component-spec
quo.components.calendar.calendar-day.component-spec
quo.components.calendar.calendar-year.component-spec
quo.components.calendar.calendar.component-spec
quo.components.calendar.calendar.month-picker.component-spec
quo.components.colors.color-picker.component-spec
quo.components.community.community-stat.component-spec
quo.components.counter.counter.component-spec
quo.components.counter.step.component-spec
quo.components.dividers.divider-label.component-spec
quo.components.dividers.strength-divider.component-spec
quo.components.drawers.action-drawers.component-spec
quo.components.drawers.bottom-actions.component-spec
quo.components.drawers.documentation-drawers.component-spec
quo.components.drawers.drawer-buttons.component-spec
quo.components.drawers.drawer-top.component-spec
quo.components.drawers.permission-context.component-spec
quo.components.dropdowns.dropdown-input.component-spec
quo.components.dropdowns.dropdown.component-spec
quo.components.dropdowns.network-dropdown.component-spec
quo.components.gradient.gradient-cover.component-spec
quo.components.graph.wallet-graph.component-spec
quo.components.inputs.address-input.component-spec
quo.components.inputs.input.component-spec
quo.components.inputs.locked-input.component-spec
quo.components.inputs.profile-input.component-spec
quo.components.inputs.recovery-phrase.component-spec
quo.components.inputs.title-input.component-spec
quo.components.keycard.component-spec
quo.components.links.link-preview.component-spec
quo.components.links.url-preview-list.component-spec
quo.components.links.url-preview.component-spec
quo.components.list-items.account.component-spec
quo.components.list-items.address.component-spec
quo.components.list-items.channel.component-spec
quo.components.list-items.community.component-spec
quo.components.list-items.dapp.component-spec
quo.components.list-items.saved-address.component-spec
quo.components.list-items.saved-contact-address.component-spec
quo.components.list-items.token-network.component-spec
quo.components.list-items.token-value.component-spec
quo.components.loaders.skeleton-list.component-spec
quo.components.markdown.list.component-spec
quo.components.markdown.text-component-spec
quo.components.navigation.top-nav.component-spec
quo.components.notifications.notification.component-spec
quo.components.numbered-keyboard.keyboard-key.component-spec
quo.components.onboarding.small-option-card.component-spec
quo.components.password.tips.component-spec
quo.components.profile.link-card.component-spec
quo.components.profile.select-profile.component-spec
quo.components.profile.showcase-nav.component-spec
quo.components.record-audio.record-audio.component-spec
quo.components.record-audio.soundtrack.component-spec
quo.components.selectors.disclaimer.component-spec
quo.components.selectors.filter.component-spec
quo.components.selectors.reactions-selector.component-spec
quo.components.selectors.selectors.component-spec
quo.components.settings.category.component-spec
quo.components.settings.data-item.component-spec
quo.components.settings.reorder-item.component-spec
quo.components.settings.settings-item.component-spec
quo.components.share.share-qr-code.component-spec
quo.components.switchers.base-card.component-spec
quo.components.switchers.group-messaging-card.component-spec
quo.components.tags.network-tags.component-spec
quo.components.tags.status-tags-component-spec
quo.components.tags.summary-tag.component-spec
quo.components.tags.tiny-tag.component-spec
quo.components.text-combinations.channel-name.component-spec
quo.components.text-combinations.page-top.component-spec
quo.components.text-combinations.username.component-spec
quo.components.wallet.account-card.component-spec
quo.components.wallet.account-origin.component-spec
quo.components.wallet.account-overview.component-spec
quo.components.wallet.account-permissions.component-spec
quo.components.wallet.confirmation-progress.component-spec
quo.components.wallet.keypair.component-spec
quo.components.wallet.network-amount.component-spec
quo.components.wallet.network-bridge.component-spec
quo.components.wallet.network-routing.component-spec
quo.components.wallet.progress-bar.component-spec
quo.components.wallet.required-tokens.component-spec
quo.components.wallet.summary-info.component-spec
quo.components.wallet.token-input.component-spec
quo.components.wallet.transaction-progress.component-spec
quo.components.wallet.transaction-summary.component-spec
quo.components.wallet.wallet-activity.component-spec
quo.components.wallet.wallet-overview.component-spec))
+2 -1
View File
@@ -3,6 +3,7 @@
[oops.core :as oops]
[quo.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]
[status-im.common.scroll-page.style :as style]
@@ -59,7 +60,7 @@
[rn/view {:style {:margin-top 0}}
top-nav]
[quo/page-nav
(cond-> {:margin-top 44
(cond-> {:margin-top (if platform/ios? 44 40)
:type :no-title
:background (if (= 1 (reanimated/get-shared-value opacity-animation))
:blur
@@ -1,10 +1,12 @@
(ns status-im.contexts.chat.messages.content.audio.component-spec
(:require
[re-frame.core :as re-frame]
[react-native.audio-toolkit :as audio]
[status-im.contexts.chat.messages.content.audio.view :as audio-message]
[test-helpers.component :as h]))
;; We can't rely on `with-redefs` with async code.
(set! audio/destroy-player #())
(def message
{:audio-duration-ms 5000
:message-id "message-id"})
@@ -12,17 +14,13 @@
(def context
{:in-pinned-view? false})
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(h/describe "audio message"
(h/setup-restorable-re-frame)
(h/before-each
#(setup-subs {:mediaserver/port 1000
:app-state "active"}))
(fn []
(h/setup-subs {:mediaserver/port 1000
:app-state "active"})))
(h/test "renders correctly"
(h/render [audio-message/audio-message message context])
@@ -31,24 +29,19 @@
(h/test "press play calls audio/toggle-playpause-player"
(with-redefs [audio/toggle-playpause-player (js/jest.fn)
audio/new-player (fn [_ _ _] {})
audio/destroy-player #()
audio/prepare-player (fn [_ on-success _] (on-success))
audio-message/download-audio-http (fn [_ on-success] (on-success "audio-uri"))]
(h/render [audio-message/audio-message message context])
(h/fire-event
:on-press
(h/get-by-label-text :play-pause-audio-message-button))
(h/fire-event :on-press (h/get-by-label-text :play-pause-audio-message-button))
(-> (h/expect audio/toggle-playpause-player)
(.toHaveBeenCalledTimes 1))))
(h/test "press play renders error"
(h/render [audio-message/audio-message message context])
(with-redefs [audio/toggle-playpause-player (fn [_ _ _ on-error] (on-error))
audio/new-player (fn [_ _ _] {})
audio/destroy-player #()
(with-redefs [audio/new-player (fn [_ _ _] {})
audio/prepare-player (fn [_ on-success _] (on-success))
audio-message/download-audio-http (fn [_ on-success] (on-success "audio-uri"))]
(h/fire-event
:on-press
(h/get-by-label-text :play-pause-audio-message-button))
(h/wait-for #(h/is-truthy (h/get-by-label-text :audio-error-label))))))
(h/render [audio-message/audio-message message context])
(h/fire-event :on-press (h/get-by-label-text :play-pause-audio-message-button)))
(with-redefs [audio/toggle-playpause-player (fn [_ _ _ on-error] (on-error))]
(h/fire-event :on-press (h/get-by-label-text :play-pause-audio-message-button))
(h/wait-for #(h/get-by-label-text :audio-error-label)))))
@@ -36,10 +36,7 @@
[]
(let [{id :community-id} (rf/sub [:get-screen-params])
{:keys [name color images]} (rf/sub [:communities/community id])
accounts (->> (rf/sub [:wallet])
:accounts
vals
(map #(assoc % :customization-color (:color %))))]
accounts (rf/sub [:wallet/accounts-with-customization-color])]
[rn/view {:style style/container}
[quo/page-nav
{:text-align :left
@@ -24,10 +24,7 @@
[]
(let [{id :community-id} (rf/sub [:get-screen-params])
{:keys [name color images]} (rf/sub [:communities/community id])
accounts (->> (rf/sub [:wallet])
:accounts
vals
(map #(assoc % :customization-color (:color %))))]
accounts (rf/sub [:wallet/accounts-with-customization-color])]
[rn/safe-area-view {:style style/container}
[quo/drawer-top
@@ -42,7 +39,7 @@
[rn/flat-list
{:render-fn account-item
:content-container-style {:padding 20}
:key-fn :key-uid
:key-fn :address
:data accounts}]
[rn/view {:style style/buttons}
@@ -27,10 +27,7 @@
(let [{id :community-id} (rf/sub [:get-screen-params])
{:keys [name images color]} (rf/sub [:communities/community id])
logo-uri (get-in images [:thumbnail :uri])
accounts (->> (rf/sub [:wallet])
:accounts
vals
(map #(assoc % :customization-color (:color %))))]
accounts (rf/sub [:wallet/accounts-with-customization-color])]
[:<>
[quo/drawer-top
{:type :context-tag
@@ -1,189 +1,123 @@
(ns status-im.contexts.communities.actions.community-options.component-spec
(:require
[re-frame.core :as re-frame]
[status-im.contexts.communities.actions.community-options.view :as options]
[test-helpers.component :as h]))
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(h/describe "community options for bottom sheets"
(h/setup-restorable-re-frame)
(h/test "joined options - Non token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mark-as-read))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :leave-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
(h/is-truthy (h/get-by-translation-text :t/leave-community)))
(h/test "joined options - Token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true
:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true
:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-token-gating))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mark-as-read))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :leave-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/view-token-gating))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
(h/is-truthy (h/get-by-translation-text :t/leave-community)))
(h/test "admin options - Non token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:admin true}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:admin true}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mark-as-read))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
(h/test "admin options - Token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:admin true
:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:admin true
:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mark-as-read))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :mute-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :notification-settings))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/mark-as-read))
(h/is-truthy (h/get-by-translation-text :t/mute-community))
(h/is-truthy (h/get-by-translation-text :t/notification-settings))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
(h/test "request sent options - Non token Gated"
(setup-subs {:communities/my-pending-request-to-join "mock-id"
:communities/community {}})
(h/setup-subs {:communities/my-pending-request-to-join "mock-id"
:communities/community {}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :cancel-request-to-join))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
(h/is-truthy (h/get-by-translation-text :t/cancel-request-to-join)))
(h/test "request sent options - Token Gated"
(setup-subs {:communities/my-pending-request-to-join "mock-id"
:communities/community {:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join "mock-id"
:communities/community {:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-token-gating))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :cancel-request-to-join))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/view-token-gating))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community))
(h/is-truthy (h/get-by-translation-text :t/cancel-request-to-join)))
(h/test "banned options - Non token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList true}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList true}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :view-members))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-community-rules))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/view-members))
(h/is-truthy (h/get-by-translation-text :t/view-community-rules))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
(h/test "banned options - Token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList 100
:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList 100
:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-token-gating))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/view-token-gating))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
(h/test "banned options - Token Gated"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList 100
:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:banList 100
:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :invite-people-from-contacts))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :view-token-gating))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :show-qr))
(.toBeTruthy))
(-> (h/expect (h/get-by-translation-text :share-community))
(.toBeTruthy)))
(h/is-truthy (h/get-by-translation-text :t/invite-people-from-contacts))
(h/is-truthy (h/get-by-translation-text :t/view-token-gating))
(h/is-truthy (h/get-by-translation-text :t/show-qr))
(h/is-truthy (h/get-by-translation-text :t/share-community)))
(h/test "joined and muted community"
(setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true
:muted true
:token-permissions []}})
(h/setup-subs {:communities/my-pending-request-to-join nil
:communities/community {:joined true
:muted true
:token-permissions []}})
(h/render [options/community-options-bottom-sheet {:id "test"}])
(-> (h/expect (h/get-by-translation-text :unmute-community))
(.toBeTruthy))))
(h/is-truthy (h/get-by-translation-text :t/unmute-community))))
@@ -1,6 +1,7 @@
(ns status-im.contexts.communities.overview.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]))
(def screen-horizontal-padding 20)
@@ -23,7 +24,7 @@
(def blur-channel-header
{:position :absolute
:top 100
:top (if platform/ios? 100 96)
:height 34
:right 0
:left 0
@@ -16,11 +16,12 @@
(defn- settings-item-view
[data]
[quo/category
{:list-type :settings
:container-style {:padding-bottom 0}
:blur? true
:data data}])
[rf/delay-render
[quo/category
{:list-type :settings
:container-style {:padding-bottom 0}
:blur? true
:data data}]])
(defn scroll-handler
[event scroll-y]
@@ -29,12 +30,13 @@
(defn- footer
[logout-press]
[rn/view {:style style/footer-container}
[quo/logout-button {:on-press logout-press}]])
[rf/delay-render
[rn/view {:style style/footer-container}
[quo/logout-button {:on-press logout-press}]]])
(defn- get-item-layout
[_ index]
#js {:length 48 :offset (* 48 index) :index index})
#js {:length 100 :offset (* 100 index) :index index})
(defn- settings-view
[theme]
@@ -60,12 +62,9 @@
{:key :list
:header [settings.header/view {:scroll-y scroll-y}]
:data settings.items/items
:key-fn :title
:get-item-layout get-item-layout
:initial-num-to-render 6
:max-to-render-per-batch 6
:shows-vertical-scroll-indicator false
:render-fn settings-item-view
:get-item-layout get-item-layout
:footer [footer logout-press]
:scroll-event-throttle 16
:on-scroll #(scroll-handler % scroll-y)
@@ -1,6 +1,7 @@
(ns status-im.contexts.wallet.account.tabs.about.view
(:require
[quo.core :as quo]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.share :as share]
@@ -28,7 +29,12 @@
:right-icon :i/external}
{:icon :i/copy
:accessibility-label :copy-address
:label (i18n/label :t/copy-address)}
:label (i18n/label :t/copy-address)
:on-press (fn []
(clipboard/set-string address)
(rf/dispatch [:toasts/upsert
{:type :positive
:text (i18n/label :t/address-copied)}]))}
{:icon :i/qr-code
:accessibility-label :show-address-qr
:label (i18n/label :t/show-address-qr)}
@@ -56,7 +62,9 @@
(let [{:keys [customization-color] :as profile} (rf/sub [:profile/profile-with-image])
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
networks (rf/sub [:wallet/network-details])]
[rn/view {:style style/about-tab}
[rn/scroll-view
{:style style/about-tab
:content-container-style {:padding-bottom 20}}
[quo/data-item
{:description :default
:icon-right? true
@@ -1,38 +1,30 @@
(ns status-im.contexts.wallet.add-address-to-watch.component-spec
(:require
[re-frame.core :as re-frame]
[status-im.contexts.wallet.add-address-to-watch.view :as add-address-to-watch]
status-im.contexts.wallet.events
[test-helpers.component :as h]))
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(h/describe "select address for watch only account"
(h/setup-restorable-re-frame)
(h/before-each
(fn []
(h/setup-subs {:wallet/scanned-address nil
:wallet/addresses #{"0x12E838Ae1f769147b12956485dc56e57138f3AC8"
"0x22E838Ae1f769147b12956485dc56e57138f3AC8"}
:wallet/watch-address-activity-state nil
:profile/customization-color :blue})))
(h/test "validation messages show for already used addressed"
(setup-subs {:wallet/scanned-address nil
:wallet/addresses #{"0x12E838Ae1f769147b12956485dc56e57138f3AC8"
"0x22E838Ae1f769147b12956485dc56e57138f3AC8"}
:wallet/watch-address-activity-state nil
:profile/customization-color :blue})
(h/render [add-address-to-watch/view])
(h/is-falsy (h/query-by-label-text :error-message))
(h/fire-event :change-text
(h/get-by-label-text :add-address-to-watch)
"0x12E838Ae1f769147b12956485dc56e57138f3AC8")
(h/is-truthy (h/get-by-translation-text :address-already-in-use))))
(h/test "validation messages show for invalid address"
(setup-subs {:wallet/scanned-address nil
:wallet/addresses #{"0x12E838Ae1f769147b12956485dc56e57138f3AC8"
"0x22E838Ae1f769147b12956485dc56e57138f3AC8"}
:wallet/watch-address-activity-state nil
:profile/customization-color :blue})
(h/render [add-address-to-watch/view])
(h/is-falsy (h/query-by-label-text :error-message))
(h/fire-event :change-text (h/get-by-label-text :add-address-to-watch) "0x12E838Ae1f769147b")
(h/is-truthy (h/get-by-translation-text :invalid-address)))
(h/is-truthy (h/get-by-translation-text :t/address-already-in-use)))
(h/test "validation messages show for invalid address"
(h/render [add-address-to-watch/view])
(h/is-falsy (h/query-by-label-text :error-message))
(h/fire-event :change-text (h/get-by-label-text :add-address-to-watch) "0x12E838Ae1f769147b")
(h/is-truthy (h/get-by-translation-text :t/invalid-address))))
@@ -1,23 +1,17 @@
(ns status-im.contexts.wallet.add-address-to-watch.confirm-address.component-spec
(:require
[re-frame.core :as re-frame]
[status-im.contexts.wallet.add-address-to-watch.confirm-address.view :as confirm-address]
[test-helpers.component :as h]
[utils.re-frame :as rf]))
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(h/describe "Add Watch Only Account Page"
(h/setup-restorable-re-frame)
(h/test "Create Account button is disabled while no account name exists"
(let [callback (h/mock-fn)]
(with-redefs [rf/dispatch #(callback)]
(setup-subs {:profile/wallet-accounts []
:get-screen-params {:address "0xmock-address"}})
(h/setup-subs {:profile/wallet-accounts []
:get-screen-params {:address "0xmock-address"}})
(h/render [confirm-address/view {}])
(h/is-truthy (h/get-by-text "0xmock-address"))
(h/was-not-called callback)
@@ -48,7 +48,6 @@
(rf/reg-event-fx :wallet/send-select-amount
(fn [{:keys [db]} [{:keys [amount]}]]
(js/alert "Not implemented yet")
{:db (assoc-in db [:wallet :ui :send :amount] amount)}))
(rf/reg-event-fx :wallet/get-suggested-routes
@@ -1,15 +1,14 @@
(ns status-im.contexts.wallet.send.input-amount.component-spec
(:require
[re-frame.core :as re-frame]
status-im.contexts.wallet.events
status-im.contexts.wallet.send.events
[status-im.contexts.wallet.send.input-amount.view :as input-amount]
[test-helpers.component :as h]))
[test-helpers.component :as h]
[utils.debounce :as debounce]
[utils.re-frame :as rf]))
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(set! rf/dispatch #())
(set! debounce/debounce-and-dispatch #())
(def sub-mocks
{:profile/profile {:currency :usd}
@@ -45,74 +44,111 @@
:wallet/wallet-send-route {:route []}})
(h/describe "Send > input amount screen"
(h/setup-restorable-re-frame)
(h/test "Default render"
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view {}])
(h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH"))
(h/is-truthy (h/get-by-text "$0.00"))
(h/is-disabled (h/get-by-label-text :button-one))))
(h/setup-subs sub-mocks)
(h/render [input-amount/view {}])
(h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH"))
(h/is-truthy (h/get-by-text "$0.00"))
(h/is-disabled (h/get-by-label-text :button-one)))
(h/test "Fill token input and confirm"
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:on-confirm on-confirm
:rate 10
:limit 1000}])
(h/setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:on-confirm on-confirm
:rate 10
:limit 1000}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/is-truthy (h/get-by-text "$1234.50")))
(-> (h/wait-for #(h/get-by-text "$1234.50"))
(.then (fn []
(h/is-truthy (h/get-by-label-text :button-one))
(h/fire-event :press (h/get-by-label-text :button-one))
(h/was-called on-confirm))))))
(h/is-truthy (h/get-by-label-text :button-one))
(h/test "Fill token input and confirm"
(h/setup-subs sub-mocks)
(h/fire-event :press (h/get-by-label-text :button-one))
(h/was-called on-confirm))))
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:rate 10
:limit 1000
:on-confirm on-confirm}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(-> (h/wait-for #(h/get-by-text "$1234.50"))
(.then (fn []
(h/is-truthy (h/get-by-label-text :button-one))
(h/fire-event :press (h/get-by-label-text :button-one))
(h/was-called on-confirm))))))
(h/test "Try to fill more than limit"
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286}])
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/is-truthy (h/get-by-text "$290.00")))
(-> (h/wait-for #(h/is-truthy (h/get-by-text "$290.00")))
(.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "$2850.00"))))))
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/is-truthy (h/get-by-text "$2850.00")))))
(h/test "Try to fill more than limit"
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286
:on-confirm #()}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(-> (h/wait-for #(h/get-by-text "$290.00"))
(.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "$2850.00"))))))
(h/test "Switch from crypto to fiat and check limit"
(with-redefs [re-frame/dispatch #()]
(setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 250}])
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 250
:on-confirm #()}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-0))
(h/wait-for #(h/is-truthy (h/get-by-text "$200.00")))
(h/fire-event :press (h/query-by-label-text :reorder))
(h/wait-for #(h/is-truthy (h/get-by-text "2.00 ETH")))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH"))))))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-0))
(-> (h/wait-for #(h/get-by-text "$200.00"))
(.then (fn []
(h/fire-event :press (h/query-by-label-text :reorder))
(h/wait-for #(h/get-by-text "2.00 ETH"))))
(.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "205.50 ETH"))))
(.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "205.50 ETH")))))))
+3 -4
View File
@@ -4,7 +4,6 @@
[status-im.contexts.chat.messages.content.audio.component-spec]
[status-im.contexts.communities.actions.community-options.component-spec]
[status-im.contexts.wallet.add-address-to-watch.component-spec]
[status-im.contexts.wallet.add-address-to-watch.confirm-address.component-spec]))
;; [status-im.contexts.wallet.create-account.edit-derivation-path.component-spec]
;; [status-im.contexts.wallet.send.input-amount.component-spec]
[status-im.contexts.wallet.add-address-to-watch.confirm-address.component-spec]
[status-im.contexts.wallet.create-account.edit-derivation-path.component-spec]
[status-im.contexts.wallet.send.input-amount.component-spec]))
+1 -1
View File
@@ -97,7 +97,7 @@
(malli.instrument/unstrument!)
(malli.dev/start! {:report (schema/reporter)})
(println "Schemas initialized.")
(log/debug "Schemas initialized.")
;; It is relatively easy to write invalid schemas, but we don't want to
;; block the app from initializing if such errors happen, at least not until
+8
View File
@@ -198,3 +198,11 @@
(fn [[current-viewing-account network-details]]
(let [network-preferences-names (:network-preferences-names current-viewing-account)]
(filter #(contains? network-preferences-names (:network-name %)) network-details))))
(rf/reg-sub
:wallet/accounts-with-customization-color
:<- [:wallet/accounts]
(fn [accounts]
(map (fn [{:keys [color] :as account}]
(assoc account :customization-color color))
accounts)))
+28
View File
@@ -10,12 +10,40 @@
;; warning: "Describe callback must not return a value".
js/undefined)))
(defmacro describe-skip
[description & body]
`(js/global.describe.skip
~description
(fn []
~@body
js/undefined)))
(defmacro describe-only
[description & body]
`(js/global.describe.only
~description
(fn []
~@body
js/undefined)))
(defmacro test
[description & body]
`(js/global.test
~description
(fn [] ~@body)))
(defmacro test-skip
[description & body]
`(js/global.test.skip
~description
(fn [] ~@body)))
(defmacro test-only
[description & body]
`(js/global.test.only
~description
(fn [] ~@body)))
(defmacro before-each
[description & body]
`(js/beforeEach
+62 -20
View File
@@ -5,6 +5,7 @@
[camel-snake-kebab.core :as camel-snake-kebab]
[oops.core :as oops]
[quo.theme :as quo.theme]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]))
@@ -124,37 +125,49 @@
(def query-all-by-test-id (with-node-or-screen :query-all-by-test-id))
(def query-by-test-id (with-node-or-screen :query-by-test-id))
(defn- prepare-translation
[translation]
(if (exists? js/jest)
;; Translations are treated differently when running with Jest. See
;; test/jest/jestSetup.js for more details.
(str "tx:" (name translation))
(i18n/label translation)))
(defn get-all-by-translation-text
([translation]
(get-all-by-translation-text rtl/screen translation))
([^js node translation & args]
(apply (with-node-or-screen :get-all-by-text) node (prepare-translation translation) args)))
(get-all-by-translation-text rtl/screen translation nil))
([translation translation-opts]
(get-all-by-translation-text rtl/screen translation translation-opts))
([^js node translation translation-opts & args]
(apply (with-node-or-screen :get-all-by-text)
node
(i18n/label translation translation-opts)
args)))
(defn get-by-translation-text
([translation]
(get-by-translation-text rtl/screen translation))
([^js node translation & args]
(apply (with-node-or-screen :get-by-text) node (prepare-translation translation) args)))
(get-by-translation-text rtl/screen translation nil))
([translation translation-opts]
(get-by-translation-text rtl/screen translation translation-opts))
([^js node translation translation-opts & args]
(apply (with-node-or-screen :get-by-text)
node
(i18n/label translation translation-opts)
args)))
(defn query-by-translation-text
([translation]
(query-by-translation-text rtl/screen translation))
([^js node translation & args]
(apply (with-node-or-screen :query-by-text) node (prepare-translation translation) args)))
(query-by-translation-text rtl/screen translation nil))
([translation translation-opts]
(query-by-translation-text rtl/screen translation translation-opts))
([^js node translation translation-opts & args]
(apply (with-node-or-screen :query-by-text)
node
(i18n/label translation translation-opts)
args)))
(defn query-all-by-translation-text
([translation]
(query-all-by-translation-text rtl/screen translation))
([^js node translation & args]
(apply (with-node-or-screen :query-all-by-text) node (prepare-translation translation) args)))
(query-all-by-translation-text rtl/screen translation nil))
([translation translation-opts]
(query-all-by-translation-text rtl/screen translation translation-opts))
([^js node translation translation-opts & args]
(apply (with-node-or-screen :query-all-by-text)
node
(i18n/label translation translation-opts)
args)))
;;; Jest utilities
@@ -251,3 +264,32 @@
(let [rerender-fn (oops/oget component "rerender")
react-element (reagent/as-element component-updated)]
(rerender-fn react-element))))
(defn setup-subs
"Registers `subscriptions`, a map of key (sub ID) to value (sub computation)."
[subscriptions]
(doseq [[sub-id v] subscriptions]
(re-frame/reg-sub sub-id
(fn [_] v))))
(defn setup-restorable-re-frame
[]
(let [restorer (atom nil)]
(js/beforeEach
(fn []
(reset! restorer (re-frame/make-restore-fn))))
(js/afterEach
(fn []
(@restorer)))))
(defn setup-fake-timers
[]
(js/beforeEach
(fn []
(use-fake-timers)))
(js/afterEach
(fn []
(clear-all-timers)
(use-real-timers))))
@@ -0,0 +1,22 @@
(ns test-helpers.component-tests-preload
{:dev/always true}
(:require
;; NOTE: Do NOT sort i18n-resources because it MUST be loaded first.
[status-im.setup.i18n-resources :as i18n-resources]
#_{:clj-kondo/ignore [:unsorted-required-namespaces]}
[status-im.setup.interceptors :as interceptors]
[utils.i18n :as i18n]))
(defn- setup
"Prerequisites to run some component tests, for example, the ones in
`status-im.contexts.wallet.send.input-amount.component-spec`.
Because of the way Jest and ShadowCLJS are set up, this is a preload file that
should never be directly required. However, it will be loaded automatically
before any component test runs."
[]
(interceptors/register-global-interceptors)
(i18n/set-language "en")
(i18n-resources/load-language "en"))
(setup)
+9
View File
@@ -3,6 +3,7 @@
(:require
[re-frame.core :as re-frame]
[re-frame.interceptor :as interceptor]
[reagent.core :as reagent]
[taoensso.timbre :as log]
[utils.datetime :as datetime])
(:refer-clojure :exclude [merge reduce]))
@@ -76,6 +77,14 @@
(swap! handler-nesting-level dec)
res))
(defn delay-render
[content]
(let [render? (reagent/atom false)]
(js/setTimeout #(reset! render? true) 0)
(fn []
(when @render?
content))))
(def sub (comp deref re-frame/subscribe))
(def dispatch re-frame/dispatch)
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.171.37",
"commit-sha1": "1adcf02f867effe39199e383d80681f47db9cef8",
"src-sha256": "1mhz0rgd3r6jvgy78ljwq2vjha5rnp5dqhh3ggbp8hpww7nqv4v3"
"version": "v0.171.39",
"commit-sha1": "debfe1cab368140b16d2383efc68007d3c28a4ef",
"src-sha256": "0cbj3796qz69ylwcvdw5jsl1cdyrcfk81d7shjkakvjh59rv5sjk"
}
@@ -92,8 +92,6 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
@marks.testrail_id(702851)
def test_activity_center_contact_request_accept_swipe_mark_all_as_read(self):
self.device_2.just_fyi('Creating a new user on Device2')
# self.home_2.navigate_back_to_home_view()
# self.home_2.profile_button.click()
self.home_2.reopen_app(sign_in=False)
new_username = "new user"
self.device_2.create_user(username=new_username, first_user=False)
@@ -153,10 +151,22 @@ class TestActivityCenterContactRequestMultipleDevicePR(MultipleSharedDeviceTestC
self.username_2, self.profile_link_2, decoded_username))
public_key_2 = self.profile_link_2.split("#")[-1]
self.home_1.just_fyi("Device 1 creates a new user")
self.profile_1.driver.reset()
new_username_1 = "test user 123"
self.device_1.create_user(username=new_username_1)
def _device_1_creates_user():
self.home_1.just_fyi("Device 1 creates a new user")
self.profile_1.driver.reset()
self.device_1.create_user(username=new_username_1)
def _device_2_sign_in():
self.home_2.just_fyi("Device 2 sign in, user name is " + self.username_2)
self.home_2.reopen_app(sign_in=False)
self.device_2.show_profiles_button.wait_and_click()
self.device_2.get_user(username=self.username_2).click()
self.device_2.sign_in()
self.loop.run_until_complete(run_in_parallel(((_device_1_creates_user, {}),
(_device_2_sign_in, {}))))
self.device_1.just_fyi('Device1 sends a contact request to Device2 using his profile link')
self.home_1.chats_tab.click()
+8 -8
View File
@@ -415,12 +415,12 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
session_id = driver.session_id
try:
sauce.jobs.update_job(username=sauce_username, job_id=session_id, name=cls.__name__)
except (RemoteDisconnected, SauceException, requests.exceptions.ConnectionError) as e:
raise e
except (RemoteDisconnected, SauceException, requests.exceptions.ConnectionError):
pass
try:
driver.quit()
except WebDriverException as e:
raise e
except WebDriverException:
pass
url = 'https://api.%s/rest/v1/%s/jobs/%s/assets/%s' % (apibase, sauce_username, session_id, "log.json")
try:
WebDriverWait(driver, 60, 2).until(lambda _: requests_session.get(url).status_code == 200)
@@ -433,10 +433,10 @@ class SauceSharedMultipleDeviceTestCase(AbstractTestCase):
test.testruns[-1].first_commands[session_id] = commands.index(command) + 1
except KeyError:
continue
except (RemoteDisconnected, requests.exceptions.ConnectionError, TimeoutException) as e:
raise e
except AttributeError as e:
raise e
except (RemoteDisconnected, requests.exceptions.ConnectionError, TimeoutException):
pass
except AttributeError:
pass
finally:
try:
cls.loop.close()
@@ -282,7 +282,7 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
messages = ['hello', '¿Cómo estás tu año?', 'ё, доброго вечерочка', '® æ ç ♥']
for message in messages:
self.chat_2.send_message(message)
if not self.chat_1.chat_element_by_text(message).is_element_displayed(10):
if not self.chat_1.chat_element_by_text(message).is_element_displayed(30):
self.errors.append("Message with text '%s' was not received" % message)
self.chat_2.just_fyi("Checking updated member photo, timestamp and username on message")
@@ -348,9 +348,9 @@ class TestOneToOneChatMultipleSharedDevicesNewUi(MultipleSharedDeviceTestCase):
chat_2.send_message(emoji.emojize(emoji_message))
self.device_1.just_fyi("Device 1 checks PN with emoji")
if not self.device_1.element_by_text_part(emoji_unicode).is_element_displayed(60):
if not self.device_1.element_by_text_part(emoji_unicode).is_element_displayed(120):
self.device_1.click_system_back_button()
self.device_2.driver.activate_app(app_package)
self.device_1.driver.activate_app(app_package)
self.device_1.driver.fail("Push notification with emoji was not received")
chat_1 = self.device_1.click_upon_push_notification_by_text(emoji_unicode)
@@ -285,7 +285,7 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
'username': self.username_1}),
(self.device_2.create_user, {'username': self.username_2}))))
self.homes = self.home_1, self.home_2 = self.device_1.get_home_view(), self.device_2.get_home_view()
self.public_key_2 = self.home_2.get_public_key_via_share_profile_tab()
self.public_key_2 = self.home_2.get_public_key()
self.profile_1 = self.home_1.get_profile_view()
[home.navigate_back_to_home_view() for home in self.homes]
[home.chats_tab.click() for home in self.homes]
@@ -682,6 +682,8 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
profile_1 = self.home_1.get_profile_view()
self.home_1.navigate_back_to_home_view()
self.chat_1.profile_button.click()
profile_1.logout_button.scroll_to_element()
profile_1.profile_legacy_button.click()
profile_1.contacts_button.wait_and_click()
profile_1.blocked_users_button.wait_and_click()
profile_1.element_by_text(self.username_2).click()
@@ -773,8 +775,8 @@ class TestCommunityMultipleDeviceMerged(MultipleSharedDeviceTestCase):
self.community_1.get_channel(self.channel_name).click()
self.channel_1.just_fyi("Receiver is checking if initial messages were delivered")
for message in message_to_edit, message_to_delete:
if not self.channel_2.chat_element_by_text(message).is_element_displayed(30):
self.channel_2.driver.fail("Message '%s' was not received")
if not self.channel_1.chat_element_by_text(message).is_element_displayed(30):
self.channel_1.driver.fail("Message '%s' was not received")
self.channel_2.just_fyi("Turning on airplane mode and editing/deleting messages")
self.channel_2.driver.set_network_connection(ConnectionType.AIRPLANE_MODE)
-15
View File
@@ -675,21 +675,6 @@ class BaseView(object):
TouchAction(self.driver).tap(None, 255, 104, 1).perform()
time.sleep(3)
def get_public_key(self):
self.driver.info("Get public key via Share QR button")
self.show_qr_button.click_until_presence_of_element(self.link_to_profile_button)
self.link_to_profile_button.click()
public_key = self.driver.get_clipboard_text()
# Legacy profile view
# profile_view = self.get_profile_view()
# self.profile_button.click_until_presence_of_element(profile_view.default_username_text)
# profile_view.share_my_profile_button.click()
# profile_view.public_key_text.wait_for_visibility_of_element(20)
# public_key = profile_view.public_key_text.text
self.click_system_back_button()
return public_key
def tap_mutual_cr_switcher(self):
profile_view = self.profile_button.click()
profile_view.advanced_button.scroll_and_click()
+1 -1
View File
@@ -1083,7 +1083,7 @@ class ChatView(BaseView):
self.driver.info("Adding one more '%s' reaction or removing an added one" % emoji)
key = emojis[emoji]
element = Button(self.driver, accessibility_id='emoji-reaction-%s' % key)
element.click()
element.wait_and_click()
def view_profile_long_press(self, message=str):
self.chat_element_by_text(message).long_press_element()
+2 -2
View File
@@ -1,7 +1,7 @@
seed = 'staff actress trash route grab crime leaf uniform dizzy reform issue keep'
display_name = 'End to end'
communities = {
'admin_open': 'Open-comm-adm',
'admin_open': 'open community',
'member_open': 'e2e_open',
'admin_closed': 'closed community',
'member_closed': 'test_comm_enc',
@@ -10,5 +10,5 @@ communities = {
# contacts = ['Test_contact', 'MyCustomNickname'] # enable back when https://github.com/status-im/status-mobile/issues/15500 is fixed
contacts = ['zQ3...pJN5P', 'zQ3...UxXqE']
contacts = ['zQ3...dWXh5', 'zQ3...Vacac']
blocked_user = 'Clear Flat Milkweedbug'
+2 -4
View File
@@ -323,9 +323,7 @@ class HomeView(BaseView):
self.mark_all_read_activity_button = Button(self.driver, translation_id="mark-all-notifications-as-read")
# Share tab
self.link_to_profile_text = Text(
self.driver,
xpath="(//*[@content-desc='link-to-profile']/preceding-sibling::*[1]/android.widget.TextView)[1]")
self.link_to_profile_text = Text(self.driver, accessibility_id="share-qr-code-info-text")
self.close_share_tab_button = Button(self.driver, accessibility_id="close-shell-share-tab")
# Discover communities
@@ -568,7 +566,7 @@ class HomeView(BaseView):
self.link_to_profile_text.click()
return self.driver.get_clipboard_text()
def get_public_key_via_share_profile_tab(self):
def get_public_key(self):
self.driver.info("Getting public key via Share tab")
link_to_profile = self.get_link_to_profile()
self.click_system_back_button()
+5 -14
View File
@@ -285,20 +285,11 @@ class SignInView(BaseView):
self.driver.info("## Multiaccount is recovered successfully!", device=False)
return self.get_home_view()
def sign_in(self, password=common_password, keycard=False, position=1):
self.driver.info("## Sign in (password:%s, keycard:%s)" % (password, str(keycard)), device=False)
if keycard:
from views.keycard_view import KeycardView
keycard_view = KeycardView(self.driver)
keycard_view.one_button.wait_for_visibility_of_element(10)
keycard_view.enter_default_pin()
if keycard_view.connect_selected_card_button.is_element_displayed():
keycard_view.connect_selected_card_button.click()
else:
self.password_input.wait_for_visibility_of_element(10)
self.password_input.send_keys(password)
self.login_button.click()
def sign_in(self, password=common_password):
self.driver.info("## Sign in (password: %s)" % password, device=False)
self.password_input.wait_for_visibility_of_element(10)
self.password_input.send_keys(password)
self.login_button.click()
self.driver.info("## Signed in successfully!", device=False)
return self.get_home_view()
+50 -4
View File
@@ -1,10 +1,51 @@
const transformIgnorePatterns = () => {
const libs = [
'@react-native',
'@react-native-community',
'@react-native-community/blur',
'react-native',
'react-native-background-timer',
'react-native-gifted-charts',
'react-native-haptic-feedback',
'react-native-hole-view',
'react-native-image-crop-picker',
'react-native-languages',
'react-native-linear-gradient',
'react-native-permissions',
'react-native-reanimated',
'react-native-redash',
'react-native-redash',
'react-native-shake',
'react-native-static-safe-area-insets',
'rn-emoji-keyboard',
].join('|');
return [`/node_modules/(?!(${libs})/).*/`];
};
const shouldUseSilentReporter = () => {
return process.env.JEST_USE_SILENT_REPORTER === 'true';
};
const reporters = () => {
let reporters = [];
if (shouldUseSilentReporter()) {
reporters.push(['jest-silent-reporter', { useDots: true }]);
} else {
reporters.push('default');
}
return reporters;
};
module.exports = {
preset: 'react-native',
setupFilesAfterEnv: [
'@testing-library/jest-native/extend-expect',
'../component-spec/status_im.setup.schema_preload.js',
'../component-spec/test_helpers.component_tests_preload.js',
'../test/jest/jestSetup.js',
],
reporters: reporters(),
setupFiles: [],
testPathIgnorePatterns: [],
moduleNameMapper: {
@@ -12,14 +53,19 @@ module.exports = {
'<rootDir>/../node_modules/react-native/Libraries/Image/RelativeImageStub',
},
testTimeout: 60000,
transformIgnorePatterns: [
'/node_modules/(?!(@react-native|react-native-haptic-feedback|react-native-redash|react-native-image-crop-picker|@react-native-community|react-native-linear-gradient|react-native-background-timer|react-native|rn-emoji-keyboard|react-native-languages|react-native-shake|react-native-reanimated|react-native-redash|react-native-permissions|@react-native-community/blur|react-native-static-safe-area-insets|react-native-hole-view|react-native-gifted-charts)/).*/',
],
transformIgnorePatterns: transformIgnorePatterns(),
// This is a workaround after upgrading to Jest 29.7.0, otherwise we get:
//
// SyntaxError: node_modules/@react-native/js-polyfills/error-guard.js:
// Missing semicolon. (14:4)
//
transform: {
'^.+\\.(js|jsx|ts|tsx)$': ['babel-jest', { configFile: './babel.config.js' }],
},
globals: {
__TEST__: true,
},
testEnvironment: 'node',
timers: 'fake',
rootDir: '../../component-spec',
testMatch: ['**/*__tests__*', '**/*.component_spec.js'],
};
+4
View File
@@ -7,6 +7,10 @@ require('react-native-reanimated/src/reanimated2/jestUtils').setUpTests();
jest.mock('@react-native-async-storage/async-storage', () => mockAsyncStorage);
jest.mock('react-native-fs', () => ({
default: {},
}));
jest.mock('react-native-navigation', () => ({
getNavigationConstants: () => ({ constants: [] }),
Navigation: {
+602 -1864
View File
File diff suppressed because it is too large Load Diff