def close(self): all_handles = self.driver.window_handles for handle in all_handles: # 切换到每一个窗口,并关闭它 self.driver.switch_to_window(handle) self.driver.close() log.debug(f'close th windows: {repr(handle)}')
def switch_context(self, context): if context.strip() == '': context = 'NATIVE_APP' if context != self.current_context: if context == '': context = None log.debug(f'switch context: {repr(context)}') self.driver.switch_to.context(context) self.current_context = context
def check(self, step): data = step['data'] if not data: data = step['expected'] element = step['element'] by = element['by'] output = step['output'] location = '' if by in ('title', 'current_url'): getattr(self, by)(data, output) else: location = self.locat(element) for key in data: # 预期结果 expected = data[key] # 切片操作处理 s = re.findall(r'\[.*?\]', key) if s: s = s[0] key = key.replace(s, '') if key == 'text': real = location.text else: real = location.get_attribute(key) if s: real = eval('real' + s) log.debug(f'DATA:{repr(expected)}') log.debug('REAL:{repr(real)}') try: compare(expected, real) except: raise Exception( f'check failure, DATA:{repr(expected)}, REAL:{repr(real)}' ) # 获取元素其他属性 for key in output: if output[key] == 'text': v = location.text vars.put({key: v}) elif output[key] in ('text…', 'text...'): if location.text.endswith('...'): v = location.text[:-3] vars.put({key: v}) else: v = location.text vars.put({key: v}) else: v = location.get_attribute(output[key]) vars.put({key: v}) return location
def title(self, data, output): log.debug(f'DATA:{repr(data["text"])}') log.debug(f'REAL:{repr(self.driver.title)}') # try: if data['text'].startswith('*'): assert data['text'][1:] in self.driver.title else: assert data['text'] == self.driver.title for key in output: vars.put({key: self.driver.title})
def switch(self): """ docstring """ current_handle = self.driver.current_window_handle use_handles = list(self.windows.values()) + [self.driver.current_window_handle] all_handles = self.driver.window_handles for handle in all_handles: # 未命名的 handle if handle not in self.windows.values(): # 切换到新窗口 self.driver.switch_to_window(handle) log.debug(f'switch the windows: #tab:<New>, handle:{repr(handle)}')
def message(self, step): data = step['data'] text = data.get('text', '') value = step['element'] if value.lower() in ('确认', 'accept'): self.driver.switch_to_alert().accept() elif value.lower() in ('取消', '关闭', 'cancel', 'close'): self.driver.switch_to_alert().dismiss() elif value.lower() in ('输入', 'input'): self.driver.switch_to_alert().send_keys(text) self.driver.switch_to_alert().accept() log.debug('switch frame: Alert') self.w.frame = 'Alert'
def open(self, step): url = step['element']['value'] if step['data'].get('#clear', ''): self.driver.delete_all_cookies() self.driver.get(url) cookie = step['data'].get('cookie', '') if cookie: self.driver.add_cookie(json2dict(cookie)) co = self.driver.get_cookie(json2dict(cookie).get('name', '')) log.debug(f'cookie is add: {co}') sleep(0.5)
def current_url(self, data, output): log.debug(f'DATA:{repr(data["text"])}') log.debug(f'REAL:{repr(self.driver.current_url)}') try: if data['text'].startswith('*'): assert data['text'][1:] in self.driver.current_url else: assert data['text'] == self.driver.current_url except: raise Exception( f'check failure, DATA:{data["text"]}, REAL:{self.driver.current_url}' ) # 只能获取到元素 url for key in output: vars.put({key: self.driver.current_url})
def _call(self, step): # 处理截图数据 # snap = Snapshot() # snap.pre(step) context = replace(step.get('frame', '')).strip() self.w.switch_context(context) if self.w.current_context.startswith('WEBVIEW'): # 切换标签页 tab = step['data'].get('#tab') if tab: del step['data']['#tab'] self.driver.switch_to_window(self.w.windows[tab]) log.debug(f'current context: {repr(self.w.current_context)}') # 根据关键字调用关键字实现 element = getattr(self, step['keyword'].lower())(step)
def switch_frame(self, frame): if frame.strip(): frame = [x.strip() for x in frame.split('|')] if frame != self.frame: if self.frame != 0: self.driver.switch_to.default_content() for f in frame: log.debug(f'frame value: {repr(f)}') if f.startswith('#'): f = int(f[1:]) elif '#' in f: from sweet.testcase import elements_format from sweet.modules.web.locator import locating_element element = elements_format('public', f)[2] f = locating_element(element) log.debug(f' switch frame: {repr(f)}') self.driver.switch_to.frame(f) self.frame = frame else: if self.frame != 0: self.driver.switch_to.default_content() self.frame = 0
def tab(self, name): current_handle = self.driver.current_window_handle if name in self.windows: if current_handle != self.windows[name]: self.driver.switch_to_window(self.windows[name]) log.debug(f'switch the windows: #tab:{name}, handle:{repr(self.windows[name])}') else: log.debug(f'current windows: #tab:{name}, handle:{repr(self.windows[name])}') else: all_handles = self.driver.window_handles for handle in all_handles: if handle not in self.windows.values(): self.windows[name] = handle if handle != current_handle: self.driver.switch_to_window(handle) log.debug(f'switch the windows: #tab:{name}, handle:{repr(handle)}') else: log.debug(f'current windows: #tab:{name}, handle:{repr(current_handle)}') self.clear()
def clear(self): # 关闭未命名的 windows current_handle = self.driver.current_window_handle current_name = '' for name in self.windows: if current_handle == self.windows[name]: current_name = name all_handles = self.driver.window_handles for handle in all_handles: # 未命名的 handle if handle not in self.windows.values(): # 切换到每一个窗口,并关闭它 self.driver.switch_to_window(handle) log.debug(f'switch the windows: #tab:<New>, handle:{repr(handle)}') self.driver.close() log.debug(f'close the windows: #tab:<New>, handle:{repr(handle)}') self.driver.switch_to_window(current_handle) log.debug(f'switch the windows: #tab:{current_name}, handle:{repr(current_handle)}')
def request(self, kw, step): url = step['element'] if url.startswith('/'): url = url[1:] data = step['data'] # 测试数据解析时,会默认添加一个 text 键,需要删除 if 'text' in data and not data['text']: data.pop('text') _data = {} _data['headers'] = json2dict(data.pop('headers', '{}')) if data.get('cookies'): data['cookies'] = json2dict(data['cookies']) if kw == 'get': _data['params'] = json2dict( data.pop('params', '{}')) or json2dict(data.pop('data', '{}')) elif kw == 'post': if data.get('text'): _data['data'] = data.pop('text').encode('utf-8') else: _data['data'] = json2dict(data.pop('data', '{}')) _data['json'] = json2dict(data.pop('json', '{}')) _data['files'] = eval(data.pop('files', 'None')) elif kw in ('put', 'patch'): _data['data'] = json2dict(data.pop('data', '{}')) for k in data: for s in ('{', '[', 'False', 'True'): if s in data[k]: try: data[k] = eval(data[k]) except: log.warning(f'try eval data failure: {data[k]}') break expected = step['expected'] expected['status_code'] = expected.get('status_code', None) expected['text'] = expected.get('text', '').encode('utf-8') expected['json'] = json2dict(expected.get('json', '{}')) expected['cookies'] = json2dict(expected.get('cookies', '{}')) expected['headers'] = json2dict(expected.get('headers', '{}')) timeout = float(expected.get('timeout', 10)) expected['time'] = float(expected.get('time', 0)) for key in keywords: if kw.upper() == key.upper(): self.r.headers.update(self.headers[key.upper()]) log.debug(f'URL: {self.path + url}') # 处理 before_send before_send = data.pop('before_send', '') if before_send: _data, data = getattr(http_handle, before_send)(kw, _data, data) else: _data, data = getattr(http_handle, 'before_send')(kw, _data, data) if _data['headers']: for k in [x for x in _data['headers']]: if not _data['headers'][k]: del self.r.headers[k] del _data['headers'][k] self.r.headers.update(_data['headers']) r = '' if kw == 'get': r = getattr(self.r, kw)(self.path + url, params=_data['params'], timeout=timeout, **data) if _data['params']: log.debug(f'PARAMS: {_data["params"]}') elif kw == 'post': r = getattr(self.r, kw)(self.path + url, data=_data['data'], json=_data['json'], files=_data['files'], timeout=timeout, **data) log.debug(f'BODY: {r.request.body}') elif kw in ('put', 'patch'): r = getattr(self.r, kw)(self.path + url, data=_data['data'], timeout=timeout, **data) log.debug(f'BODY: {r.request.body}') elif kw in ('delete', 'options'): r = getattr(self.r, kw)(self.path + url, timeout=timeout, **data) log.debug(f'status_code: {repr(r.status_code)}') try: # json 响应 log.debug(f'response json: {repr(r.json())}') except: # 其他响应 log.debug(f'response text: {repr(r.text)}') response = {'status_code': r.status_code, 'headers': r.headers, '_cookies': r.cookies, 'content': r.content, 'text': r.text} try: response['cookies'] = requests.utils.dict_from_cookiejar(r.cookies) except: response['cookies'] = r.cookies try: j = r.json() response['json'] = j except: response['json'] = {} # 处理 after_receive after_receive = expected.pop('after_receive', '') if after_receive: response = getattr(http_handle, after_receive)(response) else: response = getattr(http_handle, 'after_receive')(response) if expected['status_code']: if str(expected['status_code']) != str(response['status_code']): raise Exception( f'status_code | EXPECTED:{repr(expected["status_code"])}, REAL:{repr(response["status_code"])}') if expected['text']: if expected['text'].startswith('*'): if expected['text'][1:] not in response['text']: raise Exception( f'text | EXPECTED:{repr(expected["text"])}, REAL:{repr(response["text"])}') else: if expected['text'] == response['text']: raise Exception( f'text | EXPECTED:{repr(expected["text"])}, REAL:{repr(response["text"])}') if expected['headers']: result = check(expected['headers'], response['headers']) log.debug(f'headers check result: {result}') if result['code'] != 0: raise Exception( f'headers | EXPECTED:{repr(expected["headers"])}, REAL:{repr(response["headers"])}, RESULT: {result}') elif result['var']: # var.update(result['var']) vars.put(result['var']) log.debug(f'headers var: {repr(result["var"])}') if expected['cookies']: log.debug(f'response cookies: {response["cookies"]}') result = check(expected['cookies'], response['cookies']) log.debug(f'cookies check result: {result}') if result['code'] != 0: raise Exception( f'cookies | EXPECTED:{repr(expected["cookies"])}, REAL:{repr(response["cookies"])}, RESULT: {result}') elif result['var']: # var.update(result['var']) vars.put(result['var']) log.debug(f'cookies var: {repr(result["var"])}') if expected['json']: result = check(expected['json'], response['json']) log.debug(f'json check result: {result}') if result['code'] != 0: raise Exception( f'json | EXPECTED:{repr(expected["json"])}, REAL:{repr(response["json"])}, RESULT: {result}') elif result['var']: # var.update(result['var']) vars.put(result['var']) log.debug(f'json var: {repr(result["var"])}') if expected['time']: if expected['time'] < r.elapsed.total_seconds(): raise Exception( f'time | EXPECTED:{repr(expected["time"])}, REAL:{repr(r.elapsed.total_seconds())}') output = step['output'] # if output: # log.debug('output: %s' % repr(output)) for k, v in output.items(): if v == 'status_code': status_code = response['status_code'] vars.put({k: status_code}) log.debug(f'{k}: {status_code}') elif v == 'text': text = response['text'] vars.put({k: text}) log.debug(f'{k}: {text}') elif k == 'json': sub = json2dict(output.get('json', '{}')) result = check(sub, response['json']) # var.update(result['var']) vars.put(result['var']) log.debug(f'json var: {repr(result["var"])}') elif k == 'cookies': sub = json2dict(output.get('cookies', '{}')) result = check(sub, response['cookies']) vars.put(result['var']) log.debug(f'cookies var: {repr(result["var"])}')
def sql(self, step): response = {} _sql = step['element'] log.debug(f'SQL: {repr(_sql)}') row = {} if _sql.lower().startswith('select'): row = self.db.fetchone(_sql) log.debug(f'SQL response: {repr(row)}') if not row: raise Exception('*** Fetch None ***') elif _sql.lower().startswith('db.'): _sql_ = _sql.split('.', 2) collection = _sql_[1] sql = _sql_[2] response = self.db.mongo(collection, sql) if response: log.debug(f'find result: {repr(response)}') else: self.db.execute(_sql) if _sql.lower().startswith('select'): text = _sql[6:].split('FROM')[0].split('from')[0].strip() keys = dedup(text).split(',') for i, k in enumerate(keys): keys[i] = k.split(' ')[-1] response = dict(zip(keys, row)) log.debug(f'select result: {repr(response)}') expected = step['data'] if not expected: expected = step['expected'] if 'json' in expected: expected['json'] = json2dict(expected.get('json', '{}')) result = check(expected.pop('json'), response['json']) log.debug(f'json check result: {result}') if result['code'] != 0: raise Exception( f'json | EXPECTED:{repr(expected["json"])}, REAL:{repr(response["json"])}, RESULT: {result}' ) elif result['var']: vars.put(result['var']) log.debug(f'json var: {repr(result["var"])}') if expected: for key in expected: sv, pv = expected[key], response[key] log.debug( f'key: {repr(key)}, expect: {repr(sv)}, real: { repr(pv)}') compare(sv, pv) output = step['output'] if output: for k, v in output.items(): if k == 'json': sub = json2dict(output.get('json', '{}')) result = check(sub, response['json']) vars.put(result['var']) log.debug(f'json var: {repr(result["var"])}') else: vars.put({k: response[v]}) log.debug(f'output: {vars.output()}')