def step_impl(context, choice, element=None, order=None): driver = context.driver util = context.util if choice == "an element": button = util.find_element((By.CSS_SELECTOR, ".__start_label._p_label")) elif order is not None: ix = { "first": 0, "second": 1, }[order] button = util.find_elements( (By.CSS_SELECTOR, ".body>._real .__start_label ._element_name"))[ix] elif element is not None: element = element.replace(":", ur"\:") button = util.find_element((By.CSS_SELECTOR, ".body .__start_label._" + element + "_label")) else: raise ValueError("unexpected choice: " + choice) context.clicked_element = button assert_true("_label_clicked" not in button.get_attribute("class").split()) ActionChains(driver)\ .click(button)\ .perform()
def step_impl(context, choice): driver = context.driver util = context.util class_name = None if choice == "a placeholder": class_name = "_placeholder" elif choice == "text": class_name = "title" else: raise ValueError("unknown choice: " + choice) ActionChains(driver)\ .click(util.find_element((By.CLASS_NAME, class_name))) \ .perform() # Because we use the keyboard, the caret is our reference caret = util.find_element((By.CLASS_NAME, "_wed_caret")) # Mock it. The caret could move or disappear. trigger = Trigger() trigger.location = caret.location trigger.size = caret.size trigger.size["width"] = 0 ActionChains(driver) \ .key_down(Keys.CONTROL) \ .send_keys("/") \ .key_up(Keys.CONTROL) \ .perform() context.context_menu_trigger = trigger
def context_choices_insert(context, exists, kind): util = context.util exists = True if exists == "contains" else False search_for = None if kind == "inserting new elements": search_for = "^Create new [^ ]+$" elif kind == "creating elements before the selected element": search_for = "^Create new .+? before" elif kind == "creating elements after the selected element": search_for = "^Create new .+? after" elif kind == "wrapping text in new elements": search_for = "^Wrap in " else: raise ValueError("can't search for choices of this kind: " + kind) if exists: count = len( util.find_descendants_by_text_re(".wed-context-menu", search_for)) assert_not_equal(count, 0, "there should be options") else: # We first need to make sure the menu is up because # find_descendants_by_text_re will return immediately. util.find_element((By.CLASS_NAME, "wed-context-menu")) count = len( util.find_descendants_by_text_re(".wed-context-menu", search_for, True)) assert_equal(count, 0, "there should not be options")
def context_choices_insert(context, exists, kind): util = context.util exists = True if exists == "contains" else False search_for = None if kind == "inserting new elements": search_for = "^Create new [^ ]+$" elif kind == "creating elements before the selected element": search_for = "^Create new .+? before" elif kind == "creating elements after the selected element": search_for = "^Create new .+? after" elif kind == "wrapping text in new elements": search_for = "^Wrap in " else: raise ValueError("can't search for choices of this kind: " + kind) if exists: count = len(util.find_descendants_by_text_re(".wed-context-menu", search_for)) assert_not_equal(count, 0, "there should be options") else: # We first need to make sure the menu is up because # find_descendants_by_text_re will return immediately. util.find_element((By.CLASS_NAME, "wed-context-menu")) count = len(util.find_descendants_by_text_re(".wed-context-menu", search_for, True)) assert_equal(count, 0, "there should not be options")
def step_impl(context): driver = context.driver util = context.util element, parent, _ = get_element_parent_and_parent_text( driver, ".__start_label._title_label") ActionChains(driver)\ .click(element)\ .perform() # On IE, sending the keys to the element itself does not work. send_to = element if driver.name != "internet explorer" else \ util.find_element((By.CSS_SELECTOR, ".wed-document")) util.send_keys(send_to, # From the label to before the first letter and then past # the first letter. [Keys.ARROW_RIGHT] * 3 + # This moves 9 caracters to the right with shift down. [Keys.SHIFT] + [Keys.ARROW_RIGHT] * 9 + [Keys.SHIFT]) assert_true(util.is_something_selected(), "something must be selected") context.selection_parent = parent
def step_impl(context): driver = context.driver util = context.util element = util.find_element((By.CSS_SELECTOR, ".title")) rect = driver.execute_script( """ var title = arguments[0]; var text = title.childNodes[1]; // At index 0 is the opening label. var range = title.ownerDocument.createRange(); range.setStart(text, 0); range.setEnd(text, 1); // Just returning does not work with IEDriver... // return range.getBoundingClientRect(); var rect = range.getBoundingClientRect(); var ret = {}; for (var x in rect) ret[x] = rect[x]; return ret; """, element) last_click = { "left": round(rect["left"]) + 2, "top": int(rect["top"] + rect["height"] / 2) } ActionChains(driver) \ .move_to_element_with_offset(context.origin_object, last_click["left"], last_click["top"]) \ .click() \ .perform() context.last_click = last_click
def step_impl(context): util = context.util driver = context.driver button = util.find_element( (By.CSS_SELECTOR, ".body .__start_label._p_label")) ActionChains(driver)\ .click(button)\ .send_keys([Keys.ARROW_RIGHT] * 6) \ .perform() context.caret_path = driver.execute_script(""" var caret = wed_editor.getDataCaret(); return [wed_editor.data_updater.nodeToPath(caret.node), caret.offset]; """) pos = wedutil.caret_selection_pos(driver) # First click away so that the caret is no longer where we left it # and the subsequent click moves it again. el_pos = util.element_screen_position(button) ActionChains(driver) \ .click(button) \ .move_to_element_with_offset(button, pos["left"] - el_pos["left"] + 1, pos["top"] - el_pos["top"]) \ .click() \ .perform()
def step_impl(context): driver = context.driver util = context.util element = util.find_element((By.CSS_SELECTOR, ".title")) rect = driver.execute_script(""" var title = arguments[0]; var text = title.childNodes[1]; // At index 0 is the opening label. var range = title.ownerDocument.createRange(); range.setStart(text, 0); range.setEnd(text, 1); // Just returning does not work with IEDriver... // return range.getBoundingClientRect(); var rect = range.getBoundingClientRect(); var ret = {}; for (var x in rect) ret[x] = rect[x]; return ret; """, element) last_click = {"left": round(rect["left"]) + 2, "top": int(rect["top"] + rect["height"] / 2)} ActionChains(driver) \ .move_to_element_with_offset(context.origin_object, last_click["left"], last_click["top"]) \ .click() \ .perform() context.last_click = last_click
def step_impl(context, what): driver = context.driver util = context.util parent = util.find_element((By.CSS_SELECTOR, ".title")) label = parent.find_element_by_css_selector(".__start_label._title_label") if label.is_displayed(): ActionChains(driver) \ .click(label) \ .perform() else: ActionChains(driver) \ .move_to_element_with_offset(parent, 1, 1) \ .click() \ .perform() # We need to find the text inside the title element text = util.get_text_excluding_children(parent) start_index = text.find(what) assert_true(start_index >= 0, "should have found the text") if start_index > 0: util.send_keys(parent, # Move the caret to the start of the selection # we want. [Keys.ARROW_RIGHT] * (start_index + 1 if label.is_displayed() else 0)) start = wedutil.caret_selection_pos(driver) util.send_keys(parent, # Move to the end of the selection we want. [Keys.ARROW_RIGHT] * len(what)) end = wedutil.caret_selection_pos(driver) # We don't want to be too close to the edge to handle a problem when # labels are. The problem is that when the labels are invisible they # have 0 width and it is possible at least that the caret could be # put over the invisible label. (That is, instead of the caret being # put after the invisible start label, it would be put before the # invisible start label.) When a user selects manually, the visual # feedback tends to prevent this. In testing, we achieve the same # through shifting the boundaries inwards a bit. # # Note that we've deemed it unnecessary to change the # caret/selection code of wed to prevent the caret from moving over # an invisible label. The fix would be rather complicated but # selecting text by mouse when labels are invisible is a bit dodgy # **at any rate**, and we're not going to work around this # dodginess. For now, at least. start["left"] += 5 end["left"] -= 5 select_text(context, start, end) assert_equal(util.get_selection_text(), what, "the selected text should be what we wanted to select") context.selection_parent = parent context.caret_screen_position = wedutil.caret_screen_pos(driver) context.element_to_test_for_text = parent
def step_impl(context): util = context.util driver = context.driver where = util.find_element((By.CSS_SELECTOR, "._attribute_value")) ActionChains(driver) \ .move_to_element(where) \ .click() \ .perform()
def context_menu_on_start_label_of_top_element(context): driver = context.driver util = context.util button = util.find_element((By.CSS_SELECTOR, ".__start_label ._element_name")) ActionChains(driver)\ .context_click(button)\ .perform()
def context_menu_on_start_label_of_top_element(context): driver = context.driver util = context.util button = util.find_element( (By.CSS_SELECTOR, ".__start_label ._element_name")) ActionChains(driver)\ .context_click(button)\ .perform()
def context_menu_on_start_label_of_top_element(context): driver = context.driver util = context.util button = util.find_element((By.CLASS_NAME, "_start_button")) ActionChains(driver)\ .context_click(button)\ .perform() context.context_menu_trigger = button
def on_placeholder(context): driver = context.driver util = context.util placeholder = util.find_element((By.CLASS_NAME, "_placeholder")) ActionChains(driver) \ .context_click(placeholder) \ .perform() context.context_menu_trigger = placeholder
def context_menu_on_end_label_of_element(context): driver = context.driver util = context.util button = util.find_element((By.CSS_SELECTOR, "._end_button._p_label")) ActionChains(driver)\ .context_click(button)\ .perform() context.context_menu_trigger = button
def step_impl(context): util = context.util menu = util.find_element((By.CLASS_NAME, "wed-context-menu")) # The click was in the middle of the trigger. trigger = context.context_menu_trigger target = trigger.location target["x"] += trigger.size["width"] / 2 target["y"] += trigger.size["height"] / 2 assert_equal(selenic.util.locations_within(menu.location, target, 10), '')
def context_menu_on_text(context): driver = context.driver util = context.util element = util.find_element((By.CLASS_NAME, "title")) ActionChains(driver)\ .move_to_element(element)\ .context_click()\ .perform() context.context_menu_trigger = element
def step_impl(context, choice): driver = context.driver util = context.util class_name = None if choice == "a placeholder": parent, where = driver.execute_script(""" var $ph = jQuery("._placeholder"); var $parent = $ph.closest("._real"); return [$parent[0], $ph[0]]; """) elif choice == "text": where = util.find_element((By.CLASS_NAME, "title")) parent = where else: raise ValueError("unknown choice: " + choice) max_tries = 5 while True: # IF YOU CHANGE THIS, CHANGE THE TRIGGER wedutil.click_until_caret_in(util, where) util.ctrl_equivalent_x("/") try: # We don't want to check too fast so we do use an explicit # wait by way of ``util``. util.find_element((By.CLASS_NAME, "wed-context-menu")) # If we get here, the menu exists. break except TimeoutException: # The menu did not come up. Probably something messed up # the caret between ``click_until_caret_in`` and # ``ctrl_equivalent_x``. Try again or decide that it just # won't happen. max_tries -= 1 if max_tries == 0: raise Exception("tried multiple times to bring up " "the contextual menu, but was " "unsuccessful") # THIS TRIGGER WORKS ONLY BECAUSE OF .click(where) above. context.context_menu_trigger = Trigger(util, where) context.context_menu_for = parent
def step_impl(context, what): util = context.util driver = context.driver selector = ".body>.div:nth-of-type(11)>.__start_label._div_label " + \ ("._attribute_value" if what == "" else "._element_name") where = util.find_element((By.CSS_SELECTOR, selector)) ActionChains(driver) \ .move_to_element(where) \ .click() \ .perform()
def step_impl(context, choice, element=None): driver = context.driver util = context.util if choice == "an element": button = util.find_element((By.CSS_SELECTOR, ".__start_label._p_label")) elif element is not None: element = element.replace(":", ur"\:") button = util.find_element((By.CSS_SELECTOR, ".body .__start_label._" + element + "_label")) else: raise ValueError("unexpected choice: " + choice) context.clicked_element = button assert_true("_label_clicked" not in button.get_attribute("class").split()) ActionChains(driver)\ .click(button)\ .perform()
def context_menu_on_text(context): driver = context.driver util = context.util element = util.find_element((By.CLASS_NAME, "title")) ActionChains(driver)\ .move_to_element(element)\ .context_click()\ .perform() context.context_menu_trigger = Trigger(util, element) context.context_menu_for = None
def step_impl(context): util = context.util menu = util.find_element((By.CLASS_NAME, "wed-context-menu")) # The click was in the middle of the trigger. trigger = context.context_menu_trigger target = trigger.location size = trigger.size # Read just once = 1 network roundtrip. target["left"] += size["width"] / 2 target["top"] += size["height"] / 2 assert_equal(selenic.util.locations_within( util.element_screen_position(menu), target, 10), '')
def step_impl(context): driver = context.driver util = context.util where = util.find_element((By.CLASS_NAME, "_placeholder")) ActionChains(driver)\ .click(where) \ .perform() context.context_menu_trigger = Trigger(util, where) context.context_menu_for = where
def step_impl(context): util = context.util menu = util.find_element((By.CLASS_NAME, "wed-context-menu")) # The click was in the middle of the trigger. trigger = context.context_menu_trigger target = trigger.location size = trigger.size # Read just once = 1 network roundtrip. target["left"] += size["width"] / 2 target["top"] += size["height"] / 2 assert_equal( selenic.util.locations_within(util.element_screen_position(menu), target, 10), '')
def user_clicks_outside_context_menu(context): driver = context.driver util = context.util title = util.find_element((By.CLASS_NAME, "title")) # This simulates a user whose hand is not completely steady. ActionChains(driver)\ .move_to_element(title)\ .move_by_offset(-10, 0)\ .click_and_hold()\ .move_by_offset(-1, 0)\ .release()\ .perform()
def on_placeholder(context): driver = context.driver util = context.util placeholder = util.find_element((By.CLASS_NAME, "_placeholder")) assert_true(util.visible_to_user(placeholder), "must be visible to the user; otherwise this step " "is not something the user can do") ActionChains(driver) \ .context_click(placeholder) \ .perform() context.context_menu_trigger = Trigger(util, placeholder) context.context_menu_for = placeholder
def step_impl(context, what): driver = context.driver util = context.util parent = util.find_element((By.CSS_SELECTOR, ".title")) label = parent.find_element_by_css_selector(".__start_label._title_label") if label.is_displayed(): ActionChains(driver) \ .click(label) \ .perform() else: ActionChains(driver) \ .move_to_element_with_offset(parent, 1, 1) \ .click() \ .perform() # We need to find the text inside the title element text = util.get_text_excluding_children(parent) start_index = text.find(what) assert_true(start_index >= 0, "should have found the text") if start_index > 0: util.send_keys( parent, # Move the caret to the start of the selection # we want. [Keys.ARROW_RIGHT] * (start_index + 1 if label.is_displayed() else 0)) start = wedutil.caret_selection_pos(driver) # On FF there's an off-by 1 issue in the CSS rendering which causes # a problem unless we perform this adjustment. start["left"] += 1 util.send_keys( parent, # Move to the end of the selection we want. [Keys.ARROW_RIGHT] * len(what)) end = wedutil.caret_selection_pos(driver) # On FF there's an off-by 1 issue in the CSS rendering which causes # a problem unless we perform this adjustment. end["left"] -= 1 select_text(context, start, end) assert_equal(util.get_selection_text(), what, "the selected text should be what we wanted to select") context.selection_parent = parent context.caret_screen_position = wedutil.caret_screen_pos(driver) context.element_to_test_for_text = parent
def on_placeholder(context): driver = context.driver util = context.util placeholder = util.find_element((By.CLASS_NAME, "_placeholder")) assert_true( util.visible_to_user(placeholder), "must be visible to the user; otherwise this step " "is not something the user can do") ActionChains(driver) \ .context_click(placeholder) \ .perform() context.context_menu_trigger = Trigger(util, placeholder) context.context_menu_for = placeholder
def step_impl(context): driver = context.driver util = context.util element = util.find_element((By.CSS_SELECTOR, ".__start_label._title_label")) ActionChains(driver)\ .click(element)\ .perform() # On IE, sending the keys to the element itself does not work. send_to = element if driver.name != "internet explorer" else \ util.find_element((By.CSS_SELECTOR, ".wed-document")) util.send_keys(send_to, # From the label to before the first letter and then past # the first letter. [Keys.ARROW_RIGHT] * 3 + # This moves 9 caracters to the right with shift down. [Keys.SHIFT] + [Keys.ARROW_RIGHT] * 9 + [Keys.SHIFT]) assert_true(util.is_something_selected(), "something must be selected")
def context_choices_insert(context, kind): util = context.util cm = util.find_element((By.CLASS_NAME, "wed-context-menu")) search_for = None if kind == "inserting new elements": search_for = "Create new " elif kind == "wrapping text in new elements": search_for = "Wrap in " else: raise ValueError("can't search for choices of this kind: " + kind) cm.find_element(By.PARTIAL_LINK_TEXT, search_for)
def step_impl(context, what): driver = context.driver util = context.util parent = util.find_element((By.CSS_SELECTOR, ".title")) label = parent.find_element_by_css_selector(".__start_label._title_label") if label.is_displayed(): ActionChains(driver) \ .click(label) \ .perform() else: ActionChains(driver) \ .move_to_element_with_offset(parent, 1, 1) \ .click() \ .perform() # We need to find the text inside the title element text = util.get_text_excluding_children(parent) start_index = text.find(what) assert_true(start_index >= 0, "should have found the text") if start_index > 0: util.send_keys(parent, # Move the caret to the start of the selection # we want. [Keys.ARROW_RIGHT] * (start_index + 1 if label.is_displayed() else 0)) start = wedutil.caret_selection_pos(driver) # On FF there's an off-by 1 issue in the CSS rendering which causes # a problem unless we perform this adjustment. start["left"] += 1 util.send_keys(parent, # Move to the end of the selection we want. [Keys.ARROW_RIGHT] * len(what)) end = wedutil.caret_selection_pos(driver) # On FF there's an off-by 1 issue in the CSS rendering which causes # a problem unless we perform this adjustment. end["left"] -= 1 select_text(context, start, end) assert_equal(util.get_selection_text(), what, "the selected text should be what we wanted to select") context.selection_parent = parent context.caret_screen_position = wedutil.caret_screen_pos(driver) context.element_to_test_for_text = parent
def step_impl(context): util = context.util driver = context.driver button = util.find_element( (By.CSS_SELECTOR, ".body ._readonly .__start_label")) ActionChains(driver)\ .click(button)\ .send_keys([Keys.ARROW_RIGHT]) \ .perform() text = driver.execute_script(""" var caret = wed_editor.caretManager.getDataCaret(); return caret.node.textContent; """) assert_equal(text, "x")
def step_impl(context): util = context.util # Yep, we must use the dropdown-menu for this. menu = util.find_element( (By.CSS_SELECTOR, ".wed-context-menu>.dropdown-menu")) assert_true(util.completely_visible_to_user(menu), "menu is completely visible") # This is a check that without the adjustment made to show the # whole menu, the menu would overflow outside the editing pane. (A # freakishly small menu would not overflow, for instance, and we # would not be testing what we think we are testing.) gui_root = wedutil.gui_root(util) assert_true( context.context_menu_trigger.location["left"] - util.element_screen_position(gui_root)["left"] + menu.size["width"] > gui_root.size["width"], "the menu would otherwise overflow")
def step_impl(context): util = context.util # Yep, we must use the dropdown-menu for this. menu = util.find_element((By.CSS_SELECTOR, ".wed-context-menu>.dropdown-menu")) assert_true(util.completely_visible_to_user(menu), "menu is completely visible") # This is a check that without the adjustment made to show the # whole menu, the menu would overflow outside the editing pane. (A # freakishly small menu would not overflow, for instance, and we # would not be testing what we think we are testing.) gui_root = wedutil.gui_root(util) assert_true(context.context_menu_trigger.location["left"] - util.element_screen_position(gui_root)["left"] + menu.size["width"] > gui_root.size["width"], "the menu would otherwise overflow")
def step_impl(context): driver = context.driver util = context.util context.window_scroll_top = util.window_scroll_top() context.window_scroll_left = util.window_scroll_left() wed = util.find_element((By.CLASS_NAME, "wed-scroller")) scroll_top = util.scroll_top(wed) # This location guarantees that we are hitting the scrollbar at the top # and should not move the editor's contents ActionChains(driver) \ .move_to_element_with_offset(wed, wed.size["width"] - 1, 1) \ .click() \ .perform() # Make sure we did nothing. assert_equal(scroll_top, util.scroll_top(wed))
def step_impl(context): driver = context.driver util = context.util p = util.find_element((By.CSS_SELECTOR, ".body .p")) text = wedutil.select_contents_directly(util, p) context.expected_selection_serialization = driver.execute_script(""" var data_node = wed_editor.toDataNode(arguments[0]); var range = document.createRange(); range.selectNodeContents(data_node); var clone = range.cloneContents(); var parser = new window.DOMParser(); var doc = parser.parseFromString("<div></div>", "text/xml"); while(clone.firstChild) doc.firstChild.appendChild(clone.firstChild); return doc.firstChild.innerHTML; """, p) context.expected_selection = text context.selection_parent = p context.caret_screen_position = wedutil.caret_screen_pos(driver)
def step_impl(context): util = context.util util.find_element((By.CLASS_NAME, "wed-context-menu"))
def context_menu_appears(context): util = context.util util.find_element((By.CLASS_NAME, "wed-context-menu"))