1#! /usr/bin/env python3 2# 3# BitBake Toaster Implementation 4# 5# SPDX-License-Identifier: GPL-2.0-only 6# 7# Copyright (C) 2013-2016 Intel Corporation 8# 9 10from django.urls import reverse 11from tests.browser.selenium_helpers import SeleniumTestCase 12 13from orm.models import Layer, Layer_Version, Project, LayerSource, Release 14from orm.models import BitbakeVersion 15 16from selenium.webdriver.support import expected_conditions as EC 17from selenium.webdriver.support.ui import WebDriverWait 18from selenium.webdriver.common.by import By 19 20 21class TestLayerDetailsPage(SeleniumTestCase): 22 """ Test layerdetails page works correctly """ 23 24 def __init__(self, *args, **kwargs): 25 super(TestLayerDetailsPage, self).__init__(*args, **kwargs) 26 27 self.initial_values = None 28 self.url = None 29 self.imported_layer_version = None 30 31 def setUp(self): 32 release = Release.objects.create( 33 name='baz', 34 bitbake_version=BitbakeVersion.objects.create(name='v1') 35 ) 36 37 # project to add new custom images to 38 self.project = Project.objects.create(name='foo', release=release) 39 40 name = "meta-imported" 41 vcs_url = "git://example.com/meta-imported" 42 subdir = "/layer" 43 gitrev = "d33d" 44 summary = "A imported layer" 45 description = "This was imported" 46 47 imported_layer = Layer.objects.create(name=name, 48 vcs_url=vcs_url, 49 summary=summary, 50 description=description) 51 52 self.imported_layer_version = Layer_Version.objects.create( 53 layer=imported_layer, 54 layer_source=LayerSource.TYPE_IMPORTED, 55 branch=gitrev, 56 commit=gitrev, 57 dirpath=subdir, 58 project=self.project) 59 60 self.initial_values = [name, vcs_url, subdir, gitrev, summary, 61 description] 62 self.url = reverse('layerdetails', 63 args=(self.project.pk, 64 self.imported_layer_version.pk)) 65 66 def test_edit_layerdetails(self): 67 """ Edit all the editable fields for the layer refresh the page and 68 check that the new values exist""" 69 70 self.get(self.url) 71 72 self.click("#add-remove-layer-btn") 73 self.click("#edit-layer-source") 74 self.click("#repo") 75 76 self.wait_until_visible("#layer-git-repo-url") 77 78 # Open every edit box 79 for btn in self.find_all("dd .glyphicon-edit"): 80 btn.click() 81 82 # Wait for the inputs to become visible after animation 83 self.wait_until_visible("#layer-git input[type=text]") 84 self.wait_until_visible("dd textarea") 85 self.wait_until_visible("dd .change-btn") 86 87 # Edit each value 88 for inputs in self.find_all("#layer-git input[type=text]") + \ 89 self.find_all("dd textarea"): 90 # ignore the tt inputs (twitter typeahead input) 91 if "tt-" in inputs.get_attribute("class"): 92 continue 93 94 value = inputs.get_attribute("value") 95 96 self.assertTrue(value in self.initial_values, 97 "Expecting any of \"%s\"but got \"%s\"" % 98 (self.initial_values, value)) 99 100 # Make sure the input visible beofre sending keys 101 self.wait_until_visible("#layer-git input[type=text]") 102 inputs.send_keys("-edited") 103 104 # Save the new values 105 for save_btn in self.find_all(".change-btn"): 106 save_btn.click() 107 108 self.click("#save-changes-for-switch") 109 self.wait_until_visible("#edit-layer-source") 110 111 # Refresh the page to see if the new values are returned 112 self.get(self.url) 113 114 new_values = ["%s-edited" % old_val 115 for old_val in self.initial_values] 116 117 for inputs in self.find_all('#layer-git input[type="text"]') + \ 118 self.find_all('dd textarea'): 119 # ignore the tt inputs (twitter typeahead input) 120 if "tt-" in inputs.get_attribute("class"): 121 continue 122 123 value = inputs.get_attribute("value") 124 125 self.assertTrue(value in new_values, 126 "Expecting any of \"%s\" but got \"%s\"" % 127 (new_values, value)) 128 129 # Now convert it to a local layer 130 self.click("#edit-layer-source") 131 self.click("#dir") 132 dir_input = self.wait_until_visible("#layer-dir-path-in-details") 133 134 new_dir = "/home/test/my-meta-dir" 135 dir_input.send_keys(new_dir) 136 137 self.click("#save-changes-for-switch") 138 self.wait_until_visible("#edit-layer-source") 139 140 # Refresh the page to see if the new values are returned 141 self.get(self.url) 142 dir_input = self.find("#layer-dir-path-in-details") 143 self.assertTrue(new_dir in dir_input.get_attribute("value"), 144 "Expected %s in the dir value for layer directory" % 145 new_dir) 146 147 def test_delete_layer(self): 148 """ Delete the layer """ 149 150 self.get(self.url) 151 152 # Wait for the tables to load to avoid a race condition where the 153 # toaster tables have made an async request. If the layer is deleted 154 # before the request finishes it will cause an exception and fail this 155 # test. 156 wait = WebDriverWait(self.driver, 30) 157 158 wait.until(EC.text_to_be_present_in_element( 159 (By.CLASS_NAME, 160 "table-count-recipestable"), "0")) 161 162 wait.until(EC.text_to_be_present_in_element( 163 (By.CLASS_NAME, 164 "table-count-machinestable"), "0")) 165 166 self.click('a[data-target="#delete-layer-modal"]') 167 self.wait_until_visible("#delete-layer-modal") 168 self.click("#layer-delete-confirmed") 169 170 notification = self.wait_until_visible("#change-notification-msg") 171 expected_text = "You have deleted 1 layer from 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 instead" 176 "it was \"%s\"" % 177 (expected_text, notification.text)) 178 179 def test_addrm_to_project(self): 180 self.get(self.url) 181 182 # Add the layer 183 self.click("#add-remove-layer-btn") 184 185 notification = self.wait_until_visible("#change-notification-msg") 186 187 expected_text = "You have added 1 layer to your project: %s" % \ 188 self.imported_layer_version.layer.name 189 190 self.assertTrue(expected_text in notification.text, 191 "Expected notification text %s not found was " 192 " \"%s\" instead" % 193 (expected_text, notification.text)) 194 195 # Remove the layer 196 self.click("#add-remove-layer-btn") 197 198 notification = self.wait_until_visible("#change-notification-msg") 199 200 expected_text = "You have removed 1 layer from your project: %s" % \ 201 self.imported_layer_version.layer.name 202 203 self.assertTrue(expected_text in notification.text, 204 "Expected notification text %s not found was " 205 " \"%s\" instead" % 206 (expected_text, notification.text)) 207