1#! /usr/bin/env python3
2#
3# BitBake Toaster Implementation
4#
5# SPDX-License-Identifier: GPL-2.0-only
6#
7# Copyright (C) 2013-2016 Intel Corporation
8#
9
10from django.urls import reverse
11from django.utils import timezone
12from tests.browser.selenium_helpers import SeleniumTestCase
13from selenium.webdriver.common.by import By
14
15from orm.models import Layer, Layer_Version, Project, Build
16
17
18class TestLandingPage(SeleniumTestCase):
19    """ Tests for redirects on the landing page """
20
21    PROJECT_NAME = 'test project'
22    LANDING_PAGE_TITLE = 'This is Toaster'
23    CLI_BUILDS_PROJECT_NAME = 'command line builds'
24
25    def setUp(self):
26        """ Add default project manually """
27        self.project = Project.objects.create_project(
28            self.CLI_BUILDS_PROJECT_NAME,
29            None
30        )
31        self.project.is_default = True
32        self.project.save()
33
34    def test_icon_info_visible_and_clickable(self):
35        """ Test that the information icon is visible and clickable """
36        self.get(reverse('landing'))
37        info_sign = self.find('#toaster-version-info-sign')
38
39        # check that the info sign is visible
40        self.assertTrue(info_sign.is_displayed())
41
42        # check that the info sign is clickable
43        # and info modal is appearing when clicking on the info sign
44        info_sign.click()  # click on the info sign make attribute 'aria-describedby' visible
45        info_model_id = info_sign.get_attribute('aria-describedby')
46        info_modal = self.find(f'#{info_model_id}')
47        self.assertTrue(info_modal.is_displayed())
48        self.assertTrue("Toaster version information" in info_modal.text)
49
50    def test_documentation_link_displayed(self):
51        """ Test that the documentation link is displayed """
52        self.get(reverse('landing'))
53        documentation_link = self.find('#navbar-docs > a')
54
55        # check that the documentation link is visible
56        self.assertTrue(documentation_link.is_displayed())
57
58        # check browser open new tab toaster manual when clicking on the documentation link
59        self.assertEqual(documentation_link.get_attribute('target'), '_blank')
60        self.assertEqual(
61            documentation_link.get_attribute('href'),
62            'http://docs.yoctoproject.org/toaster-manual/index.html#toaster-user-manual')
63        self.assertTrue("Documentation" in documentation_link.text)
64
65    def test_openembedded_jumbotron_link_visible_and_clickable(self):
66        """ Test OpenEmbedded link jumbotron is visible and clickable: """
67        self.get(reverse('landing'))
68        jumbotron = self.find('.jumbotron')
69
70        # check OpenEmbedded
71        openembedded = jumbotron.find_element(By.LINK_TEXT, 'OpenEmbedded')
72        self.assertTrue(openembedded.is_displayed())
73        openembedded.click()
74        self.assertTrue("openembedded.org" in self.driver.current_url)
75
76    def test_bitbake_jumbotron_link_visible_and_clickable(self):
77        """ Test BitBake link jumbotron is visible and clickable: """
78        self.get(reverse('landing'))
79        jumbotron = self.find('.jumbotron')
80
81        # check BitBake
82        bitbake = jumbotron.find_element(By.LINK_TEXT, 'BitBake')
83        self.assertTrue(bitbake.is_displayed())
84        bitbake.click()
85        self.assertTrue(
86            "docs.yoctoproject.org/bitbake.html" in self.driver.current_url)
87
88    def test_yoctoproject_jumbotron_link_visible_and_clickable(self):
89        """ Test Yocto Project link jumbotron is visible and clickable: """
90        self.get(reverse('landing'))
91        jumbotron = self.find('.jumbotron')
92
93        # check Yocto Project
94        yoctoproject = jumbotron.find_element(By.LINK_TEXT, 'Yocto Project')
95        self.assertTrue(yoctoproject.is_displayed())
96        yoctoproject.click()
97        self.assertTrue("yoctoproject.org" in self.driver.current_url)
98
99    def test_link_setup_using_toaster_visible_and_clickable(self):
100        """ Test big magenta button setting up and using toaster link in jumbotron
101            if visible and clickable
102        """
103        self.get(reverse('landing'))
104        jumbotron = self.find('.jumbotron')
105
106        # check Big magenta button
107        big_magenta_button = jumbotron.find_element(By.LINK_TEXT,
108                                                    'Toaster is ready to capture your command line builds'
109                                                    )
110        self.assertTrue(big_magenta_button.is_displayed())
111        big_magenta_button.click()
112        self.assertTrue(
113            "docs.yoctoproject.org/toaster-manual/setup-and-use.html#setting-up-and-using-toaster" in self.driver.current_url)
114
115    def test_link_create_new_project_in_jumbotron_visible_and_clickable(self):
116        """ Test big blue button create new project jumbotron if visible and clickable """
117        # Create a layer and a layer version to make visible the big blue button
118        layer = Layer.objects.create(name='bar')
119        Layer_Version.objects.create(layer=layer)
120
121        self.get(reverse('landing'))
122        jumbotron = self.find('.jumbotron')
123
124        # check Big Blue button
125        big_blue_button = jumbotron.find_element(By.LINK_TEXT,
126                                                 'Create your first Toaster project to run manage builds'
127                                                 )
128        self.assertTrue(big_blue_button.is_displayed())
129        big_blue_button.click()
130        self.assertTrue("toastergui/newproject/" in self.driver.current_url)
131
132    def test_toaster_manual_link_visible_and_clickable(self):
133        """ Test Read the Toaster manual link jumbotron is visible and clickable: """
134        self.get(reverse('landing'))
135        jumbotron = self.find('.jumbotron')
136
137        # check Read the Toaster manual
138        toaster_manual = jumbotron.find_element(
139            By.LINK_TEXT, 'Read the Toaster manual')
140        self.assertTrue(toaster_manual.is_displayed())
141        toaster_manual.click()
142        self.assertTrue(
143            "https://docs.yoctoproject.org/toaster-manual/index.html#toaster-user-manual" in self.driver.current_url)
144
145    def test_contrib_to_toaster_link_visible_and_clickable(self):
146        """ Test Contribute to Toaster link jumbotron is visible and clickable: """
147        self.get(reverse('landing'))
148        jumbotron = self.find('.jumbotron')
149
150        # check Contribute to Toaster
151        contribute_to_toaster = jumbotron.find_element(
152            By.LINK_TEXT, 'Contribute to Toaster')
153        self.assertTrue(contribute_to_toaster.is_displayed())
154        contribute_to_toaster.click()
155        self.assertTrue(
156            "wiki.yoctoproject.org/wiki/contribute_to_toaster" in str(self.driver.current_url).lower())
157
158    def test_only_default_project(self):
159        """
160        No projects except default
161        => should see the landing page
162        """
163        self.get(reverse('landing'))
164        self.assertTrue(self.LANDING_PAGE_TITLE in self.get_page_source())
165
166    def test_default_project_has_build(self):
167        """
168        Default project has a build, no other projects
169        => should see the builds page
170        """
171        now = timezone.now()
172        build = Build.objects.create(project=self.project,
173                                     started_on=now,
174                                     completed_on=now)
175        build.save()
176
177        self.get(reverse('landing'))
178
179        elements = self.find_all('#allbuildstable')
180        self.assertEqual(len(elements), 1, 'should redirect to builds')
181        content = self.get_page_source()
182        self.assertFalse(self.PROJECT_NAME in content,
183                         'should not show builds for project %s' % self.PROJECT_NAME)
184        self.assertTrue(self.CLI_BUILDS_PROJECT_NAME in content,
185                        'should show builds for cli project')
186
187    def test_user_project_exists(self):
188        """
189        User has added a project (without builds)
190        => should see the projects page
191        """
192        user_project = Project.objects.create_project('foo', None)
193        user_project.save()
194
195        self.get(reverse('landing'))
196
197        elements = self.find_all('#projectstable')
198        self.assertEqual(len(elements), 1, 'should redirect to projects')
199
200    def test_user_project_has_build(self):
201        """
202        User has added a project (with builds), command line builds doesn't
203        => should see the builds page
204        """
205        user_project = Project.objects.create_project(self.PROJECT_NAME, None)
206        user_project.save()
207
208        now = timezone.now()
209        build = Build.objects.create(project=user_project,
210                                     started_on=now,
211                                     completed_on=now)
212        build.save()
213
214        self.get(reverse('landing'))
215
216        self.wait_until_visible("#latest-builds", poll=3)
217        elements = self.find_all('#allbuildstable')
218        self.assertEqual(len(elements), 1, 'should redirect to builds')
219        content = self.get_page_source()
220        self.assertTrue(self.PROJECT_NAME in content,
221                        'should show builds for project %s' % self.PROJECT_NAME)
222