diff options
| -rw-r--r-- | bitbake/lib/toaster/tests/functional/test_project_page.py | 118 |
1 files changed, 42 insertions, 76 deletions
diff --git a/bitbake/lib/toaster/tests/functional/test_project_page.py b/bitbake/lib/toaster/tests/functional/test_project_page.py index 5d10513d9d..40ef5f486a 100644 --- a/bitbake/lib/toaster/tests/functional/test_project_page.py +++ b/bitbake/lib/toaster/tests/functional/test_project_page.py | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | # | 7 | # |
| 8 | 8 | ||
| 9 | import os | 9 | import os |
| 10 | import random | ||
| 11 | import string | 10 | import string |
| 12 | from unittest import skip | 11 | from unittest import skip |
| 13 | import pytest | 12 | import pytest |
| @@ -22,58 +21,17 @@ from selenium.webdriver.common.by import By | |||
| 22 | 21 | ||
| 23 | from .utils import get_projectId_from_url, wait_until_build, wait_until_build_cancelled | 22 | from .utils import get_projectId_from_url, wait_until_build, wait_until_build_cancelled |
| 24 | 23 | ||
| 25 | 24 | class TestProjectPageBase(SeleniumFunctionalTestCase): | |
| 26 | @pytest.mark.django_db | ||
| 27 | @pytest.mark.order("last") | ||
| 28 | class TestProjectPage(SeleniumFunctionalTestCase): | ||
| 29 | project_id = None | 25 | project_id = None |
| 30 | PROJECT_NAME = 'TestProjectPage' | 26 | PROJECT_NAME = 'TestProjectPage' |
| 31 | 27 | ||
| 32 | def _create_project(self, project_name): | ||
| 33 | """ Create/Test new project using: | ||
| 34 | - Project Name: Any string | ||
| 35 | - Release: Any string | ||
| 36 | - Merge Toaster settings: True or False | ||
| 37 | """ | ||
| 38 | self.get(reverse('newproject')) | ||
| 39 | self.wait_until_visible('#new-project-name') | ||
| 40 | self.find("#new-project-name").send_keys(project_name) | ||
| 41 | select = Select(self.find("#projectversion")) | ||
| 42 | select.select_by_value('3') | ||
| 43 | |||
| 44 | # check merge toaster settings | ||
| 45 | checkbox = self.find('.checkbox-mergeattr') | ||
| 46 | if not checkbox.is_selected(): | ||
| 47 | checkbox.click() | ||
| 48 | |||
| 49 | if self.PROJECT_NAME != 'TestProjectPage': | ||
| 50 | # Reset project name if it's not the default one | ||
| 51 | self.PROJECT_NAME = 'TestProjectPage' | ||
| 52 | |||
| 53 | self.find("#create-project-button").click() | ||
| 54 | |||
| 55 | try: | ||
| 56 | self.wait_until_visible('#hint-error-project-name') | ||
| 57 | url = reverse('project', args=(TestProjectPage.project_id, )) | ||
| 58 | self.get(url) | ||
| 59 | self.wait_until_visible('#config-nav', poll=3) | ||
| 60 | except TimeoutException: | ||
| 61 | self.wait_until_visible('#config-nav', poll=3) | ||
| 62 | |||
| 63 | def _random_string(self, length): | ||
| 64 | return ''.join( | ||
| 65 | random.choice(string.ascii_letters) for _ in range(length) | ||
| 66 | ) | ||
| 67 | |||
| 68 | def _navigate_to_project_page(self): | 28 | def _navigate_to_project_page(self): |
| 69 | # Navigate to project page | 29 | # Navigate to project page |
| 70 | if TestProjectPage.project_id is None: | 30 | if TestProjectPageBase.project_id is None: |
| 71 | self._create_project(project_name=self._random_string(10)) | 31 | TestProjectPageBase.project_id = self.create_new_project(self.PROJECT_NAME, '3', None, True) |
| 72 | current_url = self.driver.current_url | 32 | |
| 73 | TestProjectPage.project_id = get_projectId_from_url(current_url) | 33 | url = reverse('project', args=(TestProjectPageBase.project_id,)) |
| 74 | else: | 34 | self.get(url) |
| 75 | url = reverse('project', args=(TestProjectPage.project_id,)) | ||
| 76 | self.get(url) | ||
| 77 | self.wait_until_visible('#config-nav') | 35 | self.wait_until_visible('#config-nav') |
| 78 | 36 | ||
| 79 | def _get_create_builds(self, **kwargs): | 37 | def _get_create_builds(self, **kwargs): |
| @@ -81,14 +39,14 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 81 | # parameters for builds to associate with the projects | 39 | # parameters for builds to associate with the projects |
| 82 | now = timezone.now() | 40 | now = timezone.now() |
| 83 | self.project1_build_success = { | 41 | self.project1_build_success = { |
| 84 | 'project': Project.objects.get(id=TestProjectPage.project_id), | 42 | 'project': Project.objects.get(id=TestProjectPageBase.project_id), |
| 85 | 'started_on': now, | 43 | 'started_on': now, |
| 86 | 'completed_on': now, | 44 | 'completed_on': now, |
| 87 | 'outcome': Build.SUCCEEDED | 45 | 'outcome': Build.SUCCEEDED |
| 88 | } | 46 | } |
| 89 | 47 | ||
| 90 | self.project1_build_failure = { | 48 | self.project1_build_failure = { |
| 91 | 'project': Project.objects.get(id=TestProjectPage.project_id), | 49 | 'project': Project.objects.get(id=TestProjectPageBase.project_id), |
| 92 | 'started_on': now, | 50 | 'started_on': now, |
| 93 | 'completed_on': now, | 51 | 'completed_on': now, |
| 94 | 'outcome': Build.FAILED | 52 | 'outcome': Build.FAILED |
| @@ -222,6 +180,8 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 222 | rows = self.find_all(f'#{table_selector} tbody tr') | 180 | rows = self.find_all(f'#{table_selector} tbody tr') |
| 223 | self.assertTrue(len(rows) > 0) | 181 | self.assertTrue(len(rows) > 0) |
| 224 | 182 | ||
| 183 | class TestProjectPage(TestProjectPageBase): | ||
| 184 | |||
| 225 | def test_create_project(self): | 185 | def test_create_project(self): |
| 226 | """ Create/Test new project using: | 186 | """ Create/Test new project using: |
| 227 | - Project Name: Any string | 187 | - Project Name: Any string |
| @@ -230,26 +190,6 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 230 | """ | 190 | """ |
| 231 | self._create_project(project_name=self.PROJECT_NAME) | 191 | self._create_project(project_name=self.PROJECT_NAME) |
| 232 | 192 | ||
| 233 | def test_image_recipe_editColumn(self): | ||
| 234 | """ Test the edit column feature in image recipe table on project page """ | ||
| 235 | self._get_create_builds(success=10, failure=10) | ||
| 236 | |||
| 237 | url = reverse('projectimagerecipes', args=(TestProjectPage.project_id,)) | ||
| 238 | self.get(url) | ||
| 239 | self.wait_until_present('#imagerecipestable tbody tr') | ||
| 240 | |||
| 241 | column_list = [ | ||
| 242 | 'get_description_or_summary', 'layer_version__get_vcs_reference', | ||
| 243 | 'layer_version__layer__name', 'license', 'recipe-file', 'section', | ||
| 244 | 'version' | ||
| 245 | ] | ||
| 246 | |||
| 247 | # Check that we can hide the edit column | ||
| 248 | self._mixin_test_table_edit_column( | ||
| 249 | 'imagerecipestable', | ||
| 250 | 'edit-columns-button', | ||
| 251 | [f'checkbox-{column}' for column in column_list] | ||
| 252 | ) | ||
| 253 | 193 | ||
| 254 | def test_page_header_on_project_page(self): | 194 | def test_page_header_on_project_page(self): |
| 255 | """ Check page header in project page: | 195 | """ Check page header in project page: |
| @@ -379,7 +319,7 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 379 | self.assertEqual(config_tab.get_attribute('class'), 'active') | 319 | self.assertEqual(config_tab.get_attribute('class'), 'active') |
| 380 | self.assertIn('Configuration', str(config_tab.text)) | 320 | self.assertIn('Configuration', str(config_tab.text)) |
| 381 | self.assertIn( | 321 | self.assertIn( |
| 382 | f"/toastergui/project/{TestProjectPage.project_id}", str(self.driver.current_url) | 322 | f"/toastergui/project/{TestProjectPageBase.project_id}", str(self.driver.current_url) |
| 383 | ) | 323 | ) |
| 384 | 324 | ||
| 385 | def get_tabs(): | 325 | def get_tabs(): |
| @@ -402,7 +342,7 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 402 | check_tab_link( | 342 | check_tab_link( |
| 403 | 1, | 343 | 1, |
| 404 | 'Builds', | 344 | 'Builds', |
| 405 | f"/toastergui/project/{TestProjectPage.project_id}/builds" | 345 | f"/toastergui/project/{TestProjectPageBase.project_id}/builds" |
| 406 | ) | 346 | ) |
| 407 | 347 | ||
| 408 | # check "Import layers" tab | 348 | # check "Import layers" tab |
| @@ -411,7 +351,7 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 411 | check_tab_link( | 351 | check_tab_link( |
| 412 | 2, | 352 | 2, |
| 413 | 'Import layer', | 353 | 'Import layer', |
| 414 | f"/toastergui/project/{TestProjectPage.project_id}/importlayer" | 354 | f"/toastergui/project/{TestProjectPageBase.project_id}/importlayer" |
| 415 | ) | 355 | ) |
| 416 | 356 | ||
| 417 | # check "New custom image" tab | 357 | # check "New custom image" tab |
| @@ -420,7 +360,7 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 420 | check_tab_link( | 360 | check_tab_link( |
| 421 | 3, | 361 | 3, |
| 422 | 'New custom image', | 362 | 'New custom image', |
| 423 | f"/toastergui/project/{TestProjectPage.project_id}/newcustomimage" | 363 | f"/toastergui/project/{TestProjectPageBase.project_id}/newcustomimage" |
| 424 | ) | 364 | ) |
| 425 | 365 | ||
| 426 | # check search box can be use to build recipes | 366 | # check search box can be use to build recipes |
| @@ -766,6 +706,10 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 766 | # Check layer description | 706 | # Check layer description |
| 767 | self.assertIn("Description", section.text) | 707 | self.assertIn("Description", section.text) |
| 768 | 708 | ||
| 709 | @pytest.mark.django_db | ||
| 710 | @pytest.mark.order("last") | ||
| 711 | class TestProjectPageRecipes(TestProjectPageBase): | ||
| 712 | |||
| 769 | def test_single_recipe_page(self): | 713 | def test_single_recipe_page(self): |
| 770 | """ Test recipe page | 714 | """ Test recipe page |
| 771 | - Check if title is displayed | 715 | - Check if title is displayed |
| @@ -777,9 +721,9 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 777 | # Use a recipe which is likely to exist in the layer index but not enabled | 721 | # Use a recipe which is likely to exist in the layer index but not enabled |
| 778 | # in poky out the box - xen-image-minimal from meta-virtualization | 722 | # in poky out the box - xen-image-minimal from meta-virtualization |
| 779 | self._navigate_to_project_page() | 723 | self._navigate_to_project_page() |
| 780 | prj = Project.objects.get(pk=TestProjectPage.project_id) | 724 | prj = Project.objects.get(pk=TestProjectPageBase.project_id) |
| 781 | recipe_id = prj.get_all_compatible_recipes().get(name="xen-image-minimal").pk | 725 | recipe_id = prj.get_all_compatible_recipes().get(name="xen-image-minimal").pk |
| 782 | url = reverse("recipedetails", args=(TestProjectPage.project_id, recipe_id)) | 726 | url = reverse("recipedetails", args=(TestProjectPageBase.project_id, recipe_id)) |
| 783 | self.get(url) | 727 | self.get(url) |
| 784 | self.wait_until_visible('.page-header') | 728 | self.wait_until_visible('.page-header') |
| 785 | # check title is displayed | 729 | # check title is displayed |
| @@ -802,3 +746,25 @@ class TestProjectPage(SeleniumFunctionalTestCase): | |||
| 802 | self.assertIn("Approx. packages included", section.text) | 746 | self.assertIn("Approx. packages included", section.text) |
| 803 | self.assertIn("Approx. package size", section.text) | 747 | self.assertIn("Approx. package size", section.text) |
| 804 | self.assertIn("Recipe file", section.text) | 748 | self.assertIn("Recipe file", section.text) |
| 749 | |||
| 750 | def test_image_recipe_editColumn(self): | ||
| 751 | """ Test the edit column feature in image recipe table on project page """ | ||
| 752 | self._get_create_builds(success=10, failure=10) | ||
| 753 | |||
| 754 | url = reverse('projectimagerecipes', args=(TestProjectPageBase.project_id,)) | ||
| 755 | self.get(url) | ||
| 756 | self.wait_until_present('#imagerecipestable tbody tr') | ||
| 757 | |||
| 758 | column_list = [ | ||
| 759 | 'get_description_or_summary', 'layer_version__get_vcs_reference', | ||
| 760 | 'layer_version__layer__name', 'license', 'recipe-file', 'section', | ||
| 761 | 'version' | ||
| 762 | ] | ||
| 763 | |||
| 764 | # Check that we can hide the edit column | ||
| 765 | self._mixin_test_table_edit_column( | ||
| 766 | 'imagerecipestable', | ||
| 767 | 'edit-columns-button', | ||
| 768 | [f'checkbox-{column}' for column in column_list] | ||
| 769 | ) | ||
| 770 | |||
