Skip to content

Commit a3519a5

Browse files
authored
fix failed selenium tests (#4085)
* initial commit to fix failed tests * - fix logout function - fix test_create_account - update some selectors to use the new element ID provided - fix accept terms and condition function * fix login functionality * fix bridge tests and remove skip * fix xpaths due to the new change in farm ip table "network" * fix linls url for local build. * fix farm details function * fix stats url for local setup * fix codacy checks * fix codacy checks * fix codacy checks * add package python-xlib * fix python-xlib package version * add xlip package to system dependencies * add xlip to yaml file * fix codacy checks * add logs ips for rangee IPs tests * fix codacy checks * fix codacy checks * fix generate IP method * fix codacy checks
1 parent 2e1e061 commit a3519a5

File tree

13 files changed

+195
-132
lines changed

13 files changed

+195
-132
lines changed

.github/workflows/playground_selenium.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ jobs:
1515
uses: actions/setup-python@v5
1616
with:
1717
python-version: "3.10"
18+
- name: Install system dependencies
19+
run: sudo apt-get update && sudo apt-get install -y xclip
1820
- name: Installing all necessary packages
1921
run: pip install -r packages/playground/tests/frontend_selenium/requirements.txt
2022
- name: Node install

packages/playground/tests/frontend_selenium/pages/bridge.py

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ class BridgePage:
3030
stellar_address = (By.XPATH, "//label[text()='Stellar Target Wallet Address']/following-sibling::input")
3131
amount_tft = (By.XPATH, "//input[@class='v-field__input' and @type='number']")
3232
submit_button = (By.XPATH, "//button[.//span[text()='Send']]")
33-
balance_text = (By.XPATH,'/html/body/div[1]/div/div/main/header/div/div[3]/div[2]/p[1]/strong')
33+
balance_text = (By.XPATH,"//p[contains(text(), 'Balance:')]")
34+
locked_balance_text = (By.XPATH,"//p[contains(text(), 'Locked:')]")
3435
tft_amount_text = (By.XPATH, "//*[contains(text(), 'Deposit fee is 1 TFT')]")
3536

3637

@@ -93,7 +94,7 @@ def setup_widthdraw_address(self, data):
9394
while(balance == 'Loadin'):
9495
while True:
9596
try:
96-
balance = self.browser.find_element(*self.balance_text).text[:-4]
97+
balance = self.browser.find_element(*self.balance_text).text[9:-4]
9798
break # Exit the loop if interaction is successful
9899
except StaleElementReferenceException:
99100
time.sleep(0.5)
@@ -140,7 +141,7 @@ def check_withdraw(self, address, amount):
140141
def get_balance(self):
141142
while True:
142143
try:
143-
new_balance = self.browser.find_element(*self.balance_text).text[:-4]
144+
new_balance = self.browser.find_element(*self.balance_text).text[9:-4]
144145
break # Exit the loop if interaction is successful
145146
except StaleElementReferenceException:
146147
time.sleep(0.5)
@@ -149,7 +150,25 @@ def get_balance(self):
149150
self.wait_for(' Balance: ')
150151
while True:
151152
try:
152-
new_balance = self.browser.find_element(*self.balance_text).text[:-4]
153+
new_balance = self.browser.find_element(*self.balance_text).text[9:-4]
154+
break # Exit the loop if interaction is successful
155+
except StaleElementReferenceException:
156+
time.sleep(0.5)
157+
return new_balance
158+
159+
def get_locked_balance(self):
160+
while True:
161+
try:
162+
new_balance = self.browser.find_element(*self.locked_balance_text).text[8:-4]
163+
break # Exit the loop if interaction is successful
164+
except StaleElementReferenceException:
165+
time.sleep(0.5)
166+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.transfer_tft_title))
167+
while('Loadin' in new_balance):
168+
self.wait_for(' Locked: ')
169+
while True:
170+
try:
171+
new_balance = self.browser.find_element(*self.locked_balance_text).text[8:-4]
153172
break # Exit the loop if interaction is successful
154173
except StaleElementReferenceException:
155174
time.sleep(0.5)
@@ -158,7 +177,7 @@ def get_balance(self):
158177
def get_balance_withdraw(self, balance):
159178
while True:
160179
try:
161-
new_balance = self.browser.find_element(*self.balance_text).text[:-4]
180+
new_balance = self.browser.find_element(*self.balance_text).text[9:-4]
162181
break # Exit the loop if interaction is successful
163182
except StaleElementReferenceException:
164183
time.sleep(0.5)
@@ -168,7 +187,7 @@ def get_balance_withdraw(self, balance):
168187
while(new_balance==balance):
169188
while True:
170189
try:
171-
new_balance = self.browser.find_element(*self.balance_text).text[:-4]
190+
new_balance = self.browser.find_element(*self.balance_text).text[9:-4]
172191
break # Exit the loop if interaction is successful
173192
except StaleElementReferenceException:
174193
time.sleep(0.5)

