diff options
| author | Michael Wood <michael.g.wood@intel.com> | 2016-07-06 18:22:39 +0100 |
|---|---|---|
| committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2016-07-08 09:57:29 +0100 |
| commit | 8dc159dd9372100a96bcbc9e7670894417897f92 (patch) | |
| tree | 6afc33bfb8166080249c8757111c7c63e64c6f2b /bitbake/lib/toaster/tests/browser | |
| parent | 8813726f1d5ea1d78fced7fe52abdf826e529e62 (diff) | |
| download | poky-8dc159dd9372100a96bcbc9e7670894417897f92.tar.gz | |
bitbake: toaster: tests Add selenium test for layerdetails page
This tests:
- Adding remove layer from project
- Deleting layer
- Editing layer fields
(Bitbake rev: cabe7e2459fcd561bced2d39ba5bd173576153e5)
Signed-off-by: Michael Wood <michael.g.wood@intel.com>
Signed-off-by: Elliot Smith <elliot.smith@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/toaster/tests/browser')
| -rw-r--r-- | bitbake/lib/toaster/tests/browser/test_layerdetails_page.py | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py b/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py new file mode 100644 index 0000000000..fb1007f289 --- /dev/null +++ b/bitbake/lib/toaster/tests/browser/test_layerdetails_page.py | |||
| @@ -0,0 +1,190 @@ | |||
| 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 | |||
| 22 | from django.core.urlresolvers import reverse | ||
| 23 | from tests.browser.selenium_helpers import SeleniumTestCase | ||
| 24 | |||
| 25 | from orm.models import Layer, Layer_Version, Project, LayerSource, Release | ||
| 26 | from orm.models import BitbakeVersion | ||
| 27 | |||
| 28 | from selenium.webdriver.support import expected_conditions as EC | ||
| 29 | from selenium.webdriver.support.ui import WebDriverWait | ||
| 30 | from selenium.webdriver.common.by import By | ||
| 31 | |||
| 32 | |||
| 33 | class TestLayerDetailsPage(SeleniumTestCase): | ||
| 34 | """ Test layerdetails page works correctly """ | ||
| 35 | |||
| 36 | def __init__(self, *args, **kwargs): | ||
| 37 | super(TestLayerDetailsPage, self).__init__(*args, **kwargs) | ||
| 38 | |||
| 39 | self.initial_values = None | ||
| 40 | self.url = None | ||
| 41 | self.imported_layer_version = None | ||
| 42 | |||
| 43 | def setUp(self): | ||
| 44 | release = Release.objects.create( | ||
| 45 | name='baz', | ||
| 46 | bitbake_version=BitbakeVersion.objects.create(name='v1') | ||
| 47 | ) | ||
| 48 | |||
| 49 | # project to add new custom images to | ||
| 50 | self.project = Project.objects.create(name='foo', release=release) | ||
| 51 | |||
| 52 | layer_source = LayerSource.objects.create( | ||
| 53 | sourcetype=LayerSource.TYPE_IMPORTED) | ||
| 54 | |||
| 55 | name = "meta-imported" | ||
| 56 | vcs_url = "git://example.com/meta-imported" | ||
| 57 | subdir = "/layer" | ||
| 58 | gitrev = "d33d" | ||
| 59 | summary = "A imported layer" | ||
| 60 | description = "This was imported" | ||
| 61 | |||
| 62 | imported_layer = Layer.objects.create(name=name, | ||
| 63 | vcs_url=vcs_url, | ||
| 64 | summary=summary, | ||
| 65 | description=description) | ||
| 66 | |||
| 67 | self.imported_layer_version = Layer_Version.objects.create( | ||
| 68 | layer=imported_layer, | ||
| 69 | layer_source=layer_source, | ||
| 70 | branch=gitrev, | ||
| 71 | commit=gitrev, | ||
| 72 | dirpath=subdir, | ||
| 73 | project=self.project) | ||
| 74 | |||
| 75 | self.initial_values = [name, vcs_url, subdir, gitrev, summary, | ||
| 76 | description] | ||
| 77 | self.url = reverse('layerdetails', | ||
| 78 | args=(self.project.pk, | ||
| 79 | self.imported_layer_version.pk)) | ||
| 80 | |||
| 81 | def test_edit_layerdetails(self): | ||
| 82 | """ Edit all the editable fields for the layer refresh the page and | ||
| 83 | check that the new values exist""" | ||
| 84 | |||
| 85 | self.get(self.url) | ||
| 86 | |||
| 87 | self.click("#add-remove-layer-btn") | ||
| 88 | |||
| 89 | # Open every edit box | ||
| 90 | for btn in self.find_all("dd .glyphicon-edit"): | ||
| 91 | btn.click() | ||
| 92 | |||
| 93 | self.wait_until_visible("dd input") | ||
| 94 | |||
| 95 | # Edit each value | ||
| 96 | for inputs in self.find_all("dd input[type=text]") + \ | ||
| 97 | self.find_all("dd textarea"): | ||
| 98 | # ignore the tt inputs (twitter typeahead input) | ||
| 99 | if "tt-" in inputs.get_attribute("class"): | ||
| 100 | continue | ||
| 101 | |||
| 102 | value = inputs.get_attribute("value") | ||
| 103 | |||
| 104 | self.assertTrue(value in self.initial_values, | ||
| 105 | "Expecting any of \"%s\"but got \"%s\"" % | ||
| 106 | (self.initial_values, value)) | ||
| 107 | |||
| 108 | inputs.send_keys("-edited") | ||
| 109 | |||
| 110 | for save_btn in self.find_all(".change-btn"): | ||
| 111 | save_btn.click() | ||
| 112 | |||
| 113 | # Refresh the page to see if the new values are returned | ||
| 114 | self.get(self.url) | ||
| 115 | |||
| 116 | new_values = ["%s-edited" % old_val | ||
| 117 | for old_val in self.initial_values] | ||
| 118 | |||
| 119 | for inputs in self.find_all("dd input[type=text]") + \ | ||
| 120 | self.find_all("dd textarea"): | ||
| 121 | # ignore the tt inputs (twitter typeahead input) | ||
| 122 | if "tt-" in inputs.get_attribute("class"): | ||
| 123 | continue | ||
| 124 | |||
| 125 | value = inputs.get_attribute("value") | ||
| 126 | |||
| 127 | self.assertTrue(value in new_values, | ||
| 128 | "Expecting any of \"%s\"but got \"%s\"" % | ||
| 129 | (self.initial_values, value)) | ||
| 130 | |||
| 131 | def test_delete_layer(self): | ||
| 132 | """ Delete the layer """ | ||
| 133 | |||
| 134 | self.get(self.url) | ||
| 135 | |||
| 136 | # Wait for the tables to load to avoid a race condition where the | ||
| 137 | # toaster tables have made an async request. If the layer is deleted | ||
| 138 | # before the request finishes it will cause an exception and fail this | ||
| 139 | # test. | ||
| 140 | wait = WebDriverWait(self.driver, 30) | ||
| 141 | |||
| 142 | wait.until(EC.text_to_be_present_in_element( | ||
| 143 | (By.CLASS_NAME, | ||
| 144 | "table-count-recipestable"), "0")) | ||
| 145 | |||
| 146 | wait.until(EC.text_to_be_present_in_element( | ||
| 147 | (By.CLASS_NAME, | ||
| 148 | "table-count-machinestable"), "0")) | ||
| 149 | |||
| 150 | self.click('a[data-target="#delete-layer-modal"]') | ||
| 151 | self.wait_until_visible("#delete-layer-modal") | ||
| 152 | self.click("#layer-delete-confirmed") | ||
| 153 | |||
| 154 | notification = self.wait_until_visible("#change-notification-msg") | ||
| 155 | expected_text = "You have deleted 1 layer from your project: %s" % \ | ||
| 156 | self.imported_layer_version.layer.name | ||
| 157 | |||
| 158 | self.assertTrue(expected_text in notification.text, | ||
| 159 | "Expected notification text \"%s\" not found instead" | ||
| 160 | "it was \"%s\"" % | ||
| 161 | (expected_text, notification.text)) | ||
| 162 | |||
| 163 | def test_addrm_to_project(self): | ||
| 164 | self.get(self.url) | ||
| 165 | |||
| 166 | # Add the layer | ||
| 167 | self.click("#add-remove-layer-btn") | ||
| 168 | |||
| 169 | notification = self.wait_until_visible("#change-notification-msg") | ||
| 170 | |||
| 171 | expected_text = "You have added 1 layer to your project: %s" % \ | ||
| 172 | self.imported_layer_version.layer.name | ||
| 173 | |||
| 174 | self.assertTrue(expected_text in notification.text, | ||
| 175 | "Expected notification text %s not found was " | ||
| 176 | " \"%s\" instead" % | ||
| 177 | (expected_text, notification.text)) | ||
| 178 | |||
| 179 | # Remove the layer | ||
| 180 | self.click("#add-remove-layer-btn") | ||
| 181 | |||
| 182 | notification = self.wait_until_visible("#change-notification-msg") | ||
| 183 | |||
| 184 | expected_text = "You have removed 1 layer from your project: %s" % \ | ||
| 185 | self.imported_layer_version.layer.name | ||
| 186 | |||
| 187 | self.assertTrue(expected_text in notification.text, | ||
| 188 | "Expected notification text %s not found was " | ||
| 189 | " \"%s\" instead" % | ||
| 190 | (expected_text, notification.text)) | ||
