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 test_cookie_notice_accepted_in_osweb_not_displayed_in_rex( selenium, base_url, book_slug, page_slug ): # GIVEN: Open osweb book details page book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() book.navbar.click_login() Signup(selenium).register() osweb = WebBase(selenium, base_url, book_slug=book_slug).open() osweb.wait_for_load() # AND: Accept the cookie notice assert osweb.notification_dialog_displayed osweb.click_notification_got_it() # WHEN: Click the view online link in osweb book detail page osweb.fix_view_online_url(base_url) osweb.click_view_online() # THEN: The book page is opened in REX # AND: Discard any non-cookie notice from the page # AND: Cookie notice is not displayed rex = Content(selenium) try: assert(not rex.notification_present) except AssertionError: assert(rex.notification.title != "Privacy and cookies"), ( "cookie notice displayed" ) rex.notification.got_it() assert(not rex.notification_present), ( f"Additional {rex.notification.title} message present" )
def test_able_to_close_my_highlights_with_keyboard_navigation( selenium, base_url, book_slug, page_slug): """My Highlights and Notes summary shows all types of page content.""" # GIVEN: a book section is displayed # AND: a user is logged in # AND: all content is visible # AND: the My Highlights and Notes modal is open 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, password = Signup(selenium).register(True) book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() book.toolbar.my_highlights() # WHEN: they tab to the close 'x' and send the return key to it (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.RETURN).perform()) # THEN: the My Highlights and Notes modal is closed assert not book.my_highlights_open, "My Highlights and Notes modal is still open"
def test_change_color_from_MH_page(selenium, base_url, book_slug, page_slug): """Changing highlight color from MH page, updates the highlight in content page.""" # 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 2 set of texts in the page paragraph = random.sample(book.content.paragraphs, 2) note = Utilities.random_string() content_highlight_ids = book.content.highlight_ids data = [(paragraph[0], Color.GREEN, note), (paragraph[1], Color.YELLOW, note == "")] for paragraphs, colors, note in data: book.content.highlight(target=paragraphs, offset=Highlight.RANDOM, color=colors, note=note) content_highlight_ids = content_highlight_ids + list( set(book.content.highlight_ids) - set(content_highlight_ids) ) # WHEN: Change highlight color of the 2nd highlight from MH page my_highlights = book.toolbar.my_highlights() highlight = my_highlights.highlights.edit_highlight highlight_id_0 = highlight[0].mh_highlight_id highlight_id_1 = highlight[1].mh_highlight_id new_highlight_color = Color.PINK highlight[1].toggle_menu() highlight[1].toggle_color(new_highlight_color) highlight[1].toggle_menu() my_highlights.close() # Determine the current color of the highlights in the content page highlight_classes_0 = book.content.get_highlight(by_id=highlight_id_0)[0].get_attribute("class") highlight_0_color_after_MH_color_change = Color.from_html_class(highlight_classes_0) highlight_classes_1 = book.content.get_highlight(by_id=highlight_id_1)[0].get_attribute("class") highlight_1_color_after_MH_color_change = Color.from_html_class(highlight_classes_1) # THEN: The highlight color in the content page is changed correctly assert ( highlight_1_color_after_MH_color_change == new_highlight_color ), "the current highlight color does not match the new color" assert ( highlight_0_color_after_MH_color_change == data[0][1] if content_highlight_ids[0] == highlight_id_0 else data[1][1] ), "highlight color changed for different highlight"
def test_change_highlight_color_from_MH_page_context_menu_using_keyboard( selenium, base_url, book_slug, page_slug): """Change highlight color using keyboard navigation in MH page.""" # 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 some text in the page paragraph = random.sample(book.content.paragraphs, 1) note = Utilities.random_string() book.content.highlight(target=paragraph[0], offset=Highlight.RANDOM, color=Color.GREEN, note=note) # AND: Open MH page my_highlights = book.toolbar.my_highlights() highlights = my_highlights.highlights.edit_highlight highlight_id = highlights[0].mh_highlight_id # WHEN: Tab to the context menu and hit Return (ActionChains(selenium).send_keys(Keys.TAB * 7).send_keys( Keys.RETURN).perform()) # AND: Tab 4 times to select Purple color and hit Spacebar (ActionChains(selenium).send_keys(Keys.TAB * 4).send_keys( Keys.RETURN).send_keys(Keys.SPACE).perform()) # THEN: The highlight color in MH page is changed to purple assert highlights[0].highlight_color == "purple" # AND: The focus stays on purple color assert selenium.switch_to.active_element == highlights[0].purple # WHEN: Hit Esc twice to close the MH modal (ActionChains(selenium).send_keys(Keys.ESCAPE * 2).perform()) highlight_classes = book.content.get_highlight( by_id=highlight_id)[0].get_attribute("class") highlight_color_in_content_page_after_MH_color_change = Color.from_html_class( highlight_classes) # THEN: The highlight color in the content page is changed to purple assert (highlight_color_in_content_page_after_MH_color_change == Color. PURPLE), "the current highlight color does not match the new color"
def test_keyboard_navigation_for_my_highlights_button_on_content_page( selenium, base_url, book_slug, page_slug): """Use keyboard navigation to open and close My Highlights and Notes.""" # GIVEN: a book page is displayed # AND: a user is logged in # AND: all content is visible 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() # WHEN: they select the search bar, tab twice and hit the return key (ActionChains(selenium).click(book.toolbar.search_textbox).send_keys( Keys.TAB * 2).send_keys(Keys.RETURN).perform()) # THEN: the My Highlights and Notes modal is displayed assert(book.my_highlights_open), \ "My Highlights modal not open" assert(book.my_highlights.root.is_displayed()), \ "My Highlights modal not displayed" # WHEN: they tab and hit the return key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.RETURN).perform()) # THEN: the My Highlights and Notes modal is closed assert(not book.my_highlights_open), \ "My Highlights modal is still open" # WHEN: they select the search bar, tab twice and hit the enter key (ActionChains(selenium).click(book.toolbar.search_textbox).send_keys( Keys.TAB * 2).send_keys(Keys.ENTER).perform()) # THEN: the My Highlights and Notes modal is displayed assert(book.my_highlights_open), \ "My Highlights modal not open" assert(book.my_highlights.root.is_displayed()), \ "My Highlights modal not displayed" # WHEN: they hit the escape key (ActionChains(selenium).send_keys(Keys.ESCAPE).perform()) # THEN: the My Highlights and Notes modal is closed assert(not book.my_highlights_open), \ "My Highlights modal is still open"
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 test_MH_empty_state_logged_in_user(selenium, base_url, book_slug, page_slug): """Logged in user empty state for MH page.""" # 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() # WHEN: Open MH page my_highlights = book.toolbar.my_highlights() filterbar = my_highlights.filter_bar # THEN: MH page Empty state message for logged in user is displayed assert (my_highlights.highlights.logged_in_user_empty_state_message == "You have no highlights in this book" ), "message not displayed or incorrect message" # AND: Empty state nudge is displayed in desktop if book.is_desktop: assert ( my_highlights.highlights.logged_in_user_empty_state_nudge == "Make a highlight and add a noteThen use this page to create your own study guide" ), "nudge not displayed or incorrect message" # AND: No empty state nudge is displayed in mobile else: assert my_highlights.highlights.logged_in_user_empty_state_nudge == "" # AND: All chapter dropdown options are disabled filterbar.toggle_chapter_dropdown_menu() for chapter in filterbar.chapter_filters.chapters: assert not chapter.has_highlights, ( f"Highlights present in chapter {chapter.number}," f"{chapter.title}") # AND: All color dropdown options are disabled filterbar.toggle_color_dropdown_menu() for color in filterbar.color_filters.colors: assert not color.is_checked, f"Highlights present for the color {color.color}," # AND: Print button is displayed assert filterbar.print.is_displayed
def test_select_chapter_with_highlights_and_select_color_not_used_in_that_chapter( selenium, base_url, book_slug, page_slug): """Select chapter with highlights and a color that is not used in that chapter in MH page filters dropdown.""" # NOQA # 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: Highlights are present in different chapter pages data = [ ("1-1-what-is-psychology", Color.GREEN), ("1-4-careers-in-psychology", Color.BLUE), ("2-introduction", Color.PINK), ] for page, color in data: book = Content(selenium, base_url, book_slug=book_slug, page_slug=page).open() Highlight.force_highlight(book=book, by=random.choice, group=book.content.paragraphs, offset=Highlight.ENTIRE, color=color) # WHEN: Update chapter dropdown to include only one highlighted # Chapter - ch 1 remains selected my_highlights = book.toolbar.my_highlights() filterbar = my_highlights.filter_bar filterbar.toggle_chapter_dropdown_menu() filterbar.chapter_filters.chapters[2].click() # AND: Select color not used in that chapter and unselect the remaining # colors - pink remains selected filterbar.toggle_color_dropdown_menu() filterbar.color_filters.colors[1].click() filterbar.color_filters.colors[2].click() filterbar.toggle_color_dropdown_menu() # THEN: No results message is displayed assert ( my_highlights.highlights.no_results_message == "No results.Try selecting different chapter or color filters to see different results." ), "message not displayed or incorrect message when both tags are removed"
def test_signup_as_a_new_user_via_the_highlight_nudge_overlay( selenium, base_url, book_slug, page_slug): """Signup as a new user using the highlight nudge overlay.""" # GIVEN: the Astronomy book section 1.0 introduction is displayed # AND: some content is selected book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() while book.notification_present: book.notification.got_it() paragraph = random.choice(book.content.paragraphs) book.content.highlight(target=paragraph, offset=Highlight.RANDOM, color=None) initial_page_url = selenium.current_url # WHEN: they click the "Log in" button on the highlight nudge book.content.highlight_box.log_in() # THEN: the Accounts screen is displayed assert("accounts" in selenium.current_url), "not viewing the Accounts page" assert("Log in to your OpenStax account" in selenium.page_source), \ "Accounts header not found" # WHEN: they sign up for an account Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # THEN: the same book page as the log in nudge is displayed # AND: the user is logged in assert(selenium.current_url == initial_page_url), \ "not returned to the correct book section page after account sign up" assert(book.navbar.user_is_logged_in), "user not logged in" # WHEN: they select some content paragraph = random.choice(book.content.paragraphs) book.content.highlight(target=paragraph, offset=Highlight.RANDOM, color=None) # THEN: the create note box is displayed try: book.content.highlight_box except NoSuchElementException: pytest.fail("the create note box is not open") assert(not book.content.highlight_box.login_overlay_present), \ "log in nudge overlay found"
def test_keyboard_navigation_MH_empty_state_logged_in_user( selenium, base_url, book_slug, page_slug): """Keyboard navigation for logged in user empty state MH page.""" # 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() # WHEN: Open MH page my_highlights = book.toolbar.my_highlights() filterbar = my_highlights.filter_bar # AND: Hit Tab (ActionChains(selenium).send_keys(Keys.TAB).perform()) # THEN: Close icon is focussed assert selenium.switch_to.active_element == my_highlights.close_icon # WHEN: Hit Tab (ActionChains(selenium).send_keys(Keys.TAB).perform()) # THEN: Chapter dropdown is focussed assert selenium.switch_to.active_element == filterbar.chapter_dropdown assert filterbar.chapter_dropdown.get_attribute( "aria-label") == "Filter highlights by Chapter" # WHEN: Hit Tab (ActionChains(selenium).send_keys(Keys.TAB).perform()) # THEN: Color dropdown is focussed assert selenium.switch_to.active_element == filterbar.color_dropdown assert filterbar.color_dropdown.get_attribute( "aria-label") == "Filter highlights by Color" # WHEN: Hit Tab (ActionChains(selenium).send_keys(Keys.TAB).perform()) # THEN: Print icon is focussed assert selenium.switch_to.active_element == filterbar.print
def test_keyboard_navigation_for_MH_filter_tags(selenium, base_url, book_slug, page_slug): """Keyboard navigation for the MH filter tags.""" # 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 1 paragraph Highlight.force_highlight(book=book, by=random.choice, group=book.content.paragraphs, offset=Highlight.ENTIRE, color=Color.YELLOW) # AND: Open MH page my_highlights = book.toolbar.my_highlights() filterbar = my_highlights.filter_bar # WHEN: Hit tab to focus the first filter tag and hit the return key - remove chapter tag (ActionChains(selenium).send_keys(Keys.TAB * 5).send_keys( Keys.RETURN).perform()) # THEN: No results message is displayed assert ( my_highlights.highlights.no_results_message == "No results.Try selecting different chapter or color filters to see different results." ), "message not displayed or incorrect message when both tags are removed" # WHEN: Hit Tab (ActionChains(selenium).send_keys(Keys.TAB).perform()) # THEN: The 'x' button of color filter tag is focussed assert selenium.switch_to.active_element == filterbar.active_filter_tags[ 0].remove_tag_icon
def test_highlight_is_not_created_until_a_color_is_selected( selenium, base_url, book_slug, page_slug): """A highlight is not created until the highlight color is selected.""" # GIVEN: the Astronomy book section 1.0 introduction is displayed # AND: a user is logged in # AND: all content is visible 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() Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() total_highlight_count = book.content.highlight_count # WHEN: they select some text content paragraph = random.choice(book.content.paragraphs) book.content.highlight(target=paragraph, offset=Highlight.RANDOM, color=None) new_highlight_count = book.content.highlight_count # THEN: the create note box is displayed # AND: the selected text is not a saved highlight try: book.content.highlight_box except NoSuchElementException: pytest.fail("the create note box is not open") assert(new_highlight_count == total_highlight_count), \ "a new highlight was found" total_highlight_count = book.content.highlight_count # WHEN: they select a highlight color book.content.highlight_box.toggle_color(Highlight.random_color()) new_highlight_count = book.content.highlight_count # THEN: the highlight is created assert(new_highlight_count > total_highlight_count), \ "the new highlight was not found"
def test_color_auto_selected_if_a_note_is_added( selenium, base_url, book_slug, page_slug): """The first highlight color is auto-selected if a note is typed.""" # GIVEN: the Astronomy book section 1.0 introduction is displayed # AND: a user is logged in # AND: all content is visible # AND: some content is selected 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() Signup(selenium).register() book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() paragraph = random.choice(book.content.paragraphs) book.content.highlight(target=paragraph, offset=Highlight.RANDOM, color=None) expected_color = Color.YELLOW # WHEN: they type a note in the create note box book.content.highlight_box.note = Utilities.random_string() highlight_ids = book.content.highlight_ids # THEN: the first hightlight color is automatically selected (yellow) # AND: the selected color in the color picker is checked assert(highlight_ids), "no highlights found" highlight_classes = (book.content .get_highlight(by_id=highlight_ids[0])[0] .get_attribute("class")) current_color = Color.from_html_class(highlight_classes) assert(current_color == expected_color), \ "the current highlight color does not match the default color" assert(book.content.highlight_box.is_checked(expected_color)), \ "highlight color yellow is not currently selected"
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 test_no_context_menu_in_mobile_MH_page(selenium, base_url, book_slug, page_slug): """Mobile MH page does not have context menu.""" # 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 some text in the page paragraph = random.sample(book.content.paragraphs, 1) book.content.highlight(target=paragraph[0], offset=Highlight.RANDOM) my_highlights = book.toolbar.my_highlights() highlight = my_highlights.highlights.edit_highlight assert not highlight[0].toggle_menu_visible()
def test_delete_note_using_keyboard_content_page(selenium, base_url, book_slug, page_slug): """Delete note using keyboard navigation.""" # 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 some text in the page with a note paragraphs = random.sample(book.content.paragraphs, 1) note_text = Utilities.random_string(length=15) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=Color.GREEN, note=note_text) highlight_with_note = book.content.highlight_ids[0] book.reload() # WHEN: Tab to the highlight and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Select Delete option from the context menu and hit Cancel (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB * 2).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB * 2).send_keys( Keys.ENTER).perform()) # THEN: The highlight/note is not deleted Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_with_note)[0], scroll_to=-130, ) assert (book.content.highlight_box.note == note_text ), "the highlight and note is deleted even on clicking Cancel" book.reload() # WHEN: Tab to the highlight and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Select Edit option from the context menu and hit Delete (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB * 2).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) # THEN: The highlight and note is deleted assert book.content.highlight_count == 0, ( "Highlight is not removed from content page: " f"found {book.content.highlight_count}, expected {0}") with pytest.raises(NoSuchElementException) as ex: book.content.highlight_box assert "No open highlight boxes found" in str(ex.value)
def test_change_highlight_color_using_keyboard_content_page( selenium, base_url, book_slug, page_slug): """Highlight color can be changed using keyboard navigation.""" # 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 some text in the page without a note paragraphs = random.sample(book.content.paragraphs, 1) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=Color.GREEN) highlight_no_note = book.content.highlight_ids[0] # AND: Navigate to next page and highlight some text with a note book.click_next_link() paragraphs = random.sample(book.content.paragraphs, 1) book.content.highlight( target=paragraphs[0], offset=Highlight.ENTIRE, color=Color.YELLOW, note=Utilities.random_string(), ) highlight_with_note = book.content.highlight_ids[0] book.reload() # WHEN: Tab to the highlight and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Change the highlight color in the active notecard using shift tab and spacebar keys (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.SHIFT + Keys.TAB + Keys.SHIFT).send_keys( Keys.SPACE).perform()) # AND: Navigate out of the highlight (ActionChains(selenium).send_keys("H").perform()) # THEN: The highlight color is changed highlight_classes_0 = book.content.get_highlight( by_id=highlight_with_note)[0].get_attribute("class") highlight_0_color_after_color_change = Color.from_html_class( highlight_classes_0) assert ( highlight_0_color_after_color_change == Color.PINK ), f"Highlight color in the page {selenium.current_url} is {highlight_0_color_after_color_change}" # WHEN: Navigate to the previous page, tab to the highlight without note and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Change the highlight color and navigate out of the highlight (ActionChains(selenium).send_keys(Keys.SHIFT + Keys.TAB + Keys.SHIFT).perform()) (ActionChains(selenium).send_keys(Keys.SPACE).perform()) (ActionChains(selenium).send_keys("H").send_keys(Keys.TAB).perform()) # THEN: The highlight color is changed highlight_classes_1 = book.content.get_highlight( by_id=highlight_no_note)[0].get_attribute("class") highlight_1_color_after_color_change = Color.from_html_class( highlight_classes_1) assert ( highlight_1_color_after_color_change == Color.PINK ), f"Highlight color in the page {selenium.current_url} is {highlight_1_color_after_color_change}"
def test_note_indicator_not_present_for_highlights_without_notes( selenium, base_url, book_slug, page_slug): """The note indicator is not present on highlights without notes. .. note:: The note indicator has been temporarily been replaced by off-color underlining (bottom border). """ # 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 # AND: some content is highlighted with 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() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width < DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) paragraphs = random.sample(book.content.paragraphs, 2) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=Highlight.random_color()) no_note = list(set(book.content.highlight_ids))[0] book.content.highlight(target=paragraphs[1], offset=Highlight.ENTIRE, color=Highlight.random_color(), note=Utilities.random_string()) _ids = book.content.highlight_ids with_note = _ids[0] if _ids[0] != no_note else _ids[1] if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) # WHEN: # THEN: the note indicator is not present on the highlight # AND: the note indicator is present on the highlight with a note no_note = book.content.get_highlight(by_id=no_note)[0] assert(not selenium.execute_script(HAS_INDICATOR, no_note)), \ "indicator found on a highlight without a note" with_note = book.content.get_highlight(by_id=with_note)[0] assert(selenium.execute_script(HAS_INDICATOR, with_note)), \ "indicator not found on a highlight with a note"
def test_clicking_on_the_note_indicator_opens_the_note_card( selenium, base_url, book_slug, page_slug): """Open the note card for various highlights with notes.""" # GIVEN: a book page is displayed # AND: a user is logged in # AND: all content is visible # AND: several types of content are highlighted with notes 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() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width < DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) highlight_options = [ (random.choice(book.content.figures_and_captions), Utilities.random_string()), (random.choice(book.content.lists), Utilities.random_string()), (random.choice(book.content.math), Utilities.random_string()), (random.choice(book.content.paragraphs), Utilities.random_string()), (random.choice(book.content.tables), Utilities.random_string()) ] highlight_list = {} for content, note in highlight_options: highlight_ids = book.content.highlight_ids book.content.highlight(target=content, offset=Highlight.ENTIRE, color=Highlight.random_color(), note=note) new_id = list(set(book.content.highlight_ids) - set(highlight_ids))[0] highlight_list[new_id] = note if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) for _id in book.content.highlight_ids: # WHEN: they select each highlight Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=_id)[0], scroll_to=-130) # THEN: the highlight card and note are displayed try: book.content.highlight_box except NoSuchElementException: pytest.fail("the highlight note card is not open") assert(book.content.highlight_box.note == highlight_list[_id]), \ "Displayed note does not match"
def test_modal_for_unsaved_notes_appears_on_page_navigation_using_toc( selenium, base_url, book_slug, page_slug ): """Discard modal appears when unsaved notes are present & clicking TOC link.""" # GIVEN: Login book page book = Content(selenium, base_url, book_slug=book_slug, page_slug=page_slug).open() toc = book.sidebar.toc 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 highlight_id = book.content.highlight_ids[0] # WHEN: Click on a TOC link book.offscreen_click(toc.sections[3].root) # 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=highlight_id)[0] assert "focus" in highlight.get_attribute("class"), "highlight is not in focus" assert book.content.highlight_box.note == note # WHEN: Click the TOC link again book.offscreen_click(toc.sections[3].root) # AND: click Discard changes in the modal book.click_and_wait_for_load(book.discard_modal.discard_button) # THEN: New page is loaded assert toc.sections[3].is_active # AND: No highlight box is open in the new page with pytest.raises(NoSuchElementException) as e: book.content.highlight_box assert "No open highlight boxes found" in str(e.value), "highlight box is open in the new page" # AND: No existing highlights present in the new page try: assert not book.content.highlights except NoSuchElementException: pytest.fail("existing highlight present in the page") # WHEN: Navigate back to the initial page book.click_and_wait_for_load(toc.sections[1].root) # THEN: The unsaved note in the initial page is not saved highlight = book.content.get_highlight(by_id=highlight_id)[0] assert not selenium.execute_script(HAS_INDICATOR, highlight), "note is saved for the highlight"
def test_add_note_from_MH_page(selenium, base_url, book_slug, page_slug): """Adding note from MH page, updates the highlight in content page.""" # 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 2 set of texts in the page paragraph = random.sample(book.content.paragraphs, 2) note = Utilities.random_string() content_highlight_ids = book.content.highlight_ids data = [(paragraph[0], Color.GREEN, note), (paragraph[1], Color.YELLOW, note == "")] for paragraphs, colors, note in data: book.content.highlight(target=paragraphs, offset=Highlight.RANDOM, color=colors, note=note) content_highlight_ids = content_highlight_ids + list( set(book.content.highlight_ids) - set(content_highlight_ids) ) my_highlights = book.toolbar.my_highlights() highlights = my_highlights.highlights.edit_highlight note_added = Utilities.random_string() for highlight in highlights: # WHEN: From MH page, add a note for the highlight that does not have a note if not highlight.note_present: highlight_id = highlight.mh_highlight_id highlight.add_note() (ActionChains(selenium).send_keys(note_added).perform()) highlight.save() my_highlights.close() # THEN: The corresponding highlight in the content page is updated with the note added in MH page Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_id)[0], scroll_to=-130, ) assert ( book.content.highlight_box.note == note_added ), "the note text does not match the note added or note added to incorrect highlight" highlight_id_1 = ( content_highlight_ids[0] if content_highlight_ids[0] != highlight_id else content_highlight_ids[1] ) Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_id_1)[0], scroll_to=-130, ) # AND: The highlight with note that was not updated in MH page is not affected assert ( book.content.highlight_box.note == data[0][2] ), "the note is added to incorrect highlight" break else: continue
def test_delete_highlight_from_MH_page(selenium, base_url, book_slug, page_slug): """Deleting highlight from MH page, removes the highlight in content page.""" # 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 2 set of texts in the page paragraph = random.sample(book.content.paragraphs, 2) note = Utilities.random_string(length=50) data = [(paragraph[0], Color.GREEN, note), (paragraph[1], Color.YELLOW, note == "")] for paragraphs, colors, note in data: book.content.highlight(target=paragraphs, offset=Highlight.RANDOM, color=colors, note=note) my_highlights = book.toolbar.my_highlights() highlights = my_highlights.highlights.edit_highlight # WHEN: Click delete option from the highlight's context menu highlights[0].click_delete() # THEN: Delete confirmation message is displayed assert ( highlights[0].confirm_delete_message == "Are you sure you want to delete this note and highlight?" if highlights[0].note_present else "Are you sure you want to delete this highlight?" ), ( "delete confirmation message is incorrect" f"message displayed: {highlights[0].confirm_delete_message}" ) # WHEN: Hit Cancel in the delete confirmation dialog highlights[0].cancel() # THEN: The highlight is not removed from MH page assert ( len(my_highlights.all_highlights) == 1 ), "Highlight is removed from MH page even on hitting Cancel in delete confirmation dialog" # WHEN: Click delete option from the highlight's context menu # AND: Hit save in the delete confirmation dialog highlights[0].delete() # THEN: The highlight is removed from the MH page assert ( len(my_highlights.all_highlights) == 0 ), "Highlight is not removed from MH page even on hitting Save in delete confirmation dialog" my_highlights.close() # AND: The highlight deleted in MH page is removed from the content page assert book.content.highlight_count == 0, ( "Highlight deleted in MH page is not removed from content page: " f"found {book.content.highlight_count}, expected {0}" ) with pytest.raises(NoSuchElementException) as ex: book.content.highlight_box assert "No open highlight boxes found" in str(ex.value)
def test_edit_note_from_MH_page_using_keyboard_navigation( selenium, base_url, book_slug, page_slug): """Edit note from MH page using keyboard navigation.""" # 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 some text in the page paragraph = random.sample(book.content.paragraphs, 1) note = Utilities.random_string() book.content.highlight(target=paragraph[0], offset=Highlight.RANDOM, note=note) # AND: Open MH page my_highlights = book.toolbar.my_highlights() highlight = my_highlights.highlights.edit_highlight highlight_id = highlight[0].mh_highlight_id note_append = Utilities.random_string() # WHEN: Open the context menu (ActionChains(selenium).send_keys(Keys.TAB * 7).send_keys( Keys.RETURN).perform()) # AND: Select Edit note (ActionChains(selenium).send_keys(Keys.TAB * 6).send_keys( Keys.RETURN).perform()) # AND: Update the note in the textbox and hit cancel (ActionChains(selenium).send_keys(note_append).send_keys( Keys.TAB * 2).send_keys(Keys.ENTER).perform()) # AND: Close the MH page (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) # THEN: The corresponding highlight in the content page is not updated with new note info Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_id)[0], scroll_to=-130) assert (book.content.highlight_box.note == note ), "the note is updated even on clicking Cancel in MH page" book.toolbar.my_highlights() # WHEN: Open the context menu (ActionChains(selenium).send_keys(Keys.TAB * 7).send_keys( Keys.RETURN).perform()) # AND: Select Edit note (ActionChains(selenium).send_keys(Keys.TAB * 6).send_keys( Keys.RETURN).perform()) # AND: Update the note in the textbox and hit save (ActionChains(selenium).send_keys(note_append).send_keys( Keys.TAB).send_keys(Keys.ENTER).perform()) # AND: Close the MH page (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) # THEN: The corresponding highlight in the content page is updated with the new note text Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_id)[0], scroll_to=-130) assert (book.content.highlight_box.note == note_append + note), "the note text does not match the note updated in MH page"
def test_edit_note_using_keyboard_content_page(selenium, base_url, book_slug, page_slug): """Edit note using keyboard navigation.""" # 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 some text in the page with a note paragraphs = random.sample(book.content.paragraphs, 1) note_text = Utilities.random_string(length=15) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=Color.GREEN, note=note_text) highlight_with_note = book.content.highlight_ids[0] note_append = Utilities.random_string(length=15) book.reload() # WHEN: Tab to the highlight and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Select Edit option from the context menu (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) # AND: Enter the note in the textbox and hit cancel ActionChains(selenium).send_keys(note_append).perform() ActionChains(selenium).send_keys(Keys.TAB * 2).send_keys( Keys.ENTER).perform() # THEN: The note in the content page is not updated Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_with_note)[0], scroll_to=-130, ) assert (book.content.highlight_box.note == note_text ), "the note is updated even on clicking Cancel" book.reload() # WHEN: Tab to the highlight and hit H key (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys("H").perform()) # AND: Select Edit option from the context menu (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) (ActionChains(selenium).send_keys(Keys.TAB).send_keys( Keys.ENTER).perform()) # AND: Enter the new note in the textbox and hit save (ActionChains(selenium).send_keys(note_append).send_keys( Keys.TAB).send_keys(Keys.ENTER).perform()) # THEN: The note in the content page is updated Utilities.click_option( driver=selenium, element=book.content.get_highlight(by_id=highlight_with_note)[0], scroll_to=-130, ) assert (book.content.highlight_box.note == note_append + note_text), "the note text does not match the updated text"
def test_toggle_MH_page_context_menu_using_keyboard(selenium, base_url, book_slug, page_slug): """Open/close context menu in MH page using keyboard.""" # 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 2 sets of text in the page paragraph = random.sample(book.content.paragraphs, 2) note = Utilities.random_string() data = [(paragraph[0], Color.GREEN, note), (paragraph[1], Color.YELLOW, note == "")] for paragraphs, colors, note in data: book.content.highlight(target=paragraphs, offset=Highlight.RANDOM, color=colors, note=note) # AND: Open MH page my_highlights = book.toolbar.my_highlights() highlights = my_highlights.highlights.edit_highlight # WHEN: Tab to the first context menu (present after the last breadcrumb) # AND: Hit Return (ActionChains(selenium).send_keys(Keys.TAB * 8).send_keys( Keys.RETURN).perform()) # THEN: Highlight edit box of the first highlight is open assert highlights[0].highlight_edit_box_open # AND: The focus is on the context menu of the first highlight assert selenium.switch_to.active_element == highlights[0].context_menu # WHEN: Hit Return (ActionChains(selenium).send_keys(Keys.RETURN).perform()) # THEN: The highlight edit box of the first highlight is closed assert not highlights[0].highlight_edit_box_open # AND: The focus is on the context menu of the same highlight assert selenium.switch_to.active_element == highlights[0].context_menu # WHEN: Hit tab once and Enter (ActionChains(selenium).send_keys(Keys.TAB * 1).send_keys( Keys.ENTER).perform()) # THEN: Highlight edit box of the second highlight is open assert highlights[1].highlight_edit_box_open # AND: The focus is on the context menu of the second highlight assert selenium.switch_to.active_element == highlights[1].context_menu # WHEN: Hit Escape (ActionChains(selenium).send_keys(Keys.ESCAPE).perform()) # THEN: The highlight edit box of the second highlight is closed assert not highlights[1].highlight_edit_box_open # AND: The focus is on the context menu of the same highlight assert selenium.switch_to.active_element == highlights[1].context_menu # WHEN: Hit Esc (ActionChains(selenium).send_keys(Keys.ESCAPE).perform()) # THEN: MH page is closed assert not book.my_highlights_open, "My Highlights and Notes modal is still open"
def test_display_highlights_for_returning_users( selenium, base_url, book_slug, page_slug): """Existing highlights are displayed for returning users.""" # GIVEN: a book section is displayed # AND: a user is logged in # AND: all content is visible # AND: some content is highlighted # AND: some content is highlighted with 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, password = Signup(selenium).register(True) book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width <= DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) paragraphs = random.sample(book.content.paragraphs, 2) first_highlight_color = Color.YELLOW book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=first_highlight_color) highlight_id_one = book.content.highlight_ids[0] second_highlight_color = Color.BLUE book.content.highlight(target=paragraphs[1], offset=Highlight.ENTIRE, color=second_highlight_color, note=Utilities.random_string()) highlight_ids = book.content.highlight_ids highlight_id_two = highlight_ids[1] \ if highlight_id_one == highlight_ids[0] \ else highlight_ids[0] if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) # WHEN: they log out book.navbar.click_user_name() book.navbar.click_logout() # THEN: the highlights and notes are no longer displayed assert(not book.content.highlight_count), \ "highlights found without a logged in user" # WHEN: they log in book.navbar.click_login() Login(selenium).login(email.address, password) book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() highlight_ids = book.content.highlight_ids # THEN: the highlights and notes are displayed assert(highlight_ids), "no highlights found after log in" assert(highlight_id_one in highlight_ids), "highlight not found" assert(highlight_id_two in highlight_ids), "highlight with note not found"
def test_my_highlights_summary_shows_all_types_of_content( selenium, base_url, book_slug, page_slug): """My Highlights and Notes summary shows all types of page content.""" # GIVEN: the Chemistry 2e book section 1.4 is displayed # AND: a user is logged in # AND: all content is visible # AND: a long text paragraph, an image, a figure description, a bulleted # or numbered list, a table, a footnote, a link, and a rendered math # equation are highlighted 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, password = Signup(selenium).register(True) logging.info(f'"{email.address}":"{password}"') book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width <= DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) Highlight.force_highlight(book=book, by=random.choice, group=book.content.paragraphs, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Paragraph") Highlight.force_highlight(book=book, by=random.choice, group=book.content.images, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Image") Highlight.force_highlight(book=book, by=random.choice, group=book.content.figures, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Figure") Highlight.force_highlight(book=book, by=random.choice, group=book.content.captions, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Caption") Highlight.force_highlight(book=book, by=random.choice, group=book.content.lists, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="List") Highlight.force_highlight(book=book, by=random.choice, group=book.content.tables, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Table") Highlight.force_highlight(book=book, by=random.choice, group=book.content.footnotes, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Footnote") Highlight.force_highlight(book=book, by=random.choice, group=book.content.links, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Link") Highlight.force_highlight(book=book, by=random.choice, group=book.content.math, offset=Highlight.ENTIRE, color=Highlight.random_color(), name="Math") highlight_ids = set(book.content.highlight_ids) if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) # WHEN: they click on the My highlights button my_highlights = book.toolbar.my_highlights() # THEN: the My Highlights and Notes modal is displayed # AND: all of the highlighted content is displayed in the summary page assert book.my_highlights_open, "My Highlights modal not open" assert my_highlights.root.is_displayed( ), "My Highlights modal not displayed" summary_highlights = len(my_highlights.all_highlights) assert summary_highlights == len(highlight_ids), ( "number of summary highlights different from page highlights " f"(found {summary_highlights}, expected {len(highlight_ids)})")
def test_lengthy_highlights_summary_page_has_a_floating_back_to_top_link( selenium, base_url, book_slug, page_slug): """My Highlights and Notes summary has a floating back to top button.""" # GIVEN: a book section is displayed # AND: a user is logged in # AND: all content is visible # AND: several sections are highlighted 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, password = Signup(selenium).register(True) logging.info(f'"{email.address}":"{password}"') book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width <= DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) for _ in range(10): Highlight.force_highlight(book=book, by=random.choice, group=book.content.paragraphs, offset=Highlight.ENTIRE, color=Highlight.random_color()) if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) # WHEN: they open the highlights summary modal # AND: the modal is scrolled down my_highlights = book.toolbar.my_highlights() initial_scroll_top = my_highlights.scroll_position within = max(initial_scroll_top * 0.01, 10.0) Utilities.scroll_to(selenium, element=my_highlights.all_highlights[-1].root) sleep(0.33) # THEN: a floating back to top button is displayed in the lower right # side of the modal assert my_highlights.scroll_position > initial_scroll_top, "modal not scrolled down" assert my_highlights.back_to_top_available, "back to top button not found" # WHEN: they click the back to top button my_highlights = my_highlights.back_to_top() # THEN: the modal is scrolled to the top # AND: the back to top button is not available return_position = my_highlights.scroll_position assert isclose(return_position, initial_scroll_top, rel_tol=within), ( r"return scroll position not within 1% of the initial scroll position " "({low} <= {target} <= {high})".format( low=initial_scroll_top - within, high=initial_scroll_top + within, target=return_position, )) assert not my_highlights.back_to_top_available, "back to top button still available"
def test_my_highlights_summary_shows_highlights_and_notes_on_current_page( selenium, base_url, book_slug, page_slug): """My Highlights and Notes summary shows page highlights and notes.""" # SETUP: ONE, TWO, THREE, FOUR = range(4) color = Highlight.random_color highlight_ids = [""] * 4 highlight_colors = [color(), color(), color(), color()] highlight_notes = [ "", Utilities.random_string(), "", Utilities.random_string() ] highlight_partial_text = [""] * 4 chapter_one = ("1", "Essential Ideas") sections = [("", "Introduction"), ("1.1", "Chemistry in Context")] # GIVEN: the Chemistry 2e book section 1.0 is displayed # AND: a user is logged in # AND: all content is visible # AND: some content is highlighted without a note # AND: some content is highlighted with a note # AND: some content is highlighted in section 1.1 without a note # AND: some content is highlighted in section 1.1 with 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, password = Signup(selenium).register(True) book.wait_for_page_to_load() while book.notification_present: book.notification.got_it() book.content.show_solutions() # making a highlight requires a non-mobile window width temporarily width, height = book.get_window_size() if width <= DESKTOP[0]: selenium.set_window_size(width=DESKTOP[0], height=height) paragraphs = random.sample(book.content.paragraphs, 2) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=highlight_colors[ONE]) highlight_ids[ONE] = book.content.highlight_ids[0] highlight_partial_text[ONE] = book.content.get_highlight( by_id=highlight_ids[ONE])[0].text book.content.highlight( target=paragraphs[1], offset=Highlight.ENTIRE, color=highlight_colors[TWO], note=highlight_notes[TWO], ) page_highlight_ids = book.content.highlight_ids highlight_ids[TWO] = (page_highlight_ids[1] if highlight_ids[ONE] == page_highlight_ids[0] else page_highlight_ids[0]) highlight_partial_text[TWO] = book.content.get_highlight( by_id=highlight_ids[TWO])[0].text book.click_next_link() paragraphs = random.sample(book.content.paragraphs, 2) book.content.highlight(target=paragraphs[0], offset=Highlight.ENTIRE, color=highlight_colors[THREE]) highlight_ids[THREE] = book.content.highlight_ids[0] highlight_partial_text[THREE] = book.content.get_highlight( by_id=highlight_ids[THREE])[0].text book.content.highlight( target=paragraphs[1], offset=Highlight.ENTIRE, color=highlight_colors[FOUR], note=highlight_notes[FOUR], ) page_highlight_ids = book.content.highlight_ids highlight_ids[FOUR] = (page_highlight_ids[1] if highlight_ids[THREE] == page_highlight_ids[0] else page_highlight_ids[0]) highlight_partial_text[FOUR] = book.content.get_highlight( by_id=highlight_ids[FOUR])[0].text if width != DESKTOP[0]: # reset the window width for a mobile test selenium.set_window_size(width=width, height=height) # WHEN: they click on the My highlights button my_highlights = book.toolbar.my_highlights() # THEN: the My Highlights and Notes modal is displayed # AND: sections without highlights are not included in the placeholders # AND: all highlights for the chapter are displayed # AND: each highlight color matches the corresponding page highlight color # AND: each note matches the corresponding page highlight note assert book.my_highlights_open, "My Highlights modal not open" assert my_highlights.root.is_displayed( ), "My Highlights modal not displayed" assert (len(my_highlights.highlights.chapters) == 1 ), "chapter heading not displayed in the highlights summary" highlight_chapter = ( my_highlights.highlights.chapters[0].number, my_highlights.highlights.chapters[0].title, ) assert highlight_chapter == chapter_one, "chapter number and title do not match in the summary" assert len(my_highlights.highlights.sections ) == 2, "did not find two section headings" highlight_sections = [(section.number, section.title) for section in my_highlights.highlights.sections] assert set(highlight_sections) == set( sections), "mismatched section numbers and/or names" current_summary_highlights = len(my_highlights.all_highlights) assert current_summary_highlights == len(highlight_ids), ( "unexpected number of highlights found on the summary page (" f"found {current_summary_highlights}, expected {len(highlight_ids)})") # ordering could be in sequence or reversed so check against both section # highlights for index, highlight in enumerate(my_highlights.all_highlights): option_1, option_2 = (ONE, TWO) if index <= TWO else (THREE, FOUR) assert (highlight.color == highlight_colors[option_1] or highlight.color == highlight_colors[option_2] ), f"highlight color for highlight {index + 1} does not match" content = highlight.content assert ( highlight_partial_text[option_1] in content or highlight_partial_text[option_2] in content ), f"partial note text not found in summary highlight {index + 1}" # currently the summary trims extra spaces and removes carriage returns note_1 = highlight_notes[option_1].replace("\n", " ").replace(" ", " ") note_2 = highlight_notes[option_2].replace("\n", " ").replace(" ", " ") assert (highlight.note == note_1 or highlight.note == note_2 ), f"highlight note {index + 1} does not match content note"