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 | |||