packages/playground/tests/frontend_selenium/pages/dashboard.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@ class DashboardPage:
2626
tft_info_button = (By.XPATH, '/html/body/div[1]/div/div/main/header/div/div[2]/div/div/div/a/span[3]/i')
2727
stellar_tft_price_label = (By.XPATH, "//dt[text()='Current price:']/following-sibling::dd/span[1]")
2828
stellar_tft_price_change_label = (By.XPATH, "//span[contains(@class, 'price-change') and @aria-label]")
29-
mnemonic_input = (By.XPATH, "//input[@placeholder='Please insert your Mnemonic or Hex Seed']")
30-
email_input = (By.XPATH, "//input[@placeholder='email@example.com']")
29+
mnemonic_input = (By.ID, "mnemonic-text-field")
30+
email_input = (By.ID, "email-text-field")
3131
password_input = (By.XPATH, "(//input[@size='1' and @type='password'])[2]")
32-
confirm_password_input = (By.XPATH, "(//input[@size='1' and @type='password'])[3]")
32+
confirm_password_input = (By.ID, "confirm-password-text-field")
3333
generate_account_button = (By.XPATH, "//button[.//span[text()=' create account ']]")
34-
connect_button = (By.XPATH, "//button[.//span[text()='Connect']]")
34+
connect_button = (By.ID, "connect-btn")
3535
logout_button = (By.XPATH, "/html/body/div[1]/div/div/main/header[1]/div/div[3]/button")
36-
login_button = (By.XPATH, "//button[.//span[text()='Login']]")
37-
login_password_input = (By.XPATH, "//label[text()='Password']/following-sibling::input")
36+
login_button = (By.ID, "wallet-login-tab__login-button")
37+
login_password_input = (By.ID, "wallet-password__text-field")
3838
accept_terms_condition_button = (By.XPATH, "//button[.//span[text()='Accept terms and conditions']]")
3939
connect_manual_button = (By.XPATH,"//*[contains(text(), 'Threefold Connect')]")
4040
connect_google_button = (By.XPATH, "//a[@title='Threefold Connect on Google Play Store']")
@@ -73,9 +73,14 @@ def import_account(self, seed, validation=True):
7373
WebDriverWait(self.browser, 60).until(EC.element_to_be_clickable(self.email_input))
7474

7575
def connect_your_wallet(self, email, password):
76-
self.browser.find_element(*self.email_input).send_keys(Keys.CONTROL + "a")
77-
self.browser.find_element(*self.email_input).send_keys(Keys.DELETE)
78-
self.browser.find_element(*self.email_input).send_keys(email)
76+
element = WebDriverWait(self.browser, 10).until(EC.presence_of_element_located(self.email_input))
77+
for _ in range(10):
78+
if element.is_enabled():
79+
self.browser.find_element(*self.email_input).send_keys(Keys.CONTROL + "a")
80+
self.browser.find_element(*self.email_input).send_keys(Keys.DELETE)
81+
self.browser.find_element(*self.email_input).send_keys(email)
82+
else:
83+
time.sleep(3)
7984
self.browser.find_element(*self.password_input).send_keys(Keys.CONTROL + "a")
8085
self.browser.find_element(*self.password_input).send_keys(Keys.DELETE)
8186
self.browser.find_element(*self.password_input).send_keys(password)
@@ -86,6 +91,7 @@ def connect_your_wallet(self, email, password):
8691

8792
def logout_account(self):
8893
time.sleep(3)
94+
self.press_esc_key()
8995
while True:
9096
try:
9197
self.wait_for_button(self.browser.find_element(*self.logout_button)).click()
@@ -99,11 +105,16 @@ def logout_account(self):
99105
self.browser.switch_to.window(self.browser.window_handles[0])
100106
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.profile_load_label))
101107

