Skip to content

Commit 4da0352

Browse files
test: Enhance US04 tests with improved average extraction, back navigation handling, and additional logging
1 parent fa80b67 commit 4da0352

File tree

1 file changed

+131
-53
lines changed

1 file changed

+131
-53
lines changed

tests/us4.py

Lines changed: 131 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -83,20 +83,45 @@ def _take_screenshot(self, name_suffix):
8383
def _get_current_weighted_average(self):
8484
"""Extract and return the current weighted average from the result page."""
8585
try:
86+
# Take screenshot to debug what we're seeing
87+
self._take_screenshot("result_page_before_extract_average")
88+
89+
# Make sure we are on the result page
90+
self.wait_long.until(
91+
EC.visibility_of_element_located((By.CSS_SELECTOR, self.RESULT_PAGE_CONTAINER_SELECTOR))
92+
)
93+
94+
# Wait for average display element
8695
current_avg_element = self.wait_long.until(
87-
EC.presence_of_element_located((By.CSS_SELECTOR, self.CURRENT_AVERAGE_DISPLAY_SELECTOR))
96+
EC.visibility_of_element_located((By.CSS_SELECTOR, self.CURRENT_AVERAGE_DISPLAY_SELECTOR))
8897
)
98+
99+
# Small delay to make sure text is fully loaded/rendered
100+
time.sleep(0.2)
101+
89102
current_avg_text = current_avg_element.text.strip()
90103
logger.info(f"Current average text found: '{current_avg_text}'")
91104

92105
# Extract the numeric value using regex - looking for decimal number
106+
# Example text: "Promedio actual: 1.8"
93107
match = re.search(r'(\d+\.\d+)', current_avg_text)
94108
if match:
95109
current_avg = float(match.group(1))
96110
logger.info(f"Extracted current average: {current_avg}")
97111
return current_avg
98112
else:
99113
logger.error(f"Failed to extract numeric average from text: '{current_avg_text}'")
114+
# Try an alternative approach - get the raw text content
115+
raw_text = current_avg_element.get_attribute('textContent').strip()
116+
logger.info(f"Raw text content: '{raw_text}'")
117+
118+
# Try to find any decimal number in the raw text
119+
alt_match = re.search(r'(\d+\.\d+)', raw_text)
120+
if alt_match:
121+
current_avg = float(alt_match.group(1))
122+
logger.info(f"Extracted current average from raw text: {current_avg}")
123+
return current_avg
124+
100125
self._take_screenshot("average_extraction_failed")
101126
self.fail(f"Could not extract numeric average from: '{current_avg_text}'")
102127

@@ -170,87 +195,140 @@ def _initial_setup(self):
170195
logger.error(f"An unexpected error occurred during initial setup: {e}", exc_info=True)
171196
self._take_screenshot("initial_setup_error")
172197
self.fail(f"Unexpected error during initial setup: {e}")
173-
198+
174199
def _add_grade_and_percentage(self, grade, percentage):
175200
if not hasattr(self, 'driver') or not self.driver:
176201
logger.error("Driver not available in _add_grade_and_percentage.")
177202
self.fail("Driver not available.")
178203
return
179204

205+
# First check if we're on the result page and navigate back if needed
180206
on_result_page = False
181207
try:
182-
# Check if the result page container is present
183208
if self.driver.find_element(By.CSS_SELECTOR, self.RESULT_PAGE_CONTAINER_SELECTOR).is_displayed():
184209
on_result_page = True
185210
except NoSuchElementException:
186-
on_result_page = False # Not on result page
211+
on_result_page = False
187212

