summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bitbake/lib/toaster/tests/browser/test_all_projects_page.py214
-rw-r--r--bitbake/lib/toaster/toastergui/tests.py197
2 files changed, 214 insertions, 197 deletions
diff --git a/bitbake/lib/toaster/tests/browser/test_all_projects_page.py b/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
new file mode 100644
index 0000000000..ed8e620db4
--- /dev/null
+++ b/bitbake/lib/toaster/tests/browser/test_all_projects_page.py
@@ -0,0 +1,214 @@
1#! /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)
96 self.wait_until_visible('#no-results-projectstable')
97
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'))
125
126 # find the row for the default project
127 default_project_row = self._get_row_for_project(self.default_project.name)
128
129 # check the release text for the default project
130 selector = 'span[data-project-field="release"] span.muted'
131 element = default_project_row.find_element_by_css_selector(selector)
132 text = element.text.strip()
133 self.assertEqual(text, 'Not applicable',
134 'release should be "not applicable" for default project')
135
136 # find the row for the default project
137 other_project_row = self._get_row_for_project(self.project.name)
138
139 # check the link in the release cell for the other project
140 selector = 'span[data-project-field="release"] a'
141 element = other_project_row.find_element_by_css_selector(selector)
142 text = element.text.strip()
143 self.assertEqual(text, self.release.name,
144 'release name should be shown for non-default project')
145
146 def test_default_project_machine(self):
147 """
148 The machine for the default project should display as
149 'Not applicable'
150 """
151 # need a build, otherwise project doesn't display at all
152 self._add_build_to_default_project()
153
154 # another project to test, which should show machine
155 self._add_non_default_project()
156
157 self.get(reverse('all-projects'))
158
159 # find the row for the default project
160 default_project_row = self._get_row_for_project(self.default_project.name)
161
162 # check the machine cell for the default project
163 selector = 'span[data-project-field="machine"] span.muted'
164 element = default_project_row.find_element_by_css_selector(selector)
165 text = element.text.strip()
166 self.assertEqual(text, 'Not applicable',
167 'machine should be not applicable for default project')
168
169 # find the row for the default project
170 other_project_row = self._get_row_for_project(self.project.name)
171
172 # check the link in the machine cell for the other project
173 selector = 'span[data-project-field="machine"] a'
174 element = other_project_row.find_element_by_css_selector(selector)
175 text = element.text.strip()
176 self.assertEqual(text, self.MACHINE_NAME,
177 'machine name should be shown for non-default project')
178
179 def test_project_page_links(self):
180 """
181 Test that links for the default project point to the builds
182 page /projects/X/builds for that project, and that links for
183 other projects point to their configuration pages /projects/X/
184 """
185
186 # need a build, otherwise project doesn't display at all
187 self._add_build_to_default_project()
188
189 # another project to test
190 self._add_non_default_project()
191
192 self.get(reverse('all-projects'))
193
194 # find the row for the default project
195 default_project_row = self._get_row_for_project(self.default_project.name)
196
197 # check the link on the name field
198 selector = 'span[data-project-field="name"] a'
199 element = default_project_row.find_element_by_css_selector(selector)
200 link_url = element.get_attribute('href').strip()
201 expected_url = reverse('projectbuilds', args=(self.default_project.id,))
202 msg = 'link on default project name should point to builds but was %s' % link_url
203 self.assertTrue(link_url.endswith(expected_url), msg)
204
205 # find the row for the other project
206 other_project_row = self._get_row_for_project(self.project.name)
207
208 # check the link for the other project
209 selector = 'span[data-project-field="name"] a'
210 element = other_project_row.find_element_by_css_selector(selector)
211 link_url = element.get_attribute('href').strip()
212 expected_url = reverse('project', args=(self.project.id,))
213 msg = 'link on project name should point to configuration but was %s' % link_url
214 self.assertTrue(link_url.endswith(expected_url), msg)
diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py
index 7192947326..6975ac1bfe 100644
--- a/bitbake/lib/toaster/toastergui/tests.py
+++ b/bitbake/lib/toaster/toastergui/tests.py
@@ -493,7 +493,6 @@ class ViewTests(TestCase):
493 "Changed page on table %s but first row is the " 493 "Changed page on table %s but first row is the "
494 "same as the previous page" % name) 494 "same as the previous page" % name)
495 495
496
497class LandingPageTests(TestCase): 496class LandingPageTests(TestCase):
498 """ Tests for redirects on the landing page """ 497 """ Tests for redirects on the landing page """
499 # disable bogus pylint message error: 498 # disable bogus pylint message error:
@@ -568,202 +567,6 @@ class LandingPageTests(TestCase):
568 self.assertTrue('/builds' in response.url, 567 self.assertTrue('/builds' in response.url,
569 'should redirect to builds') 568 'should redirect to builds')
570 569
571class AllProjectsPageTests(TestCase):
572 """ Tests for projects page /projects/ """
573
574 MACHINE_NAME = 'delorean'
575
576 def setUp(self):
577 """ Add default project manually """
578 project = Project.objects.create_project(CLI_BUILDS_PROJECT_NAME, None)
579 self.default_project = project
580 self.default_project.is_default = True
581 self.default_project.save()
582
583 # this project is only set for some of the tests
584 self.project = None
585
586 self.release = None
587
588 def _add_build_to_default_project(self):
589 """ Add a build to the default project (not used in all tests) """
590 now = timezone.now()
591 build = Build.objects.create(project=self.default_project,
592 started_on=now,
593 completed_on=now)
594 build.save()
595
596 def _add_non_default_project(self):
597 """ Add another project """
598 bbv = BitbakeVersion.objects.create(name="test bbv", giturl="/tmp/",
599 branch="master", dirpath="")
600 self.release = Release.objects.create(name="test release",
601 branch_name="master",
602 bitbake_version=bbv)
603 self.project = Project.objects.create_project(PROJECT_NAME, self.release)
604 self.project.is_default = False
605 self.project.save()
606
607 # fake the MACHINE variable
608 project_var = ProjectVariable.objects.create(project=self.project,
609 name='MACHINE',
610 value=self.MACHINE_NAME)
611 project_var.save()
612
613 def _get_row_for_project(self, data, project_id):
614 """ Get the object representing the table data for a project """
615 return [row for row in data['rows'] if row['id'] == project_id][0]
616
617 def test_default_project_hidden(self):
618 """ The default project should be hidden if it has no builds """
619 params = {"count": 10, "orderby": "updated:-", "page": 1}
620 response = self.client.get(reverse('all-projects'), params)
621
622 self.assertTrue(not('tr class="data"' in response.content),
623 'should be no project rows in the page')
624 self.assertTrue(not(CLI_BUILDS_PROJECT_NAME in response.content),
625 'default project "cli builds" should not be in page')
626
627 def test_default_project_has_build(self):
628 """ The default project should be shown if it has builds """
629 self._add_build_to_default_project()
630
631 params = {"count": 10, "orderby": "updated:-", "page": 1}
632
633 response = self.client.get(
634 reverse('all-projects'),
635 {'format': 'json'},
636 params
637 )
638
639 data = json.loads(response.content)
640
641 # find the row for the default project
642 default_project_row = self._get_row_for_project(data, self.default_project.id)
643
644 # check its name template has the correct text
645 self.assertEqual(default_project_row['name'], CLI_BUILDS_PROJECT_NAME,
646 'default project "cli builds" should be in page')
647
648 def test_default_project_release(self):
649 """
650 The release for the default project should display as
651 'Not applicable'
652 """
653 # need a build, otherwise project doesn't display at all
654 self._add_build_to_default_project()
655
656 # another project to test, which should show release
657 self._add_non_default_project()
658
659 response = self.client.get(
660 reverse('all-projects'),
661 {'format': 'json'},
662 follow=True
663 )
664
665 data = json.loads(response.content)
666
667 # used to find the correct span in the template output
668 attrs = {'data-project-field': 'release'}
669
670 # find the row for the default project
671 default_project_row = self._get_row_for_project(data, self.default_project.id)
672
673 # check the release text for the default project
674 soup = BeautifulSoup(default_project_row['static:release'])
675 text = soup.find('span', attrs=attrs).select('span.muted')[0].text
676 self.assertEqual(text, 'Not applicable',
677 'release should be not applicable for default project')
678
679 # find the row for the default project
680 other_project_row = self._get_row_for_project(data, self.project.id)
681
682 # check the link in the release cell for the other project
683 soup = BeautifulSoup(other_project_row['static:release'])
684 text = soup.find('span', attrs=attrs).select('a')[0].text.strip()
685 self.assertEqual(text, self.release.name,
686 'release name should be shown for non-default project')
687
688 def test_default_project_machine(self):
689 """
690 The machine for the default project should display as
691 'Not applicable'
692 """
693 # need a build, otherwise project doesn't display at all
694 self._add_build_to_default_project()
695
696 # another project to test, which should show machine
697 self._add_non_default_project()
698
699 response = self.client.get(
700 reverse('all-projects'),
701 {'format': 'json'},
702 follow=True
703 )
704
705 data = json.loads(response.content)
706
707 # used to find the correct span in the template output
708 attrs = {'data-project-field': 'machine'}
709
710 # find the row for the default project
711 default_project_row = self._get_row_for_project(data, self.default_project.id)
712
713 # check the machine cell for the default project
714 soup = BeautifulSoup(default_project_row['static:machine'])
715 text = soup.find('span', attrs=attrs).select('span.muted')[0].text.strip()
716 self.assertEqual(text, 'Not applicable',
717 'machine should be not applicable for default project')
718
719 # find the row for the default project
720 other_project_row = self._get_row_for_project(data, self.project.id)
721
722 # check the link in the machine cell for the other project
723 soup = BeautifulSoup(other_project_row['static:machine'])
724 text = soup.find('span', attrs=attrs).find('a').text.strip()
725 self.assertEqual(text, self.MACHINE_NAME,
726 'machine name should be shown for non-default project')
727
728 def test_project_page_links(self):
729 """
730 Test that links for the default project point to the builds
731 page /projects/X/builds for that project, and that links for
732 other projects point to their configuration pages /projects/X/
733 """
734
735 # need a build, otherwise project doesn't display at all
736 self._add_build_to_default_project()
737
738 # another project to test
739 self._add_non_default_project()
740
741 response = self.client.get(
742 reverse('all-projects'),
743 {'format': 'json'},
744 follow=True
745 )
746
747 data = json.loads(response.content)
748
749 # find the row for the default project
750 default_project_row = self._get_row_for_project(data, self.default_project.id)
751
752 # check the link on the name field
753 soup = BeautifulSoup(default_project_row['static:name'])
754 expected_url = reverse('projectbuilds', args=(self.default_project.id,))
755 self.assertEqual(soup.find('a')['href'], expected_url,
756 'link on default project name should point to builds')
757
758 # find the row for the other project
759 other_project_row = self._get_row_for_project(data, self.project.id)
760
761 # check the link for the other project
762 soup = BeautifulSoup(other_project_row['static:name'])
763 expected_url = reverse('project', args=(self.project.id,))
764 self.assertEqual(soup.find('a')['href'], expected_url,
765 'link on project name should point to configuration')
766
767class BuildDashboardTests(TestCase): 570class BuildDashboardTests(TestCase):
768 """ Tests for the build dashboard /build/X """ 571 """ Tests for the build dashboard /build/X """
769 572