예제 #1
0
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 == ""
예제 #2
0
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"
        )
예제 #3
0
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"
예제 #4
0
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"
예제 #5
0
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"
예제 #6
0
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"
예제 #7
0
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"
예제 #8
0
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
예제 #9
0
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"
예제 #10
0
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"
예제 #11
0
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
예제 #12
0
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
예제 #13
0
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"
예제 #14
0
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"
예제 #15
0
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"
예제 #16
0
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()
예제 #17
0
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)
예제 #18
0
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}"
예제 #19
0
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"
예제 #20
0
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"
예제 #21
0
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"
예제 #22
0
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
예제 #23
0
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)
예제 #24
0
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"
예제 #25
0
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"
예제 #26
0
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"
예제 #27
0
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"
예제 #28
0
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)})")
예제 #29
0
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"
예제 #30
0
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"