1#! /usr/bin/env python3
2# BitBake Toaster UI tests implementation
3#
4# Copyright (C) 2023 Savoir-faire Linux
5#
6# SPDX-License-Identifier: GPL-2.0-only
7#
8
9import re
10import pytest
11from django.urls import reverse
12from selenium.webdriver.support.select import Select
13from tests.functional.functional_helpers import SeleniumFunctionalTestCase
14from orm.models import Project
15from selenium.webdriver.common.by import By
16
17
18@pytest.mark.django_db
19@pytest.mark.order("last")
20class TestCreateNewProject(SeleniumFunctionalTestCase):
21
22    def _create_test_new_project(
23        self,
24        project_name,
25        release,
26        release_title,
27        merge_toaster_settings,
28    ):
29        """ Create/Test new project using:
30          - Project Name: Any string
31          - Release: Any string
32          - Merge Toaster settings: True or False
33        """
34        self.get(reverse('newproject'))
35        self.wait_until_visible('#new-project-name', poll=3)
36        self.driver.find_element(By.ID,
37                                 "new-project-name").send_keys(project_name)
38
39        select = Select(self.find('#projectversion'))
40        select.select_by_value(release)
41
42        # check merge toaster settings
43        checkbox = self.find('.checkbox-mergeattr')
44        if merge_toaster_settings:
45            if not checkbox.is_selected():
46                checkbox.click()
47        else:
48            if checkbox.is_selected():
49                checkbox.click()
50
51        self.driver.find_element(By.ID, "create-project-button").click()
52
53        element = self.wait_until_visible('#project-created-notification', poll=3)
54        self.assertTrue(
55            self.element_exists('#project-created-notification'),
56            f"Project:{project_name} creation notification not shown"
57        )
58        self.assertTrue(
59            project_name in element.text,
60            f"New project name:{project_name} not in new project notification"
61        )
62        self.assertTrue(
63            Project.objects.filter(name=project_name).count(),
64            f"New project:{project_name} not found in database"
65        )
66
67        # check release
68        self.assertTrue(re.search(
69            release_title,
70            self.driver.find_element(By.XPATH,
71                                     "//span[@id='project-release-title']"
72                                     ).text),
73                        'The project release is not defined')
74
75    def test_create_new_project_master(self):
76        """ Test create new project using:
77          - Project Name: Any string
78          - Release: Yocto Project master (option value: 3)
79          - Merge Toaster settings: False
80        """
81        release = '3'
82        release_title = 'Yocto Project master'
83        project_name = 'projectmaster'
84        self._create_test_new_project(
85            project_name,
86            release,
87            release_title,
88            False,
89        )
90
91    def test_create_new_project_kirkstone(self):
92        """ Test create new project using:
93          - Project Name: Any string
94          - Release: Yocto Project 4.0 "Kirkstone" (option value: 1)
95          - Merge Toaster settings: True
96        """
97        release = '1'
98        release_title = 'Yocto Project 4.0 "Kirkstone"'
99        project_name = 'projectkirkstone'
100        self._create_test_new_project(
101            project_name,
102            release,
103            release_title,
104            True,
105        )
106
107    def test_create_new_project_dunfell(self):
108        """ Test create new project using:
109          - Project Name: Any string
110          - Release: Yocto Project 3.1 "Dunfell" (option value: 5)
111          - Merge Toaster settings: False
112        """
113        release = '5'
114        release_title = 'Yocto Project 3.1 "Dunfell"'
115        project_name = 'projectdunfell'
116        self._create_test_new_project(
117            project_name,
118            release,
119            release_title,
120            False,
121        )
122
123    def test_create_new_project_local(self):
124        """ Test create new project using:
125          - Project Name: Any string
126          - Release: Local Yocto Project (option value: 2)
127          - Merge Toaster settings: True
128        """
129        release = '2'
130        release_title = 'Local Yocto Project'
131        project_name = 'projectlocal'
132        self._create_test_new_project(
133            project_name,
134            release,
135            release_title,
136            True,
137        )
138
139    def test_create_new_project_without_name(self):
140        """ Test create new project without project name """
141        self.get(reverse('newproject'))
142
143        select = Select(self.find('#projectversion'))
144        select.select_by_value(str(3))
145
146        # Check input name has required attribute
147        input_name = self.driver.find_element(By.ID, "new-project-name")
148        self.assertIsNotNone(input_name.get_attribute('required'),
149                        'Input name has not required attribute')
150
151        # Check create button is disabled
152        create_btn = self.driver.find_element(By.ID, "create-project-button")
153        self.assertIsNotNone(create_btn.get_attribute('disabled'),
154                        'Create button is not disabled')
155
156    def test_import_new_project(self):
157        """ Test import new project using:
158          - Project Name: Any string
159          - Project type: select (Import command line project)
160          - Import existing project directory: Wrong Path
161        """
162        project_name = 'projectimport'
163        self.get(reverse('newproject'))
164        self.driver.find_element(By.ID,
165                                 "new-project-name").send_keys(project_name)
166        # select import project
167        self.find('#type-import').click()
168
169        # set wrong path
170        wrong_path = '/wrongpath'
171        self.driver.find_element(By.ID,
172                                 "import-project-dir").send_keys(wrong_path)
173        self.driver.find_element(By.ID, "create-project-button").click()
174
175        # check error message
176        self.assertTrue(self.element_exists('.alert-danger'),
177                        'Allert message not shown')
178        self.assertTrue(wrong_path in self.find('.alert-danger').text,
179                        "Wrong path not in alert message")
180