188213
if on_result_page:
189-
logger.info("Currently on result page (detected by element presence), navigating back to home to add grades.")
214+
logger.info("Currently on result page, navigating back to home to add grades.")
190215
try:
216+
# First try with the CSS selector
191217
nav_back_button = self.wait_short.until(
192218
EC.element_to_be_clickable((By.CSS_SELECTOR, self.NAV_BACK_BUTTON_SELECTOR))
193219
)
194220
logger.info("Found back button using CSS selector in _add_grade_and_percentage.")
195221
except TimeoutException:
196-
logger.info("CSS selector failed for back button in _add_grade_and_percentage, trying XPath...")
197-
nav_back_button = self.wait_long.until(
198-
EC.element_to_be_clickable((By.XPATH, self.NAV_BACK_BUTTON_XPATH))
199-
)
200-
logger.info("Found back button using XPath selector in _add_grade_and_percentage.")
201-
222+
try:
223+
# Then try with XPath
224+
logger.info("CSS selector failed for back button in _add_grade_and_percentage, trying XPath...")
225+
nav_back_button = self.wait_long.until(
226+
EC.element_to_be_clickable((By.XPATH, self.NAV_BACK_BUTTON_XPATH))
227+
)
228+
logger.info("Found back button using XPath selector in _add_grade_and_percentage.")
229+
except TimeoutException:
230+
# As a last resort, try to find any buttons in the nav bar
231+
logger.info("XPath also failed. Looking for any button in the nav bar...")
232+
nav_bar = self.wait_long.until(
233+
EC.presence_of_element_located((By.CSS_SELECTOR, "nav.nav-bar"))
234+
)
235+
nav_buttons = nav_bar.find_elements(By.TAG_NAME, "button")
236+
if nav_buttons:
237+
nav_back_button = nav_buttons[0] # First button in nav bar is usually back
238+
logger.info("Using first button found in nav bar")
239+
else:
240+
logger.error("No buttons found in nav bar")
241+
self._take_screenshot("no_buttons_in_nav_bar_add_grade")
242+
self.fail("No buttons found in nav bar when trying to navigate back")
243+
244+
# Click the back button once found
202245
nav_back_button.click()
203246
self.wait_long.until(EC.presence_of_element_located((By.CSS_SELECTOR, self.HOME_CONTAINER_SELECTOR)))
204-
logger.info("Navigated back to home page.")
247+
logger.info("Successfully navigated back to home page.")
248+
249+
# Take a small pause to ensure the UI is fully loaded
250+
time.sleep(0.5)
205251

