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 inputs.send_keys("-edited") 101 102 # Save the new values 103 for save_btn in self.find_all(".change-btn"): 104 save_btn.click() 105 106 self.click("#save-changes-for-switch") 107 self.wait_until_visible("#edit-layer-source") 108 109 # Refresh the page to see if the new values are returned 110 self.get(self.url) 111 112 new_values = ["%s-edited" % old_val 113 for old_val in self.initial_values] 114 115 for inputs in self.find_all('#layer-git input[type="text"]') + \ 116 self.find_all('dd textarea'): 117 # ignore the tt inputs (twitter typeahead input) 118 if "tt-" in inputs.get_attribute("class"): 119 continue 120 121 value = inputs.get_attribute("value") 122 123 self.assertTrue(value in new_values, 124 "Expecting any of \"%s\" but got \"%s\"" % 125 (new_values, value)) 126 127 # Now convert it to a local layer 128 self.click("#edit-layer-source") 129 self.click("#dir") 130 dir_input = self.wait_until_visible("#layer-dir-path-in-details") 131 132 new_dir = "/home/test/my-meta-dir" 133 dir_input.send_keys(new_dir) 134 135 self.click("#save-changes-for-switch") 136 self.wait_until_visible("#edit-layer-source") 137 138 # Refresh the page to see if the new values are returned 139 self.get(self.url) 140 dir_input = self.find("#layer-dir-path-in-details") 141 self.assertTrue(new_dir in dir_input.get_attribute("value"), 142 "Expected %s in the dir value for layer directory" % 143 new_dir) 144 145 def test_delete_layer(self): 146 """ Delete the layer """ 147 148 self.get(self.url) 149 150 # Wait for the tables to load to avoid a race condition where the 151 # toaster tables have made an async request. If the layer is deleted 152 # before the request finishes it will cause an exception and fail this 153 # test. 154 wait = WebDriverWait(self.driver, 30) 155 156 wait.until(EC.text_to_be_present_in_element( 157 (By.CLASS_NAME, 158 "table-count-recipestable"), "0")) 159 160 wait.until(EC.text_to_be_present_in_element( 161 (By.CLASS_NAME, 162 "table-count-machinestable"), "0")) 163 164 self.click('a[data-target="#delete-layer-modal"]') 165 self.wait_until_visible("#delete-layer-modal") 166 self.click("#layer-delete-confirmed") 167 168 notification = self.wait_until_visible("#change-notification-msg") 169 expected_text = "You have deleted 1 layer from your project: %s" % \ 170 self.imported_layer_version.layer.name 171 172 self.assertTrue(expected_text in notification.text, 173 "Expected notification text \"%s\" not found instead" 174 "it was \"%s\"" % 175 (expected_text, notification.text)) 176 177 def test_addrm_to_project(self): 178 self.get(self.url) 179 180 # Add the layer 181 self.click("#add-remove-layer-btn") 182 183 notification = self.wait_until_visible("#change-notification-msg") 184 185 expected_text = "You have added 1 layer to your project: %s" % \ 186 self.imported_layer_version.layer.name 187 188 self.assertTrue(expected_text in notification.text, 189 "Expected notification text %s not found was " 190 " \"%s\" instead" % 191 (expected_text, notification.text)) 192 193 # Remove the layer 194 self.click("#add-remove-layer-btn") 195 196 notification = self.wait_until_visible("#change-notification-msg") 197 198 expected_text = "You have removed 1 layer from your project: %s" % \ 199 self.imported_layer_version.layer.name 200 201 self.assertTrue(expected_text in notification.text, 202 "Expected notification text %s not found was " 203 " \"%s\" instead" % 204 (expected_text, notification.text)) 205