blob: 44da640751fea5a996c2f8c8f476c739c1e24efe [file] [log] [blame]
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05001#! /usr/bin/env python
2# ex:ts=4:sw=4:sts=4:et
3# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
4#
5# BitBake Toaster Implementation
6#
7# Copyright (C) 2013-2016 Intel Corporation
8#
9# This program is free software; you can redistribute it and/or modify
10# it under the terms of the GNU General Public License version 2 as
11# published by the Free Software Foundation.
12#
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License along
19# with this program; if not, write to the Free Software Foundation, Inc.,
20# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21
22import re
23
24from django.core.urlresolvers import reverse
25from django.utils import timezone
26from tests.browser.selenium_helpers import SeleniumTestCase
27
28from orm.models import BitbakeVersion, Release, Project, Build
29from orm.models import ProjectVariable
30
31class TestAllProjectsPage(SeleniumTestCase):
32 """ Browser tests for projects page /projects/ """
33
34 PROJECT_NAME = 'test project'
35 CLI_BUILDS_PROJECT_NAME = 'command line builds'
36 MACHINE_NAME = 'delorean'
37
38 def setUp(self):
39 """ Add default project manually """
40 project = Project.objects.create_project(self.CLI_BUILDS_PROJECT_NAME, None)
41 self.default_project = project
42 self.default_project.is_default = True
43 self.default_project.save()
44
45 # this project is only set for some of the tests
46 self.project = None
47
48 self.release = None
49
50 def _add_build_to_default_project(self):
51 """ Add a build to the default project (not used in all tests) """
52 now = timezone.now()
53 build = Build.objects.create(project=self.default_project,
54 started_on=now,
55 completed_on=now)
56 build.save()
57
58 def _add_non_default_project(self):
59 """ Add another project """
60 bbv = BitbakeVersion.objects.create(name='test bbv', giturl='/tmp/',
61 branch='master', dirpath='')
62 self.release = Release.objects.create(name='test release',
63 branch_name='master',
64 bitbake_version=bbv)
65 self.project = Project.objects.create_project(self.PROJECT_NAME, self.release)
66 self.project.is_default = False
67 self.project.save()
68
69 # fake the MACHINE variable
70 project_var = ProjectVariable.objects.create(project=self.project,
71 name='MACHINE',
72 value=self.MACHINE_NAME)
73 project_var.save()
74
75 def _get_row_for_project(self, project_name):
76 """ Get the HTML row for a project, or None if not found """
77 self.wait_until_present('#projectstable tbody tr')
78 rows = self.find_all('#projectstable tbody tr')
79
80 # find the row with a project name matching the one supplied
81 found_row = None
82 for row in rows:
83 if re.search(project_name, row.get_attribute('innerHTML')):
84 found_row = row
85 break
86
87 return found_row
88
89 def test_default_project_hidden(self):
90 """
91 The default project should be hidden if it has no builds
92 and we should see the "no results" area
93 """
94 url = reverse('all-projects')
95 self.get(url)
Patrick Williamsc0f7c042017-02-23 20:41:17 -060096 self.wait_until_visible('#empty-state-projectstable')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050097
98 rows = self.find_all('#projectstable tbody tr')
99 self.assertEqual(len(rows), 0, 'should be no projects displayed')
100
101 def test_default_project_has_build(self):
102 """ The default project should be shown if it has builds """
103 self._add_build_to_default_project()
104
105 url = reverse('all-projects')
106 self.get(url)
107
108 default_project_row = self._get_row_for_project(self.default_project.name)
109
110 self.assertNotEqual(default_project_row, None,
111 'default project "cli builds" should be in page')
112
113 def test_default_project_release(self):
114 """
115 The release for the default project should display as
116 'Not applicable'
117 """
118 # need a build, otherwise project doesn't display at all
119 self._add_build_to_default_project()
120
121 # another project to test, which should show release
122 self._add_non_default_project()
123
124 self.get(reverse('all-projects'))
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600125 self.wait_until_visible("#projectstable tr")
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500126
127 # find the row for the default project
128 default_project_row = self._get_row_for_project(self.default_project.name)
129
130 # check the release text for the default project
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600131 selector = 'span[data-project-field="release"] span.text-muted'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500132 element = default_project_row.find_element_by_css_selector(selector)
133 text = element.text.strip()
134 self.assertEqual(text, 'Not applicable',
135 'release should be "not applicable" for default project')
136
137 # find the row for the default project
138 other_project_row = self._get_row_for_project(self.project.name)
139
140 # check the link in the release cell for the other project
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600141 selector = 'span[data-project-field="release"]'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500142 element = other_project_row.find_element_by_css_selector(selector)
143 text = element.text.strip()
144 self.assertEqual(text, self.release.name,
145 'release name should be shown for non-default project')
146
147 def test_default_project_machine(self):
148 """
149 The machine for the default project should display as
150 'Not applicable'
151 """
152 # need a build, otherwise project doesn't display at all
153 self._add_build_to_default_project()
154
155 # another project to test, which should show machine
156 self._add_non_default_project()
157
158 self.get(reverse('all-projects'))
159
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600160 self.wait_until_visible("#projectstable tr")
161
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500162 # find the row for the default project
163 default_project_row = self._get_row_for_project(self.default_project.name)
164
165 # check the machine cell for the default project
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600166 selector = 'span[data-project-field="machine"] span.text-muted'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500167 element = default_project_row.find_element_by_css_selector(selector)
168 text = element.text.strip()
169 self.assertEqual(text, 'Not applicable',
170 'machine should be not applicable for default project')
171
172 # find the row for the default project
173 other_project_row = self._get_row_for_project(self.project.name)
174
175 # check the link in the machine cell for the other project
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600176 selector = 'span[data-project-field="machine"]'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500177 element = other_project_row.find_element_by_css_selector(selector)
178 text = element.text.strip()
179 self.assertEqual(text, self.MACHINE_NAME,
180 'machine name should be shown for non-default project')
181
182 def test_project_page_links(self):
183 """
184 Test that links for the default project point to the builds
185 page /projects/X/builds for that project, and that links for
186 other projects point to their configuration pages /projects/X/
187 """
188
189 # need a build, otherwise project doesn't display at all
190 self._add_build_to_default_project()
191
192 # another project to test
193 self._add_non_default_project()
194
195 self.get(reverse('all-projects'))
196
197 # find the row for the default project
198 default_project_row = self._get_row_for_project(self.default_project.name)
199
200 # check the link on the name field
201 selector = 'span[data-project-field="name"] a'
202 element = default_project_row.find_element_by_css_selector(selector)
203 link_url = element.get_attribute('href').strip()
204 expected_url = reverse('projectbuilds', args=(self.default_project.id,))
205 msg = 'link on default project name should point to builds but was %s' % link_url
206 self.assertTrue(link_url.endswith(expected_url), msg)
207
208 # find the row for the other project
209 other_project_row = self._get_row_for_project(self.project.name)
210
211 # check the link for the other project
212 selector = 'span[data-project-field="name"] a'
213 element = other_project_row.find_element_by_css_selector(selector)
214 link_url = element.get_attribute('href').strip()
215 expected_url = reverse('project', args=(self.project.id,))
216 msg = 'link on project name should point to configuration but was %s' % link_url
217 self.assertTrue(link_url.endswith(expected_url), msg)