test(@wallet): allow to use ganache with goerli

This commit is contained in:
Jonathan Rainville 2022-08-18 13:51:18 -04:00 committed by Anthony Laibe
parent 0225c3e0ae
commit aba2a42c6f
25 changed files with 198 additions and 92 deletions

View File

@ -16,7 +16,6 @@ pipeline {
)
}
options {
timestamps()
/* Prevent Jenkins jobs from running forever */
@ -69,10 +68,21 @@ pipeline {
stage('build') {
steps { sh 'make' }
}
stage('Tests') {
steps {
script {
def goerli_rpc_port = 8577
def mnemonic = "pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial"
def goerli_db_path = "$WORKSPACE/test/ui-test/fixtures/ganache-dbs/goerli"
docker.image('trufflesuite/ganache:v7.4.1').withRun(
"-p 127.0.0.1:8577:8545 -v ${goerli_db_path}:/goerli-db",
"-e 10 -m='${mnemonic}' --chain.chainId 5 --database.dbPath /goerli-db"
) { c ->
sh "docker logs ${c.id}"
withEnv(["GOERLI_NETWORK_RPC_URL=http://0.0.0.0:${goerli_rpc_port}"]){
wrap([
$class: 'Xvfb',
autoDisplayName: true,
@ -104,6 +114,9 @@ pipeline {
}
}
}
}
}
}
post {
success { script { github.notifyPR(true) } }

View File

@ -88,7 +88,10 @@ proc loadTransactions*(self: Controller, address: string, toBlock: Uint256, limi
self.transactionService.loadTransactions(address, toBlock, limit, loadMore)
proc estimateGas*(self: Controller, from_addr: string, to: string, assetSymbol: string, value: string, data: string): string =
try:
result = self.transactionService.estimateGas(from_addr, to, assetSymbol, value, data)
except Exception as e:
result = "0"
proc transfer*(self: Controller, from_addr: string, to_addr: string, tokenSymbol: string,
value: string, gas: string, gasPrice: string, maxPriorityFeePerGas: string,maxFeePerGas: string,

View File

@ -12,6 +12,24 @@ let INFURA_TOKEN_RESOLVED =
else:
INFURA_TOKEN
const GOERLI_NETWORK_RPC_URL = $getEnv("GOERLI_NETWORK_RPC_URL")
let OVERRIDE_TOKENS =
if GOERLI_NETWORK_RPC_URL != "":
@[
{
"symbol": "STT",
"address": "0x8571Ddc46b10d31EF963aF49b6C7799Ea7eff818"
}
]
else:
@[]
let GOERLI_RPC_URL_RESOLVED =
if GOERLI_NETWORK_RPC_URL != "":
GOERLI_NETWORK_RPC_URL
else:
"https://goerli.infura.io/v3/" & INFURA_TOKEN_RESOLVED
const OPENSEA_API_KEY {.strdefine.} = ""
# allow runtime override via environment variable; core contributors can set a
# an opensea API key in this way for local development
@ -76,7 +94,7 @@ let NETWORKS* = %* [
{
"chainId": 5,
"chainName": "Goerli",
"rpcUrl": "https://goerli.infura.io/v3/" & INFURA_TOKEN_RESOLVED,
"rpcUrl": GOERLI_RPC_URL_RESOLVED,
"blockExplorerUrl": "https://goerli.etherscan.io/",
"iconUrl": "network/Network=Testnet",
"chainColor": "#939BA1",
@ -87,6 +105,7 @@ let NETWORKS* = %* [
"isTest": true,
"layer": 1,
"enabled": true,
"overrideTokens": OVERRIDE_TOKENS.toJson
},
{
"chainId": 10,

View File

@ -1,4 +1,3 @@
import httpclient
import json
import strformat
import os
@ -27,7 +26,6 @@ let TENOR_API_KEY_RESOLVED =
type
Service* = ref object of RootObj
settingsService: settings_service.Service
client: HttpClient
favorites: seq[GifDto]
recents: seq[GifDto]
@ -37,7 +35,6 @@ proc delete*(self: Service) =
proc newService*(settingsService: settings_service.Service): Service =
result = Service()
result.settingsService = settingsService
result.client = newHttpClient()
result.favorites = @[]
result.recents = @[]

View File

@ -40,7 +40,7 @@ proc fetchNetworks*(self: Service, useCached: bool = true): seq[NetworkDto] =
if not response.error.isNil:
raise newException(Exception, "Error getting networks: " & response.error.message)
result = if response.result.isNil or response.result.kind == JNull: @[]
else: Json.decode($response.result, seq[NetworkDto])
else: Json.decode($response.result, seq[NetworkDto], allowUnknownFields = true)
self.dirty.store(false)
self.networks = result
self.networksInited = true

View File

@ -95,9 +95,12 @@ QtObject:
return token
proc findTokenBySymbol*(self: Service, network: NetworkDto, symbol: string): TokenDto =
try:
for token in self.tokens[network]:
if token.symbol == symbol:
return token
except Exception as e:
error "Error finding token by symbol", msg = e.msg
proc findTokenByAddress*(self: Service, network: NetworkDto, address: Address): TokenDto =
for token in self.tokens[network]:

Binary file not shown.

View File

@ -0,0 +1 @@
MANIFEST-000033

View File

@ -0,0 +1,11 @@
2022/09/01-13:58:04.283373 7f4480dc2700 Recovering log #31
2022/09/01-13:58:04.283960 7f4480dc2700 Level-0 table #34: started
2022/09/01-13:58:04.290048 7f4480dc2700 Level-0 table #34: 54710 bytes OK
2022/09/01-13:58:04.292067 7f4480dc2700 Delete type=0 #31
2022/09/01-13:58:04.292135 7f4480dc2700 Delete type=3 #29
2022/09/01-13:58:38.612587 7f44727fc700 Compacting 1@0 + 1@1 files
2022/09/01-13:58:38.617019 7f44727fc700 Generated table #36@0: 522 keys, 139431 bytes
2022/09/01-13:58:38.617046 7f44727fc700 Compacted 1@0 + 1@1 files => 139431 bytes
2022/09/01-13:58:38.617833 7f44727fc700 compacted to: files[ 0 1 0 0 0 0 0 ]
2022/09/01-13:58:38.618033 7f44727fc700 Delete type=2 #34
2022/09/01-13:58:38.618127 7f44727fc700 Delete type=2 #32

View File

@ -0,0 +1,11 @@
2022/09/01-13:51:31.804496 7f5542fef700 Recovering log #27
2022/09/01-13:51:31.804725 7f5542fef700 Level-0 table #30: started
2022/09/01-13:51:31.805745 7f5542fef700 Level-0 table #30: 5250 bytes OK
2022/09/01-13:51:31.808021 7f5542fef700 Delete type=3 #25
2022/09/01-13:51:31.808081 7f5542fef700 Delete type=0 #27
2022/09/01-13:51:52.767407 7f5540feb700 Compacting 1@0 + 1@1 files
2022/09/01-13:51:52.770314 7f5540feb700 Generated table #32@0: 454 keys, 101140 bytes
2022/09/01-13:51:52.770340 7f5540feb700 Compacted 1@0 + 1@1 files => 101140 bytes
2022/09/01-13:51:52.771157 7f5540feb700 compacted to: files[ 0 1 0 0 0 0 0 ]
2022/09/01-13:51:52.771310 7f5540feb700 Delete type=2 #30
2022/09/01-13:51:52.771393 7f5540feb700 Delete type=2 #28

View File

@ -1,22 +1,28 @@
from enum import Enum
import time
import os
import sys
from drivers.SquishDriver import *
from drivers.SquishDriverVerification import *
from common.SeedUtils import *
from .StatusMainScreen import StatusMainScreen
class Tokens(Enum):
ETH: str = "ETH"
class SigningPhrasePopUp(Enum):
OK_GOT_IT_BUTTON: str = "signPhrase_Ok_Button"
class MainWalletScreen(Enum):
ADD_ACCOUNT_BUTTON: str = "mainWallet_Add_Account"
ACCOUNT_NAME: str = "mainWallet_Account_Name"
ACCOUNT_ADDRESS_PANEL: str = "mainWallet_Address_Panel"
SEND_BUTTON_FOOTER: str = "mainWallet_Footer_Send_Button"
SAVED_ADDRESSES_BUTTON: str = "mainWallet_Saved_Addresses_Button"
NETWORK_SELECTOR_BUTTON: str = "mainWallet_Network_Selector_Button"
RIGHT_SIDE_TABBAR: str = "mainWallet_Right_Side_Tab_Bar"
MAILSERVER_DIALOG: str = "mailserver_dialog"
MAILSERVER_RETRY: str = "mailserver_retry"
class AssetView(Enum):
LIST: str = "mainWallet_Assets_View_List"
@ -42,6 +48,7 @@ class SendPopup(Enum):
SCROLL_BAR: str = "mainWallet_Send_Popup_Main"
HEADER_ACCOUNTS_LIST: str = "mainWallet_Send_Popup_Header_Accounts"
AMOUNT_INPUT: str = "mainWallet_Send_Popup_Amount_Input"
GAS_PRICE_INPUT: str = "mainWallet_Send_Popup_GasPrice_Input"
MY_ACCOUNTS_TAB: str = "mainWallet_Send_Popup_My_Accounts_Tab"
MY_ACCOUNTS_LIST: str = "mainWallet_Send_Popup_My_Accounts_List"
NETWORKS_LIST: str = "mainWallet_Send_Popup_Networks_List"
@ -49,6 +56,7 @@ class SendPopup(Enum):
PASSWORD_INPUT: str = "mainWallet_Send_Popup_Password_Input"
ASSET_SELECTOR: str = "mainWallet_Send_Popup_Asset_Selector"
ASSET_LIST: str = "mainWallet_Send_Popup_Asset_List"
HIGH_GAS_BUTTON: str = "mainWallet_Send_Popup_GasSelector_HighGas_Button"
class AddAccountPopup(Enum):
SCROLL_BAR: str = "mainWallet_Add_Account_Popup_Main"
@ -129,7 +137,12 @@ class StatusWalletScreen:
input_seed_phrase(AddAccountPopup.SEED_PHRASE_INPUT_TEMPLATE.value, words)
time.sleep(1)
visible, _ = is_loaded_visible_and_enabled(MainWalletScreen.MAILSERVER_DIALOG.value, 500)
if (visible):
click_obj_by_name(MainWalletScreen.MAILSERVER_RETRY.value)
click_obj_by_name(AddAccountPopup.ADD_ACCOUNT_BUTTON.value)
time.sleep(5)
def generate_new_account(self, account_name: str, password: str):
click_obj_by_name(MainWalletScreen.ADD_ACCOUNT_BUTTON.value)
@ -144,17 +157,21 @@ class StatusWalletScreen:
verify_text_matching(MainWalletScreen.ACCOUNT_NAME.value, account_name)
def send_transaction(self, account_name, amount, token, chain_name, password):
# TODO wait for balance to update
# Maybe needs a fix on the app itself. Make the Send modal be responsive to when the balance updates
time.sleep(2)
click_obj_by_name(MainWalletScreen.SEND_BUTTON_FOOTER.value)
self._click_repeater(SendPopup.HEADER_ACCOUNTS_LIST.value, account_name)
time.sleep(1)
type(SendPopup.AMOUNT_INPUT.value, amount)
if token != "ETH":
if token != Tokens.ETH.value:
click_obj_by_name(SendPopup.ASSET_SELECTOR.value)
asset_list = get_obj(SendPopup.ASSET_LIST.value)
for index in range(asset_list.count):
if(asset_list.itemAtIndex(index).objectName == token):
tokenObj = asset_list.itemAtIndex(index)
if(not squish.isNull(tokenObj) and tokenObj.objectName == "AssetSelector_ItemDelegate_" + token):
click_obj(asset_list.itemAtIndex(index))
break
@ -167,14 +184,13 @@ class StatusWalletScreen:
break
scroll_obj_by_name(SendPopup.SCROLL_BAR.value)
time.sleep(2)
scroll_obj_by_name(SendPopup.SCROLL_BAR.value)
time.sleep(2)
scroll_obj_by_name(SendPopup.SCROLL_BAR.value)
time.sleep(2)
time.sleep(1)
self._click_repeater(SendPopup.NETWORKS_LIST.value, chain_name)
# With the simulator, the gas price estimation doesn't work
type(SendPopup.GAS_PRICE_INPUT.value, "20")
click_obj_by_name(SendPopup.SEND_BUTTON.value)
type(SendPopup.PASSWORD_INPUT.value, password)
@ -244,12 +260,15 @@ class StatusWalletScreen:
wait_for_prop_value(item, "titleTextIcon", ("star-icon" if favourite else ""))
def toggle_network(self, network_name: str):
time.sleep(2)
click_obj_by_name(MainWalletScreen.NETWORK_SELECTOR_BUTTON.value)
time.sleep(2)
list = get_obj(NetworkSelectorPopup.LAYER_1_REPEATER.value)
list = wait_and_get_obj(NetworkSelectorPopup.LAYER_1_REPEATER.value)
for index in range(list.count):
if list.itemAt(index).objectName == network_name:
click_obj(list.itemAt(index))
item = list.itemAt(index)
if item.objectName == network_name:
click_obj(item)
click_obj_by_name(MainWalletScreen.ACCOUNT_NAME.value)
time.sleep(2)
return
@ -259,13 +278,24 @@ class StatusWalletScreen:
def verify_positive_balance(self, symbol: str):
list = get_obj(AssetView.LIST.value)
reset = 0
while (reset < 3):
found = False
for index in range(list.count):
tokenListItem = list.itemAtIndex(index)
if tokenListItem.objectName == "AssetView_TokenListItem_" + symbol:
assert tokenListItem.balance != f"0 {symbol}", f"balance is not positive, balance: {balance}"
found = True
if (tokenListItem.balance == "0" and reset < 3):
break
return
assert False, "symbol not found"
if not found:
verify_failure("Symbol " + symbol + " not found in the asset list")
reset += 1
time.sleep(5)
verify_failure("Balance was not positive")
def verify_saved_address_exists(self, name: str):
list = wait_and_get_obj(SavedAddressesScreen.SAVED_ADDRESSES_LIST.value)

View File

@ -17,11 +17,11 @@ from common.Common import *
import time
@Given("the user starts the application with a specific data folder |any|")
def step(context, data):
def step(context, data_folder_path):
waitFor(lambda: currentApplicationContext().detach(), 500)
time.sleep(5)
clear_directory(context.userData["status_data_folder_path"])
copy_directory(data, context.userData["status_data_folder_path"])
copy_directory(data_folder_path, context.userData["status_data_folder_path"])
startApplication(context.userData["aut_name"])
@When("the user restarts the app")

View File

@ -4,12 +4,16 @@ from scripts.global_names import *
navBarListView_Wallet_navbar_StatusNavBarTabButton = {"checkable": True, "container": mainWindow_navBarListView_ListView, "objectName": "Wallet-navbar", "type": "StatusNavBarTabButton", "visible": True}
wallet_navbar_wallet_icon_StatusIcon = {"container": navBarListView_Wallet_navbar_StatusNavBarTabButton, "objectName": "wallet-icon", "type": "StatusIcon", "visible": True}
mainWallet_Account_Name = {"container": statusDesktop_mainWindow, "objectName": "accountName", "type": "StatusBaseText", "visible": True}
mainWallet_Address_Panel = {"container": statusDesktop_mainWindow, "objectName": "addressPanel", "type": "StatusAddressPanel", "visible": True}
mainWallet_Add_Account = {"container": statusDesktop_mainWindow, "text": "Add account", "type": "StatusBaseText", "unnamed": 1, "visible": True}
signPhrase_Ok_Button = {"container": statusDesktop_mainWindow, "type": "StatusFlatButton", "objectName": "signPhraseModalOkButton", "visible": True}
mainWallet_Saved_Addresses_Button = {"container": statusDesktop_mainWindow, "objectName": "savedAddressesBtn", "type": "StatusButton"}
mainWallet_Network_Selector_Button = {"container": statusDesktop_mainWindow, "objectName": "networkSelectorButton", "type": "StatusListItem"}
mainWallet_Right_Side_Tab_Bar = {"container": statusDesktop_mainWindow, "objectName": "rightSideWalletTabBar", "type": "StatusTabBar"}
mailserver_dialog = {"container": statusDesktop_mainWindow_overlay, "objectName": "mailserverConnectionDialog", "type": "StatusDialog"}
mailserver_retry = {"container": mailserver_dialog, "objectName": "mailserverConnectionDialog_retryButton", "type": "StatusButton"}
# Assets view:
mainWallet_Assets_View_List = {"container": statusDesktop_mainWindow, "objectName": "assetViewStatusListView", "type": "StatusListView"}
@ -28,6 +32,10 @@ mainWallet_Send_Popup_Send_Button = {"container": statusDesktop_mainWindow, "obj
mainWallet_Send_Popup_Password_Input = {"container": statusDesktop_mainWindow, "objectName": "transactionSignerPasswordInput", "type": "StyledTextField"}
mainWallet_Send_Popup_Asset_Selector = {"container": statusDesktop_mainWindow, "objectName": "assetSelectorButton", "type": "StatusComboBox"}
mainWallet_Send_Popup_Asset_List = {"container": statusDesktop_mainWindow, "objectName": "assetSelectorList", "type": "StatusListView"}
mainWallet_Send_Popup_GasPrice_Input = {"container": statusDesktop_mainWindow, "objectName": "gasPriceSelectorInput", "type": "StyledTextField"}
mainWallet_Send_Popup_GasSelector_LowGas_Button = {"container": statusDesktop_mainWindow, "objectName": "GasSelector_lowGasButton", "type": "GasSelectorButton"}
mainWallet_Send_Popup_GasSelector_OptimalGas_Button = {"container": statusDesktop_mainWindow, "objectName": "GasSelector_optimalGasButton", "type": "GasSelectorButton"}
mainWallet_Send_Popup_GasSelector_HighGas_Button = {"container": statusDesktop_mainWindow, "objectName": "GasSelector_highGasButton", "type": "GasSelectorButton"}
# Add account popup:
mainWallet_Add_Account_Popup_Main = {"container": statusDesktop_mainWindow, "objectName": "AddAccountModalContent", "type": "StatusScrollView", "visible": True}

View File

@ -2,30 +2,30 @@ Feature: Status Desktop Transaction
As a user I want to perform transaction
Background: Sign up & Enable wallet section & Toggle test networks
Given A first time user lands on the status desktop and navigates to import seed phrase
When The user inputs the seed phrase pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial
And user clicks on the following ui-component seedPhraseView_Submit_Button
When user signs up with username tester123 and password qqqqqqqqqq
Then the user lands on the signed in app
When the user opens app settings screen
When the user activates wallet and opens the wallet settings
When the user toggles test networks
When the user opens wallet screen
When the user accepts the signing phrase
# Background: Sign up & Enable wallet section & Toggle test networks
# Given A first time user lands on the status desktop and navigates to import seed phrase
# When The user inputs the seed phrase pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial
# And user clicks on the following ui-component seedPhraseView_Submit_Button
# When user signs up with username tester123 and password qqqqqqqqqq
# Then the user lands on the signed in app
# When the user opens app settings screen
# And the user activates wallet and opens the wallet settings
# And the user toggles test networks
# And the user opens wallet screen
# And the user accepts the signing phrase
# Scenario Outline: User sends a transaction
# When the user sends a transaction to himself from account Status account of <amount> <token> on <chain_name> with password TesTEr16843/!@00
# Then the transaction is in progress
# Scenario Outline: User sends a transaction
# When the user sends a transaction to himself from account Status account of <amount> <token> on <chain_name> with password qqqqqqqqqq
# Then the transaction is in progress
# Examples:
# | amount | token | chain_name |
# | 0.000001 | ETH | Ropsten |
# | 0 | ETH | Ropsten |
# | 1 | STT | Goerli |
# | 0 | STT | Goerli |
# Examples:
# | amount | token | chain_name |
# | 1 | ETH | Goerli |
# | 0 | ETH | Goerli |
# | 1 | STT | Goerli |
# | 0 | STT | Goerli |
# Scenario: User registers a ENS name
# When the user registers a random ens name with password qqqqqqqqqq
# Then the transaction is in progress
# @mayfail
# Scenario: User registers a ENS name
# When the user registers a random ens name with password qqqqqqqqqq
# Then the transaction is in progress

View File

@ -91,15 +91,15 @@ Feature: Status Desktop Wallet
| name | address |
| favourite | 0x8397bc3c5a60a1883174f722403d63a8833312b7 |
@mayfail
@onlythis
Scenario: User can toggle network and see balances
When the user opens app settings screen
And the user opens the wallet settings
And the user toggles test networks
And the user opens wallet screen
And the user adds watch only account with one and 0x5fFa75CE51c3a7ebE23BdE37b5E3A0143DfBceE0
And the user toggles the network Ropsten
Then the user has a positive balance of ETH
And the user imports a seed phrase with one and TesTEr16843/!@00 and pelican chief sudden oval media rare swamp elephant lawsuit wheat knife initial
Then the new account one is added
And the user has a positive balance of ETH
And the user has a positive balance of STT
Scenario Outline: User can edit the default wallet account

View File

@ -58,6 +58,7 @@ Item {
}
StatusAddressPanel {
objectName: "addressPanel"
address: currentAccount.mixedcaseAddress
autHideCopyIcon: true

View File

@ -58,6 +58,8 @@ Popup {
Repeater {
id: chainRepeater1
width: parent.width
height: parent.height
objectName: "networkSelectPopupChainRepeaterLayer1"
model: popup.layer1Networks

View File

@ -1,6 +1,7 @@
import QtQuick 2.13
import QtQuick.Layouts 1.13
import StatusQ.Core 0.1
import StatusQ.Controls 0.1
import utils 1.0

View File

@ -11,6 +11,7 @@ import utils 1.0
StatusDialog {
id: root
objectName: "mailserverConnectionDialog"
title: qsTr("Can not connect to mailserver")
@ -29,6 +30,7 @@ StatusDialog {
}
}
StatusButton {
objectName: "mailserverConnectionDialog_retryButton"
text: qsTr("Retry")
onClicked: {
// Retrying already happens automatically, so doing nothing

View File

@ -216,6 +216,7 @@ Item {
GasSelectorButton {
id: lowGasButton
objectName: "GasSelector_lowGasButton"
primaryText: qsTr("Low")
gasLimit: inputGasLimit ? inputGasLimit.text : ""
getGasEthValue: root.getGasEthValue
@ -241,6 +242,7 @@ Item {
GasSelectorButton {
id: optimalGasButton
objectName: "GasSelector_optimalGasButton"
primaryText: qsTr("Optimal")
price: {
if (!root.suggestedFees.eip1559Enabled) {
@ -271,6 +273,7 @@ Item {
GasSelectorButton {
id: highGasButton
objectName: "GasSelector_highGasButton"
primaryText: qsTr("High")
price: {
if (!root.suggestedFees.eip1559Enabled) return root.suggestedFees.gasPrice;
@ -360,6 +363,7 @@ Item {
Input {
id: inputGasPrice
textField.objectName: "gasPriceSelectorInput"
label: qsTr("Per-gas overall limit")
inputLabel.color: Style.current.secondaryText
anchors.top: parent.top

View File

@ -120,7 +120,7 @@ Item {
width: comboBox.control.popup.width
highlighted: index === comboBox.control.highlightedIndex
padding: 16
objectName: symbol
objectName: "AssetSelector_ItemDelegate_" + symbol
onClicked: {
// TODO: move this out of StatusQ, this involves dependency on BE code
// WARNING: Wrong ComboBox value processing. Check `StatusAccountSelector` for more info.

View File

@ -42,7 +42,7 @@ Item {
}
delegate: StatusListItem {
readonly property int balance: enabledNetworkBalance // Needed for the tests
readonly property string balance: enabledNetworkBalance // Needed for the tests
objectName: "AssetView_TokenListItem_" + symbol
width: parent.width
title: name

2
vendor/status-go vendored

@ -1 +1 @@
Subproject commit 341a2e773f7ec06a1d3fecd619e21028d1a8cca1
Subproject commit cdca3d86e2b7fc65a601eec4259930304cf79c24