1# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import ap_spec 6import dynamic_ap_configurator 7import os 8import time 9 10from selenium.common.exceptions import ElementNotVisibleException 11 12 13class EdimaxAPConfigurator( 14 dynamic_ap_configurator.DynamicAPConfigurator): 15 """Derived class to control the Edimax AP.""" 16 17 def navigate_to_page(self, page_number): 18 """Navigate to the required page. 19 20 @param page_number: The page number to navigate to. 21 22 """ 23 if page_number != 1 and page_number != 2: 24 raise RuntimeError('Invalid page number passed. Number of pages is' 25 '%d, page value sent was %d' % 26 (self.get_number_of_pages(), page_number)) 27 page_url = os.path.join(self.admin_interface_url ,'index.asp') 28 self.get_url(page_url, page_title='EDIMAX Technology') 29 frame = self.driver.find_element_by_xpath('//frame[@name="mainFrame"]') 30 self.driver.switch_to_frame(frame) 31 main_tabs = self.driver.find_elements_by_css_selector('div') 32 main_tabs[2].click() 33 sub_tabs = self.driver.find_elements_by_xpath( \ 34 '//span[@class="style11"]') 35 sub_tabs[2].click() 36 if page_number == 1: 37 # Open the general settings page. 38 self.click_button_by_xpath('//input[@onclick="c_fun(0)" and \ 39 @name="sys"]') 40 self.wait_for_object_by_xpath('//select[@name="band"]') 41 else: 42 # Open the security settings page. 43 self.click_button_by_xpath('//input[@onclick="c_fun(1)" and \ 44 @name="sys"]') 45 self.wait_for_object_by_xpath('//select[@name="method"]') 46 47 48 def get_number_of_pages(self): 49 return 2 50 51 52 def save_page(self, page_number): 53 """ Save page after applying settings. 54 55 @param page_number: The page number to be saved. 56 57 """ 58 xpath_ok = ('//input[@name="okbutton"]') 59 try: 60 self.click_button_by_xpath('//input[@name="B1" and @value="Apply"]', 61 alert_handler=self._alert_handler) 62 except ElementNotVisibleException, e: 63 # If the default Apply button is not visible then we are on Security 64 # settings page that has a different Apply button. Click that. 65 xpath = '//input[@type="submit" and @value="Apply"]' 66 apply_tabs = self.driver.find_elements_by_xpath(xpath) 67 apply_tabs[2].click() 68 self.driver.find_element_by_xpath('//input[@value="APPLY"]').click() 69 element = self.wait_for_object_by_xpath(xpath_ok) 70 xpath_done = '//input[@name="okbutton" and @value="OK"]' 71 while element and not(self.object_by_xpath_exist(xpath_done)): 72 time.sleep(0.5) 73 self.click_button_by_xpath(xpath_ok, alert_handler=self._alert_handler) 74 75 76 def get_supported_bands(self): 77 return [{'band': ap_spec.BAND_2GHZ, 'channels': range(1, 11)}] 78 79 80 def set_band(self, band): 81 return None 82 83 84 def get_supported_modes(self): 85 return [{'band': ap_spec.BAND_2GHZ, 86 'modes': [ap_spec.MODE_B, 87 ap_spec.MODE_G, 88 ap_spec.MODE_N, 89 ap_spec.MODE_B | ap_spec.MODE_G, 90 ap_spec.MODE_B | ap_spec.MODE_G | ap_spec.MODE_N]}] 91 92 93 def set_mode(self, mode, band=None): 94 self.add_item_to_command_list(self._set_mode, (mode,), 1, 800) 95 96 97 def _set_mode(self, mode, band=None): 98 # Different bands are not supported so we ignore. 99 # Create the mode to popup item mapping 100 mode_mapping = {ap_spec.MODE_B | ap_spec.MODE_G | ap_spec.MODE_N: 101 '2.4 GHz (B+G+N)', 102 ap_spec.MODE_N: '2.4 GHz (N)', 103 ap_spec.MODE_B: '2.4 GHz (B)', 104 ap_spec.MODE_G: '2.4 GHz (G)', 105 ap_spec.MODE_B | ap_spec.MODE_G: '2.4 GHz (B+G)'} 106 mode_name = '' 107 if mode in mode_mapping.keys(): 108 mode_name = mode_mapping[mode] 109 else: 110 raise RuntimeError('The mode selected %d is not supported by router' 111 ' %s.', hex(mode), self.name) 112 xpath = '//select[@name="band"]' 113 self.select_item_from_popup_by_xpath(mode_name, xpath) 114 115 116 def set_channel(self, channel): 117 self.add_item_to_command_list(self._set_channel, (channel,), 1, 900) 118 119 120 def _set_channel(self, channel): 121 position = self._get_channel_popup_position(channel) 122 channel_choices = ['1', '2', '3', '4', '5', 123 '6', '7', '8', '9', '10', '11'] 124 self.select_item_from_popup_by_xpath(channel_choices[position], 125 '//select[@name="chan"]') 126 127 128 def is_security_mode_supported(self, security_mode): 129 """Check if the AP supports this mode of security. 130 131 @param security_mode: Type of security. 132 133 """ 134 return security_mode in (ap_spec.SECURITY_TYPE_DISABLED, 135 ap_spec.SECURITY_TYPE_WEP, 136 ap_spec.SECURITY_TYPE_WPAPSK) 137 138 139 def set_ssid(self, ssid): 140 self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 1000) 141 142 143 def _set_ssid(self, ssid): 144 self.set_content_of_text_field_by_xpath(ssid, '//input[@name="ssid"]', 145 abort_check=True) 146 self._ssid = ssid 147 148 149 def is_visibility_supported(self): 150 """ 151 Returns if AP supports setting the visibility (SSID broadcast). 152 153 @return True if supported; False otherwise. 154 155 """ 156 return False 157 158 159 def is_update_interval_supported(self): 160 """ 161 Returns True if setting the PSK refresh interval is supported. 162 163 @return True is supported; False otherwise. 164 165 """ 166 return False 167 168 169 def set_radio(self, enabled=True): 170 # AP does not aupport setting Radio. 171 return None 172 173 174 def set_security_disabled(self): 175 self.add_item_to_command_list(self._set_security_disabled, (), 2, 1000) 176 177 178 def _set_security_disabled(self): 179 self.select_item_from_popup_by_xpath('Disable', 180 '//select[@name="method"]') 181 182 183 def set_security_wpapsk(self, security, shared_key, update_interval=None): 184 self.add_item_to_command_list(self._set_security_wpapsk, 185 (security, shared_key, update_interval), 186 2, 1000) 187 188 189 def _set_security_wpapsk(self, security, shared_key, update_interval=None): 190 self.wait_for_object_by_xpath('//input[@name="pskValue"]') 191 self.select_item_from_popup_by_xpath('WPA pre-shared key', 192 '//select[@name="method"]') 193 if security == ap_spec.SECURITY_TYPE_WPAPSK: 194 wpa_item = 'wpaCipher1' 195 else: 196 wpa_item = 'wpaCipher2' 197 self.click_button_by_id(wpa_item, alert_handler=self._alert_handler) 198 self.select_item_from_popup_by_xpath('Passphrase', 199 '//select[@name="pskFormat"]') 200 self.set_content_of_text_field_by_xpath(shared_key, 201 '//input[@name="pskValue"]') 202 203 204 def set_security_wep(self, key_value, authentication): 205 self.add_item_to_command_list(self._set_security_wep, 206 (key_value, authentication), 2, 1000) 207 208 209 def _set_security_wep(self, key_value, authentication): 210 self.wait_for_object_by_xpath('//input[@name="key1"]') 211 self.select_item_from_popup_by_xpath('WEP', '//select[@name="method"]') 212 self.select_item_from_popup_by_xpath('64-bit', 213 '//select[@name="length"]') 214 self.select_item_from_popup_by_xpath('ASCII (5 characters)', 215 '//select[@name="format"]') 216 self.set_content_of_text_field_by_xpath(key_value, 217 '//input[@name="key1"]') 218 219 220 def _alert_handler(self, alert): 221 """Checks for any modal dialogs which popup to alert the user and 222 either raises a RuntimeError or ignores the alert. 223 224 @param alert: The modal dialog's contents. 225 """ 226 text = alert.text 227 if 'Pre-Shared Key values should be set at least characters' in text: 228 alert.accept() 229 else: 230 raise RuntimeError('An unexpected modal dialog blocked the' 231 'operation, dialog text: %s', text) 232