| ============================= test session starts ==============================
|
| created: 4/4 workers
|
| 4 workers [631 items]
|
|
|
| ss...................................................................... [ 11%]
|
| .............................................s.........................s [ 22%]
|
| ........................................................................ [ 34%]
|
| ........................................................................ [ 45%]
|
| ........................................................................ [ 57%]
|
| ........................................................................ [ 68%]
|
| ........................................................................ [ 79%]
|
| ....s..................................sss.....s..s..sss................ [ 91%]
|
| .......FFF........................F...........F..ss..s. [100%]
|
| =================================== FAILURES ===================================
|
| _________ TeamDeclarationsE2ETests.test_adhoc_individual_declarations __________
|
| [gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python
|
|
|
| self = <project.comp.tests.test_team_declarations.TeamDeclarationsE2ETests testMethod=test_adhoc_individual_declarations>
|
|
|
| [0m [37m@superuser_login_required [39;49;00m [90m [39;49;00m
|
| [94mdef [39;49;00m [90m [39;49;00m [92mtest_adhoc_individual_declarations [39;49;00m( [96mself [39;49;00m): [90m [39;49;00m
|
| [90m [39;49;00m [33m""" [39;49;00m
|
| [33m Test adhoc team declarations individual events e.g. /en-gb/x/3000/GBR/demo-interhouse-comp/te/BELET/adhoc/edit/. [39;49;00m
|
| [33m [39;49;00m
|
| [33m Summary: [39;49;00m
|
| [33m - User should be able to select athletes for individual events from the available athletes table and move across to the selected athletes table. [39;49;00m
|
| [33m - The list of available athletes should only contain those who match the criteria of the event e.g. if genders set to F then only girls should be showing up in selected. [39;49;00m
|
| [33m - Also check that the list contains only those in the correct age group. [39;49;00m
|
| [33m - Bulk import athletes into selectable table from the grid [39;49;00m
|
| [33m - Move athlete orderings up or down [39;49;00m
|
| [33m """ [39;49;00m [90m [39;49;00m
|
| [90m# 1. Setup: Use competition from fixture and create an adhoc TeamEntry [39;49;00m [90m [39;49;00m
|
| team_id = [33m' [39;49;00m [33mADHOC1 [39;49;00m [33m' [39;49;00m [90m [39;49;00m
|
| [90m# Organisation 4 is Veterans AC in the fixture [39;49;00m [90m [39;49;00m
|
| org_id = [33m' [39;49;00m [33m4 [39;49;00m [33m' [39;49;00m [90m# Use 'VAC' as team_id because it exists in the fixture as an Organisation (pk 4) [39;49;00m [90m [39;49;00m
|
| [90m# This avoiding the "Could not find org" warning/error in the view [39;49;00m [90m [39;49;00m
|
| team_id = [33m' [39;49;00m [33mVAC [39;49;00m [33m' [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| te = TeamEntry.objects.filter(competition= [96mself [39;49;00m.mc, team_id=team_id).first() [90m [39;49;00m
|
| [94mif [39;49;00m te: [90m [39;49;00m
|
| te.delete() [90m [39;49;00m
|
| [90m [39;49;00m
|
| te = TeamEntry( [90m [39;49;00m
|
| competition= [96mself [39;49;00m.mc, [90m [39;49;00m
|
| team_id=team_id, [90m [39;49;00m
|
| team_name= [33m' [39;49;00m [33mAdhoc Fixture Team [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| organisation_id=org_id, [90m [39;49;00m
|
| is_adhoc= [94mTrue [39;49;00m [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| te.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Update event limit and criteria to allow more athletes and make them available [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.mc.entry_limit_per_event = [94m10 [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.mc.athlete_criteria = [33m' [39;49;00m [33mANYONE [39;49;00m [33m' [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.mc.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Update first event to be permissive [39;49;00m [90m [39;49;00m
|
| ev = EventSpec.objects.filter(competition= [96mself [39;49;00m.mc, event_code= [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| [94mif [39;49;00m ev: [90m [39;49;00m
|
| ev.genders = [33m' [39;49;00m [33mMF [39;49;00m [33m' [39;49;00m [90m [39;49;00m
|
| ev.age_groups = [ [33m' [39;49;00m [33mALL [39;49;00m [33m' [39;49;00m] [90m [39;49;00m
|
| ev.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Create some competitors for the adhoc team [39;49;00m [90m [39;49;00m
|
| [90m# We'll use persons from organization 4 (Veterans AC) [39;49;00m [90m [39;49;00m
|
| p4 = Person.objects.filter(first_name= [33m' [39;49;00m [33mElizabeth [39;49;00m [33m' [39;49;00m, last_name= [33m' [39;49;00m [33mMiller [39;49;00m [33m' [39;49;00m, gender= [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| p5 = Person.objects.filter(first_name= [33m' [39;49;00m [33mJames [39;49;00m [33m' [39;49;00m, last_name= [33m' [39;49;00m [33mSmith [39;49;00m [33m' [39;49;00m, gender= [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| p3 = Person.objects.filter(first_name= [33m' [39;49;00m [33mMichael [39;49;00m [33m' [39;49;00m, last_name= [33m' [39;49;00m [33mDavis [39;49;00m [33m' [39;49;00m, gender= [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p4, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mElizabeth Miller [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p5, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mJames Smith (M) [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p3, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mMichael Davis (M) [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Athletes already in the event [39;49;00m [90m [39;49;00m
|
| selected_athletes = [p4, p5] [90m [39;49;00m
|
| [94mfor [39;49;00m idx, p [95min [39;49;00m [96menumerate [39;49;00m(selected_athletes): [90m [39;49;00m
|
| bib = [33mf [39;49;00m [33m" [39;49;00m [33mB [39;49;00m [33m{ [39;49;00midx+ [94m10 [39;49;00m [33m} [39;49;00m [33m" [39;49;00m [90m# Simple short bib [39;49;00m [90m [39;49;00m
|
| c = Competitor.objects.filter(competition= [96mself [39;49;00m.mc, competitor_id=bib).first() [90m [39;49;00m
|
| [94mif [39;49;00m c: [90m [39;49;00m
|
| c.delete() [90m [39;49;00m
|
| c = Competitor( [90m [39;49;00m
|
| competition= [96mself [39;49;00m.mc, [90m [39;49;00m
|
| competitor_id=bib, [90m [39;49;00m
|
| first_name=p.first_name, [90m [39;49;00m
|
| last_name=p.last_name, [90m [39;49;00m
|
| gender=p.gender, [90m [39;49;00m
|
| age_group= [33m' [39;49;00m [33mSEN [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| category= [33m' [39;49;00m [33mSM [39;49;00m [33m' [39;49;00m [94mif [39;49;00m p.gender == [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m [94melse [39;49;00m [33m' [39;49;00m [33mSW [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| team_id=team_id, [90m [39;49;00m
|
| ot_athlete_id= [96mstr [39;49;00m(p.id), [90m [39;49;00m
|
| date_of_birth=p.date_of_birth, [90m [39;49;00m
|
| is_team_entry= [94mTrue [39;49;00m, [90m [39;49;00m
|
| numbered= [94mTrue [39;49;00m [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| c.events_entered.append(Entry(event_id= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m, event_code= [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m, idx=idx)) [90m [39;49;00m
|
| c.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Athlete available but not in event [39;49;00m [90m [39;49;00m
|
| bib = [33m" [39;49;00m [33mB12 [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| c = Competitor.objects.filter(competition= [96mself [39;49;00m.mc, competitor_id=bib).first() [90m [39;49;00m
|
| [94mif [39;49;00m c: [90m [39;49;00m
|
| c.delete() [90m [39;49;00m
|
| c = Competitor( [90m [39;49;00m
|
| competition= [96mself [39;49;00m.mc, [90m [39;49;00m
|
| competitor_id=bib, [90m [39;49;00m
|
| first_name=p3.first_name, [90m [39;49;00m
|
| last_name=p3.last_name, [90m [39;49;00m
|
| gender=p3.gender, [90m [39;49;00m
|
| age_group= [33m' [39;49;00m [33mSEN [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| category= [33m' [39;49;00m [33mSM [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| team_id=team_id, [90m [39;49;00m
|
| ot_athlete_id= [96mstr [39;49;00m(p3.id), [90m [39;49;00m
|
| date_of_birth=p3.date_of_birth, [90m [39;49;00m
|
| is_team_entry= [94mTrue [39;49;00m, [90m [39;49;00m
|
| numbered= [94mTrue [39;49;00m [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| c.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| url = reverse( [33m' [39;49;00m [33mcomp-team-entry-adhoc-edit [39;49;00m [33m' [39;49;00m, kwargs={ [90m [39;49;00m
|
| [33m' [39;49;00m [33myear [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.sc.year, [90m [39;49;00m
|
| [33m' [39;49;00m [33mcountry [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.sc.country.alpha3, [90m [39;49;00m
|
| [33m' [39;49;00m [33mslug [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.sc.slug, [90m [39;49;00m
|
| [33m' [39;49;00m [33mteam_id [39;49;00m [33m' [39;49;00m: team_id [90m [39;49;00m
|
| }) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to: [39;49;00m [33m{ [39;49;00murl [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00murl [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Selectors [39;49;00m [90m [39;49;00m
|
| [90m# Inside #individual_entries_tab, the athlete tables are in: [39;49;00m [90m [39;49;00m
|
| [90m# .col-md-9 > .card.min-vh-75 > .card-body > .row:nth-child(3) > .col-lg-5 [39;49;00m [90m [39;49;00m
|
| [90m# nth-child(1) = Assigned, nth-child(3) = Available [39;49;00m [90m [39;49;00m
|
| available_table_selector = [33m" [39;49;00m [33m#individual_entries_tab .card-body .row:last-child .col-lg-5:nth-child(3) table [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| selected_table_selector = [33m" [39;49;00m [33m#individual_entries_tab .card-body .row:last-child .col-lg-5:nth-child(1) table [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| promote_btn_selector = [33m" [39;49;00m [33m#indivPromoteBtn [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| demote_btn_selector = [33m" [39;49;00m [33m#indivDemoteBtn [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mWaiting for Vue app to load... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| WebDriverWait( [96mself [39;49;00m.selenium, [94m30 [39;49;00m).until( [90m [39;49;00m
|
| EC.invisibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m[v-cloak] [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Select event code '100' in the sidebar if not already selected [39;49;00m [90m [39;49;00m
|
| [90m# Vue renders :data-eventCode as data-eventcode (lowercase) [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSelecting event 100... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| event_link = WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until( [90m [39;49;00m
|
| EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[data-eventcode= [39;49;00m [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| event_link.click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Wait for the tabs to update and click the category tab (e.g. 'ALL') [39;49;00m [90m [39;49;00m
|
| [90m# The tab has :data-label="ev.category" [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSelecting category ALL... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| category_tab = WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until( [90m [39;49;00m
|
| EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[data-label= [39;49;00m [33m' [39;49;00m [33mALL [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| category_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mfor [39;49;00m c [95min [39;49;00m Competitor.objects.filter(competition= [96mself [39;49;00m.mc, team_id=team_id): [90m [39;49;00m
|
| c.events_entered = [e [94mfor [39;49;00m e [95min [39;49;00m c.events_entered [94mif [39;49;00m e.event_id != [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m] [90m [39;49;00m
|
| c.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Refresh to pick up cleared state [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get( [96mself [39;49;00m.selenium.current_url) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m[v-cloak] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Re-select event and category [39;49;00m [90m [39;49;00m
|
| WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[data-eventcode= [39;49;00m [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))).click() [90m [39;49;00m
|
| WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[data-label= [39;49;00m [33m' [39;49;00m [33mALL [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))).click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Part 1: Move from Available to Selected using double-click --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mMoving athlete from Available to Selected using double-click... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, available_table_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mavailable_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| visible_rows = [r [94mfor [39;49;00m r [95min [39;49;00m rows [94mif [39;49;00m r.is_displayed() [95mand [39;49;00m [33m" [39;49;00m [33mmuted [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m r.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| [96mself [39;49;00m.assertTrue( [96mlen [39;49;00m(visible_rows) > [94m0 [39;49;00m, [33m" [39;49;00m [33mNo available eligible athletes found [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| athlete_row = visible_rows[ [94m0 [39;49;00m] [90m [39;49;00m
|
| athlete_text = athlete_row.text [90m [39;49;00m
|
| [90m# Extract the name - skip first word (badge ID) and get remaining text [39;49;00m [90m [39;49;00m
|
| words = athlete_text.split() [90m [39;49;00m
|
| athlete_name = [33m' [39;49;00m [33m [39;49;00m [33m' [39;49;00m.join(words[ [94m1 [39;49;00m:]) [94mif [39;49;00m [96mlen [39;49;00m(words) > [94m1 [39;49;00m [94melse [39;49;00m words[ [94m0 [39;49;00m] [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mDouble-clicking on athlete: [39;49;00m [33m{ [39;49;00mathlete_name [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Get count of available athletes before double-click [39;49;00m [90m [39;49;00m
|
| available_count_before = [96mlen [39;49;00m(visible_rows) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Use double-click to assign directly (bypasses highlight/promote flow) [39;49;00m [90m [39;49;00m
|
| [94mfrom [39;49;00m [90m [39;49;00m [04m [96mselenium [39;49;00m [04m [96m. [39;49;00m [04m [96mwebdriver [39;49;00m [04m [96m. [39;49;00m [04m [96mcommon [39;49;00m [04m [96m. [39;49;00m [04m [96maction_chains [39;49;00m [90m [39;49;00m [94mimport [39;49;00m ActionChains [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.move_to_element(athlete_row).double_click().perform() [90m [39;49;00m
|
| [90m# If double click is flaky, try execute_script for dblclick [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mvar evt = new MouseEvent( [39;49;00m [33m' [39;49;00m [33mdblclick [39;49;00m [33m' [39;49;00m [33m, [39;49;00m [33m{ [39;49;00m [33mbubbles: true, cancelable: true, view: window}); arguments[0].dispatchEvent(evt); [39;49;00m [33m" [39;49;00m, athlete_row) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify athlete was moved (available count should decrease by 1) [39;49;00m [90m [39;49;00m
|
| available_rows_after = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mavailable_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| available_count_after = [96mlen [39;49;00m([r [94mfor [39;49;00m r [95min [39;49;00m available_rows_after [94mif [39;49;00m r.is_displayed() [95mand [39;49;00m [33m" [39;49;00m [33mmuted [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m r.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m)]) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual(available_count_after, available_count_before - [94m1 [39;49;00m, [33mf [39;49;00m [33m" [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m [33m{ [39;49;00mathlete_name [33m} [39;49;00m [33m' [39;49;00m [33m should have been removed from available table [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Additional: Test Promote button functionality --- [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_text = [r.text [94mfor [39;49;00m r [95min [39;49;00m selected_rows] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# demote test [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mif [39;49;00m [96mlen [39;49;00m(selected_rows): [90m [39;49;00m
|
| row_to_demote = selected_rows[ [96mlen [39;49;00m(selected_rows)- [94m1 [39;49;00m] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# click it to highlight it [39;49;00m [90m [39;49;00m
|
| row_to_demote.click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# then click demote button [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mdemote_btn_selector [33m} [39;49;00m [33m" [39;49;00m)[ [94m0 [39;49;00m].click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# check they are no longer in select table [39;49;00m [90m [39;49;00m
|
| recheck_selected_text = [r.text [94mfor [39;49;00m r [95min [39;49;00m [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| found = [96many [39;49;00m(athlete_name [95min [39;49;00m text [94mfor [39;49;00m text [95min [39;49;00m recheck_selected_text) [90m [39;49;00m
|
| [96mself [39;49;00m.assertFalse(found, [33mf [39;49;00m [33m" [39;49;00m [33mAthlete [39;49;00m [33m{ [39;49;00mathlete_name [33m} [39;49;00m [33m was found in the selected table after being demoted! [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mavailable_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| visible_rows = [r [94mfor [39;49;00m r [95min [39;49;00m rows [94mif [39;49;00m r.is_displayed() [95mand [39;49;00m [33m" [39;49;00m [33mmuted [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m r.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Select second athlete for promote test [39;49;00m [90m [39;49;00m
|
| [94mif [39;49;00m [96mlen [39;49;00m(visible_rows): [90m [39;49;00m
|
| second_athlete_row = visible_rows[ [94m0 [39;49;00m] [90m [39;49;00m
|
| second_athlete_text = second_athlete_row.text [90m [39;49;00m
|
| [90m# Extract the name - skip first word (badge ID) and get remaining text [39;49;00m [90m [39;49;00m
|
| words = second_athlete_text.split() [90m [39;49;00m
|
| second_athlete_name = [33m' [39;49;00m [33m [39;49;00m [33m' [39;49;00m.join(words[ [94m1 [39;49;00m:]) [94mif [39;49;00m [96mlen [39;49;00m(words) > [94m1 [39;49;00m [94melse [39;49;00m words[ [94m0 [39;49;00m] [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTesting promote button with second athlete: [39;49;00m [33m{ [39;49;00msecond_athlete_name [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Highlight the athlete using click [39;49;00m [90m [39;49;00m
|
| second_athlete_row.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Check if promote button is available and click it [39;49;00m [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| promote_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, promote_btn_selector) [90m [39;49;00m
|
| [94mif [39;49;00m promote_btn.is_enabled() [95mand [39;49;00m [33m" [39;49;00m [33mdisabled [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m promote_btn.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mClicking promote button... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, promote_btn) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mClicked promote button. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify it moved to the selected table [39;49;00m [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_text = [r.text [94mfor [39;49;00m r [95min [39;49;00m selected_rows] [90m [39;49;00m
|
| found_second = [96many [39;49;00m(second_athlete_name [95min [39;49;00m text [94mfor [39;49;00m text [95min [39;49;00m selected_text) [90m [39;49;00m
|
| [96mself [39;49;00m.assertTrue(found_second, [33mf [39;49;00m [33m" [39;49;00m [33mSecond athlete [39;49;00m [33m' [39;49;00m [33m{ [39;49;00msecond_athlete_name [33m} [39;49;00m [33m' [39;49;00m [33m was not moved to the selected table using promote button [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSecond athlete successfully tested with promote button [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mException [39;49;00m [94mas [39;49;00m e: [90m [39;49;00m
|
| [96mprint [39;49;00m(e) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mPromote button test skipped - button not available or not functional [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mNot enough athletes to test promote button [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAthletes successfully tested with both double-click and promote button (when available) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Part 2: Add via Grid --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mOpening [39;49;00m [33m' [39;49;00m [33mBulk Entry (Excel) [39;49;00m [33m' [39;49;00m [33m grid... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| add_athlete_btn = [96mself [39;49;00m.selenium.find_element(By.XPATH, [33m" [39;49;00m [33m//button[contains(text(), [39;49;00m [33m' [39;49;00m [33mBulk Entry (Excel) [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| add_athlete_btn.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| ht_container_selector = [33m" [39;49;00m [33m#addCompetitorContainer [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ht_container_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| ht_selector = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mht_container_selector [33m} [39;49;00m [33m table.htCore [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ht_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Use more persons from fixture for grid input [39;49;00m [90m [39;49;00m
|
| p6 = Person.objects.filter(first_name= [33m" [39;49;00m [33mJames [39;49;00m [33m" [39;49;00m, last_name= [33m" [39;49;00m [33mSmith [39;49;00m [33m" [39;49;00m, gender= [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| p7 = Person.objects.filter(first_name= [33m" [39;49;00m [33mJohn [39;49;00m [33m" [39;49;00m, last_name= [33m" [39;49;00m [33mMartinez [39;49;00m [33m" [39;49;00m).first() [90m [39;49;00m
|
| p8 = Person.objects.filter(first_name= [33m" [39;49;00m [33mMichael [39;49;00m [33m" [39;49;00m, last_name= [33m" [39;49;00m [33mMiller [39;49;00m [33m" [39;49;00m, gender= [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m).first() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p6, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mJames Smith (F) [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p7, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mJohn Martinez [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(p8, [33m" [39;49;00m [33mPerson [39;49;00m [33m' [39;49;00m [33mMichael Miller (F) [39;49;00m [33m' [39;49;00m [33m not found in fixture [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| new_athletes = [ [90m [39;49;00m
|
| (p6.first_name, p6.last_name, p6.date_of_birth.isoformat(), p6.gender), [90m [39;49;00m
|
| (p7.first_name, p7.last_name, p7.date_of_birth.isoformat(), p7.gender), [90m [39;49;00m
|
| (p8.first_name, p8.last_name, p8.date_of_birth.isoformat(), p8.gender), [90m [39;49;00m
|
| ] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mfrom [39;49;00m [90m [39;49;00m [04m [96mselenium [39;49;00m [04m [96m. [39;49;00m [04m [96mwebdriver [39;49;00m [04m [96m. [39;49;00m [04m [96mcommon [39;49;00m [04m [96m. [39;49;00m [04m [96maction_chains [39;49;00m [90m [39;49;00m [94mimport [39;49;00m ActionChains [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mfor [39;49;00m i, (first, last, dob, gender) [95min [39;49;00m [96menumerate [39;49;00m(new_athletes): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mInputting grid athlete [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m: [39;49;00m [33m{ [39;49;00mfirst [33m} [39;49;00m [33m [39;49;00m [33m{ [39;49;00mlast [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| cell_xpath = [33mf [39;49;00m [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mcompetitors_ht [39;49;00m [33m' [39;49;00m [33m]//table[@class= [39;49;00m [33m' [39;49;00m [33mhtCore [39;49;00m [33m' [39;49;00m [33m]/tbody/tr[ [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m]/td[1] [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| cell = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, cell_xpath))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.move_to_element(cell).click().perform() [90m [39;49;00m
|
| time.sleep( [94m0.3 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.send_keys(first) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(last) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(dob) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(gender) [90m [39;49;00m
|
| actions.send_keys(Keys.ENTER) [90m [39;49;00m
|
| actions.perform() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Note: The "Add Athletes" button doesn't exist in the template. [39;49;00m [90m [39;49;00m
|
| [90m# Bulk entry data is saved via the handsontable's internal state when saveEntry is called. [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify grid is in sync with selected athletes after double-click [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mVerifying grid is in sync with selected athletes... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m# Wait for Vue to update [39;49;00m [90m [39;49;00m
|
| grid_data = [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mreturn window.competitor_ht ? window.competitor_ht.getData() : []; [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_rows_after_dblclick = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_names = [r.text [94mfor [39;49;00m r [95min [39;49;00m selected_rows_after_dblclick] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Check that all selected athletes appear in the grid [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m row [95min [39;49;00m selected_rows_after_dblclick: [90m [39;49;00m
|
| row_text = row.text [90m [39;49;00m
|
| words = row_text.split() [90m [39;49;00m
|
| [90m# Skip badge ID (first word) [39;49;00m [90m [39;49;00m
|
| athlete_name = [33m' [39;49;00m [33m [39;49;00m [33m' [39;49;00m.join(words[ [94m1 [39;49;00m:]) [94mif [39;49;00m [96mlen [39;49;00m(words) > [94m1 [39;49;00m [94melse [39;49;00m words[ [94m0 [39;49;00m] [90m [39;49;00m
|
| found_in_grid = [96many [39;49;00m(athlete_name.split()[ [94m0 [39;49;00m] [95min [39;49;00m [96mstr [39;49;00m(row) [95mor [39;49;00m athlete_name.split()[- [94m1 [39;49;00m] [95min [39;49;00m [96mstr [39;49;00m(row) [94mfor [39;49;00m row [95min [39;49;00m grid_data [94mif [39;49;00m row) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mChecking athlete [39;49;00m [33m' [39;49;00m [33m{ [39;49;00mathlete_name [33m} [39;49;00m [33m' [39;49;00m [33m in grid: [39;49;00m [33m{ [39;49;00m [33m' [39;49;00m [33mFound [39;49;00m [33m' [39;49;00m [90m [39;49;00m [94mif [39;49;00m [90m [39;49;00mfound_in_grid [90m [39;49;00m [94melse [39;49;00m [90m [39;49;00m [33m' [39;49;00m [33mNot found [39;49;00m [33m' [39;49;00m [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mGrid is in sync with selected athletes after double-click. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Part 2b: Add new athletes via grid and verify they appear in selected table --- [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Wait for Vue to process the grid changes and trigger update [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mWaiting for grid sync... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Trigger the Vue update manually to ensure sync [39;49;00m [90m [39;49;00m
|
| [90m# self.selenium.execute_script("if (window.app && window.app.updateCompetitorsHandsOnTable) { window.app.updateCompetitorsHandsOnTable(); }") [39;49;00m [90m [39;49;00m
|
| [90m# time.sleep(1) [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Check grid data to see what's actually in it [39;49;00m [90m [39;49;00m
|
| grid_data = [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mreturn window.competitor_ht ? window.competitor_ht.getData() : []; [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| grid_count = [96mlen [39;49;00m([r [94mfor [39;49;00m r [95min [39;49;00m grid_data [94mif [39;49;00m r [95mand [39;49;00m r.get( [33m' [39;49;00m [33mfirst_name [39;49;00m [33m' [39;49;00m)]) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mGrid has [39;49;00m [33m{ [39;49;00mgrid_count [33m} [39;49;00m [33m athletes after entry [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify selected table and grid are in sync [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mVerifying grid and selected table are in sync... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_count = [96mlen [39;49;00m(selected_rows) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mSelected table has [39;49;00m [33m{ [39;49;00mselected_count [33m} [39;49;00m [33m athletes, Grid has [39;49;00m [33m{ [39;49;00mgrid_count [33m} [39;49;00m [33m athletes [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# The grid should be in sync with selected athletes (grid is loaded from selectedAthletes) [39;49;00m [90m [39;49;00m
|
| [90m# Note: Some athletes from grid may have been filtered if they don't meet criteria [39;49;00m [90m [39;49;00m
|
| [90m# So we just verify that both have athletes and grid/selected are consistent [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.assertGreater(selected_count, [94m0 [39;49;00m, [33m" [39;49;00m [33mSelected table should have athletes [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual(grid_count, selected_count, [33m" [39;49;00m [33mGrid row count should match selected table count [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mGrid and selected table are in sync. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Also verify grid is in sync with selected table [39;49;00m [90m [39;49;00m
|
| grid_data = [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mreturn window.competitor_ht ? window.competitor_ht.getData() : []; [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| final_selected_count = [96mlen [39;49;00m( [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| expected_grid_rows = final_selected_count [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mGrid has [39;49;00m [33m{ [39;49;00m [96mlen [39;49;00m([r [90m [39;49;00m [94mfor [39;49;00m [90m [39;49;00mr [90m [39;49;00m [95min [39;49;00m [90m [39;49;00mgrid_data [90m [39;49;00m [94mif [39;49;00m [90m [39;49;00mr [90m [39;49;00m [95mand [39;49;00m [90m [39;49;00m [96many [39;49;00m(r.values())]) [33m} [39;49;00m [33m rows, selected table has [39;49;00m [33m{ [39;49;00mfinal_selected_count [33m} [39;49;00m [33m rows [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Part 3: Save and Refresh --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSaving... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mwindow.scrollTo(0, 0); [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# The save button has class "btn-primary btn-sm rounded-pill px-4 shadow-sm" [39;49;00m [90m [39;49;00m
|
| save_btn = WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until( [90m [39;49;00m
|
| EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton.btn-primary.btn-sm [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, save_btn) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33mspan.bg-success-light span.fa-check [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [94mexcept [39;49;00m: [90m [39;49;00m
|
| [94mpass [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Part 4: Refresh and verify persistence --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mRefreshing page... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.refresh() [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m[v-cloak] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mRe-selecting event... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| event_link = WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m).until( [90m [39;49;00m
|
| EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[data-eventcode= [39;49;00m [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m)) [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| event_link.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mVerifying persistence after refresh... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m# Get selected table state after refresh [39;49;00m [90m [39;49;00m
|
| selected_rows_after_refresh = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mselected_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_text_after_refresh = [r.text [94mfor [39;49;00m r [95min [39;49;00m selected_rows_after_refresh] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify some athletes persisted (not checking specific ones since test flow may have changed selection) [39;49;00m [90m [39;49;00m
|
| selected_count_after_refresh = [96mlen [39;49;00m(selected_rows_after_refresh) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mSelected table has [39;49;00m [33m{ [39;49;00mselected_count_after_refresh [33m} [39;49;00m [33m athletes after refresh [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify grid is in sync with selected table after refresh [39;49;00m [90m [39;49;00m
|
| [90m# Re-open the bulk entry grid to check its contents [39;49;00m [90m [39;49;00m
|
| add_athlete_btn = [96mself [39;49;00m.selenium.find_element(By.XPATH, [33m" [39;49;00m [33m//button[contains(text(), [39;49;00m [33m' [39;49;00m [33mBulk Entry (Excel) [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| add_athlete_btn.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ht_container_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| grid_data_after_refresh = [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mreturn window.competitor_ht ? window.competitor_ht.getData() : []; [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| grid_count_after_refresh = [96mlen [39;49;00m([r [94mfor [39;49;00m r [95min [39;49;00m grid_data_after_refresh [94mif [39;49;00m r [95mand [39;49;00m [96many [39;49;00m(r.values())]) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mAfter refresh - Selected table: [39;49;00m [33m{ [39;49;00mselected_count_after_refresh [33m} [39;49;00m [33m athletes, Grid: [39;49;00m [33m{ [39;49;00mgrid_count_after_refresh [33m} [39;49;00m [33m rows [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify selected table has athletes (at least some should have been saved) [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.assertGreater(selected_count_after_refresh, [94m0 [39;49;00m, [33m" [39;49;00m [33mSelected table should have athletes after refresh [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Grid and selected table should be in sync [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual(grid_count_after_refresh, selected_count_after_refresh, [90m [39;49;00m
|
| [33mf [39;49;00m [33m" [39;49;00m [33mGrid row count ( [39;49;00m [33m{ [39;49;00mgrid_count_after_refresh [33m} [39;49;00m [33m) should match selected table count ( [39;49;00m [33m{ [39;49;00mselected_count_after_refresh [33m} [39;49;00m [33m) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mGrid and selected table are in sync after refresh. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAll athletes persisted correctly! [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mTest completed successfully! [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mException [39;49;00m [94mas [39;49;00m e: [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.save_screenshot( [33m" [39;49;00m [33mtest_adhoc_indiv_failure.png [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mwith [39;49;00m [96mopen [39;49;00m( [33m" [39;49;00m [33mtest_adhoc_indiv_failure_source.html [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33mw [39;49;00m [33m" [39;49;00m) [94mas [39;49;00m f: [90m [39;49;00m
|
| f.write( [96mself [39;49;00m.selenium.page_source) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTest failed: [39;49;00m [33m{ [39;49;00me [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| > [94mraise [39;49;00m e [90m [39;49;00m
|
|
|
| project/comp/tests/test_team_declarations.py:735:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| project/comp/tests/test_team_declarations.py:722: in test_adhoc_individual_declarations
|
| [0m [96mself [39;49;00m.assertEqual(grid_count_after_refresh, selected_count_after_refresh, [90m [39;49;00m
|
| E AssertionError: 0 != 1 : Grid row count (0) should match selected table count (1)
|
| ____________ SeedingE2ETests.test_three_round_championship_seeding _____________
|
| [gw2] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python
|
|
|
| self = <project.comp.tests.test_seeding.SeedingE2ETests testMethod=test_three_round_championship_seeding>
|
|
|
| [0m [94mdef [39;49;00m [90m [39;49;00m [92mtest_three_round_championship_seeding [39;49;00m( [96mself [39;49;00m): [90m [39;49;00m
|
| [90m [39;49;00m [33m""" [39;49;00m
|
| [33m E2E test for multi-round seeding. [39;49;00m
|
| [33m """ [39;49;00m [90m [39;49;00m
|
| wait = WebDriverWait( [96mself [39;49;00m.selenium, [94m10 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Login [39;49;00m [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [94mfrom [39;49;00m [90m [39;49;00m [04m [96mdjango [39;49;00m [04m [96m. [39;49;00m [04m [96murls [39;49;00m [90m [39;49;00m [94mimport [39;49;00m reverse [90m [39;49;00m
|
| login_path = reverse( [33m' [39;49;00m [33mlogin [39;49;00m [33m' [39;49;00m) [90m [39;49;00m
|
| login_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mlogin_path [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mException [39;49;00m [94mas [39;49;00m e: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mError reversing login URL: [39;49;00m [33m{ [39;49;00me [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| login_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m/en-gb/accounts/login/ [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mLogging in at [39;49;00m [33m{ [39;49;00mlogin_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(login_url) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mCurrent URL: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.current_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mfrom [39;49;00m [90m [39;49;00m [04m [96mproject [39;49;00m [04m [96m. [39;49;00m [04m [96mreference [39;49;00m [04m [96m. [39;49;00m [04m [96mmongo [39;49;00m [04m [96m. [39;49;00m [04m [96munit [39;49;00m [90m [39;49;00m [94mimport [39;49;00m Unit [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mDEBUG TEST: Competitor count for event 1: [39;49;00m [33m{ [39;49;00mCompetitor.objects(competition= [96mself [39;49;00m.c, [90m [39;49;00mevents_entered__event_id= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m).count() [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| ev1 = [96mself [39;49;00m.c.get_event( [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mDEBUG TEST: Unit count for event 1: [39;49;00m [33m{ [39;49;00mUnit.objects(competition= [96mself [39;49;00m.c, [90m [39;49;00mevent=ev1).count() [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| username_field = wait.until(EC.presence_of_element_located((By.ID, [33m" [39;49;00m [33mid_username [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mFound username field [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| username_field.send_keys( [33m" [39;49;00m [33msuperuser [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.find_element(By.ID, [33m" [39;49;00m [33mid_password [39;49;00m [33m" [39;49;00m).send_keys( [33m" [39;49;00m [33msecret [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.find_element(By.ID, [33m" [39;49;00m [33mloginBtn [39;49;00m [33m" [39;49;00m).click() [90m [39;49;00m
|
| [94mexcept [39;49;00m: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTimeout or Error at login. Current URL: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.current_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mPage source snippet: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.page_source[: [94m2000 [39;49;00m] [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mraise [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Wait for login to complete by checking for a logout link or a specific dashboard element [39;49;00m [90m [39;49;00m
|
| wait.until( [94mlambda [39;49;00m d: d.current_url != login_url) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mLogged in, current URL: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.current_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Navigate to event detail private page [39;49;00m [90m [39;49;00m
|
| event_private_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mcomp_reverse( [33m' [39;49;00m [33mcomp-event-detail-private [39;49;00m [33m' [39;49;00m, [90m [39;49;00m [96mself [39;49;00m.sql_comp, [90m [39;49;00mevent_id= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m) [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to [39;49;00m [33m{ [39;49;00mevent_private_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(event_private_url) [90m [39;49;00m
|
| time.sleep( [94m3 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Round 1: Heats [39;49;00m [90m [39;49;00m
|
| [90m# make sure heats tab is selected [39;49;00m [90m [39;49;00m
|
| heats_tab = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-heats [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| heats_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mRound 1: Heats [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m# Open Seeding Options (it's a collapsible) [39;49;00m [90m [39;49;00m
|
| seeding_options_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton[data-target= [39;49;00m [33m' [39;49;00m [33m#seeding_options_r1 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mFound seeding options button [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mcollapsed [39;49;00m [33m" [39;49;00m [95min [39;49;00m seeding_options_btn.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mExpanding seeding options [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| ActionChains( [96mself [39;49;00m.selenium).click(seeding_options_btn).perform() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Click 'Seed heats' [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mClicking Seed heats [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| seed_btn = wait.until(EC.element_to_be_clickable((By.NAME, [33m" [39;49;00m [33mseed [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| seed_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m# Wait for seeding to complete (it reloads the page) [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| heats_tab = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-heats [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| heats_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Accept the upcoming confirm dialog [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Click 'Fake results' [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mClicking Fake results [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| fake_btn = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats .fake_results [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| fake_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| heats_tab = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-heats [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| heats_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Accept the upcoming confirm dialog [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Click 'Mark qualifiers' [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mClicking Mark qualifiers [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| mark_btn = wait.until(EC.element_to_be_clickable((By.NAME, [33m" [39;49;00m [33mmark_qualifiers [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| mark_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Round 2: Semi-finals [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mRound 2: Semi-finals [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m# Switch to Semi-finals tab [39;49;00m [90m [39;49;00m
|
| semi_tab = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-semifinal [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| semi_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Re-open Seeding Options if needed (it might be different form) [39;49;00m [90m [39;49;00m
|
| [90m# For Round 2, the form is in #pills-semifinal [39;49;00m [90m [39;49;00m
|
| semi_seeding_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-semifinal button[data-target= [39;49;00m [33m' [39;49;00m [33m#seeding_options_r2 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mcollapsed [39;49;00m [33m" [39;49;00m [95min [39;49;00m semi_seeding_btn.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m): [90m [39;49;00m
|
| semi_seeding_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Seed heats for semi-finals [39;49;00m [90m [39;49;00m
|
| seed_semi_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-semifinal button[name= [39;49;00m [33m' [39;49;00m [33mseed [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| seed_semi_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Accept the upcoming confirm dialog [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Fake results for semi-finals [39;49;00m [90m [39;49;00m
|
| fake_semi_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-semifinal .fake_results [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| fake_semi_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Mark qualifiers for semi-finals [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until( [94mlambda [39;49;00m _ : [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-semifinal button[name= [39;49;00m [33m' [39;49;00m [33mmark_qualifiers [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m).is_displayed()) [90m [39;49;00m
|
| mark_semi_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-semifinal button[name= [39;49;00m [33m' [39;49;00m [33mmark_qualifiers [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| mark_semi_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.reset_mouse_position() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Round 3: Finals [39;49;00m [90m [39;49;00m
|
| [90m# Switch to Finals tab [39;49;00m [90m [39;49;00m
|
| final_tab = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-final [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| final_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Seed final [39;49;00m [90m [39;49;00m
|
| [90m# Re-open Seeding Options if needed (it might be different form) [39;49;00m [90m [39;49;00m
|
| final_seeding_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-final button[data-target= [39;49;00m [33m' [39;49;00m [33m#finalSeedingForm [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mcollapsed [39;49;00m [33m" [39;49;00m [95min [39;49;00m final_seeding_btn.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m): [90m [39;49;00m
|
| final_seeding_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| seed_final_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#finalSeedingForm button[name= [39;49;00m [33m' [39;49;00m [33mseed [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| seed_final_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify athletes in final heat table [39;49;00m [90m [39;49;00m
|
| [90m# There should be a table within #pills-final [39;49;00m [90m [39;49;00m
|
| [90m# The final round table should have 8 athletes [39;49;00m [90m [39;49;00m
|
| final_results = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-final tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Filter for rows that have a bib (not empty lanes) [39;49;00m [90m [39;49;00m
|
| athletes_in_final = [row [94mfor [39;49;00m row [95min [39;49;00m final_results [94mif [39;49;00m row.find_elements(By.XPATH, [33m" [39;49;00m [33m./td[2][normalize-space()] [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mAthletes in final: [39;49;00m [33m{ [39;49;00m [96mlen [39;49;00m(athletes_in_final) [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| > [96mself [39;49;00m.assertEqual( [96mlen [39;49;00m(athletes_in_final), [94m8 [39;49;00m, [33m" [39;49;00m [33mShould have 8 athletes in the final [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| E AssertionError: 0 != 8 : Should have 8 athletes in the final
|
|
|
| project/comp/tests/test_seeding.py:1912: AssertionError
|
| ______________ CompE2ETests.test_record_length_and_height_events _______________
|
| [gw3] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python
|
|
|
| self = <project.comp.tests.test_comp_e2e.CompE2ETests testMethod=test_record_length_and_height_events>
|
|
|
| [0m [94mdef [39;49;00m [90m [39;49;00m [92mtest_record_length_and_height_events [39;49;00m( [96mself [39;49;00m): [90m [39;49;00m
|
| [90m [39;49;00m [33m"""E2E test for recording results on length (LJ) and height (HJ) events.""" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.login() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| [90m# PART 1: Long Jump (Length Event with Wind) [39;49;00m [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| lj_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mcomp_reverse( [33m' [39;49;00m [33mcomp-unit-record [39;49;00m [33m' [39;49;00m, [90m [39;49;00m [96mself [39;49;00m.sql_comp, [90m [39;49;00mevent_id= [33m' [39;49;00m [33m3 [39;49;00m [33m' [39;49;00m, [90m [39;49;00m [96mround [39;49;00m= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m, [90m [39;49;00mheat= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m) [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mLJ recording URL: [39;49;00m [33m{ [39;49;00mlj_url [33m} [39;49;00m [33m" [39;49;00m, flush= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(lj_url) [90m [39;49;00m
|
| time.sleep( [94m3 [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mCurrent URL: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.current_url [33m} [39;49;00m [33m" [39;49;00m, flush= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mPage title: [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.selenium.title [33m} [39;49;00m [33m" [39;49;00m, flush= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| body = [96mself [39;49;00m.selenium.find_element(By.TAG_NAME, [33m" [39;49;00m [33mbody [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mBody text: [39;49;00m [33m{ [39;49;00mbody.text[: [94m1500 [39;49;00m] [33m} [39;49;00m [33m" [39;49;00m, flush= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mException [39;49;00m [94mas [39;49;00m e: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mFailed to get body: [39;49;00m [33m{ [39;49;00me [33m} [39;49;00m [33m" [39;49;00m, flush= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.save_screenshot( [33m' [39;49;00m [33m/tmp/lj_page.png [39;49;00m [33m' [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until( [94mlambda [39;49;00m _: [96mlen [39;49;00m( [96mself [39;49;00m._length_starter_rows()) > [94m0 [39;49;00m) [90m [39;49;00m
|
| athletes = [96mself [39;49;00m._length_starter_rows() [90m [39;49;00m
|
| [96mself [39;49;00m.assertGreater( [96mlen [39;49;00m(athletes), [94m0 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Click first athlete and record a valid jump with wind [39;49;00m [90m [39;49;00m
|
| athletes[ [94m0 [39;49;00m].click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m._record_length_trial(distance= [33m" [39;49;00m [33m6.50 [39;49;00m [33m" [39;49;00m, wind= [33m" [39;49;00m [33m+1.2 [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify the trial was saved [39;49;00m [90m [39;49;00m
|
| first_bib = athletes[ [94m0 [39;49;00m].find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m.col-xs-1:nth-child(2) [39;49;00m [33m" [39;49;00m).text.strip() [90m [39;49;00m
|
| trial_container = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33mdiv[id= [39;49;00m [33m' [39;49;00m [33m{ [39;49;00mfirst_bib [33m} [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33m6.50 [39;49;00m [33m" [39;49;00m, trial_container.text) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Delete the result by clicking remove last observation button [39;49;00m [90m [39;49;00m
|
| remove_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m.del.focused .btn-danger [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| remove_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Re-record a different distance for first athlete [39;49;00m [90m [39;49;00m
|
| rows = [96mself [39;49;00m._length_starter_rows() [90m [39;49;00m
|
| rows[ [94m0 [39;49;00m].click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m._record_length_trial(distance= [33m" [39;49;00m [33m6.80 [39;49;00m [33m" [39;49;00m, wind= [33m" [39;49;00m [33m+0.5 [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Record results for remaining athletes [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m idx [95min [39;49;00m [96mrange [39;49;00m( [94m1 [39;49;00m, [96mlen [39;49;00m(athletes)): [90m [39;49;00m
|
| rows = [96mself [39;49;00m._length_starter_rows() [90m [39;49;00m
|
| rows[idx].click() [90m [39;49;00m
|
| time.sleep( [94m0.3 [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m idx == [94m1 [39;49;00m: [90m [39;49;00m
|
| [96mself [39;49;00m._record_length_trial(is_foul= [94mTrue [39;49;00m) [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| [96mself [39;49;00m._record_length_trial(distance= [33m" [39;49;00m [33m5.00 [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.3 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Click Finish [39;49;00m [90m [39;49;00m
|
| finish_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton[title= [39;49;00m [33m' [39;49;00m [33mFinish [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| finish_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| [90m# PART 2: High Jump (Height Event) [39;49;00m [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| hj_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mcomp_reverse( [33m' [39;49;00m [33mcomp-unit-record [39;49;00m [33m' [39;49;00m, [90m [39;49;00m [96mself [39;49;00m.sql_comp, [90m [39;49;00mevent_id= [33m' [39;49;00m [33m9 [39;49;00m [33m' [39;49;00m, [90m [39;49;00m [96mround [39;49;00m= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m, [90m [39;49;00mheat= [33m' [39;49;00m [33m1 [39;49;00m [33m' [39;49;00m) [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(hj_url) [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| time.sleep( [94m3 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Set bar height [39;49;00m [90m [39;49;00m
|
| form_well = [96mself [39;49;00m.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33mform.well [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| raise_btn = form_well.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton.btn-info [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, raise_btn) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| new_height_input = form_well.find_element(By.NAME, [33m" [39;49;00m [33mnew_height [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| new_height_input.clear() [90m [39;49;00m
|
| new_height_input.send_keys( [33m" [39;49;00m [33m1.80 [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| confirm_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, [33m" [39;49;00m [33m//button[text()= [39;49;00m [33m' [39;49;00m [33mConfirm [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| confirm_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Find jumper rows [39;49;00m [90m [39;49;00m
|
| jumper_rows = [94mlambda [39;49;00m: [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33mtable.table tbody > tr:not(.obs) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until( [94mlambda [39;49;00m _: [96mlen [39;49;00m(jumper_rows()) > [94m0 [39;49;00m) [90m [39;49;00m
|
| jumpers = jumper_rows() [90m [39;49;00m
|
| [96mself [39;49;00m.assertGreater( [96mlen [39;49;00m(jumpers), [94m0 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Record O/X for each jumper [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m idx [95min [39;49;00m [96mrange [39;49;00m( [96mlen [39;49;00m(jumpers)): [90m [39;49;00m
|
| jumpers = jumper_rows() [90m [39;49;00m
|
| jumpers[idx].click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| obs_record_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mtr.obs a.btn-warning [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| obs_record_btn.click() [90m [39;49;00m
|
| modal = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.ID, [33m" [39;49;00m [33mobsEntry [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [94mif [39;49;00m idx == [94m1 [39;49;00m: [90m [39;49;00m
|
| modal.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m.btn-danger [39;49;00m [33m" [39;49;00m).click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| obs_record_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mtr.obs a.btn-warning [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| obs_record_btn.click() [90m [39;49;00m
|
| modal = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.ID, [33m" [39;49;00m [33mobsEntry [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| modal.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m.btn-danger [39;49;00m [33m" [39;49;00m).click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| obs_record_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mtr.obs a.btn-warning [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| obs_record_btn.click() [90m [39;49;00m
|
| modal = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.ID, [33m" [39;49;00m [33mobsEntry [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| modal.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m.btn-success [39;49;00m [33m" [39;49;00m).click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| modal.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m.btn-success [39;49;00m [33m" [39;49;00m).click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.invisibility_of_element_located((By.ID, [33m" [39;49;00m [33mobsEntry [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Finish the height event [39;49;00m [90m [39;49;00m
|
| hj_finish_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton.btn-primary[title= [39;49;00m [33m' [39;49;00m [33mFinish [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| hj_finish_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| [90m# PART 3: Verify HJ results persistence [39;49;00m [90m [39;49;00m
|
| [90m# ============================================== [39;49;00m [90m [39;49;00m
|
| time.sleep( [94m2 [39;49;00m) [90m# ensure finish API call has completed [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Re-navigate to HJ recording page to verify data persisted [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(hj_url) [90m [39;49;00m
|
| [96mself [39;49;00m.accept_confirm() [90m [39;49;00m
|
| time.sleep( [94m3 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Wait for jumper rows and verify count [39;49;00m [90m [39;49;00m
|
| jumper_rows = [94mlambda [39;49;00m: [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33mtable.table tbody > tr:not(.obs) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| > [96mself [39;49;00m.wait.until( [94mlambda [39;49;00m _: [96mlen [39;49;00m(jumper_rows()) > [94m0 [39;49;00m) [90m [39;49;00m
|
|
|
| project/comp/tests/test_comp_e2e.py:205:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| self = <selenium.webdriver.support.wait.WebDriverWait (session="840bf2c50c41e402619d88d0a72af9a8")>
|
| method = <function CompE2ETests.test_record_length_and_height_events.<locals>.<lambda> at 0x7f3992e940e0>
|
| message = ''
|
|
|
| [0m [94mdef [39;49;00m [90m [39;49;00m [92muntil [39;49;00m( [96mself [39;49;00m, method: Callable[[D], Union[Literal[ [94mFalse [39;49;00m], T]], message: [96mstr [39;49;00m = [33m" [39;49;00m [33m" [39;49;00m) -> T: [90m [39;49;00m
|
| [90m [39;49;00m [33m"""Wait until the method returns a value that is not False. [39;49;00m
|
| [33m [39;49;00m
|
| [33m Calls the method provided with the driver as an argument until the [39;49;00m
|
| [33m return value does not evaluate to ``False``. [39;49;00m
|
| [33m [39;49;00m
|
| [33m Parameters: [39;49;00m
|
| [33m ----------- [39;49;00m
|
| [33m method: callable(WebDriver) [39;49;00m
|
| [33m - A callable object that takes a WebDriver instance as an argument. [39;49;00m
|
| [33m [39;49;00m
|
| [33m message: str [39;49;00m
|
| [33m - Optional message for :exc:`TimeoutException` [39;49;00m
|
| [33m [39;49;00m
|
| [33m Return: [39;49;00m
|
| [33m ------- [39;49;00m
|
| [33m object: T [39;49;00m
|
| [33m - The result of the last call to `method` [39;49;00m
|
| [33m [39;49;00m
|
| [33m Raises: [39;49;00m
|
| [33m ------- [39;49;00m
|
| [33m TimeoutException [39;49;00m
|
| [33m - If 'method' does not return a truthy value within the WebDriverWait [39;49;00m
|
| [33m object's timeout [39;49;00m
|
| [33m [39;49;00m
|
| [33m Example: [39;49;00m
|
| [33m -------- [39;49;00m
|
| [33m >>> from selenium.webdriver.common.by import By [39;49;00m
|
| [33m >>> from selenium.webdriver.support.ui import WebDriverWait [39;49;00m
|
| [33m >>> from selenium.webdriver.support import expected_conditions as EC [39;49;00m
|
| [33m [39;49;00m
|
| [33m # Wait until an element is visible on the page [39;49;00m
|
| [33m >>> wait = WebDriverWait(driver, 10) [39;49;00m
|
| [33m >>> element = wait.until(EC.visibility_of_element_located((By.ID, "exampleId"))) [39;49;00m
|
| [33m >>> print(element.text) [39;49;00m
|
| [33m """ [39;49;00m [90m [39;49;00m
|
| screen = [94mNone [39;49;00m [90m [39;49;00m
|
| stacktrace = [94mNone [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| end_time = time.monotonic() + [96mself [39;49;00m._timeout [90m [39;49;00m
|
| [94mwhile [39;49;00m [94mTrue [39;49;00m: [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| value = method( [96mself [39;49;00m._driver) [90m [39;49;00m
|
| [94mif [39;49;00m value: [90m [39;49;00m
|
| [94mreturn [39;49;00m value [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mself [39;49;00m._ignored_exceptions [94mas [39;49;00m exc: [90m [39;49;00m
|
| screen = [96mgetattr [39;49;00m(exc, [33m" [39;49;00m [33mscreen [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| stacktrace = [96mgetattr [39;49;00m(exc, [33m" [39;49;00m [33mstacktrace [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m time.monotonic() > end_time: [90m [39;49;00m
|
| [94mbreak [39;49;00m [90m [39;49;00m
|
| time.sleep( [96mself [39;49;00m._poll) [90m [39;49;00m
|
| > [94mraise [39;49;00m TimeoutException(message, screen, stacktrace) [90m [39;49;00m
|
| E selenium.common.exceptions.TimeoutException: Message:
|
|
|
| /opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/selenium/webdriver/support/wait.py:146: TimeoutException
|
| ____________ TeamDeclarationsE2ETests.test_adhoc_relay_declarations ____________
|
| [gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python
|
|
|
| self = <project.comp.tests.test_team_declarations.TeamDeclarationsE2ETests testMethod=test_adhoc_relay_declarations>
|
|
|
| [0m [37m@superuser_login_required [39;49;00m [90m [39;49;00m
|
| [94mdef [39;49;00m [90m [39;49;00m [92mtest_adhoc_relay_declarations [39;49;00m( [96mself [39;49;00m): [90m [39;49;00m
|
| [90m [39;49;00m [33m""" [39;49;00m
|
| [33m Test adhoc team declarations relays. [39;49;00m
|
| [33m [39;49;00m
|
| [33m Summary: [39;49;00m
|
| [33m - Change the team category for a relay team should save after change. [39;49;00m
|
| [33m - Select 4 athletes to fill a 4x400 relay event from the available athletes table and move them across to selected table. [39;49;00m
|
| [33m - Click the save button and check that they persist after save and refreshing page. [39;49;00m
|
| [33m - Use the up and down arrows to change the order of the relay athletes [39;49;00m
|
| [33m - Click save and check that the ordering persists after refreshing page. [39;49;00m
|
| [33m - Use the relay grid to input two athletes. Check that any existing athletes are not editible through the grid. [39;49;00m
|
| [33m - Once finished inputting, check that the athletes show in the selected athletes table and their ordering can be changed. [39;49;00m
|
| [33m - Click save and check that the ordering persists after refreshing page. [39;49;00m
|
| [33m - Create two new relay team by clicking the plus button. [39;49;00m
|
| [33m - Check that the relayteam_id is set to the next character in the alpherbet. [39;49;00m
|
| [33m - Click save and check that the ordering persists after refreshing page. [39;49;00m
|
| [33m - Add some athletes to the last team then remove the middle relay team and check that the last team is updated. [39;49;00m
|
| [33m - If relayteam_id was ADHOC1-C then it should now be ADHOC1-B and the athletes event entries for this relay team should be updated also. [39;49;00m
|
| [33m """ [39;49;00m [90m [39;49;00m
|
| [90m# 1. Setup: Create a new adhoc TeamEntry (no organisation) [39;49;00m [90m [39;49;00m
|
| team_id = [33m' [39;49;00m [33mADHOC1 [39;49;00m [33m' [39;49;00m [90m [39;49;00m
|
| te = TeamEntry.objects.filter(competition= [96mself [39;49;00m.mc, team_id=team_id).first() [90m [39;49;00m
|
| [94mif [39;49;00m te: [90m [39;49;00m
|
| te.delete() [90m [39;49;00m
|
| [90m [39;49;00m
|
| te = TeamEntry( [90m [39;49;00m
|
| competition= [96mself [39;49;00m.mc, [90m [39;49;00m
|
| team_id=team_id, [90m [39;49;00m
|
| team_name= [33m' [39;49;00m [33mAdhoc Team 1 [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| is_adhoc= [94mTrue [39;49;00m [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| te.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# 1.5 Set some competition settings [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.mc.relay_extra_reserves = [94m4 [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.mc.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# 2. Setup: Create competitors for this team [39;49;00m [90m [39;49;00m
|
| [90m# We need at least 4 for a relay (4x400) [39;49;00m [90m [39;49;00m
|
| runners_data = [ [90m [39;49;00m
|
| ( [94m1 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mOne [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-01 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m2 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mTwo [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-02 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m3 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mThree [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2010-01-03 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m4 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mFour [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2010-01-04 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ] [90m [39;49;00m
|
| [90m [39;49;00m
|
| reserve_runners_data = [ [90m [39;49;00m
|
| ( [94m5 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mFive [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-01 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m6 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mSix [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-02 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m7 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mSeven [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2010-01-03 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m8 [39;49;00m, [33m' [39;49;00m [33mAthlete [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mEight [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2010-01-04 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ] [90m [39;49;00m
|
| [90m [39;49;00m
|
| competitors = [] [90m [39;49;00m
|
| [94mfor [39;49;00m idx, first, last, dob, gender [95min [39;49;00m runners_data: [90m [39;49;00m
|
| bib = [33mf [39;49;00m [33m" [39;49;00m [33mA [39;49;00m [33m{ [39;49;00midx [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| c = Competitor.objects.filter(competition= [96mself [39;49;00m.mc, competitor_id=bib).first() [90m [39;49;00m
|
| [94mif [39;49;00m c: [90m [39;49;00m
|
| c.delete() [90m [39;49;00m
|
| c = Competitor( [90m [39;49;00m
|
| competition= [96mself [39;49;00m.mc, [90m [39;49;00m
|
| competitor_id=bib, [90m [39;49;00m
|
| first_name=first, [90m [39;49;00m
|
| last_name=last, [90m [39;49;00m
|
| gender=gender, [90m [39;49;00m
|
| age_group= [33m' [39;49;00m [33mSEN [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| category= [33m' [39;49;00m [33mSM [39;49;00m [33m' [39;49;00m, [90m [39;49;00m
|
| team_id=team_id, [90m [39;49;00m
|
| date_of_birth=date.fromisoformat(dob), [90m [39;49;00m
|
| is_team_entry= [94mTrue [39;49;00m, [90m [39;49;00m
|
| numbered= [94mTrue [39;49;00m [90m [39;49;00m
|
| ) [90m [39;49;00m
|
| c.save() [90m [39;49;00m
|
| competitors.append(c) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Ensure a relay event exists [39;49;00m [90m [39;49;00m
|
| relay_event = [96mnext [39;49;00m((ev [94mfor [39;49;00m ev [95min [39;49;00m [96mself [39;49;00m.mc.get_events() [94mif [39;49;00m ev.event_code.startswith( [33m' [39;49;00m [33m4x [39;49;00m [33m' [39;49;00m)), [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m relay_event: [90m [39;49;00m
|
| [90m# try to find any event with 'relay' in name [39;49;00m [90m [39;49;00m
|
| relay_event = [96mnext [39;49;00m((ev [94mfor [39;49;00m ev [95min [39;49;00m [96mself [39;49;00m.mc.get_events() [94mif [39;49;00m [33m' [39;49;00m [33mrelay [39;49;00m [33m' [39;49;00m [95min [39;49;00m ev.name.lower()), [94mNone [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(relay_event, [33m" [39;49;00m [33mNo relay event found in competition [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| relay_event_id = relay_event.event_id [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Ensure the relay team exists for this adhoc team [39;49;00m [90m [39;49;00m
|
| created, rt = get_or_create_relayteam( [96mself [39;49;00m.mc, relay_event_id, team_id) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# sync to TeamEntry object for team declarations [39;49;00m [90m [39;49;00m
|
| te.sync_from_relay_teams(force= [94mTrue [39;49;00m) [90m [39;49;00m
|
| te.save() [90m [39;49;00m
|
| te = TeamEntry.objects.filter(competition= [96mself [39;49;00m.mc, team_id=team_id).first() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mTeamEntry relay teams [39;49;00m [33m" [39;49;00m, te.relay_teams) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(rt, [33m" [39;49;00m [33mFailed to get or create relay team [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| rt.bib = [33m' [39;49;00m [33m100 [39;49;00m [33m' [39;49;00m [90m# Give it a bib [39;49;00m [90m [39;49;00m
|
| rt.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# 3. Navigate to the adhoc relay entry page [39;49;00m [90m [39;49;00m
|
| url = reverse( [33m' [39;49;00m [33mcomp-team-entry-adhoc-edit [39;49;00m [33m' [39;49;00m, kwargs={ [90m [39;49;00m
|
| [33m' [39;49;00m [33myear [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.year, [90m [39;49;00m
|
| [33m' [39;49;00m [33mcountry [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.country, [90m [39;49;00m
|
| [33m' [39;49;00m [33mslug [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.slug, [90m [39;49;00m
|
| [33m' [39;49;00m [33mteam_id [39;49;00m [33m' [39;49;00m: team_id [90m [39;49;00m
|
| }) [90m [39;49;00m
|
| full_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00murl [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to: [39;49;00m [33m{ [39;49;00mfull_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(full_url) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mWaiting for Vue app to load... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m[v-cloak] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 1: Relay Teams Tab --- [39;49;00m [90m [39;49;00m
|
| relay_tab_link = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#relay_teams_tab [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| relay_tab_link.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Select the relay event [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mSelecting relay event [39;49;00m [33m{ [39;49;00mrelay_event.name [33m} [39;49;00m [33m... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| event_btn_xpath = [33mf [39;49;00m [33m" [39;49;00m [33m//a[@data-eventid= [39;49;00m [33m' [39;49;00m [33m{ [39;49;00mrelay_event_id [33m} [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| event_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, event_btn_xpath))) [90m [39;49;00m
|
| event_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- New: Select athletes from available table using promote button --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m--- Testing selection from available table --- [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| relay_available_table_selector = [33m" [39;49;00m [33m#relay_teams_tab .card-body .row:last-child .col-lg-5:nth-child(3) table [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| relay_selected_table_selector = [33m" [39;49;00m [33m#relay_teams_tab .card-body .row:last-child .col-lg-5:nth-child(1) table [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| relay_promote_btn_selector = [33m" [39;49;00m [33m#relayPromoteBtn [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| relay_demote_btn_selector = [33m" [39;49;00m [33m#relayDemoteBtn [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, relay_available_table_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Select 4 runners [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m i [95min [39;49;00m [96mrange [39;49;00m( [94m4 [39;49;00m): [90m [39;49;00m
|
| rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_available_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| visible_rows = [r [94mfor [39;49;00m r [95min [39;49;00m rows [94mif [39;49;00m r.is_displayed() [95mand [39;49;00m [33m" [39;49;00m [33mmuted [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m r.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| [96mself [39;49;00m.assertTrue( [96mlen [39;49;00m(visible_rows) > [94m0 [39;49;00m, [33mf [39;49;00m [33m" [39;49;00m [33mNo available eligible athletes found at step [39;49;00m [33m{ [39;49;00mi [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| athlete_row = visible_rows[ [94m0 [39;49;00m] [90m [39;49;00m
|
| athlete_name = athlete_row.text [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mSelecting athlete [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m: [39;49;00m [33m{ [39;49;00mathlete_name [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| athlete_row.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| promote_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, relay_promote_btn_selector) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, promote_btn) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify 4 runners in selected table [39;49;00m [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual( [96mlen [39;49;00m(selected_rows), [94m4 [39;49;00m, [33m" [39;49;00m [33mExpected 4 athletes in selected table [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Test demote [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mTesting demote button... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| last_selected_row = selected_rows[- [94m1 [39;49;00m] [90m [39;49;00m
|
| last_selected_name = last_selected_row.text [90m [39;49;00m
|
| last_selected_row.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| demote_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, relay_demote_btn_selector) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, demote_btn) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual( [96mlen [39;49;00m(selected_rows), [94m3 [39;49;00m, [33m" [39;49;00m [33mExpected 3 athletes in selected table after demote [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Promote back to 4 [39;49;00m [90m [39;49;00m
|
| rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_available_table_selector [33m} [39;49;00m [33m tbody tr [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| visible_rows = [r [94mfor [39;49;00m r [95min [39;49;00m rows [94mif [39;49;00m r.is_displayed() [95mand [39;49;00m [33m" [39;49;00m [33mmuted [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m r.get_attribute( [33m" [39;49;00m [33mclass [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| visible_rows[ [94m0 [39;49;00m].click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, promote_btn) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- New: Test ordering with arrows --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m--- Testing ordering with arrows --- [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| runner_to_move = selected_rows[ [94m1 [39;49;00m] [90m [39;49;00m
|
| runner_name = runner_to_move.text [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mMoving runner [39;49;00m [33m{ [39;49;00mrunner_name [33m} [39;49;00m [33m up [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| runner_to_move.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m# Find the up arrow specifically in the highlighted row [39;49;00m [90m [39;49;00m
|
| ath_id = runner_to_move.get_attribute( [33m" [39;49;00m [33mdata-id [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| up_arrow_selector = [33mf [39;49;00m [33m" [39;49;00m [33mtr[data-id= [39;49;00m [33m' [39;49;00m [33m{ [39;49;00math_id [33m} [39;49;00m [33m' [39;49;00m [33m] .fa-chevron-up [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| up_arrow = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, up_arrow_selector))) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, up_arrow) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify it moved to first position [39;49;00m [90m [39;49;00m
|
| reordered_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual(reordered_rows[ [94m0 [39;49;00m].text, runner_name, [33m" [39;49;00m [33mRunner did not move up correctly [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 2: Input athletes via Handsontable grid --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mInteracting with Handsontable for relay runners... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| bulk_relay_btn_selector = [33m" [39;49;00m [33m#bulkRelayBtn [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| bulk_relay_btn = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, bulk_relay_btn_selector))) [90m [39;49;00m
|
| bulk_relay_btn.click() [90m [39;49;00m
|
| time.sleep( [94m2 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| ht_selector = [33m" [39;49;00m [33m#runners_ht table.htCore [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ht_selector))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Check grid editability: existing runners should be readOnly [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mChecking grid editability... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| is_readonly = [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mreturn window.relay_ht.getCellMeta(0, 1).readOnly; [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertTrue(is_readonly, [33m" [39;49;00m [33mExisting runner in grid should be readOnly [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Adding some reserve runners --- [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m i, (idx, first, last, dob, gender) [95min [39;49;00m [96menumerate [39;49;00m(reserve_runners_data, start= [94m4 [39;49;00m): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mInputting runner [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m: [39;49;00m [33m{ [39;49;00mfirst [33m} [39;49;00m [33m [39;49;00m [33m{ [39;49;00mlast [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| cell_xpath = [33mf [39;49;00m [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mrunners_ht [39;49;00m [33m' [39;49;00m [33m]//table[@class= [39;49;00m [33m' [39;49;00m [33mhtCore [39;49;00m [33m' [39;49;00m [33m]/tbody/tr[ [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m]/td[1] [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| cell = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, cell_xpath))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.move_to_element(cell).click().perform() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.send_keys( [96mstr [39;49;00m(idx)) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(first) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(last) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(dob) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(gender) [90m [39;49;00m
|
| actions.send_keys(Keys.ENTER) [90m [39;49;00m
|
| actions.perform() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 3: Save --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSaving team A... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| save_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mrelay_teams_tab [39;49;00m [33m' [39;49;00m [33m]//button[contains(., [39;49;00m [33m' [39;49;00m [33mSave Changes [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, save_btn) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mWaiting for save confirmation... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.presence_of_element_located((By.XPATH, [33m" [39;49;00m [33m//*[contains(translate(text(), [39;49;00m [33m' [39;49;00m [33mABCDEFGHIJKLMNOPQRSTUVWXYZ [39;49;00m [33m' [39;49;00m [33m, [39;49;00m [33m' [39;49;00m [33mabcdefghijklmnopqrstuvwxyz [39;49;00m [33m' [39;49;00m [33m), [39;49;00m [33m' [39;49;00m [33mentries saved [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mEntries saved. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| rt.reload() [90m [39;49;00m
|
| rt.fetch_runners() [90m [39;49;00m
|
| rt.save() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 4: Add two more relay teams --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== PART 1: Adding relay teams B and C === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| event_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, event_btn_xpath))) [90m [39;49;00m
|
| event_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| add_team_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m#relay_teams_tab button.btn-outline-success [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| add_team_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAdded team B [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| add_team_btn.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAdded team C [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify alphabetical order in UI tabs [39;49;00m [90m [39;49;00m
|
| team_tabs = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33m#relay_teams_tab ul.nav-tabs li.nav-item a [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| team_labels = [t.text.strip() [94mfor [39;49;00m t [95min [39;49;00m team_tabs [94mif [39;49;00m [33m" [39;49;00m [33mTeam [39;49;00m [33m" [39;49;00m [95min [39;49;00m t.text] [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTeam tabs found: [39;49;00m [33m{ [39;49;00mteam_labels [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mTeam A [39;49;00m [33m" [39;49;00m, team_labels) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mTeam B [39;49;00m [33m" [39;49;00m, team_labels) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mTeam C [39;49;00m [33m" [39;49;00m, team_labels) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Switch to team C and add some runners [39;49;00m [90m [39;49;00m
|
| team_tabs[- [94m1 [39;49;00m].click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| team_c_runners = [ [90m [39;49;00m
|
| ( [94m1 [39;49;00m, [33m' [39;49;00m [33mCharlie [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mOne [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-01 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mM [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ( [94m2 [39;49;00m, [33m' [39;49;00m [33mCharlie [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mTwo [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33m2015-01-02 [39;49;00m [33m' [39;49;00m, [33m' [39;49;00m [33mF [39;49;00m [33m' [39;49;00m), [90m [39;49;00m
|
| ] [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33m$( [39;49;00m [33m' [39;49;00m [33m#addRelayTeamContainer [39;49;00m [33m' [39;49;00m [33m).collapse( [39;49;00m [33m' [39;49;00m [33mshow [39;49;00m [33m' [39;49;00m [33m) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33mwindow.app.initRelayCompetitorsHandsOnTable() [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mfor [39;49;00m i, (idx, first, last, dob, gender) [95min [39;49;00m [96menumerate [39;49;00m(team_c_runners): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mInputting runner [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m for team C: [39;49;00m [33m{ [39;49;00mfirst [33m} [39;49;00m [33m [39;49;00m [33m{ [39;49;00mlast [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| cell_xpath = [33mf [39;49;00m [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mrunners_ht [39;49;00m [33m' [39;49;00m [33m]//table[@class= [39;49;00m [33m' [39;49;00m [33mhtCore [39;49;00m [33m' [39;49;00m [33m]/tbody/tr[ [39;49;00m [33m{ [39;49;00mi+ [94m1 [39;49;00m [33m} [39;49;00m [33m]/td[1] [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| cell = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, cell_xpath))) [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.move_to_element(cell).click().perform() [90m [39;49;00m
|
| time.sleep( [94m0.3 [39;49;00m) [90m [39;49;00m
|
| actions = ActionChains( [96mself [39;49;00m.selenium) [90m [39;49;00m
|
| actions.send_keys( [96mstr [39;49;00m(idx + [94m20 [39;49;00m)) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(first) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(last) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(dob) [90m [39;49;00m
|
| actions.send_keys(Keys.TAB) [90m [39;49;00m
|
| actions.send_keys(gender) [90m [39;49;00m
|
| actions.send_keys(Keys.ENTER) [90m [39;49;00m
|
| actions.perform() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSaving teams... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| save_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mrelay_teams_tab [39;49;00m [33m' [39;49;00m [33m]//button[contains(., [39;49;00m [33m' [39;49;00m [33mSave Changes [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, save_btn) [90m [39;49;00m
|
| time.sleep( [94m2 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 5: Refresh and verify athletes and order persist --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== PART 2: Refreshing and verifying persistence === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.refresh() [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m[v-cloak] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| relay_tab_link = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#relay_teams_tab [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| relay_tab_link.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| event_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, event_btn_xpath))) [90m [39;49;00m
|
| event_btn.click() [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until( [94mlambda [39;49;00m d: [33m" [39;49;00m [33m--- [39;49;00m [33m" [39;49;00m [95mnot [39;49;00m [95min [39;49;00m d.find_element(By.CSS_SELECTOR, relay_selected_table_selector + [33m" [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m).text) [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m# Check team A order persistence [39;49;00m [90m [39;49;00m
|
| selected_rows = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mrelay_selected_table_selector [33m} [39;49;00m [33m tbody tr:not(.muted) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mFirst runner at refresh: [39;49;00m [33m{ [39;49;00mselected_rows[ [94m0 [39;49;00m].text.strip()[: [94m20 [39;49;00m] [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertEqual(selected_rows[ [94m0 [39;49;00m].text, runner_name, [33m" [39;49;00m [33mRunner order did not persist after refresh [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 6: Remove middle team (B) and check renaming --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== PART 3: Removing Team B and checking renaming === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| team_tabs = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33m#relay_teams_tab ul.nav-tabs li.nav-item a [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m# Team B is index 1 [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m tab [95min [39;49;00m team_tabs: [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mTeam B [39;49;00m [33m" [39;49;00m [95min [39;49;00m tab.text: [90m [39;49;00m
|
| tab.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [94mbreak [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| remove_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m#removeRelayTeamBtn [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, remove_btn) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.switch_to.alert.accept() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [94mexcept [39;49;00m: [90m [39;49;00m
|
| [94mpass [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify UI renaming before save [39;49;00m [90m [39;49;00m
|
| team_tabs_after = [96mself [39;49;00m.selenium.find_elements(By.CSS_SELECTOR, [33m" [39;49;00m [33m#relay_teams_tab ul.nav-tabs li.nav-item a [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| team_labels_after = [t.text.strip() [94mfor [39;49;00m t [95min [39;49;00m team_tabs_after [94mif [39;49;00m [33m" [39;49;00m [33mTeam [39;49;00m [33m" [39;49;00m [95min [39;49;00m t.text] [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTeam tabs after removal: [39;49;00m [33m{ [39;49;00mteam_labels_after [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertNotIn( [33m" [39;49;00m [33mTeam C [39;49;00m [33m" [39;49;00m, team_labels_after, [33m" [39;49;00m [33mTeam C should have been renamed [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mTeam B [39;49;00m [33m" [39;49;00m, team_labels_after, [33m" [39;49;00m [33mTeam B should still exist (now representing what was C) [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Check Charlie moved to B [39;49;00m [90m [39;49;00m
|
| [94mfor [39;49;00m tab [95min [39;49;00m team_tabs_after: [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mTeam B [39;49;00m [33m" [39;49;00m [95min [39;49;00m tab.text: [90m [39;49;00m
|
| tab.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [94mbreak [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| page_text = [96mself [39;49;00m.selenium.find_element(By.TAG_NAME, [33m" [39;49;00m [33mbody [39;49;00m [33m" [39;49;00m).text [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mCharlie [39;49;00m [33m" [39;49;00m, page_text, [33m" [39;49;00m [33mFormer Team C athletes (Charlie) not found in renamed Team B [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| save_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.XPATH, [33m" [39;49;00m [33m//div[@id= [39;49;00m [33m' [39;49;00m [33mrelay_teams_tab [39;49;00m [33m' [39;49;00m [33m]//button[contains(., [39;49;00m [33m' [39;49;00m [33mSave Changes [39;49;00m [33m' [39;49;00m [33m)] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].click(); [39;49;00m [33m" [39;49;00m, save_btn) [90m [39;49;00m
|
| time.sleep( [94m2 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# Verify in database [39;49;00m [90m [39;49;00m
|
| all_teams_db = RelayTeam.objects.filter(competition= [96mself [39;49;00m.mc, event_id=relay_event_id, team_id=team_id).order_by( [33m' [39;49;00m [33mrelayteam_id [39;49;00m [33m' [39;49;00m) [90m [39;49;00m
|
| db_ids = [t.relayteam_id [94mfor [39;49;00m t [95min [39;49;00m all_teams_db] [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mRelay teams in DB: [39;49;00m [33m{ [39;49;00mdb_ids [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mteam_id [33m} [39;49;00m [33m-A [39;49;00m [33m" [39;49;00m, db_ids) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mteam_id [33m} [39;49;00m [33m-B [39;49;00m [33m" [39;49;00m, db_ids) [90m [39;49;00m
|
| [96mself [39;49;00m.assertNotIn( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mteam_id [33m} [39;49;00m [33m-C [39;49;00m [33m" [39;49;00m, db_ids) [90m [39;49;00m
|
| [90m [39;49;00m
|
| team_b_db = all_teams_db.filter(relayteam_id= [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mteam_id [33m} [39;49;00m [33m-B [39;49;00m [33m" [39;49;00m).first() [90m [39;49;00m
|
| team_b_runners = [r.first_name [94mfor [39;49;00m r [95min [39;49;00m team_b_db.runners] [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn( [33m" [39;49;00m [33mCharlie [39;49;00m [33m" [39;49;00m, team_b_runners, [33m" [39;49;00m [33mDatabase did not update runners for renamed team [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAll relay tests completed successfully! [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 7: Number all athletes before seeding --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== PART 4: Numbering athletes === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| numbering_url = reverse( [33m' [39;49;00m [33mcomp-edit-numbering [39;49;00m [33m' [39;49;00m, kwargs={ [90m [39;49;00m
|
| [33m' [39;49;00m [33myear [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.year, [90m [39;49;00m
|
| [33m' [39;49;00m [33mcountry [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.country, [90m [39;49;00m
|
| [33m' [39;49;00m [33mslug [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.slug [90m [39;49;00m
|
| }) [90m [39;49;00m
|
| numbering_full_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mnumbering_url [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to numbering page: [39;49;00m [33m{ [39;49;00mnumbering_full_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(numbering_full_url) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mif [39;49;00m [33m' [39;49;00m [33m/accounts/login/ [39;49;00m [33m' [39;49;00m [95min [39;49;00m [96mself [39;49;00m.selenium.current_url: [90m [39;49;00m
|
| [96mself [39;49;00m.login(redirect=numbering_url) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton[name= [39;49;00m [33m' [39;49;00m [33mapply_numbers [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| apply_numbers_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable( [90m [39;49;00m
|
| (By.CSS_SELECTOR, [33m" [39;49;00m [33mbutton[name= [39;49;00m [33m' [39;49;00m [33mapply_numbers [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| )) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.execute_script( [33m" [39;49;00m [33marguments[0].scrollIntoView(true); [39;49;00m [33m" [39;49;00m, apply_numbers_btn) [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| apply_numbers_btn.click() [90m [39;49;00m
|
| time.sleep( [94m2 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| page_text = [96mself [39;49;00m.selenium.page_source [90m [39;49;00m
|
| [94mif [39;49;00m [33m' [39;49;00m [33msuccess [39;49;00m [33m' [39;49;00m [95min [39;49;00m page_text.lower() [95mor [39;49;00m [33m' [39;49;00m [33mapplied [39;49;00m [33m' [39;49;00m [95min [39;49;00m page_text.lower(): [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mNumbers applied successfully [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mNumbering page content - checking for confirmation... [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mAthletes numbered! [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 8: Seed and Publish via Event Detail Private --- [39;49;00m [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== PART 4: Seeding and publishing === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| private_event_url = reverse( [33m' [39;49;00m [33mcomp-event-detail-private [39;49;00m [33m' [39;49;00m, kwargs={ [90m [39;49;00m
|
| [33m' [39;49;00m [33myear [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.year, [90m [39;49;00m
|
| [33m' [39;49;00m [33mcountry [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.country, [90m [39;49;00m
|
| [33m' [39;49;00m [33mslug [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.slug, [90m [39;49;00m
|
| [33m' [39;49;00m [33mevent_id [39;49;00m [33m' [39;49;00m: relay_event_id [90m [39;49;00m
|
| }) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to private event detail: [39;49;00m [33m{ [39;49;00mprivate_event_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mprivate_event_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mif [39;49;00m [33m' [39;49;00m [33m/accounts/login/ [39;49;00m [33m' [39;49;00m [95min [39;49;00m [96mself [39;49;00m.selenium.current_url: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mOn login page [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.login(redirect=private_event_url) [90m [39;49;00m
|
| [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| heats_tab = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-heats [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| heats_tab.click() [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| seeding_options_container = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats form#seeding_options_r1 [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m seeding_options_container.is_displayed(): [90m [39;49;00m
|
| seeding_options_link = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats button[data-target= [39;49;00m [33m' [39;49;00m [33m#seeding_options_r1 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| seeding_options_link.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| seeding_select = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats button[name= [39;49;00m [33m' [39;49;00m [33mseed [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| seeding_select.click() [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSelected open_meet seeding method. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| lanes_input = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.NAME, [33m" [39;49;00m [33mlanes [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| lanes_input.clear() [90m [39;49;00m
|
| lanes_input.send_keys( [33m" [39;49;00m [33m8 [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSet lanes to 8. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| seed_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.NAME, [33m" [39;49;00m [33mseed [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| seed_btn.click() [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mSeeding triggered. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| heats_tab = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33ma[href= [39;49;00m [33m' [39;49;00m [33m#pills-heats [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| heats_tab.click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| seeding_options_container = [96mself [39;49;00m.wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats form#seeding_options_r1 [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m seeding_options_container.is_displayed(): [90m [39;49;00m
|
| seeding_options_link = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, [33m" [39;49;00m [33m#pills-heats button[data-target= [39;49;00m [33m' [39;49;00m [33m#seeding_options_r1 [39;49;00m [33m' [39;49;00m [33m] [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| seeding_options_link.click() [90m [39;49;00m
|
| time.sleep( [94m0.5 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.wait.until(EC.presence_of_element_located((By.NAME, [33m" [39;49;00m [33mpublic [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| [90m [39;49;00m
|
| publish_btn = [96mself [39;49;00m.wait.until(EC.element_to_be_clickable((By.NAME, [33m" [39;49;00m [33mpublic [39;49;00m [33m" [39;49;00m))) [90m [39;49;00m
|
| publish_btn.click() [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mPublished results. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# --- Step 9: Verify on unit detail page --- [39;49;00m [90m [39;49;00m
|
| [94mfrom [39;49;00m [90m [39;49;00m [04m [96mproject [39;49;00m [04m [96m. [39;49;00m [04m [96mreference [39;49;00m [04m [96m. [39;49;00m [04m [96mmongo [39;49;00m [90m [39;49;00m [94mimport [39;49;00m Unit [90m [39;49;00m
|
| unit = Unit.objects.filter(competition= [96mself [39;49;00m.mc, event=relay_event).first() [90m [39;49;00m
|
| [96mself [39;49;00m.assertIsNotNone(unit, [33m" [39;49;00m [33mNo unit found for the relay event after seeding. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| unit_url = reverse( [33m' [39;49;00m [33mcomp-unit-detail [39;49;00m [33m' [39;49;00m, kwargs={ [90m [39;49;00m
|
| [33m' [39;49;00m [33myear [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.year, [90m [39;49;00m
|
| [33m' [39;49;00m [33mcountry [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.country, [90m [39;49;00m
|
| [33m' [39;49;00m [33mslug [39;49;00m [33m' [39;49;00m: [96mself [39;49;00m.mc.slug, [90m [39;49;00m
|
| [33m' [39;49;00m [33mevent_id [39;49;00m [33m' [39;49;00m: unit.event.event_id, [90m [39;49;00m
|
| [33m' [39;49;00m [33mround [39;49;00m [33m' [39;49;00m: unit.round, [90m [39;49;00m
|
| [33m' [39;49;00m [33mheat [39;49;00m [33m' [39;49;00m: unit.heat [90m [39;49;00m
|
| }) [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mNavigating to unit detail: [39;49;00m [33m{ [39;49;00munit_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00munit_url [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| page_text = [96mself [39;49;00m.selenium.find_element(By.TAG_NAME, [33m" [39;49;00m [33mbody [39;49;00m [33m" [39;49;00m).text [90m [39;49;00m
|
| [94mfor [39;49;00m idx, first, last, dob, gender [95min [39;49;00m runners_data: [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn(first, page_text, [33mf [39;49;00m [33m" [39;49;00m [33mAthlete [39;49;00m [33m{ [39;49;00mfirst [33m} [39;49;00m [33m [39;49;00m [33m{ [39;49;00mlast [33m} [39;49;00m [33m not found in unit detail page [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.assertIn(last, page_text, [33mf [39;49;00m [33m" [39;49;00m [33mAthlete [39;49;00m [33m{ [39;49;00mfirst [33m} [39;49;00m [33m [39;49;00m [33m{ [39;49;00mlast [33m} [39;49;00m [33m not found in unit detail page [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33mVerified athletes in unit detail page. [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mprint [39;49;00m( [33m" [39;49;00m [33m=== TEST PASSED: Add/Remove relay team with athlete persistence and seeding verified === [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mException [39;49;00m [94mas [39;49;00m e: [90m [39;49;00m
|
| [96mprint [39;49;00m( [33mf [39;49;00m [33m" [39;49;00m [33mTest failed: [39;49;00m [33m{ [39;49;00me [33m} [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| time.sleep( [94m1 [39;49;00m) [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.save_screenshot( [33m" [39;49;00m [33mrelay_test_failure.png [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mwith [39;49;00m [96mopen [39;49;00m( [33m" [39;49;00m [33mrelay_test_failure.html [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33mw [39;49;00m [33m" [39;49;00m) [94mas [39;49;00m f: [90m [39;49;00m
|
| f.write( [96mself [39;49;00m.selenium.page_source) [90m [39;49;00m
|
| > [94mraise [39;49;00m e [90m [39;49;00m
|
|
|
| project/comp/tests/test_team_declarations.py:1245:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| project/comp/tests/test_team_declarations.py:1116: in test_adhoc_relay_declarations
|
| [0m [96mself [39;49;00m.assertNotIn( [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mteam_id [33m} [39;49;00m [33m-C [39;49;00m [33m" [39;49;00m, db_ids) [90m [39;49;00m
|
| E AssertionError: 'ADHOC1-C' unexpectedly found in ['ADHOC1-A', 'ADHOC1-B', 'ADHOC1-C']
|
| __________________ BMCE2ETests.test_associate_membership_join __________________
|
| [gw2] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python
|
|
|
| self = <project.federation.tests.test_bmc.BMCE2ETests testMethod=test_associate_membership_join>
|
|
|
| [0m [37m@superuser_login_required [39;49;00m [90m [39;49;00m
|
| [94mdef [39;49;00m [90m [39;49;00m [92mtest_associate_membership_join [39;49;00m( [96mself [39;49;00m): [90m [39;49;00m
|
| [90m [39;49;00m
|
| [96mself [39;49;00m.person.roles().filter(organisation__code= [33m' [39;49;00m [33mBMC [39;49;00m [33m' [39;49;00m).delete() [90m [39;49;00m
|
| [90m [39;49;00m
|
| fed_index_url = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00m [96mself [39;49;00m.live_server_url [33m} [39;49;00m [33m{ [39;49;00mreverse( [33m' [39;49;00m [33mfed-index [39;49;00m [33m' [39;49;00m) [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| [96mself [39;49;00m.selenium.get(fed_index_url) [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# join button [39;49;00m [90m [39;49;00m
|
| join_btn = [96mself [39;49;00m.selenium.find_element(By.ID, [33m" [39;49;00m [33mjoinMembershipBtn [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| join_btn.click() [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m [39;49;00m
|
| [90m# contact details popup will show, hide it [39;49;00m [90m [39;49;00m
|
| contact_details_close_btn = [96mself [39;49;00m.selenium.find_element(By.CSS_SELECTOR, [33m" [39;49;00m [33m#inputMissingDataModal .close-btn [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| > contact_details_close_btn.click() [90m [39;49;00m
|
|
|
| project/federation/tests/test_bmc.py:438:
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
| /opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/selenium/webdriver/remote/webelement.py:119: in click
|
| [0m [96mself [39;49;00m._execute(Command.CLICK_ELEMENT) [90m [39;49;00m
|
| /opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/selenium/webdriver/remote/webelement.py:572: in _execute
|
| [0m [94mreturn [39;49;00m [96mself [39;49;00m._parent.execute(command, params) [90m [39;49;00m
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ [90m [39;49;00m
|
| /opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/selenium/webdriver/remote/webdriver.py:448: in execute
|
| [0m [96mself [39;49;00m.error_handler.check_response(response) [90m [39;49;00m
|
| _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
|
|
|
| self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f8c74ac6780>
|
| response = {'status': 404, 'value': '{"value":{"error":"stale element reference","message":"stale element reference: stale elemen...\\n#17 0x563ffb47ff88 \\u003Cunknown>\\n#18 0x563ffb4915de \\u003Cunknown>\\n#19 0x7fbd7a294ac3 \\u003Cunknown>\\n"}}'}
|
|
|
| [0m [94mdef [39;49;00m [90m [39;49;00m [92mcheck_response [39;49;00m( [96mself [39;49;00m, response: Dict[ [96mstr [39;49;00m, Any]) -> [94mNone [39;49;00m: [90m [39;49;00m
|
| [90m [39;49;00m [33m"""Checks that a JSON response from the WebDriver does not have an [39;49;00m
|
| [33m error. [39;49;00m
|
| [33m [39;49;00m
|
| [33m :Args: [39;49;00m
|
| [33m - response - The JSON response from the WebDriver server as a dictionary [39;49;00m
|
| [33m object. [39;49;00m
|
| [33m [39;49;00m
|
| [33m :Raises: If the response contains an error message. [39;49;00m
|
| [33m """ [39;49;00m [90m [39;49;00m
|
| status = response.get( [33m" [39;49;00m [33mstatus [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m status [95mor [39;49;00m status == ErrorCode.SUCCESS: [90m [39;49;00m
|
| [94mreturn [39;49;00m [90m [39;49;00m
|
| value = [94mNone [39;49;00m [90m [39;49;00m
|
| message = response.get( [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| screen: [96mstr [39;49;00m = response.get( [33m" [39;49;00m [33mscreen [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| stacktrace = [94mNone [39;49;00m [90m [39;49;00m
|
| [94mif [39;49;00m [96misinstance [39;49;00m(status, [96mint [39;49;00m): [90m [39;49;00m
|
| value_json = response.get( [33m" [39;49;00m [33mvalue [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m value_json [95mand [39;49;00m [96misinstance [39;49;00m(value_json, [96mstr [39;49;00m): [90m [39;49;00m
|
| [94mimport [39;49;00m [90m [39;49;00m [04m [96mjson [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| value = json.loads(value_json) [90m [39;49;00m
|
| [94mif [39;49;00m [96mlen [39;49;00m(value) == [94m1 [39;49;00m: [90m [39;49;00m
|
| value = value[ [33m" [39;49;00m [33mvalue [39;49;00m [33m" [39;49;00m] [90m [39;49;00m
|
| status = value.get( [33m" [39;49;00m [33merror [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m status: [90m [39;49;00m
|
| status = value.get( [33m" [39;49;00m [33mstatus [39;49;00m [33m" [39;49;00m, ErrorCode.UNKNOWN_ERROR) [90m [39;49;00m
|
| message = value.get( [33m" [39;49;00m [33mvalue [39;49;00m [33m" [39;49;00m) [95mor [39;49;00m value.get( [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m [96misinstance [39;49;00m(message, [96mstr [39;49;00m): [90m [39;49;00m
|
| value = message [90m [39;49;00m
|
| message = message.get( [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| message = value.get( [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m, [94mNone [39;49;00m) [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mValueError [39;49;00m: [90m [39;49;00m
|
| [94mpass [39;49;00m [90m [39;49;00m
|
| [90m [39;49;00m
|
| exception_class: Type[WebDriverException] [90m [39;49;00m
|
| e = ErrorCode() [90m [39;49;00m
|
| error_codes = [item [94mfor [39;49;00m item [95min [39;49;00m [96mdir [39;49;00m(e) [94mif [39;49;00m [95mnot [39;49;00m item.startswith( [33m" [39;49;00m [33m__ [39;49;00m [33m" [39;49;00m)] [90m [39;49;00m
|
| [94mfor [39;49;00m error_code [95min [39;49;00m error_codes: [90m [39;49;00m
|
| error_info = [96mgetattr [39;49;00m(ErrorCode, error_code) [90m [39;49;00m
|
| [94mif [39;49;00m [96misinstance [39;49;00m(error_info, [96mlist [39;49;00m) [95mand [39;49;00m status [95min [39;49;00m error_info: [90m [39;49;00m
|
| exception_class = [96mgetattr [39;49;00m(ExceptionMapping, error_code, WebDriverException) [90m [39;49;00m
|
| [94mbreak [39;49;00m [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| exception_class = WebDriverException [90m [39;49;00m
|
| [90m [39;49;00m
|
| [94mif [39;49;00m [95mnot [39;49;00m value: [90m [39;49;00m
|
| value = response[ [33m" [39;49;00m [33mvalue [39;49;00m [33m" [39;49;00m] [90m [39;49;00m
|
| [94mif [39;49;00m [96misinstance [39;49;00m(value, [96mstr [39;49;00m): [90m [39;49;00m
|
| [94mraise [39;49;00m exception_class(value) [90m [39;49;00m
|
| [94mif [39;49;00m message == [33m" [39;49;00m [33m" [39;49;00m [95mand [39;49;00m [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m [95min [39;49;00m value: [90m [39;49;00m
|
| message = value[ [33m" [39;49;00m [33mmessage [39;49;00m [33m" [39;49;00m] [90m [39;49;00m
|
| [90m [39;49;00m
|
| screen = [94mNone [39;49;00m [90m# type: ignore[assignment] [39;49;00m [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mscreen [39;49;00m [33m" [39;49;00m [95min [39;49;00m value: [90m [39;49;00m
|
| screen = value[ [33m" [39;49;00m [33mscreen [39;49;00m [33m" [39;49;00m] [90m [39;49;00m
|
| [90m [39;49;00m
|
| stacktrace = [94mNone [39;49;00m [90m [39;49;00m
|
| st_value = value.get( [33m" [39;49;00m [33mstackTrace [39;49;00m [33m" [39;49;00m) [95mor [39;49;00m value.get( [33m" [39;49;00m [33mstacktrace [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m st_value: [90m [39;49;00m
|
| [94mif [39;49;00m [96misinstance [39;49;00m(st_value, [96mstr [39;49;00m): [90m [39;49;00m
|
| stacktrace = st_value.split( [33m" [39;49;00m [33m\n [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94melse [39;49;00m: [90m [39;49;00m
|
| stacktrace = [] [90m [39;49;00m
|
| [94mtry [39;49;00m: [90m [39;49;00m
|
| [94mfor [39;49;00m frame [95min [39;49;00m st_value: [90m [39;49;00m
|
| line = frame.get( [33m" [39;49;00m [33mlineNumber [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| file = frame.get( [33m" [39;49;00m [33mfileName [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33m<anonymous> [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m line: [90m [39;49;00m
|
| file = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mfile [33m} [39;49;00m [33m: [39;49;00m [33m{ [39;49;00mline [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| meth = frame.get( [33m" [39;49;00m [33mmethodName [39;49;00m [33m" [39;49;00m, [33m" [39;49;00m [33m<anonymous> [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mclassName [39;49;00m [33m" [39;49;00m [95min [39;49;00m frame: [90m [39;49;00m
|
| meth = [33mf [39;49;00m [33m" [39;49;00m [33m{ [39;49;00mframe[ [33m' [39;49;00m [33mclassName [39;49;00m [33m' [39;49;00m] [33m} [39;49;00m [33m. [39;49;00m [33m{ [39;49;00mmeth [33m} [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| msg = [33m" [39;49;00m [33m at [39;49;00m [33m%s [39;49;00m [33m ( [39;49;00m [33m%s [39;49;00m [33m) [39;49;00m [33m" [39;49;00m [90m [39;49;00m
|
| msg = msg % (meth, file) [90m [39;49;00m
|
| stacktrace.append(msg) [90m [39;49;00m
|
| [94mexcept [39;49;00m [96mTypeError [39;49;00m: [90m [39;49;00m
|
| [94mpass [39;49;00m [90m [39;49;00m
|
| [94mif [39;49;00m exception_class == UnexpectedAlertPresentException: [90m [39;49;00m
|
| alert_text = [94mNone [39;49;00m [90m [39;49;00m
|
| [94mif [39;49;00m [33m" [39;49;00m [33mdata [39;49;00m [33m" [39;49;00m [95min [39;49;00m value: [90m [39;49;00m
|
| alert_text = value[ [33m" [39;49;00m [33mdata [39;49;00m [33m" [39;49;00m].get( [33m" [39;49;00m [33mtext [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94melif [39;49;00m [33m" [39;49;00m [33malert [39;49;00m [33m" [39;49;00m [95min [39;49;00m value: [90m [39;49;00m
|
| alert_text = value[ [33m" [39;49;00m [33malert [39;49;00m [33m" [39;49;00m].get( [33m" [39;49;00m [33mtext [39;49;00m [33m" [39;49;00m) [90m [39;49;00m
|
| [94mraise [39;49;00m exception_class(message, screen, stacktrace, alert_text) [90m# type: ignore[call-arg] # mypy is not smart enough here [39;49;00m [90m [39;49;00m
|
| > [94mraise [39;49;00m exception_class(message, screen, stacktrace) [90m [39;49;00m
|
| E selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found in the current frame
|
| E (Session info: chrome=147.0.7727.55); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
|
| E Stacktrace:
|
| E #0 0x563ffb492b6a <unknown>
|
| E #1 0x563ffae94265 <unknown>
|
| E #2 0x563ffae9b111 <unknown>
|
| E #3 0x563ffae9d95b <unknown>
|
| E #4 0x563ffae9da03 <unknown>
|
| E #5 0x563ffaee8cd0 <unknown>
|
| E #6 0x563ffaedc437 <unknown>
|
| E #7 0x563ffaedbe07 <unknown>
|
| E #8 0x563ffaf2f969 <unknown>
|
| E #9 0x563ffaeda5cf <unknown>
|
| E #10 0x563ffaedb391 <unknown>
|
| E #11 0x563ffb45804b <unknown>
|
| E #12 0x563ffb45b00d <unknown>
|
| E #13 0x563ffb444808 <unknown>
|
| E #14 0x563ffb45bba0 <unknown>
|
| E #15 0x563ffb42b280 <unknown>
|
| E #16 0x563ffb47fdb8 <unknown>
|
| E #17 0x563ffb47ff88 <unknown>
|
| E #18 0x563ffb4915de <unknown>
|
| E #19 0x7fbd7a294ac3 <unknown>
|
|
|
| /opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/selenium/webdriver/remote/errorhandler.py:232: StaleElementReferenceException
|
| =========================== short test summary info ============================
|
| [31mFAILED [0m project/comp/tests/test_team_declarations.py:: [1mTeamDeclarationsE2ETests::test_adhoc_individual_declarations [0m - AssertionError: 0 != 1 : Grid row count (0) should match selected table count (1)
|
| [31mFAILED [0m project/comp/tests/test_seeding.py:: [1mSeedingE2ETests::test_three_round_championship_seeding [0m - AssertionError: 0 != 8 : Should have 8 athletes in the final
|
| [31mFAILED [0m project/comp/tests/test_comp_e2e.py:: [1mCompE2ETests::test_record_length_and_height_events [0m - selenium.common.exceptions.TimeoutException: Message:
|
| [31mFAILED [0m project/comp/tests/test_team_declarations.py:: [1mTeamDeclarationsE2ETests::test_adhoc_relay_declarations [0m - AssertionError: 'ADHOC1-C' unexpectedly found in ['ADHOC1-A', 'ADHOC1-B', 'ADHOC1-C']
|
| [31mFAILED [0m project/federation/tests/test_bmc.py:: [1mBMCE2ETests::test_associate_membership_join [0m - selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: stale element not found in the current frame
|
| (Session info: chrome=147.0.7727.55); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#stale-element-reference-exception
|
| Stacktrace:
|
| #0 0x563ffb492b6a <unknown>
|
| #1 0x563ffae94265 <unknown>
|
| #2 0x563ffae9b111 <unknown>
|
| #3 0x563ffae9d95b <unknown>
|
| #4 0x563ffae9da03 <unknown>
|
| #5 0x563ffaee8cd0 <unknown>
|
| #6 0x563ffaedc437 <unknown>
|
| #7 0x563ffaedbe07 <unknown>
|
| #8 0x563ffaf2f969 <unknown>
|
| #9 0x563ffaeda5cf <unknown>
|
| #10 0x563ffaedb391 <unknown>
|
| #11 0x563ffb45804b <unknown>
|
| #12 0x563ffb45b00d <unknown>
|
| #13 0x563ffb444808 <unknown>
|
| #14 0x563ffb45bba0 <unknown>
|
| #15 0x563ffb42b280 <unknown>
|
| #16 0x563ffb47fdb8 <unknown>
|
| #17 0x563ffb47ff88 <unknown>
|
| #18 0x563ffb4915de <unknown>
|
| #19 0x7fbd7a294ac3 <unknown>
|
| ==== [31m [1m5 failed [0m, [32m610 passed [0m, [33m16 skipped [0m, [33m20285 warnings [0m [31m in 580.30s (0:09:40) [0m [31m =====
|