102-
def login_account(self, password):
108+
def login_account(self, password, validation=False):
103109
self.browser.find_element(*self.login_password_input).send_keys(Keys.CONTROL + "a")
104110
self.browser.find_element(*self.login_password_input).send_keys(Keys.DELETE)
105111
self.browser.find_element(*self.login_password_input).send_keys(password)
106-
return self.browser.find_element(*self.login_button)
112+
if validation:
113+
assert WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.login_button)).is_enabled()
114+
self.browser.find_element(*self.login_button).click()
115+
self.open_profile(True)
116+
else:
117+
return self.browser.find_element(*self.login_button)
107118

108119
def create_account(self):
109120
self.browser.find_element(*self.generate_account_button).click()
@@ -113,8 +124,7 @@ def accept_terms_conditions(self):
113124
self.browser.find_element(*self.iframe_load_label).click()
114125
webdriver.ActionChains(self.browser).send_keys(Keys.PAGE_DOWN).perform()
115126
self.browser.find_element(*self.accept_terms_condition_button).click()
116-
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.generate_account_button))
117-
WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.password_input))
127+
WebDriverWait(self.browser, 60).until(EC.visibility_of_element_located(self.generate_account_button))
118128

119129
def click_button(self, button):
120130
WebDriverWait(self.browser, 60).until(EC.element_to_be_clickable(button))
@@ -171,12 +181,12 @@ def get_dashboard_stats(self):
171181
stats.append(int(self.browser.find_element(*self.cores_stats).text))
172182
return stats
173183

174-
def open_profile(self):
184+
def open_profile(self, click=False):
175185
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.profile_label))
176-
self.browser.find_element(*self.profile_button).click()
186+
if click:
187+
self.browser.find_element(*self.profile_button).click() #by default now the profile page popup when connect no need to click
177188
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.qr_code_img))
178189
WebDriverWait(self.browser, 30).until(EC.presence_of_element_located((By.XPATH, "//*[contains(text(), 'TFChain Wallet')]")))
179-
time.sleep(3)
180190

181191
def get_link(self):
182192
WebDriverWait(self.browser, 30).until(EC.number_of_windows_to_be(2))
@@ -235,5 +245,5 @@ def wait_for_button(self, button):
235245
return button
236246

237247
def wait_for(self, keyword):
238-
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '"+ keyword +"')]")))
248+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, f'//*[contains(text(), "{keyword}")]')))
239249
return True

packages/playground/tests/frontend_selenium/pages/farm.py

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from selenium.webdriver.common.keys import Keys
55
from selenium.webdriver.support.ui import WebDriverWait
66
from selenium.webdriver.support import expected_conditions as EC
7+
import pyperclip
78

89
class FarmPage:
910

@@ -40,9 +41,10 @@ class FarmPage:
4041
zero = (By.XPATH,'//html/body/main/div[1]/div/h1')
4142
table_farm_name=(By.XPATH, '//*[@id="app"]/div[1]/div[2]/div/div[1]/div[4]/div[1]/table/tbody/tr[1]/td[3]')
4243
stellar_payout_address = (By.XPATH, '//table/tbody/tr[2]/td/div[1]/div/div/div[3]/div/div/div[1]/div[2]/p')
44+
stellar_payout_address_copy = (By.XPATH, "//i[contains(@class, 'mdi-content-copy') and contains(@class, 'v-icon--clickable')]")
4345
dedicated = (By.XPATH, '//table/tbody/tr[2]/td/div[1]/div/div/div[3]/div/div/div[2]/div[2]/p')
4446
pricing_policy = (By.XPATH, '//table/tbody/tr[2]/td/div[1]/div/div/div[3]/div/div/div[3]/div[2]/p')
45-
ip_dropdown = (By.XPATH, "(//i[contains(@class, 'mdi-menu-down')])[3]")
47+
ip_dropdown = (By.XPATH, "(//i[contains(@class, 'mdi-menu-down')])[4]")
4648
range_selection = (By.XPATH, "//div[@class='v-list-item-title'][text()='Range']")
4749
from_ip_input = (By.XPATH, "//label[text()='From IP']/following-sibling::input")
4850
to_ip_input = (By.XPATH, "//label[text()='To IP']/following-sibling::input")
@@ -80,7 +82,7 @@ def create_farm_invalid_name(self, data):
8082
self.browser.find_element(*self.farm_name_text_field).send_keys(char)
8183