252+
# Now we're on the home page
253+
# Take a screenshot of the current state for debugging
254+
self._take_screenshot("before_adding_grade")
255+
256+
# Find all grade rows currently in the UI
206257
grade_rows = self.driver.find_elements(By.CSS_SELECTOR, self.GRADES_LIST_ITEM_SELECTOR)
207-
if not grade_rows:
208-
logger.warning("No grade rows found. Attempting to add one by clicking the global 'Add Grade' button.")
209-
self._take_screenshot("no_grade_rows_found")
258+
logger.info(f"Found {len(grade_rows)} grade rows before adding.")
259+
260+
# First check if we need to add a new row
261+
need_new_row = True
262+
if grade_rows:
263+
# Check if the last row is empty (which means we can use it)
264+
last_row = grade_rows[-1]
210265
try:
211-
# This assumes ADD_GRADE_BUTTON_SELECTOR is the button that adds a new empty row for input
212-
add_button_global = self.wait_long.until(EC.element_to_be_clickable((By.CSS_SELECTOR, self.ADD_GRADE_BUTTON_SELECTOR)))
213-
add_button_global.click()
214-
time.sleep(0.5) # Allow time for the row to be added dynamically
215-
grade_rows = self.driver.find_elements(By.CSS_SELECTOR, self.GRADES_LIST_ITEM_SELECTOR)
216-
if not grade_rows:
217-
logger.error("Still no grade rows found after attempting to add one.")
218-
self._take_screenshot("failed_to_add_initial_row")
219-
self.fail("Still no grade rows found after attempting to add one.")
220-
return
221-
logger.info(f"Successfully added an initial grade row. Now {len(grade_rows)} rows.")
222-
except Exception as ex:
223-
logger.error(f"Failed to create an initial grade row by clicking add button: {ex}", exc_info=True)
224-
self._take_screenshot("create_initial_row_exception")
225-
self.fail(f"Failed to create an initial grade row: {ex}")
226-
return
227-
266+
grade_input = last_row.find_element(By.CSS_SELECTOR, self.GRADE_INPUT_SELECTOR)
267+
percentage_input = last_row.find_element(By.CSS_SELECTOR, self.PERCENTAGE_INPUT_SELECTOR)
268+
269+
grade_value = grade_input.get_attribute("value")
270+
percentage_value = percentage_input.get_attribute("value")
271+
272+
# If both inputs are empty, we can use this row
273+
if not grade_value and not percentage_value:
274+
need_new_row = False
275+
logger.info("Found empty row to use for new grade entry.")
276+
except NoSuchElementException:
277+
# If we can't find inputs in the last row, we'll add a new one
278+
logger.warning("Last row doesn't have expected input elements.")
279+
need_new_row = True
280+
281+
# If we need a new row or there are no rows, add one
282+
if need_new_row or not grade_rows:
283+
logger.info("Adding a new grade row...")
284+
add_button = self.wait_long.until(EC.element_to_be_clickable((By.CSS_SELECTOR, self.ADD_GRADE_BUTTON_SELECTOR)))
285+
add_button.click()
286+
time.sleep(0.5) # Wait for the row to be added
287+
288+
# Refresh the list of grade rows
289+
grade_rows = self.driver.find_elements(By.CSS_SELECTOR, self.GRADES_LIST_ITEM_SELECTOR)
290+
if not grade_rows:
291+
logger.error("Failed to add grade row - no rows found after clicking 'Add' button")
292+
self._take_screenshot("failed_to_add_grade_row")
293+
self.fail("Failed to add grade row - no rows found after clicking 'Add' button")
294+
295+
# Now use the last row to add our grade
228296
last_row = grade_rows[-1]
229-
logger.info(f"Targeting the last of {len(grade_rows)} grade rows for input.")
230-
297+
logger.info(f"Using the last of {len(grade_rows)} rows to add grade: {grade}, percentage: {percentage}")
298+
231299
try:
232300
grade_input_element = last_row.find_element(By.CSS_SELECTOR, self.GRADE_INPUT_SELECTOR)
233301
percentage_input_element = last_row.find_element(By.CSS_SELECTOR, self.PERCENTAGE_INPUT_SELECTOR)
302+
303+
# Clear and enter the grade and percentage
304+
grade_input_element.clear()
305+
grade_input_element.send_keys(str(grade))
306+
percentage_input_element.clear()
307+
percentage_input_element.send_keys(str(percentage))
308+
309+
# Take screenshot after entering values
310+
self._take_screenshot(f"after_entering_grade_{grade}_percent_{percentage}")
311+
312+
# Click the add button to confirm this grade
313+
add_button = self.wait_long.until(EC.element_to_be_clickable((By.CSS_SELECTOR, self.ADD_GRADE_BUTTON_SELECTOR)))
314+
add_button.click()
315+
logger.info(f"Clicked 'Add' button after entering grade: {grade}, percentage: {percentage}")
316+
317+
# Allow time for the UI to update
318+
time.sleep(0.5)
319+
320+
# Verify the grade was added by checking for more rows or for values in the inputs
321+
new_grade_rows = self.driver.find_elements(By.CSS_SELECTOR, self.GRADES_LIST_ITEM_SELECTOR)
322+
logger.info(f"After adding: {len(new_grade_rows)} grade rows (previously {len(grade_rows)})")
323+
324+
# Take screenshot after adding grade
325+
self._take_screenshot("after_adding_grade")
326+
234327
except NoSuchElementException as e:
235-
logger.error(f"Could not find grade or percentage input in the last row: {e}")
236-
logger.info(f"HTML of last row: {last_row.get_attribute('outerHTML')}")
237-
self._take_screenshot("input_not_found_in_last_row")
238-
self.fail(f"Input elements not found in the last row: {e}")
328+
logger.error(f"Could not find input elements in the grade row: {e}")
329+
self._take_screenshot("input_elements_not_found")
330+
self.fail(f"Input elements not found: {e}")
239331
return
240-
241-
# Assuming ADD_GRADE_BUTTON_SELECTOR is the button to confirm/add the currently entered grade,
242-
# not necessarily the one that creates a new blank row if that's different.
243-
# If the app auto-adds a new row upon filling the last one and clicking a general "add" button, this is fine.
244-
add_button = self.wait_long.until(EC.element_to_be_clickable((By.CSS_SELECTOR, self.ADD_GRADE_BUTTON_SELECTOR)))
245-
246-
grade_input_element.clear()
247-
grade_input_element.send_keys(str(grade))
248-
percentage_input_element.clear()
249-
percentage_input_element.send_keys(str(percentage))
250-
251-
add_button.click()
252-
logger.info(f"Clicked 'Agregar nota' after filling grade: {grade}, percentage: {percentage} into the last available row.")
253-
time.sleep(0.5) # Brief pause for UI to update, e.g., adding a new empty row
254332

255333
def test_us04_verify_calculation_of_current_weighted_average(self):
256334
test_name = self._testMethodName
@@ -322,7 +400,7 @@ def test_us04_verify_calculation_of_current_weighted_average(self):
322400
logger.warning("CSS selector failed for back button in step 1, trying XPath with more wait time...")
323401
# Take debug screenshot
324402
self._take_screenshot("css_selector_failed_step1")
325-
# Try a more verbose approach to locate the button
403+
# Try a more verbose approach to locate the button
326404
try:
327405
# First, check if there's a nav bar
328406
nav_bar = self.wait_long.until(

0 commit comments

Comments
 (0)