============================= test session starts ==============================
created: 2/2 workers
2 workers [808 items]

ss........................s...........s................................. [  8%]
........................................................................ [ 17%]
.....................FF.....................F........................... [ 26%]
........s.....s......................................................... [ 35%]
........................................................................ [ 44%]
........................................................................ [ 53%]
....................................................................F... [ 62%]
.........F.............................................................. [ 71%]
...............................F........................................ [ 80%]
........................................................................ [ 89%]
...........F................sss...s..s..sss...........F................. [ 98%]
...........sss..                                                         [100%]
=================================== FAILURES ===================================
________________ UnitAPITestCase.test_create_unit_with_results _________________
[gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.drapi.tests.test_unit_api.UnitAPITestCase testMethod=test_create_unit_with_results>

    def test_create_unit_with_results(self):
        headers = self._auth_header("jollyroger", "secret")
        payload = {
            "competition": self.sql_comp.id,
            "event_id": "11",
            "heat": 1,
            "round": 1,
            "day": 1,
            "results": [
                {"bib": "101", "performance": "16:30.00", "place": 1},
                {"bib": "102", "performance": "17:00.00", "place": 2},
            ],
        }
        resp = self.client.post("/api/units/", json.dumps(payload),
                                content_type="application/json", **headers)
        self.assertEqual(resp.status_code, 201)
        data = resp.json()
        self.assertEqual(len(data["results"]), 2)
        self.assertEqual(data["results"][0]["bib"], "101")
        self.assertEqual(data["results"][0]["performance"], "16:30.00")
    
        from urllib.parse import urlparse
>       sql_unit = SQLUnit.objects.get(pk=urlparse(data["id"]).path.rstrip("/").rpartition("/")[2])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

project/drapi/tests/test_unit_api.py:153: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/db/models/manager.py:87: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <QuerySet [<Unit: Unit object (1)>, <Unit: Unit object (2)>, <Unit: Unit object (3)>, <Unit: Unit object (4)>, <Unit: ...Unit object (6)>, <Unit: Unit object (7)>, <Unit: Unit object (8)>, <Unit: Unit object (9)>, <Unit: Unit object (10)>]>
args = (), kwargs = {'pk': '2'}

    def get(self, *args, **kwargs):
        """
        Perform the query and return a single object matching the given
        keyword arguments.
        """
        if self.query.combinator and (args or kwargs):
            raise NotSupportedError(
                "Calling QuerySet.get(...) with filters after %s() is not "
                "supported." % self.query.combinator
            )
        clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
        if self.query.can_filter() and not self.query.distinct_fields:
            clone = clone.order_by()
        limit = None
        if (
            not clone.query.select_for_update
            or connections[clone.db].features.supports_select_for_update_with_limit
        ):
            limit = MAX_GET_RESULTS
            clone.query.set_limits(high=limit)
        num = len(clone)
        if num == 1:
            return clone._result_cache[0]
        if not num:
>           raise self.model.DoesNotExist(
                "%s matching query does not exist." % self.model._meta.object_name
            )
E           project.reference.models.Unit.DoesNotExist: Unit matching query does not exist.

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/db/models/query.py:633: DoesNotExist
________________ UnitAPITestCase.test_director_can_create_unit _________________
[gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.drapi.tests.test_unit_api.UnitAPITestCase testMethod=test_director_can_create_unit>

    def test_director_can_create_unit(self):
        headers = self._auth_header("dave", "secret")
        payload = {
            "competition": self.sql_comp.id,
            "event_id": "11",
            "heat": 1,
            "round": 1,
        }
        resp = self.client.post("/api/units/", json.dumps(payload),
                                content_type="application/json", **headers)
        self.assertEqual(resp.status_code, 201)
        data = resp.json()
        from urllib.parse import urlparse
>       sql_unit = SQLUnit.objects.get(pk=urlparse(data["id"]).path.rstrip("/").rpartition("/")[2])
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

project/drapi/tests/test_unit_api.py:213: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/db/models/manager.py:87: in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <QuerySet [<Unit: Unit object (1)>, <Unit: Unit object (2)>, <Unit: Unit object (3)>, <Unit: Unit object (4)>, <Unit: ...Unit object (6)>, <Unit: Unit object (7)>, <Unit: Unit object (8)>, <Unit: Unit object (9)>, <Unit: Unit object (10)>]>
args = (), kwargs = {'pk': '2'}

    def get(self, *args, **kwargs):
        """
        Perform the query and return a single object matching the given
        keyword arguments.
        """
        if self.query.combinator and (args or kwargs):
            raise NotSupportedError(
                "Calling QuerySet.get(...) with filters after %s() is not "
                "supported." % self.query.combinator
            )
        clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
        if self.query.can_filter() and not self.query.distinct_fields:
            clone = clone.order_by()
        limit = None
        if (
            not clone.query.select_for_update
            or connections[clone.db].features.supports_select_for_update_with_limit
        ):
            limit = MAX_GET_RESULTS
            clone.query.set_limits(high=limit)
        num = len(clone)
        if num == 1:
            return clone._result_cache[0]
        if not num:
>           raise self.model.DoesNotExist(
                "%s matching query does not exist." % self.model._meta.object_name
            )
E           project.reference.models.Unit.DoesNotExist: Unit matching query does not exist.

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/db/models/query.py:633: DoesNotExist
_________ UnitAPITestCase.test_superuser_can_delete_unit_with_results __________
[gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = [<HeightUnit: 4,1,1 []>, <HeightUnit: 9,1,1 []>, <LengthUnit: 2,1,1 []>, <LengthUnit: 10,1,1 []>, <LengthUnit: 3,1,1 [...,2,1 []>, <Race: 5,1,1 []>, <Race: 7,1,1 []>, <Race: 8,1,1 []>, <Race: 11,1,1 []>, <Race: 1,1,2 []>, <Relay: 6,1,1 []>]
q_objs = (), query = {'pk': ''}

    def get(self, *q_objs, **query):
        """Retrieve the matching object raising
        :class:`~mongoengine.queryset.MultipleObjectsReturned` or
        `DocumentName.MultipleObjectsReturned` exception if multiple results
        and :class:`~mongoengine.queryset.DoesNotExist` or
        `DocumentName.DoesNotExist` if no results are found.
        """
        queryset = self.clone()
        queryset = queryset.order_by().limit(2)
        queryset = queryset.filter(*q_objs, **query)
    
        try:
>           result = next(queryset)
                     ^^^^^^^^^^^^^^

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/mongoengine/queryset/base.py:274: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/mongoengine/queryset/base.py:1646: in __next__
    raw_doc = next(self._cursor)
              ^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <pymongo.cursor.Cursor object at 0x7f3c0e321d10>

    def next(self) -> _DocumentType:
        """Advance the cursor."""
        if self.__empty:
            raise StopIteration
        if len(self.__data) or self._refresh():
            return self.__data.popleft()
        else:
>           raise StopIteration
E           StopIteration

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/pymongo/cursor.py:1246: StopIteration

During handling of the above exception, another exception occurred:

self = <project.drapi.tests.test_unit_api.UnitAPITestCase testMethod=test_superuser_can_delete_unit_with_results>

    def test_superuser_can_delete_unit_with_results(self):
        """Superusers can still delete a unit that already has results."""
        from urllib.parse import urlparse
        headers = self._auth_header("jollyroger", "secret")
        ev = self.comp.get_event("5")
        # Create a fresh unit so we don't delete the test fixture
        payload = {
            "competition": self.sql_comp.id,
            "event_id": "5",
            "heat": 99,
            "round": 1,
        }
        resp = self.client.post("/api/units/", json.dumps(payload),
                                content_type="application/json", **headers)
        self.assertEqual(resp.status_code, 201)
        data = resp.json()
        print(data)
        new_sql_pk = urlparse(data["id"]).path.rstrip("/").rpartition("/")[2]
        print(new_sql_pk)
        new_sql_unit = SQLUnit.objects.get(id=new_sql_pk)
    
>       new_mongo_unit = MongoUnit.objects.get(pk=new_sql_unit.mongo_unit_id)
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

project/drapi/tests/test_unit_api.py:397: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = [<HeightUnit: 4,1,1 []>, <HeightUnit: 9,1,1 []>, <LengthUnit: 2,1,1 []>, <LengthUnit: 10,1,1 []>, <LengthUnit: 3,1,1 [...,2,1 []>, <Race: 5,1,1 []>, <Race: 7,1,1 []>, <Race: 8,1,1 []>, <Race: 11,1,1 []>, <Race: 1,1,2 []>, <Relay: 6,1,1 []>]
q_objs = (), query = {'pk': ''}

    def get(self, *q_objs, **query):
        """Retrieve the matching object raising
        :class:`~mongoengine.queryset.MultipleObjectsReturned` or
        `DocumentName.MultipleObjectsReturned` exception if multiple results
        and :class:`~mongoengine.queryset.DoesNotExist` or
        `DocumentName.DoesNotExist` if no results are found.
        """
        queryset = self.clone()
        queryset = queryset.order_by().limit(2)
        queryset = queryset.filter(*q_objs, **query)
    
        try:
            result = next(queryset)
        except StopIteration:
            msg = "%s matching query does not exist." % queryset._document._class_name
>           raise queryset._document.DoesNotExist(msg)
E           project.reference.mongo.unit.DoesNotExist: Unit matching query does not exist.

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/mongoengine/queryset/base.py:277: DoesNotExist
______ EventSpecAPITestCase.test_superuser_can_delete_event_with_results _______
[gw0] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.drapi.tests.test_eventspec_api.EventSpecAPITestCase testMethod=test_superuser_can_delete_event_with_results>

    def test_superuser_can_delete_event_with_results(self):
        """Superusers can still delete an event even when a unit under it has results."""
        headers = self._auth_header("jollyroger", "secret")
    
        if not EventSpec.objects.filter(competition=self.sql_comp, event_id="99").count():
            # Create a fresh event so we don't delete the test fixture
            payload = {
                "competition": self.sql_comp.id,
                "event_id": "99",
                "event_code": "1500",
                "age_groups": "SEN",
                "genders": "M",
                "category": "SM",
                "name": "Delete Me Event",
            }
            resp = self.client.post("/api/events/", json.dumps(payload),
                                    content_type="application/json", **headers)
            self.assertEqual(resp.status_code, 201)
            data = resp.json()
        sql_event = EventSpec.objects.get(competition=self.sql_comp, event_id="99")
>       mongo_event = MongoEventSpec.objects.get(competition=self.comp.id, event_id="99")
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

project/drapi/tests/test_eventspec_api.py:657: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = [<EventSpec: 99>, <EventSpec: 99>, <EventSpec: 1>, <EventSpec: 2>, <EventSpec: 3>, <EventSpec: 4>, <EventSpec: 5>, <EventSpec: 6>, <EventSpec: 7>, <EventSpec: 8>, <EventSpec: 9>, <EventSpec: 10>, <EventSpec: 11>]
q_objs = ()
query = {'competition': 'd2226400-a5bf-49df-902e-5aa0f8ec5aa1', 'event_id': '99'}

    def get(self, *q_objs, **query):
        """Retrieve the matching object raising
        :class:`~mongoengine.queryset.MultipleObjectsReturned` or
        `DocumentName.MultipleObjectsReturned` exception if multiple results
        and :class:`~mongoengine.queryset.DoesNotExist` or
        `DocumentName.DoesNotExist` if no results are found.
        """
        queryset = self.clone()
        queryset = queryset.order_by().limit(2)
        queryset = queryset.filter(*q_objs, **query)
    
        try:
            result = next(queryset)
        except StopIteration:
            msg = "%s matching query does not exist." % queryset._document._class_name
            raise queryset._document.DoesNotExist(msg)
    
        try:
            # Check if there is another match
            next(queryset)
        except StopIteration:
            return result
    
        # If we were able to retrieve the 2nd doc, raise the MultipleObjectsReturned exception.
>       raise queryset._document.MultipleObjectsReturned(
            "2 or more items returned, instead of 1"
        )
E       project.reference.mongo.eventspec.MultipleObjectsReturned: 2 or more items returned, instead of 1

/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/mongoengine/queryset/base.py:286: MultipleObjectsReturned
____________ EventSpecAPITestCase.test_update_rounds_creates_units _____________
[gw0] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.drapi.tests.test_eventspec_api.EventSpecAPITestCase testMethod=test_update_rounds_creates_units>

    def test_update_rounds_creates_units(self):
        """
        Changing rounds via PUT should create/remove Units accordingly.
        Event '1' starts with rounds='2,1' (2 heats + 1 final).
        Changing to '3,2,1' should create 6 units total.
        """
        headers = self._auth_header("jollyroger", "secret")
        sql_event = EventSpec.objects.get(competition=self.sql_comp, event_id="1")
    
        initial_units = Unit.objects.filter(event=sql_event).count()
        # The existing comp has the 100m with rounds='2,1' so should have 3 units
    
        payload = {
            "competition": self.sql_comp.id,
            "event_id": "1",
            "event_code": "100",
            "age_groups": "SEN,U20,U18",
            "genders": "M",
            "category": "SM",
            "limit": 24,
            "name": "100m with more rounds",
            "rounds": "3,2,1",
        }
        resp = self.client.put(f"/api/events/{sql_event.pk}/", json.dumps(payload),
                               content_type="application/json", **headers)
        self.assertEqual(resp.status_code, 200)
    
        # Verify Mongo rounds updated
        mongo_event = MongoEventSpec.objects.get(
            competition=self.comp.id, event_id="1"
        )
        self.assertEqual(mongo_event.rounds, "3,2,1")
    
    
        # these bg tasks normally get run in the background, but we need to run them manually here to verify the Unit changes
        ensure_units_and_timetable.now(
            self.sql_comp.id,
            [str(mongo_event.id)],
        )
    
        # Verify units updated
        updated_units = MongoUnit.objects.filter(event=mongo_event)
        for u in updated_units:
            u.sql_sync()
        self.assertEqual(updated_units.count(), 6)  # 3+2+1
    
        updated_units = Unit.objects.filter(event=sql_event)
>       self.assertEqual(updated_units.count(), 6)  # 3+2+1
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
E       AssertionError: 4 != 6

project/drapi/tests/test_eventspec_api.py:475: AssertionError
___________ ScottishAthleticsSyncTests.test_sync_sa_status_from_data ___________
[gw1] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.reference.tests.test_sa_sync.ScottishAthleticsSyncTests testMethod=test_sync_sa_status_from_data>

    def test_sync_sa_status_from_data(self):
        """ Verify Person.sync_sa_status_from_data updates role, identifier and clubs """
        sa_role = self.person.has_role_with(self.sa_org, create_if_missing={'role_type': 'REGISTERED'})
    
        self.person.sync_sa_status_from_data(self.sample_feed_data)
    
        sa_role.refresh_from_db()
        self.assertEqual(sa_role.identifier, "JS006670")
        self.assertEqual(sa_role.role_status, "OK")
        self.assertEqual(sa_role.date_to, date(2027, 1, 18))
    
        # Newburgh should be primary
        self.assertTrue(Role.objects.filter(person=self.person, organisation=self.newburgh, ordering=1).exists())
        # Aberdeen should be secondary
>       self.assertTrue(Role.objects.filter(person=self.person, organisation=self.aberdeen, ordering=None).exists())
E       AssertionError: False is not true

project/reference/tests/test_sa_sync.py:65: AssertionError
_______________________ EventTests.test_event_split_form _______________________
[gw0] linux -- Python 3.13.2 /opt/hostedtoolcache/Python/3.13.2/x64/bin/python

self = <project.comp.tests.test_events.EventTests testMethod=test_event_split_form>

    def test_event_split_form(self):
    
    	self.reset()
    
    	comp = self.ema_comp
    	F01 = comp.get_event('F01')
    
    	form_data = {
    		# id, suffix, gender, age_groups
    		'events': [[None, 'A', 'M', 'V35,V40'], [None, 'B', 'F', 'V60']]
    	}
    	valid_event_split_form = EventSplitForm(form_data, instance=comp, event=F01)
>   	self.assertEqual(valid_event_split_form.is_valid(), True, msg='EventSplitForm is_valid should return True with correct data')
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

project/comp/tests/test_events.py:437: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/forms/forms.py:206: in is_valid
    return self.is_bound and not self.errors
                                 ^^^^^^^^^^^
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/forms/forms.py:201: in errors
    self.full_clean()
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/forms/forms.py:337: in full_clean
    self._clean_fields()
/opt/hostedtoolcache/Python/3.13.2/x64/lib/python3.13/site-packages/django/forms/forms.py:347: in _clean_fields
    value = getattr(self, "clean_%s" % name)()
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <EventSplitForm bound=True, valid=True, fields=(events)>

    def clean_events(self):
        cd = self.cleaned_data['events']
        event_id = self.event.event_id
    
        male_split_params = ''
        female_split_params = ''
        choosen_suffixes = []
        all_age_groups = []
        for n, ev in enumerate(cd, start=1):
            suffix = ev[1]
            gender = ev[2]
            age_groups = ev[3]
            age_groups.replace(" ", "")
    
    
            if suffix in choosen_suffixes:
                # duplicate
                raise forms.ValidationError(_("suffixes must be unique '%(value)s' at row %(row)s") % {'value': suffix, 'row': n})
    
            choosen_suffixes.append(suffix)
    
            for ag in age_groups.split(','):
                all_age_groups.append(ag)
                self._check_age_group(ag, n)
    
            if gender == 'M':
                male_split_params += f'{event_id}{suffix}: {age_groups};'
            elif gender == 'F':
                female_split_params += f'{event_id}{suffix}: {age_groups};'
    
        try:
            if male_split_params:
                self.event.validate_split_children_spec(male_split_params)
        except Exception as e:
            raise forms.ValidationError(_("Invalid event splitting data '%(value)s'") % {'value': male_split_params})
    
        try:
            if female_split_params:
                self.event.validate_split_children_spec(female_split_params)
        except Exception as e:
            raise forms.ValidationError(_("Invalid event splitting data '%(value)s'") % {'value': female_split_params})
    
        # check that all competitors would be split out.
        all_competitors_for_event = self.event.get_competitors()
>       competitors_after_split = all_competitors.filter(age_group__in=all_age_groups)
                                  ^^^^^^^^^^^^^^^
E       NameError: name 'all_competitors' is not defined

project/comp/forms.py:2269: NameError
______________ CompE2ETests.test_record_length_and_height_events _______________
[gw1] 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>

    def test_record_length_and_height_events(self):
        """E2E test for recording results on length (LJ) and height (HJ) events."""
        self.login()
    
        # ==============================================
        # PART 1: Long Jump (Length Event with Wind)
        # ==============================================
        lj_url = f"{self.live_server_url}{comp_reverse('comp-unit-record', self.sql_comp, event_id='3', round='1', heat='1')}"
        print(f"LJ recording URL: {lj_url}", flush=True)
        self.selenium.get(lj_url)
        time.sleep(3)
        print(f"Current URL: {self.selenium.current_url}", flush=True)
        print(f"Page title: {self.selenium.title}", flush=True)
        try:
            body = self.selenium.find_element(By.TAG_NAME, "body")
            print(f"Body text: {body.text[:1500]}", flush=True)
        except Exception as e:
            print(f"Failed to get body: {e}", flush=True)
        self.selenium.save_screenshot('/tmp/lj_page.png')
        self.accept_confirm()
        time.sleep(1)
>       self.wait.until(lambda _: len(self._length_starter_rows()) > 0)

project/comp/tests/test_comp_e2e.py:87: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.support.wait.WebDriverWait (session="23736e9461a7b7e30c19d89cc90be1ac")>
method = <function CompE2ETests.test_record_length_and_height_events.<locals>.<lambda> at 0x7f3c076f7d80>
message = ''

    def until(self, method: Callable[[D], Union[Literal[False], T]], message: str = "") -> T:
        """Wait until the method returns a value that is not False.
    
        Calls the method provided with the driver as an argument until the
        return value does not evaluate to ``False``.
    
        Parameters:
        -----------
        method: callable(WebDriver)
            - A callable object that takes a WebDriver instance as an argument.
    
        message: str
            - Optional message for :exc:`TimeoutException`
    
        Return:
        -------
        object: T
            - The result of the last call to `method`
    
        Raises:
        -------
        TimeoutException
            - If 'method' does not return a truthy value within the WebDriverWait
            object's timeout
    
        Example:
        --------
        >>> from selenium.webdriver.common.by import By
        >>> from selenium.webdriver.support.ui import WebDriverWait
        >>> from selenium.webdriver.support import expected_conditions as EC
    
        # Wait until an element is visible on the page
        >>> wait = WebDriverWait(driver, 10)
        >>> element = wait.until(EC.visibility_of_element_located((By.ID, "exampleId")))
        >>> print(element.text)
        """
        screen = None
        stacktrace = None
    
        end_time = time.monotonic() + self._timeout
        while True:
            try:
                value = method(self._driver)
                if value:
                    return value
            except self._ignored_exceptions as exc:
                screen = getattr(exc, "screen", None)
                stacktrace = getattr(exc, "stacktrace", None)
            if time.monotonic() > end_time:
                break
            time.sleep(self._poll)
>       raise TimeoutException(message, screen, stacktrace)
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
=========================== short test summary info ============================
FAILED project/drapi/tests/test_unit_api.py::UnitAPITestCase::test_create_unit_with_results - project.reference.models.Unit.DoesNotExist: Unit matching query does not exist.
FAILED project/drapi/tests/test_unit_api.py::UnitAPITestCase::test_director_can_create_unit - project.reference.models.Unit.DoesNotExist: Unit matching query does not exist.
FAILED project/drapi/tests/test_unit_api.py::UnitAPITestCase::test_superuser_can_delete_unit_with_results - project.reference.mongo.unit.DoesNotExist: Unit matching query does not exist.
FAILED project/drapi/tests/test_eventspec_api.py::EventSpecAPITestCase::test_superuser_can_delete_event_with_results - project.reference.mongo.eventspec.MultipleObjectsReturned: 2 or more items returned, instead of 1
FAILED project/drapi/tests/test_eventspec_api.py::EventSpecAPITestCase::test_update_rounds_creates_units - AssertionError: 4 != 6
FAILED project/reference/tests/test_sa_sync.py::ScottishAthleticsSyncTests::test_sync_sa_status_from_data - AssertionError: False is not true
FAILED project/comp/tests/test_events.py::EventTests::test_event_split_form - NameError: name 'all_competitors' is not defined
FAILED project/comp/tests/test_comp_e2e.py::CompE2ETests::test_record_length_and_height_events - selenium.common.exceptions.TimeoutException: Message:
==== 8 failed, 783 passed, 17 skipped, 18242 warnings in 709.38s (0:11:49) =====
