Patrick Williams | 169d7bc | 2024-01-05 11:33:25 -0600 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # -*- coding: utf-8 -*- |
| 3 | # BitBake Toaster UI tests implementation |
| 4 | # |
| 5 | # Copyright (C) 2023 Savoir-faire Linux |
| 6 | # |
| 7 | # SPDX-License-Identifier: GPL-2.0-only |
| 8 | |
| 9 | |
| 10 | from time import sleep |
| 11 | from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException, TimeoutException |
| 12 | from selenium.webdriver.common.by import By |
| 13 | |
| 14 | from orm.models import Build |
| 15 | |
| 16 | |
| 17 | def wait_until_build(test_instance, state): |
| 18 | timeout = 60 |
| 19 | start_time = 0 |
| 20 | build_state = '' |
| 21 | while True: |
| 22 | try: |
| 23 | if start_time > timeout: |
| 24 | raise TimeoutException( |
| 25 | f'Build did not reach {state} state within {timeout} seconds' |
| 26 | ) |
| 27 | last_build_state = test_instance.driver.find_element( |
| 28 | By.XPATH, |
| 29 | '//*[@id="latest-builds"]/div[1]//div[@class="build-state"]', |
| 30 | ) |
| 31 | build_state = last_build_state.get_attribute( |
| 32 | 'data-build-state') |
| 33 | state_text = state.lower().split() |
| 34 | if any(x in str(build_state).lower() for x in state_text): |
| 35 | return str(build_state).lower() |
| 36 | if 'failed' in str(build_state).lower(): |
| 37 | break |
| 38 | except NoSuchElementException: |
| 39 | continue |
| 40 | except TimeoutException: |
| 41 | break |
| 42 | start_time += 1 |
| 43 | sleep(1) # take a breath and try again |
| 44 | |
| 45 | def wait_until_build_cancelled(test_instance): |
| 46 | """ Cancel build take a while sometime, the method is to wait driver action |
| 47 | until build being cancelled |
| 48 | """ |
| 49 | timeout = 30 |
| 50 | start_time = 0 |
| 51 | build = None |
| 52 | while True: |
| 53 | try: |
| 54 | if start_time > timeout: |
| 55 | raise TimeoutException( |
| 56 | f'Build did not reach cancelled state within {timeout} seconds' |
| 57 | ) |
| 58 | last_build_state = test_instance.driver.find_element( |
| 59 | By.XPATH, |
| 60 | '//*[@id="latest-builds"]/div[1]//div[@class="build-state"]', |
| 61 | ) |
| 62 | build_state = last_build_state.get_attribute( |
| 63 | 'data-build-state') |
| 64 | if 'failed' in str(build_state).lower(): |
| 65 | break |
| 66 | if 'cancelling' in str(build_state).lower(): |
| 67 | # Change build state to cancelled |
| 68 | if not build: # get build object only once |
| 69 | build = Build.objects.last() |
| 70 | build.outcome = Build.CANCELLED |
| 71 | build.save() |
| 72 | if 'cancelled' in str(build_state).lower(): |
| 73 | break |
| 74 | except NoSuchElementException: |
| 75 | continue |
| 76 | except StaleElementReferenceException: |
| 77 | continue |
| 78 | except TimeoutException: |
| 79 | break |
| 80 | start_time += 1 |
| 81 | sleep(1) # take a breath and try again |
| 82 | |
| 83 | def get_projectId_from_url(url): |
| 84 | # url = 'http://domainename.com/toastergui/project/1656/whatever |
| 85 | # or url = 'http://domainename.com/toastergui/project/1/ |
| 86 | # or url = 'http://domainename.com/toastergui/project/186 |
| 87 | assert '/toastergui/project/' in url, "URL is not valid" |
| 88 | url_to_list = url.split('/toastergui/project/') |
| 89 | return int(url_to_list[1].split('/')[0]) # project_id |