Home | History | Annotate | Download | only in ap_configurators
      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 """Class to control the DlinkAP router."""
      6 
      7 import os
      8 
      9 import dynamic_ap_configurator
     10 import ap_spec
     11 from selenium.common.exceptions import TimeoutException as \
     12     SeleniumTimeoutException
     13 
     14 class DLinkAPConfigurator(
     15         dynamic_ap_configurator.DynamicAPConfigurator):
     16     """Derived class to control the DLink DAP-1522."""
     17 
     18     def _open_landing_page(self):
     19         self.get_url('%s/index.php' % self.admin_interface_url,
     20                      page_title='D-Link Corporation')
     21         page_name = os.path.basename(self.driver.current_url)
     22         if page_name == 'login.php' or page_name == 'index.php':
     23             try:
     24                 self.wait_for_object_by_xpath('//*[@name="login"]')
     25             except SeleniumTimeoutException, e:
     26                 # Maybe we were re-routed to the configuration page
     27                 if (os.path.basename(self.driver.current_url) ==
     28                     'bsc_wizard.php'):
     29                     return
     30                 raise SeleniumTimeoutException('Unable to navigate to the '
     31                                                'login or configuration page. '
     32                                                'WebDriver exception:%s', str(e))
     33             login_button = self.driver.find_element_by_xpath(
     34                 '//*[@name="login"]')
     35             login_button.click()
     36 
     37 
     38     def _open_configuration_page(self):
     39         self._open_landing_page()
     40         if os.path.basename(self.driver.current_url) != 'bsc_wizard.php':
     41             raise SeleniumTimeoutException('Taken to an unknown page %s' %
     42                 os.path.basename(self.driver.current_url))
     43 
     44         # Else we are being logged in automatically to the landing page
     45         wlan = '//*[@name="wlan_wireless"]'
     46         self.wait_for_object_by_xpath(wlan)
     47         wlan_button = self.driver.find_element_by_xpath(wlan)
     48         wlan_button.click()
     49         # Wait for the main configuration page, look for the radio button
     50         self.wait_for_object_by_id('enable')
     51 
     52 
     53     def get_number_of_pages(self):
     54         return 1
     55 
     56 
     57     def get_supported_bands(self):
     58         return [{'band': ap_spec.BAND_2GHZ,
     59                  'channels': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]},
     60                 {'band': ap_spec.BAND_5GHZ,
     61                  'channels': [26, 40, 44, 48, 149, 153, 157, 161, 165]}]
     62 
     63 
     64     def get_supported_modes(self):
     65         return [{'band': ap_spec.BAND_2GHZ,
     66                  'modes': [ap_spec.MODE_B, ap_spec.MODE_G, ap_spec.MODE_N,
     67                            ap_spec.MODE_B | ap_spec.MODE_G,
     68                            ap_spec.MODE_G | ap_spec.MODE_N]},
     69                 {'band': ap_spec.BAND_5GHZ,
     70                  'modes': [ap_spec.MODE_A, ap_spec.MODE_N,
     71                            ap_spec.MODE_A | ap_spec.MODE_N]}]
     72 
     73 
     74     def is_security_mode_supported(self, security_mode):
     75         """
     76         Returns if a given security_type is supported.
     77 
     78         @param security_mode: one security modes defined in the APSpec
     79 
     80         @return True if the security mode is supported; False otherwise.
     81 
     82         """
     83         return security_mode in (self.security_disabled,
     84                                  self.security_wpapsk,
     85                                  self.security_wep)
     86 
     87 
     88     def navigate_to_page(self, page_number):
     89         """
     90         Navigates to the page corresponding to the given page number.
     91 
     92         This method performs the translation between a page number and a url to
     93         load. This is used internally by apply_settings.
     94 
     95         @param page_number: page number of the page to load
     96 
     97         """
     98         # All settings are on the same page, so we always open the config page
     99         self._open_configuration_page()
    100 
    101 
    102     def save_page(self, page_number):
    103         """
    104         Saves the given page.
    105 
    106         @param page_number: Page number of the page to save.
    107 
    108         """
    109         # All settings are on the same page, we can ignore page_number
    110         button = self.driver.find_element_by_xpath('//input[@name="apply"]')
    111         button.click()
    112         # If we did not make changes we are sent to the continue screen.
    113         continue_screen = True
    114         button_xpath = '//input[@name="bt"]'
    115         try:
    116             self.wait_for_object_by_xpath(button_xpath)
    117         except SeleniumTimeoutException, e:
    118             continue_screen = False
    119         if continue_screen:
    120             button = self.driver.find_element_by_xpath(button_xpath)
    121             button.click()
    122         # We will be returned to the landing page when complete
    123         self.wait_for_object_by_id('enable')
    124 
    125 
    126     def set_mode(self, mode, band=None):
    127         # Mode overrides the band.  So if a band change is made after a mode
    128         # change it may make an incompatible pairing.
    129         self.add_item_to_command_list(self._set_mode, (mode, band), 1, 800)
    130 
    131 
    132     def _set_mode(self, mode, band=None):
    133         # Create the mode to popup item mapping
    134         mode_mapping = {ap_spec.MODE_B: '802.11b Only',
    135             ap_spec.MODE_G: '802.11g Only',
    136             ap_spec.MODE_N: '802.11n Only',
    137             ap_spec.MODE_B | ap_spec.MODE_G: 'Mixed 802.11g and 802.11b',
    138             ap_spec.MODE_N | ap_spec.MODE_G: 'Mixed 802.11n and 802.11g',
    139             ap_spec.MODE_N | ap_spec.MODE_G | ap_spec.MODE_B:
    140             'Mixed 802.11n, 802.11g, and 802.11b',
    141             ap_spec.MODE_N | ap_spec.MODE_G | ap_spec.MODE_B:
    142             'Mixed 802.11n, 802.11g, and 802.11b',
    143             ap_spec.MODE_A: '802.11a Only',
    144             ap_spec.MODE_N | ap_spec.MODE_A: 'Mixed 802.11n and 802.11a'}
    145         band_value = ap_spec.BAND_2GHZ
    146         if mode in mode_mapping.keys():
    147             popup_value = mode_mapping[mode]
    148             # If the mode contains 802.11a we use 5Ghz
    149             if mode & ap_spec.MODE_A == ap_spec.MODE_A:
    150                 band_value = ap_spec.BAND_5GHZ
    151             # If the mode is 802.11n mixed with 802.11a it must be 5Ghz
    152             elif (mode & (ap_spec.MODE_N | ap_spec.MODE_A) ==
    153                  (ap_spec.MODE_N | ap_spec.MODE_A)):
    154                 band_value = ap_spec.BAND_5GHZ
    155             # If the mode is 802.11n mixed with other than 802.11a its 2Ghz
    156             elif (mode & ap_spec.MODE_N == ap_spec.MODE_N and
    157                   mode ^ ap_spec.MODE_N > 0):
    158                 band_value = ap_spec.BAND_2GHZ
    159             # If the mode is 802.11n then default to 5Ghz unless there is a band
    160             elif mode == ap_spec.MODE_N:
    161                 band_value = ap_spec.BAND_5GHZ
    162             if band:
    163                 band_value = band
    164         else:
    165             raise SeleniumTimeoutException('The mode selected %s is not '
    166                                            'supported by router %s.' %
    167                                            (hex(mode), self.name))
    168         # Set the band first
    169         self._set_band(band_value)
    170         popup_id = 'mode_80211_11g'
    171         if band_value == ap_spec.BAND_5GHZ:
    172             popup_id = 'mode_80211_11a'
    173         self.select_item_from_popup_by_id(popup_value, popup_id)
    174 
    175 
    176     def set_radio(self, enabled=True):
    177         # If we are enabling we are activating all other UI components, do
    178         # it first. Otherwise we are turning everything off so do it last.
    179         if enabled:
    180             weight = 1
    181         else:
    182             weight = 1000
    183         self.add_item_to_command_list(self._set_radio, (enabled,), 1, weight)
    184 
    185 
    186     def _set_radio(self, enabled=True):
    187         # The radio checkbox for this router always has a value of 1. So we need
    188         # to use other methods to determine if the radio is on or not. Check if
    189         # the ssid textfield is disabled.
    190         ssid = self.driver.find_element_by_xpath('//input[@name="ssid"]')
    191         if ssid.get_attribute('disabled') == 'true':
    192             radio_enabled = False
    193         else:
    194             radio_enabled = True
    195         if radio_enabled == enabled:
    196             # Nothing to do
    197             return
    198         self.set_check_box_selected_by_id('enable', selected=False,
    199             wait_for_xpath='id("security_type_ap")')
    200 
    201 
    202     def set_ssid(self, ssid):
    203         # Can be done as long as it is enabled
    204         self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
    205 
    206 
    207     def _set_ssid(self, ssid):
    208         self._set_radio(enabled=True)
    209         self.set_content_of_text_field_by_id(ssid, 'ssid')
    210         self._ssid = ssid
    211 
    212 
    213     def set_channel(self, channel):
    214         self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
    215 
    216 
    217     def _set_channel(self, channel):
    218         position = self._get_channel_popup_position(channel)
    219         self._set_radio(enabled=True)
    220         self.set_check_box_selected_by_id('autochann', selected=False)
    221         self.select_item_from_popup_by_id(str(position), 'channel_g')
    222 
    223 
    224     def get_band(self):
    225         """
    226         This is experimental
    227         The radio buttons do more than run a script that adjusts the possible
    228         channels. We will just check the channel to popup.
    229         """
    230         self.set_radioSetting(enabled=True)
    231         xpath = ('id("channel_g")')
    232         self._open_configuration_page()
    233         self.wait_for_object_by_xpath(xpath)
    234         element = self.driver.find_element_by_xpath(xpath)
    235         if element.find_elements_by_tag_name('option')[0].text == '1':
    236             return ap_spec.BAND_2GHZ
    237         return ap_spec.BAND_5GHZ
    238 
    239 
    240     def set_band(self, band):
    241         if band != ap_spec.BAND_2GHZ or band != ap_spec.BAND_5GHZ:
    242             raise RuntimeError('Invalid band sent %s' % band)
    243         self.add_item_to_command_list(self._set_band, (band,), 1, 900)
    244 
    245 
    246     def _set_band(self, band):
    247         self._set_radio(enabled=True)
    248         if band == ap_spec.BAND_2GHZ:
    249             int_value = 0
    250             wait_for_id = 'mode_80211_11g'
    251         elif band == ap_spec.BAND_5GHZ:
    252             int_value = 1
    253             wait_for_id = 'mode_80211_11a'
    254             xpath = ('//*[contains(@class, "l_tb")]/input[@value="%d" '
    255                      'and @name="band"]' % int_value)
    256             element = self.driver.find_element_by_xpath(xpath)
    257             element.click()
    258         self.wait_for_object_by_id(wait_for_id)
    259 
    260 
    261     def set_security_disabled(self):
    262         self.add_item_to_command_list(self._set_security_disabled, (), 1, 900)
    263 
    264 
    265     def _set_security_disabled(self):
    266         self._set_radio(enabled=True)
    267         security_disabled = 'Disable Wireless Security (not recommended)'
    268         self.select_item_from_popup_by_id(security_disabled, 'security_type_ap')
    269 
    270 
    271     def set_security_wep(self, key_value, authentication):
    272         self.add_item_to_command_list(self._set_security_wep,
    273                                       (key_value, authentication), 1, 900)
    274 
    275 
    276     def _set_security_wep(self, key_value, authentication):
    277         self._set_radio(enabled=True)
    278         self.select_item_from_popup_by_id('WEP', 'security_type_ap',
    279                                           wait_for_xpath='id("auth_type")')
    280         self.select_item_from_popup_by_id(authentication, 'auth_type',
    281                                           wait_for_xpath='id("wep_key_value")')
    282         self.set_content_of_text_field_by_id(key_value, 'wep_key_value')
    283         self.set_content_of_text_field_by_id(key_value, 'verify_wep_key_value')
    284 
    285 
    286     def set_security_wpapsk(self, shared_key, update_interval=1800):
    287         self.add_item_to_command_list(self._set_security_wpapsk,
    288                                       (shared_key, update_interval), 1, 900)
    289 
    290 
    291     def _set_security_wpapsk(self, shared_key, update_interval=1800):
    292         self._set_radio(enabled=True)
    293         self.select_item_from_popup_by_id('WPA-Personal',
    294                                           'security_type_ap',
    295                                           wait_for_xpath='id("wpa_mode")')
    296         self.select_item_from_popup_by_id('WPA Only', 'wpa_mode',
    297             wait_for_xpath='id("grp_key_interval")')
    298         self.set_content_of_text_field_by_id(str(update_interval),
    299                                              'grp_key_interval')
    300         self.set_content_of_text_field_by_id(shared_key, 'wpapsk1')
    301 
    302 
    303     def set_visibility(self, visible=True):
    304         self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
    305 
    306 
    307     def _set_visibility(self, visible=True):
    308         self._set_radio(enabled=True)
    309         # value=0 is visible; value=1 is invisible
    310         int_value = int(not visible)
    311         xpath = ('//*[contains(@class, "l_tb")]/input[@value="%d" '
    312                  'and @name="visibility_status"]' % int_value)
    313         self.click_button_by_xpath(xpath)
    314