def click_login(self): if self.is_desktop: log_in = self.find_element(*self._desktop_log_in_link_locator) else: self.click_mobile_user_nav() log_in = self.find_element(*self._mobile_log_in_link_locator) Utilities.click_option(self.driver, element=log_in)
def test_modal_for_unsaved_notes_appears_on_clicking_another_highlight( selenium, base_url, book_slug, page_slug ): """Discard modal appears when unsaved notes are present & clicking another highlight.""" # GIVEN: Login book page book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() while book.notification_present: book.notification.got_it() book.navbar.click_login() name, email = Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # AND: Highlight 2 paragraphs paragraphs = random.sample(book.content.paragraphs, 2) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE) id_1 = list(set(book.content.highlight_ids))[0] book.content.highlight(target=paragraphs[1], offset=Highlight.ENTIRE, close_box=False) _ids = book.content.highlight_ids id_2 = _ids[0] if _ids[0] != id_1 else _ids[1] # AND: Add note to the 2nd highlight and do not save note = Utilities.random_string() book.content.highlight_box.note = note # WHEN: click the first highlight highlight = book.content.get_highlight(by_id=id_1) Utilities.click_option(driver=selenium, element=highlight[0], scroll_to=-150) # THEN: Discard modal is displayed assert book.discard_changes_modal_displayed assert book.discard_modal.content == "You have an unsaved note on this page." assert book.discard_modal.title == "Discard unsaved changes?" # AND: Clicking Cancel closes the modal and the unsaved note is retained in the page book.discard_modal.click_cancel_changes() assert book.content.highlight_box.is_open, "Highlight box not open" assert book.content.highlight_box.is_edit_box highlight = book.content.get_highlight(by_id=id_2)[0] assert "focus" in highlight.get_attribute("class"), "highlight is not in focus" assert book.content.highlight_box.note == note # WHEN: click the 1st highlight again highlight = book.content.get_highlight(by_id=id_1) Utilities.click_option(driver=selenium, element=highlight[0], scroll_to=-150) # AND: click Discard changes in the modal book.discard_modal.click_discard_changes() # THEN: Unsaved note is abandoned and the highlight box is opened for the 1st highlight assert book.content.highlight_box.is_open, "Highlight box not open" highlight = book.content.get_highlight(by_id=id_1)[0] assert "focus" in highlight.get_attribute("class"), "highlight is not in focus" assert book.content.highlight_box.note == ""
def click(self): """Click the filter checkbox. Toggles between selected and unchecked. """ checkbox = self.find_element(*self._checkbox_locator) Utilities.click_option(self.driver, element=checkbox)
def sign_up(self): """Click the sign up link.""" WebDriverWait(self.driver, 1).until( expect.visibility_of_element_located( self._signup_link_or_tab_locator)) signup_link = self.find_element(*self._signup_link_or_tab_locator) Utilities.click_option(self.driver, element=signup_link)
def toggle_menu(self) -> MyHighlights.Highlights.EditHighlight: """Toggle the highlight context menu open or close. :return: the edit highlight box :rtype: :py:class:`~MyHighlights.Highlights.EditHighlight` """ Utilities.click_option(self.driver, element=self.toggle) return self
def remove_tag(self) -> MyHighlights: """Click the remove filter 'x' button. :return: the My Highlights and Notes modal :rtype: :py:class:`~MyHighlights` """ Utilities.click_option(self.driver, element=self.remove_tag_icon) return self.page.page
def save(self) -> MyHighlights: """Click the save note button. :return: the My Highlights and Notes modal :rtype: :py:class:`~MyHighlights` """ Utilities.click_option(self.driver, element=self.save_button) return self.page
def close_search_sidebar(self): try: button = self.close_search_sidebar_button except NoSuchElementException: return Utilities.click_option(self.driver, element=button) self.wait.until( lambda _: not self.driver.execute_script( VISIBILITY, self.close_search_sidebar_button))
def select(self): """Select this answer for the current question. :return: None """ radio_button = self.find_element(*self._radio_button_locator) Utilities.click_option(self.driver, element=radio_button) sleep(0.2)
def close(self) -> Page: """Close the Practice modal. :return: the parent page :rtype: :py:class:`~pages.base.Page` """ Utilities.click_option(self.driver, element=self.close_x_button) return self.page
def select(self) -> Practice: """Select the section to practice. :return: the practice modal :rtype: :py:class:`~regions.practice.Practice` """ Utilities.click_option(self.driver, element=self.root) sleep(0.25) return self.page.page.page
def click_notification_got_it(self): """Click the 'Got it!' button. :return: the home page :rtype: :py:class:`~pages.web.home.WebHome` """ button = self.find_element(*self._got_it_button_locator) Utilities.click_option(self.driver, element=button) self.wait.until(lambda _: not self.notification_dialog_displayed)
def close(self) -> Page: """Click the close 'x' button. :return: the modal's parent page :rtype: :py:class:`~pypom.Page` """ Utilities.click_option(self.driver, element=self.close_icon) self.wait.until(expect.staleness_of(self.root)) return self.page
def toggle(self) -> Practice.Filters: """Toggle the chapter/section selector menu. :return: the practice selector menu :rtype: :py:class:`~regions.practice.Practice.Filters` """ Utilities.click_option(self.driver, element=self.root) sleep(0.1) return self.page
def select_none(self) -> MyHighlights: """Click the select None link to clear all filter options. :return: the My Highlights and Notes modal :rtype: :py:class:`~MyHighlights` """ link = self.find_element(*self._select_none_locator) Utilities.click_option(self.driver, element=link) return self.page
def toggle(self) -> Practice.Filters: """Toggle the chapter/section selector menu. :return: the practice selector menu :rtype: :py:class:`~regions.practice.Practice.Filters` """ button = self.find_element(*self._toggle_button_locator) Utilities.click_option(self.driver, element=button) sleep(0.1) return self
def log_in(self) -> Login: """Click the 'Log in' link. :return: the Accounts log in page :rtype: :py:class:`~pages.accounts.Login` """ Utilities.click_option(self.driver, element=self.log_in_link) page = Login(self.driver) page.wait_for_page_to_load() return page
def test_modal_for_unsaved_notes_appears_on_clicking_content_links( selenium, base_url, book_slug, page_slug ): """Discard modal appears when unsaved notes are present & clicking in-content link.""" # GIVEN: Login book page book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() while book.notification_present: book.notification.got_it() book.navbar.click_login() name, email = Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() # AND: Highlight a paragraph, add a note & do not save paragraphs = random.sample(book.content.paragraphs, 1) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, close_box=False) note = Utilities.random_string() book.content.highlight_box.note = note id_1 = book.content.highlight_ids[0] # WHEN: Click on a in-content link link = random.sample(book.content.links, 1) Utilities.click_option(selenium, element=link[0]) # THEN: Discard modal is displayed assert book.discard_changes_modal_displayed assert book.discard_modal.content == "You have an unsaved note on this page." assert book.discard_modal.title == "Discard unsaved changes?" # WHEN: Click Cancel on the modal book.discard_modal.click_cancel_changes() # THEN: The modal is closed and the unsaved note is retained on the page assert book.content.highlight_box.is_open, "Highlight box not open" assert book.content.highlight_box.is_edit_box highlight = book.content.get_highlight(by_id=id_1)[0] assert "focus" in highlight.get_attribute("class"), "highlight is not in focus" assert book.content.highlight_box.note == note # WHEN: Click the same link again Utilities.click_option(selenium, element=link[0]) # AND: click Discard changes in the modal book.discard_modal.click_discard_changes() book.wait_for_page_to_load() # THEN: The page scrolls to the clicked link assert book.element_in_viewport(link[0]) # AND: The unsaved note is not saved assert not selenium.execute_script(HAS_INDICATOR, highlight), "note is saved for the highlight"
def click_delete(self) -> MyHighlights.Highlights.EditHighlight: """Toggle the highlight delete menu option. :return: the note delete box :rtype: :py:class:`~MyHighlights.Highlights.EditHighlight` """ self.toggle_menu() Utilities.click_option(self.driver, element=self.delete_button) return self
def edit_note(self) -> MyHighlights.Highlights.EditHighlight: """Toggle the annotation edit menu option. :return: the note edit box :rtype: :py:class:`~MyHighlights.Highlights.EditHighlight` """ self.toggle_menu() Utilities.click_option(self.driver, element=self.edit_button) return self
def _click_helper(self, locator: Locator) -> Practice.Content: """Click a link or button. :param locator: a By-style element selector :type locator: tuple(str, str) :return: the practice content pane :rtype: :py:class:`~regions.practice.Practice.Content` """ button = self.find_element(*locator) Utilities.click_option(self.driver, element=button) return self
def back_to_top(self) -> MyHighlights: """Click the back to top arrow button. :return: the My Highlights and Notes modal scrolled to the top :rtype: :py:class:`~regions.my_highlights.MyHighlights` """ if self.back_to_top_available: button = self.find_element(*self._back_to_top_button_locator) Utilities.click_option(self.driver, element=button) sleep(0.33) return self
def confirm_email(self, email: RestMail): """Confirm the user's email address. :param email: the user's RestMail instance :type email: :py:class:`~utils.utility.RestMail` """ inbox = email.wait_for_mail() verification_pin = inbox[-1].pin pin_field = self.find_element(*self._pin_entry_input_locator) pin_field.send_keys(verification_pin) confirm_button = self.find_element(*self._confirm_button_locator) Utilities.click_option(self.driver, element=confirm_button)
def select_password(self, password: str): """Select and confirm the user's password. :param str password: the user's password """ password_field = self.find_element( *self._password_select_input_locator) password_field.send_keys(password) password_confirmation_field = self.find_element( *self._password_confirmation_input_locator) password_confirmation_field.send_keys(password) submit_button = self.find_element(*self._submit_button_locator) Utilities.click_option(self.driver, element=submit_button)
def select_role(self, email: str): """Select the user's role and enter their email address. :param str email: the user's email address """ if self._use_new_accounts_flow: as_a_student_button = self.find_element( *self._as_a_student_button_locator) Utilities.click_option(self.driver, element=as_a_student_button) return # old flow role_menu = Select(self.find_element(*self._user_select_role_locator)) role_menu.select_by_visible_text("Student") email_field = self.find_element(*self._email_signup_input_locator) email_field.send_keys(email) next_button = self.find_element(*self._next_button_locator) Utilities.click_option(self.driver, element=next_button)
def book_status_on_amazon(self): """Open the Book Order modal.""" try: print_locator = (self._print_copy_mobile_locator if self.is_mobile else self._print_copy_locator) individual_locator = (self._individual_copy_locator if self.is_mobile else self._order_a_personal_copy_locator) Utilities.click_option(self.driver, locator=print_locator) individual = self.find_elements(*individual_locator) if individual: Utilities.switch_to(self.driver, element=individual[0]) sleep(1) amazon_link = self.current_url self.driver.close() self.driver.switch_to.window(self.driver.window_handles[0]) return amazon_link except NoSuchElementException: return None
def toggle_color(self, color: Color) -> MyHighlights.Highlights.EditHighlight: """Toggle a highlight color. :param color: the color to toggle on or off :type color: :py:class:`~utils.utility.Color` :return: the edit highlight box :rtype: :py:class:`~MyHighlights.Highlights.EditHighlight` """ colors = { Color.PINK: self.pink, Color.GREEN: self.green, Color.BLUE: self.blue, Color.PURPLE: self.purple, Color.YELLOW: self.yellow, } Utilities.click_option(self.driver, element=colors[color]) return self
def read_section(self) -> Page: """Click the read section link. :return: the referenced book section page :rtype: :py:class:`~pages.base.Page` """ base_url = Utilities.parent_page().base_url book = self.driver.current_url.split("/")[4] link = self.find_element(*self._link_to_section_locator) page = link.get_attribute("href") if "/" in page: page = page.split("/")[-1] Utilities.click_option(self.driver, element=link) from pages.content import Content new_page = Content(driver=self.driver, base_url=base_url, book_slug=book, page_slug=page) new_page.wait_for_page_to_load() return new_page
def test_note_indicator_added_when_highlight_without_a_note_has_a_note_added( selenium, base_url, book_slug, page_slug): """Adding a note to a highlight also adds the indicator to the highlight. """ # GIVEN: a book page is displayed # AND: a user is logged in # AND: all content is visible # AND: some content is highlighted without a note book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() while book.notification_present: book.notification.got_it() book.navbar.click_login() name, email = Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() width, height = book.get_window_size() paragraph = random.choice(book.content.paragraphs) book.content.highlight(paragraph, Highlight.ENTIRE, Color.YELLOW) highlight_id = book.content.highlight_ids[0] highlight = book.content.get_highlight(by_id=highlight_id)[0] # WHEN: they click the highlight # AND: add a note # AND: click the 'Save' button Utilities.click_option(selenium, element=highlight, scroll_to=-130) book.content.highlight_box.note = Utilities.random_string() book.content.highlight_box.save() # THEN: the note indicator is present on the highlight assert(selenium.execute_script(HAS_INDICATOR, highlight)), \ "indicator not found after adding a note"
def close_dialogs(self): """Close OSWeb dialog and survey boxes. :return: None """ # Pulse Insights survey pi_close_button = self.find_elements(*self._pi_close_button_locator) if pi_close_button: Utilities.click_option(self.driver, element=pi_close_button[0]) # Sticky note alert or donation bar sticky_note_close_button = self.find_elements( *self._sticky_note_put_away_button_locator) if sticky_note_close_button: Utilities.click_option(self.driver, element=sticky_note_close_button[0]) # In-line call out modal for phone or full view call_out_put_away_button = [ button for button in self.find_elements( *self._call_out_put_away_button_locator) if self.driver.execute_script(HAS_HEIGHT, button) ] if call_out_put_away_button: Utilities.click_option(self.driver, element=call_out_put_away_button[0])