def edge_scroll(self, frame, direction, dist, release=True): """edge scroll - performs task switching action. direction = 'LtoR' or 'RtoL' (finger movement direction) dist = percentage of horizontal distance travel, max is 1.0 release = if set to False, the Action object will be returned so the user can complete the release action""" start_x = 0 dist_travelled = 0 time_increment = 0.01 if dist > 1: dist = 1 if direction == 'LtoR': start_x = 0 elif direction == 'RtoL': start_x = frame.size['width'] dist *= -1 # travel opposite direction limit = dist * frame.size['width'] dist_unit = limit * time_increment action = Actions(self.marionette) action.press(frame, start_x, frame.size['height'] / 2) # press either the left or right edge while abs(dist_travelled) < abs(limit): action.move_by_offset(dist_unit, 0) action.wait(time_increment) dist_travelled += dist_unit if release: action.release() action.perform() return action
def move_seek_slider(self, offset): scale = self.marionette.find_element(*self._video_seek_head_locator) finger = Actions(self.marionette) finger.press(scale) finger.move_by_offset(offset, 0) finger.release() finger.perform()
def move_slider(self, slider, dir_x): scale = self.marionette.find_element(*slider) finger = Actions(self.marionette) finger.press(scale) finger.move_by_offset(dir_x, 0) finger.release() finger.perform() time.sleep(2)
def wait_with_value(marionette, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) button = marionette.find_element(By.ID, "button1") action = Actions(marionette) action.press(button).wait(0.01).release() action.perform() wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def move_element_offset(marionette, wait_for_condition, expected1, expected2): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) ele = marionette.find_element(By.ID, "button1") action = Actions(marionette) action.press(ele).move_by_offset(0,150).move_by_offset(0, 150).release() action.perform() wait_for_condition_else_raise(marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;") wait_for_condition_else_raise(marionette, wait_for_condition, expected2, "return document.getElementById('button2').innerHTML;")
def wait_with_value(marionette, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) button = marionette.find_element(By.ID, "button1") action = Actions(marionette) action.press(button).wait(0.01).release() action.perform() wait_for_condition_else_raise( marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def _flick_menu_down(self, locator): self.parent.parent.wait_for_element_displayed(*self._current_element(*locator), timeout=2) current_element = self.marionette.find_element(*self._current_element(*locator)) next_element = self.marionette.find_element(*self._next_element(*locator)) # TODO: update this with more accurate Actions action = Actions(self.marionette) action.press(current_element) action.move(next_element) action.release() action.perform()
def press_release(marionette, times, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) action = Actions(marionette) button = marionette.find_element(By.ID, "button1") action.press(button).release() # Insert wait between each press and release chain. for _ in range(times-1): action.wait(0.1) action.press(button).release() action.perform() wait_for_condition_else_raise(marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def move_element_offset(marionette, wait_for_condition, expected1, expected2): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) ele = marionette.find_element(By.ID, "button1") action = Actions(marionette) action.press(ele).move_by_offset(0, 150).move_by_offset(0, 150).release() action.perform() wait_for_condition_else_raise( marionette, wait_for_condition, expected1, "return document.getElementById('button1').innerHTML;") wait_for_condition_else_raise( marionette, wait_for_condition, expected2, "return document.getElementById('button2').innerHTML;")
def press_release(marionette, times, wait_for_condition, expected): testAction = marionette.absolute_url("testAction.html") marionette.navigate(testAction) action = Actions(marionette) button = marionette.find_element(By.ID, "button1") action.press(button).release() # Insert wait between each press and release chain. for _ in range(times - 1): action.wait(0.1) action.press(button).release() action.perform() wait_for_condition_else_raise( marionette, wait_for_condition, expected, "return document.getElementById('button1').innerHTML;")
def send_message(self, to_user, message, wait_load=0.5): # Make firefox go to the users page. self.client.navigate("https://www.messenger.com/t/{}".format(to_user)) # Give a little bit of time to load. time.sleep(wait_load) for letter in message: # Make the typing look realistic. keep_down = random.uniform(0.005, 0.010) wait_time = keep_down + random.uniform(0.02, 0.05) # Send off the action action = Actions(self.client) if letter != '\n': action.key_down(letter).wait(keep_down).key_up(letter) else: # Handle multi line messages. action.key_down(Keys.SHIFT).key_down(Keys.ENTER)\ .wait(keep_down).key_up(Keys.SHIFT).key_up(Keys.ENTER) action.perform() # wait for it to complete. time.sleep(wait_time) # Send message. action.key_down('\n').wait(keep_down).key_up('\n') action.perform()
def click(self): action = Actions(driver) action.click(self) action.perform()
def context_click(self): action = Actions(driver) action.context_click(self) action.perform()
def middle_click(self): action = Actions(driver) action.middle_click(self) action.perform()
def double_tap_image(self): image = self.marionette.find_element(*self._current_image_locator) action = Actions(self.marionette) action.double_tap(image) action.perform()
def cnet(client): global dl_dir_abs url = 'http://download.cnet.com/' elementExists = True try: client.navigate(url) except timeout as texp: log.info("ignoring timeout: %s" % str(texp)) pass element = client.find_element(By.ID, 'pop') elementList = element.find_elements(By.TAG_NAME, 'a') if (len(elementList) == 0): log.critical('no links found! cnet() function broken?') return Status.CRIT, None # remove blacklisted downloads # added self-link ("most-popular") to blacklist whiteList = [ i for i in elementList if not any(b in i.get_attribute('href') for b in blacklist_dls) ] log.info("dls: %s" % str([i.get_attribute('href') for i in whiteList])) # select at random element = choice(whiteList) nextUrl = element.get_attribute('href') # random delay sleep(randint(1, 5)) # open next page in dl process if nextUrl.startswith('/'): nextUrl = url + nextUrl try: client.navigate(nextUrl) except timeout as texp: log.info("ignoring timeout: %s" % str(texp)) pass # random delay sleep(randint(1, 5)) # click on donwload button element = client.find_element(By.CSS_SELECTOR, 'a.dln-a') finalUrl = None try: finalUrl = element.get_attribute('data-href') except errors.MarionetteException: log.warn('error on finalUrl.') return Status.NODL, None if finalUrl is None: log.warn('no finalUrl.') return Status.NODL, None action = Actions(client) action.click(element) assert (dl_dir_abs is not None) file_list = os.listdir(dl_dir_abs) log.info("files: %s" % str(file_list)) action.perform() # wait until dl finishes fn = wait_for_dl_to_finish(dl_dir_abs, file_list, nextUrl, client) # hash downloaded file log.info('-----------------------') if fn is not None: tordl_hash = sha256sum(fn) log.info("file %s downloaded successfully from %s, hash: %s" % (fn, finalUrl, sha256sum(fn))) else: return Status.NODL, None # dl same file over normal internet r = requests.get(finalUrl) soup = BeautifulSoup.BeautifulSoup(r.text) result = soup.find("meta", attrs={"http-equiv": "refresh"}) dl_url = None if result: wait, text = result["content"].split(";") sleep(int(wait)) dl_url = '='.join(text.split('=')[1:]).strip() if dl_url.startswith('/'): dl_url = url + dl_url else: dl_url = finalUrl log.info("file url %s" % dl_url) r = requests.get(dl_url) fo = open('test.exe', 'wb') fo.write(r.content) fo.close() # hash clearnet-downloaded file orig_hash = sha256sum('test.exe') if orig_hash == tordl_hash: return Status.IDENTICAL, fn else: return Status.NONIDENT, fn
class element(object): def __init__(self, parent): self.parent = parent self.marionette = parent.marionette self.actions = Actions(self.marionette) def getElement(self, elem, msg, is_displayed=True, timeout=5, stop_on_error=True): """ Returns an element, or False it it's not found """ x = self.getElements(elem, msg, is_displayed, timeout, stop_on_error) if x: # We're expecting ONE element back (it has different methods if it's one). return x[0] else: return False def getElements(self, elem, msg, is_displayed=True, timeout=5, stop_on_error=True): """ Returns a list of matching elements, or False if none are found """ boolEl = self.waitForElements(elem, msg, is_displayed, timeout, stop_on_error) if boolEl: el = self.marionette.find_elements(*elem) return el else: return False def headerCheck(self, value): """ Returns the header that matches a string. NOTE: ALL headers in this iframe return true for ".is_displayed()"! """ is_ok = False try: self.parent.parent.wait_for_element_present(*DOM.GLOBAL.app_head, timeout=1) headerNames = self.marionette.find_elements(*DOM.GLOBAL.app_head) for i in headerNames: if i.text == value: if i.is_displayed(): is_ok = True break except: is_ok = False self.parent.test.test(is_ok, "Header is \"" + value + "\".") return is_ok def move_scroller(self, scroller, forward=True): """Move the scroller one item forward or backwards. """ x_pos = scroller.size['width'] / 2 y_start = scroller.size['height'] / 2 y_end = -scroller.size['height'] if forward else scroller.size['height'] self.actions.flick(scroller, x_pos, y_start, x_pos, y_end, 100) self.actions.perform() def set_scroller_val(self, scroller_elem, number): """ Set the numeric value of a scroller (only works with numbers right now). """ current_value = int(scroller_elem.find_element(*DOM.GLOBAL.scroller_curr_val).text) # Now flick the scroller as many times as required n = int(number) while n != current_value: # Do we need to go forwards or backwards? if n > int(current_value): self.move_scroller(scroller_elem, True) if n < int(current_value): self.move_scroller(scroller_elem, False) # Get the new 'current_value'. current_value = int(scroller_elem.find_element(*DOM.GLOBAL.scroller_curr_val).text) # From gaiatest Clock -> regions -> alarm.py def _flick_menu_up(self, locator): self.parent.parent.wait_for_element_displayed(*self._current_element(*locator), timeout=2) current_element = self.marionette.find_element(*self._current_element(*locator)) next_element = self.marionette.find_element(*self._next_element(*locator)) # TODO: update this with more accurate Actions action = Actions(self.marionette) action.press(next_element) action.move(current_element) action.release() action.perform() def _flick_menu_down(self, locator): self.parent.parent.wait_for_element_displayed(*self._current_element(*locator), timeout=2) current_element = self.marionette.find_element(*self._current_element(*locator)) next_element = self.marionette.find_element(*self._next_element(*locator)) # TODO: update this with more accurate Actions action = Actions(self.marionette) action.press(current_element) action.move(next_element) action.release() action.perform() def _current_element(self, method, target): self.parent.reporting.debug("*** Finding current element for target {}".format(target)) return (method, '{}.picker-unit.selected'.format(target)) def _next_element(self, method, target): self.parent.reporting.debug("*** Finding next element for target {}".format(target)) return (method, '{}.picker-unit.selected + div'.format(target)) def simulateClick(self, element): self.marionette.execute_script(""" /** * Helper method to simulate clicks on iFrames which is not currently * working in the Marionette JS Runner. * @param {Marionette.Element} element The element to simulate the click on. **/ var event = new MouseEvent('click', { 'view': window, 'bubbles': true, 'cancelable': true }); arguments[0].dispatchEvent(event); """, script_args=[element]) def simulateClickAtPos(self, element, posX, posY): self.parent.reporting.logResult('info', 'Simulating click....') self.marionette.execute_script(""" /** * Helper method to simulate clicks on iFrames which is not currently * working in the Marionette JS Runner. * @param {Marionette.Element} element The element to simulate the click on. **/ var event = document.createEvent('MouseEvents'); event.initMouseEvent( 'click', true, true, window, 0, 0, 0, arguments[1], arguments[2], false, false, false, false, 0, null ); arguments[0].dispatchEvent(event); """, script_args=[element, posX, posY]) def waitForElements(self, elem, msg, is_displayed=True, timeout=5, stop_on_error=True): """ Waits for an element to be displayed and captures the error if not """ is_ok = True msg = u"" + msg try: if is_displayed: msg = u"{} displayed within {} seconds.|{}".format(msg, timeout, elem) self.parent.parent.wait_for_element_displayed(*elem, timeout=timeout) else: msg = u"{} present within {} seconds.|{}".format(msg, timeout, elem) self.parent.parent.wait_for_element_present(*elem, timeout=timeout) except Exception: is_ok = False self.parent.test.test(is_ok, msg, stop_on_error) return is_ok def waitForNotElements(self, elem, msg, is_displayed=True, timeout=5, stop_on_error=True): """ Waits for an element to be displayed and captures the error if not """ is_ok = True try: if is_displayed: msg = "{} no longer displayed within {} seconds.|{}".format(msg, timeout, elem) self.parent.parent.wait_for_element_not_displayed(*elem, timeout=timeout) else: msg = "{} no longer present within {} seconds.|{}".format(msg, timeout, elem) self.parent.parent.wait_for_element_not_present(*elem, timeout=timeout) except: is_ok = False self.parent.test.test(is_ok, msg, stop_on_error) return is_ok def getElementByXpath(self, path): """ Use this function when normal getElement did not work """ return self.marionette.execute_script(""" return document.evaluate(arguments[0], document, null, 9, null).singleNodeValue; """, script_args=[path]) def getParent(self, element): """ Gets the element's parent. Can be called recursively """ return self.marionette.execute_script(""" return arguments[0].parentNode; """, script_args=[element]) def getChildren(self, element): """ Gets the element's children """ return self.marionette.execute_script(""" return arguments[0].children; """, script_args=[element]) def find_nested(self, context, css_selector): return self.marionette.execute_script(""" return arguments[0].querySelector(arguments[1]) """, script_args=[context, css_selector]) def get_css_value(self, element, css_property): """ Gets the value of a certain css property. """ return self.marionette.execute_script(""" function getStyle (el, styleProp) { if (el.currentStyle) var y = x.currentStyle[styleProp]; else if (window.getComputedStyle) var y = document.defaultView.getComputedStyle(el,null) .getPropertyValue(styleProp); return y; } return getStyle(arguments[0], arguments[1]) """, script_args=[element, css_property]) def is_ellipsis_active(self, element): """ Checks whether a certain element is really ellipsed when its content overflows its width """ return self.marionette.execute_script(""" function isEllipsisActive(element) { return (element.offsetWidth < element.scrollWidth); } return isEllipsisActive(arguments[0]) """, script_args=[element]) def scroll_into_view(self, element): self.marionette.execute_script(""" arguments[0].scrollIntoView(); """, script_args=[element]) def perform_action_over_element(self, locator, action, position=None): script = """ var _locatorMap = { "id": document.getElementById, "class name": document.getElementsByClassName, "css selector": document.querySelector, "xpath": function () { return document.evaluate(arguments[0], document, null, 9, null).singleNodeValue }, "tag name": document.getElementsByTagName }; // TODO - Add more events here var _actionMap = { "click": new MouseEvent('click', { 'view': window, 'bubbles': true, 'cancelable': true }), //HTMLElement.prototype.click } var location_method = arguments[0][0]; var locator = arguments[0][1]; var action = arguments[1]; var position = arguments[2]; if (position) { var element = _locatorMap[location_method].call(document, locator)[position]; } else { if ((locator === "class name") || (locator === "tag name")) { var e = 'JavaScriptException: InvalidParametersException: ' var msg = 'If using "class name" or "tag name", it is mandatory to specify a position' throw e + msg } var element = _locatorMap[location_method].call(document, locator); } if (element) { if (_actionMap.hasOwnProperty(action)) { element.dispatchEvent(_actionMap[action]) } else { var e = 'JavaScriptException: InvalidParametersException: ' var msg = 'Specified action <' + action + '> not supported'; throw e + msg } } """ self.marionette.execute_script(script, script_args=[list(locator), action, position])