8284
def search_functionality(self, farm_name):
83-
tries = 3
85+
tries = 5
8486
table = 'No data available'
8587
while('No data available' in table and tries > 0):
8688
sleep(5)
@@ -318,10 +320,9 @@ def delete_ip(self, farm_name, ip, gateway):
318320
self.setup_farmpayout_address(farm_name)
319321
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, self.farm_public_ips)))
320322
for i in range(len(self.browser.find_elements(By.XPATH, self.farm_public_ips))):
321-
if(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[2]").text == ip):
322-
if(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[3]").text == gateway):
323-
#WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[1]/div/div/div/div/div/input")))
324-
self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[1]/div/div/div/div/div/input").click()
323+
if self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[2]").text == ip:
324+
if self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[4]").text == gateway:
325+
self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[1]/div/div/div/input").click()
325326
WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.delete_button))
326327
self.browser.find_element(*self.delete_button).click()
327328
WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.confirm_button))
@@ -336,19 +337,32 @@ def get_ip(self, ip, gateway):
336337
gateway_len = len(self.browser.find_elements(By.XPATH, "//td[contains(@class, 'v-data-table__td') and contains(@class, 'v-data-table-column--align-center') and text()='"+ gateway +"']"))
337338
return ip_len, gateway_len
338339

339-
def farm_detials(self):
340+
def farm_details(self, farm_name):
341+
self.search_functionality(farm_name)
342+
self.wait_for_farm_name(farm_name)
343+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.details_arrow))
344+
WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.details_arrow))
345+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, "//span[contains(@class, 'v-btn__content')]/i[contains(@class, 'mdi-chevron-down')]")))
346+
self.browser.find_element(*self.details_arrow).click()
347+
sleep(10)
340348
details = []
341349
details.append(self.browser.find_element(By.XPATH, f"{self.node_expand_details}[1]").text) # Farm ID
342350
details.append(self.browser.find_element(By.XPATH, f"{self.node_expand_details}[2]").text) # Farm Name
343351
details.append(self.browser.find_element(By.XPATH, f"{self.node_expand_details}[3]").text) # Linked Twin ID
344352
details.append(self.browser.find_element(By.XPATH, f"{self.node_expand_details}[4]").text) # Certification Type
345-
details.append(self.browser.find_element(*self.stellar_payout_address).text) # Stellar Address
353+
# details.append(self.browser.find_element(*self.stellar_payout_address).text) # Stellar Address
354+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located(self.stellar_payout_address_copy))
355+
WebDriverWait(self.browser, 30).until(EC.element_to_be_clickable(self.stellar_payout_address_copy))
356+
self.browser.find_element(*self.stellar_payout_address_copy).click()
357+
sleep(1)
358+
copied_value = pyperclip.paste()
359+
details.append(copied_value)
346360
details.append(True if self.browser.find_element(*self.dedicated).text != "No" else False) # Dedicated
347361
details.append(self.browser.find_element(*self.pricing_policy).text) # Pricing Policy
348362
for i in range(len(self.browser.find_elements(By.XPATH, self.farm_public_ips))):
349363
details.append(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[2]").text) # IP
350-
details.append(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[4]").text) # Deployed Contract ID
351-
details.append(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[3]").text) # Gateway
364+
details.append(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[5]").text) # Deployed Contract ID
365+
details.append(self.browser.find_element(By.XPATH, f"{self.farm_public_ips}[{str(i+1)}]/td[4]").text) # Gateway
352366
return details
353367

354368
def verify_the_availability_of_zero_os_bootstrap(self):
@@ -379,5 +393,5 @@ def wait_for_button(self, button):
379393
return button
380394

381395
def wait_for(self, keyword):
382-
WebDriverWait(self.browser, 60).until(EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '"+ keyword +"')]")))
396+
WebDriverWait(self.browser, 30).until(EC.visibility_of_element_located((By.XPATH, "//*[contains(text(), '"+ keyword +"')]")))
383397
return True

packages/playground/tests/frontend_selenium/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ pytest==8.3.2
22
selenium==4.23.1
33
webdriver_manager==4.0.2
44
requests==2.32.3
5-
pyvirtualdisplay==3.0
5+
pyvirtualdisplay==3.0
6+
pyperclip==1.9.0

0 commit comments

Comments
 (0)