diff options
| author | Elliot Smith <elliot.smith@intel.com> | 2016-01-15 13:01:05 +0200 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-01-15 16:30:01 +0000 |
| commit | c4b50111e9887c4d69f6a8b5fb50824fc44f7128 (patch) | |
| tree | 76073d697e3161606847c629ecf3747928398be5 | |
| parent | 88a262cbd231b452f0b50cc37bec7189e5796710 (diff) | |
| download | poky-c4b50111e9887c4d69f6a8b5fb50824fc44f7128.tar.gz | |
bitbake: toaster tests: fix Django tests for new ToasterTable pages
The Django command-line tests can no longer test the content
of the projects/, builds/ and projectbuilds/ pages, as
ToasterTable pages are populated by JavaScript.
Fix/remove affected tests by converting them to tests on the
JSON returned by the ToasterTable.
[YOCTO #8738]
(Bitbake rev: 85efa9530fa6181855e051bfd14de1c15db9c3b7)
Signed-off-by: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Ed Bartosh <ed.bartosh@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
| -rw-r--r-- | bitbake/lib/toaster/toastergui/tests.py | 265 |
1 files changed, 180 insertions, 85 deletions
diff --git a/bitbake/lib/toaster/toastergui/tests.py b/bitbake/lib/toaster/toastergui/tests.py index c927fe1d8d..0987721180 100644 --- a/bitbake/lib/toaster/toastergui/tests.py +++ b/bitbake/lib/toaster/toastergui/tests.py | |||
| @@ -38,11 +38,14 @@ import toastergui | |||
| 38 | 38 | ||
| 39 | from toastergui.tables import SoftwareRecipesTable | 39 | from toastergui.tables import SoftwareRecipesTable |
| 40 | import json | 40 | import json |
| 41 | from datetime import timedelta | ||
| 41 | from bs4 import BeautifulSoup | 42 | from bs4 import BeautifulSoup |
| 42 | import re | 43 | import re |
| 43 | import string | 44 | import string |
| 45 | import json | ||
| 44 | 46 | ||
| 45 | PROJECT_NAME = "test project" | 47 | PROJECT_NAME = "test project" |
| 48 | PROJECT_NAME2 = "test project 2" | ||
| 46 | CLI_BUILDS_PROJECT_NAME = 'Command line builds' | 49 | CLI_BUILDS_PROJECT_NAME = 'Command line builds' |
| 47 | 50 | ||
| 48 | class ViewTests(TestCase): | 51 | class ViewTests(TestCase): |
| @@ -54,14 +57,46 @@ class ViewTests(TestCase): | |||
| 54 | release = Release.objects.create(name="test release", | 57 | release = Release.objects.create(name="test release", |
| 55 | branch_name="master", | 58 | branch_name="master", |
| 56 | bitbake_version=bbv) | 59 | bitbake_version=bbv) |
| 60 | release2 = Release.objects.create(name="test release 2", | ||
| 61 | branch_name="master", | ||
| 62 | bitbake_version=bbv) | ||
| 63 | |||
| 57 | self.project = Project.objects.create_project(name=PROJECT_NAME, | 64 | self.project = Project.objects.create_project(name=PROJECT_NAME, |
| 58 | release=release) | 65 | release=release) |
| 66 | |||
| 67 | self.project2 = Project.objects.create_project(name=PROJECT_NAME2, | ||
| 68 | release=release2) | ||
| 69 | |||
| 59 | now = timezone.now() | 70 | now = timezone.now() |
| 71 | later = now + timedelta(days=1) | ||
| 60 | 72 | ||
| 61 | build = Build.objects.create(project=self.project, | 73 | build = Build.objects.create(project=self.project, |
| 62 | started_on=now, | 74 | started_on=now, |
| 63 | completed_on=now) | 75 | completed_on=now) |
| 64 | 76 | ||
| 77 | # for testing BuildsTable | ||
| 78 | build1 = Build.objects.create(project=self.project, | ||
| 79 | started_on=now, | ||
| 80 | completed_on=now, | ||
| 81 | outcome=Build.SUCCEEDED, | ||
| 82 | machine="raspberrypi2") | ||
| 83 | |||
| 84 | Build.objects.create(project=self.project, | ||
| 85 | started_on=later, | ||
| 86 | completed_on=later, | ||
| 87 | outcome=Build.FAILED, | ||
| 88 | machine="qemux86") | ||
| 89 | |||
| 90 | Build.objects.create(project=self.project2, | ||
| 91 | started_on=later, | ||
| 92 | completed_on=later, | ||
| 93 | outcome=Build.SUCCEEDED, | ||
| 94 | machine="qemux86") | ||
| 95 | |||
| 96 | # to test sorting by errors and warnings in BuildsTable | ||
| 97 | LogMessage.objects.create(build=build1, level=LogMessage.WARNING) | ||
| 98 | LogMessage.objects.create(build=build1, level=LogMessage.ERROR) | ||
| 99 | |||
| 65 | layersrc = LayerSource.objects.create(sourcetype=LayerSource.TYPE_IMPORTED) | 100 | layersrc = LayerSource.objects.create(sourcetype=LayerSource.TYPE_IMPORTED) |
| 66 | self.priority = ReleaseLayerSourcePriority.objects.create(release=release, | 101 | self.priority = ReleaseLayerSourcePriority.objects.create(release=release, |
| 67 | layer_source=layersrc) | 102 | layer_source=layersrc) |
| @@ -172,8 +207,7 @@ class ViewTests(TestCase): | |||
| 172 | response = self.client.get(reverse('all-projects'), follow=True) | 207 | response = self.client.get(reverse('all-projects'), follow=True) |
| 173 | self.assertEqual(response.status_code, 200) | 208 | self.assertEqual(response.status_code, 200) |
| 174 | self.assertTrue(response['Content-Type'].startswith('text/html')) | 209 | self.assertTrue(response['Content-Type'].startswith('text/html')) |
| 175 | self.assertTemplateUsed(response, "projects.html") | 210 | self.assertTemplateUsed(response, "projects-toastertable.html") |
| 176 | self.assertTrue(PROJECT_NAME in response.content) | ||
| 177 | 211 | ||
| 178 | def test_get_json_call_returns_json(self): | 212 | def test_get_json_call_returns_json(self): |
| 179 | """Test for all projects output in json format""" | 213 | """Test for all projects output in json format""" |
| @@ -191,13 +225,6 @@ class ViewTests(TestCase): | |||
| 191 | self.assertTrue(PROJECT_NAME in [x["name"] for x in data["rows"]]) | 225 | self.assertTrue(PROJECT_NAME in [x["name"] for x in data["rows"]]) |
| 192 | self.assertTrue("id" in data["rows"][0]) | 226 | self.assertTrue("id" in data["rows"][0]) |
| 193 | 227 | ||
| 194 | self.assertEqual(sorted(data["rows"][0]), | ||
| 195 | ['bitbake_version_id', 'created', 'id', | ||
| 196 | 'is_default', 'layersTypeAheadUrl', 'name', | ||
| 197 | 'num_builds', 'projectBuildsUrl', 'projectPageUrl', | ||
| 198 | 'recipesTypeAheadUrl', 'release_id', | ||
| 199 | 'short_description', 'updated', 'user_id']) | ||
| 200 | |||
| 201 | def test_typeaheads(self): | 228 | def test_typeaheads(self): |
| 202 | """Test typeahead ReST API""" | 229 | """Test typeahead ReST API""" |
| 203 | layers_url = reverse('xhr_layerstypeahead', args=(self.project.id,)) | 230 | layers_url = reverse('xhr_layerstypeahead', args=(self.project.id,)) |
| @@ -450,7 +477,7 @@ class ViewTests(TestCase): | |||
| 450 | all_data = get_data(table) | 477 | all_data = get_data(table) |
| 451 | 478 | ||
| 452 | self.assertTrue(len(all_data['rows']) > 1, | 479 | self.assertTrue(len(all_data['rows']) > 1, |
| 453 | "Cannot test on a table with < 1 row") | 480 | "Cannot test on the table %s with < 1 row" % name) |
| 454 | 481 | ||
| 455 | if table.default_orderby: | 482 | if table.default_orderby: |
| 456 | row_one = all_data['rows'][0][table.default_orderby.strip("-")] | 483 | row_one = all_data['rows'][0][table.default_orderby.strip("-")] |
| @@ -512,16 +539,20 @@ class ViewTests(TestCase): | |||
| 512 | # This is the name of the filter:action | 539 | # This is the name of the filter:action |
| 513 | # e.g. project_filter:not_in_project | 540 | # e.g. project_filter:not_in_project |
| 514 | filter_string = "%s:%s" % (column['filter_name'], | 541 | filter_string = "%s:%s" % (column['filter_name'], |
| 515 | filter_action['name']) | 542 | filter_action['action_name']) |
| 516 | # Now get the data with the filter applied | 543 | # Now get the data with the filter applied |
| 517 | filtered_data = get_data(table_cls(), | 544 | filtered_data = get_data(table_cls(), |
| 518 | {"filter" : filter_string}) | 545 | {"filter" : filter_string}) |
| 519 | self.assertEqual(len(filtered_data['rows']), | 546 | |
| 520 | int(filter_action['count']), | 547 | # date range filter actions can't specify the |
| 521 | "We added a table filter for %s but " | 548 | # number of results they return, so their count is 0 |
| 522 | "the number of rows returned was not " | 549 | if filter_action['count'] != None: |
| 523 | "what the filter info said there " | 550 | self.assertEqual(len(filtered_data['rows']), |
| 524 | "would be" % name) | 551 | int(filter_action['count']), |
| 552 | "We added a table filter for %s but " | ||
| 553 | "the number of rows returned was not " | ||
| 554 | "what the filter info said there " | ||
| 555 | "would be" % name) | ||
| 525 | 556 | ||
| 526 | 557 | ||
| 527 | # Test search functionality on the table | 558 | # Test search functionality on the table |
| @@ -673,6 +704,10 @@ class AllProjectsPageTests(TestCase): | |||
| 673 | value=self.MACHINE_NAME) | 704 | value=self.MACHINE_NAME) |
| 674 | project_var.save() | 705 | project_var.save() |
| 675 | 706 | ||
| 707 | def _get_row_for_project(self, data, project_id): | ||
| 708 | """ Get the object representing the table data for a project """ | ||
| 709 | return [row for row in data['rows'] if row['id'] == project_id][0] | ||
| 710 | |||
| 676 | def test_default_project_hidden(self): | 711 | def test_default_project_hidden(self): |
| 677 | """ The default project should be hidden if it has no builds """ | 712 | """ The default project should be hidden if it has no builds """ |
| 678 | params = {"count": 10, "orderby": "updated:-", "page": 1} | 713 | params = {"count": 10, "orderby": "updated:-", "page": 1} |
| @@ -688,11 +723,20 @@ class AllProjectsPageTests(TestCase): | |||
| 688 | self._add_build_to_default_project() | 723 | self._add_build_to_default_project() |
| 689 | 724 | ||
| 690 | params = {"count": 10, "orderby": "updated:-", "page": 1} | 725 | params = {"count": 10, "orderby": "updated:-", "page": 1} |
| 691 | response = self.client.get(reverse('all-projects'), params) | ||
| 692 | 726 | ||
| 693 | self.assertTrue('tr class="data"' in response.content, | 727 | response = self.client.get( |
| 694 | 'should be a project row in the page') | 728 | reverse('all-projects'), |
| 695 | self.assertTrue(CLI_BUILDS_PROJECT_NAME in response.content, | 729 | {'format': 'json'}, |
| 730 | params | ||
| 731 | ) | ||
| 732 | |||
| 733 | data = json.loads(response.content) | ||
| 734 | |||
| 735 | # find the row for the default project | ||
| 736 | default_project_row = self._get_row_for_project(data, self.default_project.id) | ||
| 737 | |||
| 738 | # check its name template has the correct text | ||
| 739 | self.assertEqual(default_project_row['name'], CLI_BUILDS_PROJECT_NAME, | ||
| 696 | 'default project "cli builds" should be in page') | 740 | 'default project "cli builds" should be in page') |
| 697 | 741 | ||
| 698 | def test_default_project_release(self): | 742 | def test_default_project_release(self): |
| @@ -706,24 +750,32 @@ class AllProjectsPageTests(TestCase): | |||
| 706 | # another project to test, which should show release | 750 | # another project to test, which should show release |
| 707 | self._add_non_default_project() | 751 | self._add_non_default_project() |
| 708 | 752 | ||
| 709 | response = self.client.get(reverse('all-projects'), follow=True) | 753 | response = self.client.get( |
| 710 | soup = BeautifulSoup(response.content) | 754 | reverse('all-projects'), |
| 755 | {'format': 'json'}, | ||
| 756 | follow=True | ||
| 757 | ) | ||
| 711 | 758 | ||
| 712 | # check the release cell for the default project | 759 | data = json.loads(response.content) |
| 713 | attrs = {'data-project': str(self.default_project.id)} | 760 | |
| 714 | rows = soup.find_all('tr', attrs=attrs) | 761 | # used to find the correct span in the template output |
| 715 | self.assertEqual(len(rows), 1, 'should be one row for default project') | 762 | attrs = {'data-project-field': 'release'} |
| 716 | cells = rows[0].find_all('td', attrs={'data-project-field': 'release'}) | 763 | |
| 717 | self.assertEqual(len(cells), 1, 'should be one release cell') | 764 | # find the row for the default project |
| 718 | text = cells[0].select('span.muted')[0].text | 765 | default_project_row = self._get_row_for_project(data, self.default_project.id) |
| 766 | |||
| 767 | # check the release text for the default project | ||
| 768 | soup = BeautifulSoup(default_project_row['static:release']) | ||
| 769 | text = soup.find('span', attrs=attrs).select('span.muted')[0].text | ||
| 719 | self.assertEqual(text, 'Not applicable', | 770 | self.assertEqual(text, 'Not applicable', |
| 720 | 'release should be not applicable for default project') | 771 | 'release should be not applicable for default project') |
| 721 | 772 | ||
| 773 | # find the row for the default project | ||
| 774 | other_project_row = self._get_row_for_project(data, self.project.id) | ||
| 775 | |||
| 722 | # check the link in the release cell for the other project | 776 | # check the link in the release cell for the other project |
| 723 | attrs = {'data-project': str(self.project.id)} | 777 | soup = BeautifulSoup(other_project_row['static:release']) |
| 724 | rows = soup.find_all('tr', attrs=attrs) | 778 | text = soup.find('span', attrs=attrs).select('a')[0].text.strip() |
| 725 | cells = rows[0].find_all('td', attrs={'data-project-field': 'release'}) | ||
| 726 | text = cells[0].select('a')[0].text | ||
| 727 | self.assertEqual(text, self.release.name, | 779 | self.assertEqual(text, self.release.name, |
| 728 | 'release name should be shown for non-default project') | 780 | 'release name should be shown for non-default project') |
| 729 | 781 | ||
| @@ -738,24 +790,32 @@ class AllProjectsPageTests(TestCase): | |||
| 738 | # another project to test, which should show machine | 790 | # another project to test, which should show machine |
| 739 | self._add_non_default_project() | 791 | self._add_non_default_project() |
| 740 | 792 | ||
| 741 | response = self.client.get(reverse('all-projects'), follow=True) | 793 | response = self.client.get( |
| 742 | soup = BeautifulSoup(response.content) | 794 | reverse('all-projects'), |
| 795 | {'format': 'json'}, | ||
| 796 | follow=True | ||
| 797 | ) | ||
| 798 | |||
| 799 | data = json.loads(response.content) | ||
| 800 | |||
| 801 | # used to find the correct span in the template output | ||
| 802 | attrs = {'data-project-field': 'machine'} | ||
| 803 | |||
| 804 | # find the row for the default project | ||
| 805 | default_project_row = self._get_row_for_project(data, self.default_project.id) | ||
| 743 | 806 | ||
| 744 | # check the machine cell for the default project | 807 | # check the machine cell for the default project |
| 745 | attrs = {'data-project': str(self.default_project.id)} | 808 | soup = BeautifulSoup(default_project_row['static:machine']) |
| 746 | rows = soup.find_all('tr', attrs=attrs) | 809 | text = soup.find('span', attrs=attrs).select('span.muted')[0].text.strip() |
| 747 | self.assertEqual(len(rows), 1, 'should be one row for default project') | ||
| 748 | cells = rows[0].find_all('td', attrs={'data-project-field': 'machine'}) | ||
| 749 | self.assertEqual(len(cells), 1, 'should be one machine cell') | ||
| 750 | text = cells[0].select('span.muted')[0].text | ||
| 751 | self.assertEqual(text, 'Not applicable', | 810 | self.assertEqual(text, 'Not applicable', |
| 752 | 'machine should be not applicable for default project') | 811 | 'machine should be not applicable for default project') |
| 812 | |||
| 813 | # find the row for the default project | ||
| 814 | other_project_row = self._get_row_for_project(data, self.project.id) | ||
| 753 | 815 | ||
| 754 | # check the link in the machine cell for the other project | 816 | # check the link in the machine cell for the other project |
| 755 | attrs = {'data-project': str(self.project.id)} | 817 | soup = BeautifulSoup(other_project_row['static:machine']) |
| 756 | rows = soup.find_all('tr', attrs=attrs) | 818 | text = soup.find('span', attrs=attrs).find('a').text.strip() |
| 757 | cells = rows[0].find_all('td', attrs={'data-project-field': 'machine'}) | ||
| 758 | text = cells[0].select('a')[0].text | ||
| 759 | self.assertEqual(text, self.MACHINE_NAME, | 819 | self.assertEqual(text, self.MACHINE_NAME, |
| 760 | 'machine name should be shown for non-default project') | 820 | 'machine name should be shown for non-default project') |
| 761 | 821 | ||
| @@ -769,24 +829,33 @@ class AllProjectsPageTests(TestCase): | |||
| 769 | # need a build, otherwise project doesn't display at all | 829 | # need a build, otherwise project doesn't display at all |
| 770 | self._add_build_to_default_project() | 830 | self._add_build_to_default_project() |
| 771 | 831 | ||
| 772 | # another project to test, which should show machine | 832 | # another project to test |
| 773 | self._add_non_default_project() | 833 | self._add_non_default_project() |
| 774 | 834 | ||
| 775 | response = self.client.get(reverse('all-projects'), follow=True) | 835 | response = self.client.get( |
| 776 | soup = BeautifulSoup(response.content) | 836 | reverse('all-projects'), |
| 837 | {'format': 'json'}, | ||
| 838 | follow=True | ||
| 839 | ) | ||
| 840 | |||
| 841 | data = json.loads(response.content) | ||
| 777 | 842 | ||
| 778 | # link for default project | 843 | # find the row for the default project |
| 779 | row = soup.find('tr', attrs={'data-project': self.default_project.id}) | 844 | default_project_row = self._get_row_for_project(data, self.default_project.id) |
| 780 | cell = row.find('td', attrs={'data-project-field': 'name'}) | 845 | |
| 846 | # check the link on the name field | ||
| 847 | soup = BeautifulSoup(default_project_row['static:name']) | ||
| 781 | expected_url = reverse('projectbuilds', args=(self.default_project.id,)) | 848 | expected_url = reverse('projectbuilds', args=(self.default_project.id,)) |
| 782 | self.assertEqual(cell.find('a')['href'], expected_url, | 849 | self.assertEqual(soup.find('a')['href'], expected_url, |
| 783 | 'link on default project name should point to builds') | 850 | 'link on default project name should point to builds') |
| 784 | 851 | ||
| 785 | # link for other project | 852 | # find the row for the other project |
| 786 | row = soup.find('tr', attrs={'data-project': self.project.id}) | 853 | other_project_row = self._get_row_for_project(data, self.project.id) |
| 787 | cell = row.find('td', attrs={'data-project-field': 'name'}) | 854 | |
| 855 | # check the link for the other project | ||
| 856 | soup = BeautifulSoup(other_project_row['static:name']) | ||
| 788 | expected_url = reverse('project', args=(self.project.id,)) | 857 | expected_url = reverse('project', args=(self.project.id,)) |
| 789 | self.assertEqual(cell.find('a')['href'], expected_url, | 858 | self.assertEqual(soup.find('a')['href'], expected_url, |
| 790 | 'link on project name should point to configuration') | 859 | 'link on project name should point to configuration') |
| 791 | 860 | ||
| 792 | class ProjectBuildsPageTests(TestCase): | 861 | class ProjectBuildsPageTests(TestCase): |
| @@ -846,9 +915,9 @@ class ProjectBuildsPageTests(TestCase): | |||
| 846 | def _get_rows_for_project(self, project_id): | 915 | def _get_rows_for_project(self, project_id): |
| 847 | """ Helper to retrieve HTML rows for a project """ | 916 | """ Helper to retrieve HTML rows for a project """ |
| 848 | url = reverse("projectbuilds", args=(project_id,)) | 917 | url = reverse("projectbuilds", args=(project_id,)) |
| 849 | response = self.client.get(url, follow=True) | 918 | response = self.client.get(url, {'format': 'json'}, follow=True) |
| 850 | soup = BeautifulSoup(response.content) | 919 | data = json.loads(response.content) |
| 851 | return soup.select('tr[class="data"]') | 920 | return data['rows'] |
| 852 | 921 | ||
| 853 | def test_show_builds_for_project(self): | 922 | def test_show_builds_for_project(self): |
| 854 | """ Builds for a project should be displayed """ | 923 | """ Builds for a project should be displayed """ |
| @@ -889,10 +958,14 @@ class ProjectBuildsPageTests(TestCase): | |||
| 889 | """ Task should be shown as suffix on build name """ | 958 | """ Task should be shown as suffix on build name """ |
| 890 | build = Build.objects.create(**self.project1_build_success) | 959 | build = Build.objects.create(**self.project1_build_success) |
| 891 | Target.objects.create(build=build, target='bash', task='clean') | 960 | Target.objects.create(build=build, target='bash', task='clean') |
| 892 | url = reverse("projectbuilds", args=(self.project1.id,)) | 961 | |
| 893 | response = self.client.get(url, follow=True) | 962 | url = reverse('projectbuilds', args=(self.project1.id,)) |
| 894 | result = re.findall('^ +bash:clean$', response.content, re.MULTILINE) | 963 | response = self.client.get(url, {'format': 'json'}, follow=True) |
| 895 | self.assertEqual(len(result), 2) | 964 | data = json.loads(response.content) |
| 965 | cell = data['rows'][0]['static:target'] | ||
| 966 | |||
| 967 | result = re.findall('^ +bash:clean', cell, re.MULTILINE) | ||
| 968 | self.assertEqual(len(result), 1) | ||
| 896 | 969 | ||
| 897 | def test_cli_builds_hides_tabs(self): | 970 | def test_cli_builds_hides_tabs(self): |
| 898 | """ | 971 | """ |
| @@ -952,32 +1025,46 @@ class AllBuildsPageTests(TestCase): | |||
| 952 | "outcome": Build.SUCCEEDED | 1025 | "outcome": Build.SUCCEEDED |
| 953 | } | 1026 | } |
| 954 | 1027 | ||
| 1028 | def _get_row_for_build(self, data, build_id): | ||
| 1029 | """ Get the object representing the table data for a project """ | ||
| 1030 | return [row for row in data['rows'] | ||
| 1031 | if row['id'] == build_id][0] | ||
| 1032 | |||
| 955 | def test_show_tasks_in_allbuilds(self): | 1033 | def test_show_tasks_in_allbuilds(self): |
| 956 | """ Task should be shown as suffix on build name """ | 1034 | """ Task should be shown as suffix on build name """ |
| 957 | build = Build.objects.create(**self.project1_build_success) | 1035 | build = Build.objects.create(**self.project1_build_success) |
| 958 | Target.objects.create(build=build, target='bash', task='clean') | 1036 | Target.objects.create(build=build, target='bash', task='clean') |
| 1037 | |||
| 959 | url = reverse('all-builds') | 1038 | url = reverse('all-builds') |
| 960 | response = self.client.get(url, follow=True) | 1039 | response = self.client.get(url, {'format': 'json'}, follow=True) |
| 961 | result = re.findall('bash:clean', response.content, re.MULTILINE) | 1040 | data = json.loads(response.content) |
| 962 | self.assertEqual(len(result), 3) | 1041 | cell = data['rows'][0]['static:target'] |
| 963 | 1042 | ||
| 964 | def test_no_run_again_for_cli_build(self): | 1043 | result = re.findall('bash:clean', cell, re.MULTILINE) |
| 965 | """ "Run again" button should not be shown for command-line builds """ | 1044 | self.assertEqual(len(result), 1) |
| 966 | build = Build.objects.create(**self.default_project_build_success) | 1045 | |
| 1046 | def test_run_again(self): | ||
| 1047 | """ | ||
| 1048 | "Run again" button should not be shown for command-line builds, | ||
| 1049 | but should be shown for other builds | ||
| 1050 | """ | ||
| 1051 | build1 = Build.objects.create(**self.project1_build_success) | ||
| 1052 | default_build = Build.objects.create(**self.default_project_build_success) | ||
| 967 | url = reverse('all-builds') | 1053 | url = reverse('all-builds') |
| 968 | response = self.client.get(url, follow=True) | 1054 | response = self.client.get(url, follow=True) |
| 969 | soup = BeautifulSoup(response.content) | 1055 | soup = BeautifulSoup(response.content) |
| 970 | 1056 | ||
| 971 | attrs = {'data-latest-build-result': build.id} | ||
| 972 | result = soup.find('div', attrs=attrs) | ||
| 973 | |||
| 974 | # shouldn't see a run again button for command-line builds | 1057 | # shouldn't see a run again button for command-line builds |
| 1058 | attrs = {'data-latest-build-result': default_build.id} | ||
| 1059 | result = soup.find('div', attrs=attrs) | ||
| 975 | run_again_button = result.select('button') | 1060 | run_again_button = result.select('button') |
| 976 | self.assertEqual(len(run_again_button), 0) | 1061 | self.assertEqual(len(run_again_button), 0) |
| 977 | 1062 | ||
| 978 | # should see a help icon for command-line builds | 1063 | # should see a run again button for non-command-line builds |
| 979 | help_icon = result.select('i.get-help-green') | 1064 | attrs = {'data-latest-build-result': build1.id} |
| 980 | self.assertEqual(len(help_icon), 1) | 1065 | result = soup.find('div', attrs=attrs) |
| 1066 | run_again_button = result.select('button') | ||
| 1067 | self.assertEqual(len(run_again_button), 1) | ||
| 981 | 1068 | ||
| 982 | def test_tooltips_on_project_name(self): | 1069 | def test_tooltips_on_project_name(self): |
| 983 | """ | 1070 | """ |
| @@ -989,20 +1076,28 @@ class AllBuildsPageTests(TestCase): | |||
| 989 | default_build = Build.objects.create(**self.default_project_build_success) | 1076 | default_build = Build.objects.create(**self.default_project_build_success) |
| 990 | 1077 | ||
| 991 | url = reverse('all-builds') | 1078 | url = reverse('all-builds') |
| 992 | response = self.client.get(url, follow=True) | 1079 | response = self.client.get(url, {'format': 'json'}, follow=True) |
| 993 | soup = BeautifulSoup(response.content) | 1080 | data = json.loads(response.content) |
| 1081 | |||
| 1082 | # get the data row for the non-command-line builds project | ||
| 1083 | other_project_row = self._get_row_for_build(data, build1.id) | ||
| 1084 | |||
| 1085 | # make sure there is some HTML | ||
| 1086 | soup = BeautifulSoup(other_project_row['static:project']) | ||
| 1087 | self.assertEqual(len(soup.select('a')), 1, | ||
| 1088 | 'should be a project name link') | ||
| 994 | 1089 | ||
| 995 | # no help icon on non-default project name | 1090 | # no help icon on non-default project name |
| 996 | result = soup.find('tr', attrs={'data-table-build-result': build1.id}) | 1091 | icons = soup.select('i.get-help') |
| 997 | name = result.select('td.project-name')[0] | ||
| 998 | icons = name.select('i.get-help') | ||
| 999 | self.assertEqual(len(icons), 0, | 1092 | self.assertEqual(len(icons), 0, |
| 1000 | 'should not be a help icon for non-cli builds name') | 1093 | 'should not be a help icon for non-cli builds name') |
| 1001 | 1094 | ||
| 1095 | # get the data row for the command-line builds project | ||
| 1096 | default_project_row = self._get_row_for_build(data, default_build.id) | ||
| 1097 | |||
| 1002 | # help icon on default project name | 1098 | # help icon on default project name |
| 1003 | result = soup.find('tr', attrs={'data-table-build-result': default_build.id}) | 1099 | soup = BeautifulSoup(default_project_row['static:project']) |
| 1004 | name = result.select('td.project-name')[0] | 1100 | icons = soup.select('i.get-help') |
| 1005 | icons = name.select('i.get-help') | ||
| 1006 | self.assertEqual(len(icons), 1, | 1101 | self.assertEqual(len(icons), 1, |
| 1007 | 'should be a help icon for cli builds name') | 1102 | 'should be a help icon for cli builds name') |
| 1008 | 1103 | ||
