blob: fba627bd215a72a6c07e0c3bafd485191e7129c6 [file] [log] [blame]
Brad Bishop96ff1982019-08-19 13:50:42 -04001#! /usr/bin/env python3
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05002#
3# BitBake Toaster Implementation
4#
5# Copyright (C) 2013-2016 Intel Corporation
6#
Brad Bishopc342db32019-05-15 21:57:59 -04007# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05008#
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05009
10import re
11
12from django.core.urlresolvers import reverse
13from django.utils import timezone
14from tests.browser.selenium_helpers import SeleniumTestCase
15
16from orm.models import BitbakeVersion, Release, Project, Build, Target
17
Patrick Williamsc0f7c042017-02-23 20:41:17 -060018
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050019class TestAllBuildsPage(SeleniumTestCase):
20 """ Tests for all builds page /builds/ """
21
22 PROJECT_NAME = 'test project'
23 CLI_BUILDS_PROJECT_NAME = 'command line builds'
24
25 def setUp(self):
26 bbv = BitbakeVersion.objects.create(name='bbv1', giturl='/tmp/',
27 branch='master', dirpath='')
28 release = Release.objects.create(name='release1',
29 bitbake_version=bbv)
30 self.project1 = Project.objects.create_project(name=self.PROJECT_NAME,
31 release=release)
32 self.default_project = Project.objects.create_project(
33 name=self.CLI_BUILDS_PROJECT_NAME,
34 release=release
35 )
36 self.default_project.is_default = True
37 self.default_project.save()
38
39 # parameters for builds to associate with the projects
40 now = timezone.now()
41
42 self.project1_build_success = {
43 'project': self.project1,
44 'started_on': now,
45 'completed_on': now,
46 'outcome': Build.SUCCEEDED
47 }
48
Patrick Williamsc0f7c042017-02-23 20:41:17 -060049 self.project1_build_failure = {
50 'project': self.project1,
51 'started_on': now,
52 'completed_on': now,
53 'outcome': Build.FAILED
54 }
55
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050056 self.default_project_build_success = {
57 'project': self.default_project,
58 'started_on': now,
59 'completed_on': now,
60 'outcome': Build.SUCCEEDED
61 }
62
Patrick Williamsc0f7c042017-02-23 20:41:17 -060063 def _get_build_time_element(self, build):
64 """
65 Return the HTML element containing the build time for a build
66 in the recent builds area
67 """
68 selector = 'div[data-latest-build-result="%s"] ' \
69 '[data-role="data-recent-build-buildtime-field"]' % build.id
70
71 # because this loads via Ajax, wait for it to be visible
72 self.wait_until_present(selector)
73
74 build_time_spans = self.find_all(selector)
75
76 self.assertEqual(len(build_time_spans), 1)
77
78 return build_time_spans[0]
79
80 def _get_row_for_build(self, build):
81 """ Get the table row for the build from the all builds table """
82 self.wait_until_present('#allbuildstable')
83
84 rows = self.find_all('#allbuildstable tr')
85
86 # look for the row with a download link on the recipe which matches the
87 # build ID
88 url = reverse('builddashboard', args=(build.id,))
89 selector = 'td.target a[href="%s"]' % url
90
91 found_row = None
92 for row in rows:
93
94 outcome_links = row.find_elements_by_css_selector(selector)
95 if len(outcome_links) == 1:
96 found_row = row
97 break
98
99 self.assertNotEqual(found_row, None)
100
101 return found_row
102
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500103 def test_show_tasks_with_suffix(self):
104 """ Task should be shown as suffix on build name """
105 build = Build.objects.create(**self.project1_build_success)
106 target = 'bash'
107 task = 'clean'
108 Target.objects.create(build=build, target=target, task=task)
109
110 url = reverse('all-builds')
111 self.get(url)
112 self.wait_until_present('td[class="target"]')
113
114 cell = self.find('td[class="target"]')
115 content = cell.get_attribute('innerHTML')
116 expected_text = '%s:%s' % (target, task)
117
118 self.assertTrue(re.search(expected_text, content),
119 '"target" cell should contain text %s' % expected_text)
120
121 def test_rebuild_buttons(self):
122 """
123 Test 'Rebuild' buttons in recent builds section
124
125 'Rebuild' button should not be shown for command-line builds,
126 but should be shown for other builds
127 """
128 build1 = Build.objects.create(**self.project1_build_success)
129 default_build = Build.objects.create(**self.default_project_build_success)
130
131 url = reverse('all-builds')
132 self.get(url)
133
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600134 # shouldn't see a rebuild button for command-line builds
135 selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % default_build.id
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500136 run_again_button = self.find_all(selector)
137 self.assertEqual(len(run_again_button), 0,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600138 'should not see a rebuild button for cli builds')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500139
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600140 # should see a rebuild button for non-command-line builds
141 selector = 'div[data-latest-build-result="%s"] .rebuild-btn' % build1.id
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500142 run_again_button = self.find_all(selector)
143 self.assertEqual(len(run_again_button), 1,
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600144 'should see a rebuild button for non-cli builds')
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500145
146 def test_tooltips_on_project_name(self):
147 """
148 Test tooltips shown next to project name in the main table
149
150 A tooltip should be present next to the command line
151 builds project name in the all builds page, but not for
152 other projects
153 """
154 Build.objects.create(**self.project1_build_success)
155 Build.objects.create(**self.default_project_build_success)
156
157 url = reverse('all-builds')
158 self.get(url)
159
160 # get the project name cells from the table
161 cells = self.find_all('#allbuildstable td[class="project"]')
162
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600163 selector = 'span.get-help'
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500164
165 for cell in cells:
166 content = cell.get_attribute('innerHTML')
167 help_icons = cell.find_elements_by_css_selector(selector)
168
169 if re.search(self.PROJECT_NAME, content):
170 # no help icon next to non-cli project name
171 msg = 'should not be a help icon for non-cli builds name'
172 self.assertEqual(len(help_icons), 0, msg)
173 elif re.search(self.CLI_BUILDS_PROJECT_NAME, content):
174 # help icon next to cli project name
175 msg = 'should be a help icon for cli builds name'
176 self.assertEqual(len(help_icons), 1, msg)
177 else:
178 msg = 'found unexpected project name cell in all builds table'
179 self.fail(msg)
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600180
181 def test_builds_time_links(self):
182 """
183 Successful builds should have links on the time column and in the
184 recent builds area; failed builds should not have links on the time column,
185 or in the recent builds area
186 """
187 build1 = Build.objects.create(**self.project1_build_success)
188 build2 = Build.objects.create(**self.project1_build_failure)
189
190 # add some targets to these builds so they have recipe links
191 # (and so we can find the row in the ToasterTable corresponding to
192 # a particular build)
193 Target.objects.create(build=build1, target='foo')
194 Target.objects.create(build=build2, target='bar')
195
196 url = reverse('all-builds')
197 self.get(url)
198
199 # test recent builds area for successful build
200 element = self._get_build_time_element(build1)
201 links = element.find_elements_by_css_selector('a')
202 msg = 'should be a link on the build time for a successful recent build'
203 self.assertEquals(len(links), 1, msg)
204
205 # test recent builds area for failed build
206 element = self._get_build_time_element(build2)
207 links = element.find_elements_by_css_selector('a')
208 msg = 'should not be a link on the build time for a failed recent build'
209 self.assertEquals(len(links), 0, msg)
210
211 # test the time column for successful build
212 build1_row = self._get_row_for_build(build1)
213 links = build1_row.find_elements_by_css_selector('td.time a')
214 msg = 'should be a link on the build time for a successful build'
215 self.assertEquals(len(links), 1, msg)
216
217 # test the time column for failed build
218 build2_row = self._get_row_for_build(build2)
219 links = build2_row.find_elements_by_css_selector('td.time a')
220 msg = 'should not be a link on the build time for a failed build'
221 self.assertEquals(len(links), 0, msg)