• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2016 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that
3# can be found in the LICENSE file.
4
5"""Class to control Asus RT-AC68U router."""
6
7import logging
8
9import ap_spec
10import dynamic_ap_configurator
11
12from selenium.common.exceptions import UnexpectedAlertPresentException
13
14
15class AsusRTAC68UAPConfigurator(
16        dynamic_ap_configurator.DynamicAPConfigurator):
17    """Configurator for Asus RT-AC68U router."""
18
19
20    def _alert_handler(self, alert):
21        """Checks for any modal dialogs which popup to alert the user and
22        either raises a RuntimeError or ignores the alert.
23
24        @param alert: The modal dialog's contents.
25        """
26        text = alert.text
27        if 'Open System' in text:
28            alert.accept()
29        else:
30            raise RuntimeError('Unhandled alert message: %s' % text)
31
32
33    def get_number_of_pages(self):
34        """Returns the number of available pages."""
35        return 1
36
37
38    def get_supported_bands(self):
39        """Returns a list of dictionaries describing the supported bands."""
40        return [{'band': ap_spec.BAND_2GHZ,
41                 'channels': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]},
42                {'band': ap_spec.BAND_5GHZ,
43                 'channels': [36, 40, 44, 48, 149, 153, 157, 161, 165]}]
44
45
46    def get_supported_modes(self):
47        """Returns a list of dictionaries with the supported bands and modes."""
48        return [{'band': ap_spec.BAND_2GHZ,
49                 'modes': [ap_spec.MODE_N]},
50                {'band': ap_spec.BAND_5GHZ,
51                 'modes': [ap_spec.MODE_N, ap_spec.MODE_N|ap_spec.MODE_AC]}]
52
53
54    def get_supported_channel_widths(self):
55        """
56        Returns a dictionary describing supported channel widths based on
57        band and mode.
58
59        @return a dictionary as described above.
60        """
61        return {ap_spec.BAND_2GHZ: {ap_spec.MODE_N: [20]},
62                ap_spec.BAND_5GHZ: {ap_spec.MODE_N: [20],
63                                    ap_spec.MODE_N|ap_spec.MODE_AC: [20]}}
64
65
66    def is_security_mode_supported(self, security_mode):
67        """Returns if a given security_type is supported for 2.4GHz and
68        5GHz bands.
69
70        @param security_mode: one security modes defined in the ap_spec.
71
72        @return True if the security mode is supported; False otherwise.
73        """
74        return security_mode in (ap_spec.SECURITY_TYPE_DISABLED,
75                                 ap_spec.SECURITY_TYPE_WPA2PSK,
76                                 ap_spec.SECURITY_TYPE_MIXED)
77
78
79    def navigate_to_page(self, page_number):
80        """Navigates to the page corresponding to the given page number.
81
82        This method performs the translation between a page number and a url
83        to load. This is used internally by apply_setting.
84
85        @param page_number: page number of the page to load.
86        """
87        self.get_url(self.admin_interface_url)
88        self._ap_login()
89        xpath = '//div[@id="subMenu"]//div[@id="option_str1"]'
90        self.click_button_by_xpath(xpath)
91        ssid_xpath = '//table[@id="WLgeneral"]//input[@id="wl_ssid"]'
92        self.wait_for_object_by_xpath(ssid_xpath)
93
94
95    def _ap_login(self):
96        """Login as admin to configure settings."""
97        username = '//input[@id="login_username"]'
98        self.set_content_of_text_field_by_xpath('admin', username,
99                                                abort_check=True)
100        password = '//div[@class="password_gap"]//input[@name="login_passwd"]'
101        self.set_content_of_text_field_by_xpath('password', password,
102                                                abort_check=True)
103        self.click_button_by_xpath('//div[@class="button"]')
104
105
106    def _is_alert_present(self, xpath):
107        """Handle alerts if there is an alert on Save."""
108        try:
109            self.driver.find_element_by_xpath(xpath)
110            return
111        except UnexpectedAlertPresentException:
112            alert = self.driver.switch_to_alert()
113            self._alert_handler(alert)
114
115
116    def save_page(self, page_number):
117        """Saves the given page.
118
119        @param page_number: Page number of the page to be saved.
120        """
121        apply = '//div[@class="apply_gen"]//input[@id="applyButton"]'
122        self.click_button_by_xpath(apply)
123        self._is_alert_present(apply)
124        self.wait_for_object_by_xpath(apply)
125
126
127    def set_mode(self, mode, band=None):
128        """Sets the network mode.
129
130         @param mode: must be one of the modes listed in __init__().
131         @param band: the band to select.
132        """
133        self.add_item_to_command_list(self._set_mode, (mode, band), 1, 800)
134
135
136    def _set_mode(self, mode, band=None):
137        """Sets the network mode.
138
139        @param mode: must be one of the modes listed in __init__().
140        @param band: the band to select.
141        """
142        modes_2GHZ = {ap_spec.MODE_N:'N only'}
143        modes_5GHZ = {ap_spec.MODE_N:'N only',
144                      ap_spec.MODE_N|ap_spec.MODE_AC:'N/AC mixed'}
145        modes = {ap_spec.BAND_2GHZ: modes_2GHZ,
146                 ap_spec.BAND_5GHZ: modes_5GHZ}
147        mode_selected = modes.get(self.current_band).get(mode)
148        if not mode_selected:
149            raise RunTimeError('Mode %s with Band %s is not supported'
150                               % (mode,band))
151        self.driver.switch_to_default_content()
152        xpath = '//select[@name="wl_nmode_x"]'
153        self.wait_for_object_by_xpath(xpath)
154        self.select_item_from_popup_by_xpath(mode_selected, xpath)
155
156
157    def set_radio(self, enabled=True):
158        """Turns the radio on and off.
159
160        @param enabled: True to turn on the radio; False otherwise.
161        """
162        self.add_item_to_command_list(self._set_radio, (enabled,), 1, 700)
163
164
165    def _set_radio(self, enabled=True):
166        """Turns the radio on and off.
167
168        @param enabled: True to turn on the radio; False otherwise.
169        """
170        xpath = '//div[@id="tabMenu"]/table/tbody/tr/td[6]/div/span'
171        self.wait_for_object_by_xpath(xpath)
172        self.click_button_by_xpath(xpath)
173
174        if enabled:
175            xpath = '//input[@name="wl_radio" and @value="1"]'
176        else:
177            xpath = '//input[@name="wl_radio" and @value="0"]'
178        self.click_button_by_xpath(xpath)
179
180        xpath = '//div[@class="apply_gen"]//input[@class="button_gen"]'
181        self.click_button_by_xpath(xpath)
182
183        self.set_wait_time(30)
184        self.wait.until(lambda _:
185                        self.wait_for_object_by_xpath(xpath).is_displayed())
186        self.restore_default_wait_time()
187
188        xpath = '//div[@id="tabMenu"]/table/tbody/tr/td[1]/div/span/table/\
189                 tbody/tr/td'
190        self.click_button_by_xpath(xpath)
191
192
193    def set_ssid(self, ssid):
194        """Sets the SSID of the wireless network.
195
196        @param ssid: name of the wireless network.
197        """
198        self.add_item_to_command_list(self._set_ssid, (ssid,), 1, 900)
199
200
201    def _set_ssid(self, ssid):
202        """Sets the SSID of the wireless network.
203
204        @param ssid: name of the wireless network.
205        """
206        xpath = '//input[@id="wl_ssid"]'
207        self.set_content_of_text_field_by_xpath(ssid, xpath)
208        self._ssid = ssid
209
210
211    def set_channel(self, channel):
212        """Sets the channel of the wireless network.
213
214        @param channel: Integer value of the channel.
215        """
216        self.add_item_to_command_list(self._set_channel, (channel,), 1, 900)
217
218
219    def _set_channel(self, channel):
220        """Sets the channel of the wireless network.
221
222        @param channel: Integer value of the channel.
223        """
224        xpath = '//select[@name="wl_channel"]'
225        self.select_item_from_popup_by_xpath(str(channel), xpath)
226
227
228    def set_channel_width(self, channel_width):
229        """Adjusts the channel width.
230
231        @param width: the channel width.
232        """
233        self.add_item_to_command_list(self._set_channel_width,
234                                      (channel_width,), 1, 900)
235
236
237    def _set_channel_width(self, channel_width):
238        """Adjusts the channel width.
239
240        @param width: the channel width.
241        """
242        channel_width_choice = {20:'20 MHz'}
243        xpath = '//tr[@id="wl_bw_field"]//select[@name="wl_bw"]'
244        self.select_item_from_popup_by_xpath(
245                channel_width_choice.get(channel_width), xpath)
246
247
248    def set_band(self, band):
249        """Sets the band of the wireless network.
250
251        @param band: Constant describing band type.
252        """
253        if band == ap_spec.BAND_5GHZ:
254            self.current_band = ap_spec.BAND_5GHZ
255        elif band == ap_spec.BAND_2GHZ:
256            self.current_band = ap_spec.BAND_2GHZ
257        else:
258            raise RuntimeError('Invalid band sent %s' % band)
259        self.add_item_to_command_list(self._set_band, (), 1, 700)
260
261
262    def _set_band(self):
263        """Sets the band of the wireless network."""
264        xpath = '//tr[@id="wl_unit_field"]//select[@name="wl_unit"]'
265        if self.current_band == ap_spec.BAND_5GHZ:
266            selected_band = '5GHz'
267        else:
268            selected_band = '2.4GHz'
269        self.select_item_from_popup_by_xpath(selected_band, xpath)
270
271
272    def set_security_disabled(self):
273        """Disables the security of the wireless network."""
274        self.add_item_to_command_list(self._set_security_disabled, (), 1, 900)
275
276
277    def _set_security_disabled(self):
278        """Disables the security of the wireless network."""
279        xpath = ' //select[@name="wl_auth_mode_x"]'
280        self.select_item_from_popup_by_xpath('Open System', xpath)
281
282
283    def set_security_wep(self, key_value, authentication):
284        """Enables WEP security for the wireless network.
285
286        @param key_value: encryption key to use.
287        @param authentication: Open or Shared authentication types.
288        """
289        logging.debug('WEP mode is not supported.')
290
291
292    def set_security_wpapsk(self, security, shared_key, update_interval=None):
293        """Enables WPA2-Personal security type for the wireless network.
294
295        @param security: security type to configure.
296        @param shared_key: shared encryption key to use.
297        @param updat_interval: number of seconds to wait before updating.
298        """
299        self.add_item_to_command_list(self._set_security_wpapsk,
300                                      (security, shared_key, update_interval),
301                                       1, 900)
302
303
304    def _set_security_wpapsk(self, security, shared_key, update_interval=None):
305        """Enables WPA2-Personal and WPA-Auto-Personal(mixed mode) security type
306        for the wireless network.
307
308        @param security: security type to configure.
309        @param shared_key: shared encryption key to use.
310        @param update_interval: number of seconds to wait before updating.
311        """
312        xpath = '//select[@name="wl_auth_mode_x"]'
313        passphrase = '//input[@name="wl_wpa_psk" and @class="input_32_table"]'
314
315        if security == ap_spec.SECURITY_TYPE_WPA2PSK:
316            popup_value  = 'WPA2-Personal'
317        elif security == ap_spec.SECURITY_TYPE_MIXED:
318            popup_value = 'WPA-Auto-Personal'
319        else:
320            raise RunTimeError('Invalid Security Mode %s passed' % security)
321
322        self.select_item_from_popup_by_xpath(popup_value, xpath)
323        self.set_content_of_text_field_by_xpath(shared_key, passphrase,
324                                                abort_check=True)
325
326
327    def set_visibility(self, visible=True):
328        """Sets the SSID broadcast ON
329
330        @param visible: True to enable SSID broadcast. False otherwise.
331        """
332        self.add_item_to_command_list(self._set_visibility, (visible,), 1, 900)
333
334
335    def _set_visibility(self, visible=True):
336        """Sets the SSID broadcast ON
337
338        @param visible: True to enable SSID broadcast. False otherwise.
339        """
340        if visible == True:
341            xpath = '//input[@name="wl_closed" and @value="0"]'
342        else:
343            xpath = '//input[@name="wl_closed" and @value="1"]'
344        self.click_button_by_xpath(xpath)
345