1# Licensed to the Software Freedom Conservancy (SFC) under one 2# or more contributor license agreements. See the NOTICE file 3# distributed with this work for additional information 4# regarding copyright ownership. The SFC licenses this file 5# to you under the Apache License, Version 2.0 (the 6# "License"); you may not use this file except in compliance 7# with the License. You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, 12# software distributed under the License is distributed on an 13# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14# KIND, either express or implied. See the License for the 15# specific language governing permissions and limitations 16# under the License. 17 18""" 19The Utils methods. 20""" 21import socket 22from selenium.webdriver.common.keys import Keys 23 24try: 25 basestring 26except NameError: 27 # Python 3 28 basestring = str 29 30 31def free_port(): 32 """ 33 Determines a free port using sockets. 34 """ 35 free_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 36 free_socket.bind(('0.0.0.0', 0)) 37 free_socket.listen(5) 38 port = free_socket.getsockname()[1] 39 free_socket.close() 40 return port 41 42 43def find_connectable_ip(host, port=None): 44 """Resolve a hostname to an IP, preferring IPv4 addresses. 45 46 We prefer IPv4 so that we don't change behavior from previous IPv4-only 47 implementations, and because some drivers (e.g., FirefoxDriver) do not 48 support IPv6 connections. 49 50 If the optional port number is provided, only IPs that listen on the given 51 port are considered. 52 53 :Args: 54 - host - A hostname. 55 - port - Optional port number. 56 57 :Returns: 58 A single IP address, as a string. If any IPv4 address is found, one is 59 returned. Otherwise, if any IPv6 address is found, one is returned. If 60 neither, then None is returned. 61 62 """ 63 try: 64 addrinfos = socket.getaddrinfo(host, None) 65 except socket.gaierror: 66 return None 67 68 ip = None 69 for family, _, _, _, sockaddr in addrinfos: 70 connectable = True 71 if port: 72 connectable = is_connectable(port, sockaddr[0]) 73 74 if connectable and family == socket.AF_INET: 75 return sockaddr[0] 76 if connectable and not ip and family == socket.AF_INET6: 77 ip = sockaddr[0] 78 return ip 79 80 81def join_host_port(host, port): 82 """Joins a hostname and port together. 83 84 This is a minimal implementation intended to cope with IPv6 literals. For 85 example, _join_host_port('::1', 80) == '[::1]:80'. 86 87 :Args: 88 - host - A hostname. 89 - port - An integer port. 90 91 """ 92 if ':' in host and not host.startswith('['): 93 return '[%s]:%d' % (host, port) 94 return '%s:%d' % (host, port) 95 96 97def is_connectable(port, host="localhost"): 98 """ 99 Tries to connect to the server at port to see if it is running. 100 101 :Args: 102 - port - The port to connect. 103 """ 104 socket_ = None 105 try: 106 socket_ = socket.create_connection((host, port), 1) 107 result = True 108 except socket.error: 109 result = False 110 finally: 111 if socket_: 112 socket_.close() 113 return result 114 115 116def is_url_connectable(port): 117 """ 118 Tries to connect to the HTTP server at /status path 119 and specified port to see if it responds successfully. 120 121 :Args: 122 - port - The port to connect. 123 """ 124 try: 125 from urllib import request as url_request 126 except ImportError: 127 import urllib2 as url_request 128 129 try: 130 res = url_request.urlopen("http://127.0.0.1:%s/status" % port) 131 if res.getcode() == 200: 132 return True 133 else: 134 return False 135 except Exception: 136 return False 137 138 139def keys_to_typing(value): 140 """Processes the values that will be typed in the element.""" 141 typing = [] 142 for val in value: 143 if isinstance(val, Keys): 144 typing.append(val) 145 elif isinstance(val, int): 146 val = str(val) 147 for i in range(len(val)): 148 typing.append(val[i]) 149 else: 150 for i in range(len(val)): 151 typing.append(val[i]) 152 return typing 153