1# Copyright (c) 2012 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 5"""Base class for objects to configure Linksys single band access points 6 using webdriver.""" 7 8import logging 9import urlparse 10 11import dynamic_ap_configurator 12import ap_spec 13 14from selenium.common.exceptions import WebDriverException 15 16 17class LinksyseSingleBandAPConfigurator( 18 dynamic_ap_configurator.DynamicAPConfigurator): 19 """Base class for objects to configure Linksys single band access points 20 using webdriver.""" 21 22 def __init__(self, ap_config): 23 super(LinksyseSingleBandAPConfigurator, self).__init__(ap_config) 24 self._dhcp_delay = 30 25 26 27 def _sec_alert(self, alert): 28 text = alert.text 29 if 'Your wireless security mode is not compatible with' in text: 30 alert.accept() 31 elif 'WARNING: Your Wireless-N devices will only operate' in text: 32 alert.accept() 33 elif 'Wireless security is currently disabled.' in text: 34 alert.accept() 35 self.click_button_by_id('divBT1', alert_handler=self._sec_alert) 36 elif 'Your new setting will disable Wi-Fi Protected Setup.' in text: 37 alert.accept() 38 elif 'Illegal characters [ acceptable characters: 0 to 9 ]' in text: 39 alert.accept() 40 raise RuntimeError('Invalid characters used for key renewal. ' 41 'Error: %s' % text) 42 elif 'The Key must be between 8 and 63 ASCII characters' in text: 43 alert.accept() 44 else: 45 raise RuntimeError('Unhandled alert message: %s' % text) 46 47 48 def get_number_of_pages(self): 49 return 2 50 51 52 def get_supported_modes(self): 53 return [{'band': ap_spec.BAND_2GHZ, 54 'modes': [ap_spec.MODE_M, ap_spec.MODE_B | ap_spec.MODE_G, 55 ap_spec.MODE_G, ap_spec.MODE_B, ap_spec.MODE_N]}] 56 57 58 def get_supported_bands(self): 59 return [{'band': ap_spec.BAND_2GHZ, 60 'channels': ['Auto', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]}] 61 62 63 def is_security_mode_supported(self, security_mode): 64 """Returns if the passes security mode is supported. 65 66 @param security_mode: a valid ap_spec security mode 67 68 @returns True if the mode is supported; False otherwise 69 70 """ 71 return security_mode in (ap_spec.SECURITY_TYPE_DISABLED, 72 ap_spec.SECURITY_TYPE_WPAPSK, 73 ap_spec.SECURITY_TYPE_WPA2PSK, 74 ap_spec.SECURITY_TYPE_WEP) 75 76 77 def navigate_to_page(self, page_number): 78 """Navigates to the passed in page. 79 80 @param page_number: the page number as an integer 81 82 """ 83 if page_number == 1: 84 page_url = urlparse.urljoin(self.admin_interface_url, 85 'Wireless_Basic.asp') 86 self.get_url(page_url, page_title='Settings') 87 elif page_number == 2: 88 page_url = urlparse.urljoin(self.admin_interface_url, 89 'WL_WPATable.asp') 90 self.get_url(page_url, page_title='Security') 91 else: 92 raise RuntimeError('Invalid page number passed. Number of pages ' 93 '%d, page value sent was %d' % 94 (self.get_number_of_pages(), page_number)) 95 96 97 def save_page(self, page_number): 98 """Save the given page. 99 100 @param page_number: the page number as an integer 101 102 """ 103 try: 104 self.click_button_by_id('divBT1', alert_handler=self._sec_alert) 105 except: 106 self._handle_alert('//input[@id="divBT1"]', self._sec_alert) 107 xpath_continue = '//input[@value="Continue"]' 108 self.wait_for_object_by_xpath(xpath_continue, wait_time=20) 109 self.click_button_by_xpath(xpath_continue, 110 alert_handler=self._sec_alert) 111 112 113 def set_mode(self, mode, band=None): 114 self.add_item_to_command_list(self._set_mode, (mode,), 1, 900) 115 116 117 def _set_mode(self, mode, band=None): 118 mode_mapping = {ap_spec.MODE_M:'Mixed', 119 ap_spec.MODE_B | ap_spec.MODE_G:'Wireless-B/G Only', 120 ap_spec.MODE_G:'Wireless-G Only', 121 ap_spec.MODE_B:'Wireless-B Only', 122 ap_spec.MODE_N:'Wireless-N Only', 123 'Disabled':'Disabled'} 124 mode_name = mode_mapping.get(mode) 125 if not mode_name: 126 raise RuntimeError('The mode %d not supported by router %s. ', 127 hex(mode), self.name) 128 xpath = '//select[@name="net_mode_24g"]' 129 self.select_item_from_popup_by_xpath(mode_name, xpath, 130 alert_handler=self._sec_alert) 131 132 133 def set_ssid(self, ssid): 134 self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900) 135 136 137 def _set_ssid(self, ssid): 138 xpath = '//input[@maxlength="32" and @name="ssid_24g"]' 139 self.set_content_of_text_field_by_xpath(ssid, xpath, abort_check=False) 140 # If security is off leaving focus from the field will throw 141 # a alert dialog. 142 ssid_field = self.driver.find_element_by_xpath(xpath) 143 self._ssid = ssid 144 try: 145 ssid_field.send_keys('\t') 146 return 147 except WebDriverException, e: 148 message = str(e) 149 if message.find('An open modal dialog blocked the operation') == -1: 150 return 151 self._sec_alert(self.driver.switch_to_alert()) 152 153 154 def set_channel(self, channel): 155 self.add_item_to_command_list(self._set_channel, (channel,), 1, 900) 156 157 158 def _set_channel(self, channel): 159 position = self._get_channel_popup_position(channel) 160 xpath = '//select[@name="_wl0_channel"]' 161 channels = ['Auto', 162 '1 - 2.412GHZ', '2 - 2.417GHZ', '3 - 2.422GHZ', 163 '4 - 2.427GHZ', '5 - 2.432GHZ', '6 - 2.437GHZ', 164 '7 - 2.442GHZ', '8 - 2.447GHZ', '9 - 2.452GHZ', 165 '10 - 2.457GHZ', '11 - 2.462GHZ'] 166 self.select_item_from_popup_by_xpath(channels[position], xpath) 167 168 169 def set_channel_width(self, channel_wid): 170 """ 171 Adjusts the channel channel width. 172 173 @param channel_width: the channel width 174 """ 175 self.add_item_to_command_list(self._set_channel_width,(channel_wid,), 176 1, 900) 177 178 179 def _set_channel_width(self, channel_wid): 180 channel_width_choice = ['Auto (20 MHz or 40 MHz)', '20 MHz Only'] 181 xpath = '//select[@name="_wl0_nbw"]' 182 self.select_item_from_popup_by_xpath(channel_width_choice[channel_wid], 183 xpath) 184 185 186 def set_radio(self, enabled=True): 187 weight = 1 if enabled else 1000 188 self.add_item_to_command_list(self._set_radio, (enabled,), 1, weight) 189 190 191 def _set_radio(self, enabled=True): 192 if not enabled: 193 self._set_mode('Disabled') 194 else: 195 self._set_mode(ap_spec.MODE_G) 196 197 198 def set_band(self, enabled=True): 199 logging.debug('set_band is not supported in Linksys single band AP.') 200 return None 201 202 203 def set_security_disabled(self): 204 self.add_item_to_command_list(self._set_security_disabled, (), 2, 1000) 205 206 207 def _set_security_disabled(self): 208 xpath = '//select[@name="wl0_security_mode"]' 209 self.select_item_from_popup_by_xpath('Disabled', xpath, 210 alert_handler=self._sec_alert) 211 212 213 def set_security_wep(self, key_value, authentication): 214 self.add_item_to_command_list(self._set_security_wep, 215 (key_value, authentication), 2, 1000) 216 217 218 def _set_security_wep(self, key_value, authentication): 219 # WEP and WPA-Personal are not supported for Wireless-N only mode 220 # and Mixed mode. 221 # WEP and WPA-Personal do not show up in the list, no alert is thrown. 222 popup = '//select[@name="wl0_security_mode"]' 223 if not self.item_in_popup_by_xpath_exist('WEP', popup): 224 raise RuntimeError('The popup %s did not contain the item %s. ' 225 'Is the mode N?' % (popup, self.security_wep)) 226 self.select_item_from_popup_by_xpath('WEP', popup, 227 alert_handler=self._sec_alert) 228 text = '//input[@name="wl0_passphrase"]' 229 self.set_content_of_text_field_by_xpath(key_value, text, 230 abort_check=True) 231 xpath = '//input[@value="Generate"]' 232 self.click_button_by_xpath(xpath, alert_handler=self._sec_alert) 233 234 235 def set_security_wpapsk(self, security, shared_key, update_interval=None): 236 # WEP and WPA-Personal are not supported for Wireless-N only mode, 237 self.add_item_to_command_list(self._set_security_wpapsk, 238 (security, shared_key, update_interval), 239 2, 900) 240 241 242 def _set_security_wpapsk(self, security, shared_key, upadate_interval=None): 243 """Common method to set wpapsk and wpa2psk modes.""" 244 popup = '//select[@name="wl0_security_mode"]' 245 self.wait_for_object_by_xpath(popup) 246 if security == ap_spec.SECURITY_TYPE_WPAPSK: 247 wpa_item = 'WPA Personal' 248 else: 249 wpa_item = 'WPA2 Personal' 250 self.select_item_from_popup_by_xpath(wpa_item, popup, 251 alert_handler=self._sec_alert) 252 text = '//input[@name="wl0_wpa_psk"]' 253 self.set_content_of_text_field_by_xpath(shared_key, text, 254 abort_check=False) 255 256 257 def is_update_interval_supported(self): 258 """ 259 Returns True if setting the PSK refresh interval is supported. 260 261 @return True is supported; False otherwise 262 """ 263 return False 264 265 266 def set_visibility(self, visible=True): 267 self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900) 268 269 270 def _set_visibility(self, visible=True): 271 int_value = 0 if visible else 1 272 xpath = ('//input[@value="%d" and @name="closed_24g"]' % int_value) 273 self.click_button_by_xpath(xpath, alert_handler=self._sec_alert) 274