This will remove imports from __future__ that are no longer needed. https://docs.python.org/3.5/library/2to3.html#2to3fixer-future
102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
"""
|
|
Annotation Component Page.
|
|
"""
|
|
|
|
|
|
from bok_choy.page_object import PageObject
|
|
from selenium.webdriver import ActionChains
|
|
|
|
|
|
class AnnotationComponentPage(PageObject):
|
|
"""
|
|
View of annotation component page.
|
|
"""
|
|
|
|
url = None
|
|
active_problem = 0
|
|
|
|
def is_browser_on_page(self):
|
|
return self.q(css='.annotatable-title').present
|
|
|
|
@property
|
|
def component_name(self):
|
|
"""
|
|
Return the current problem name.
|
|
"""
|
|
return self.q(css='.annotatable-title').text[0]
|
|
|
|
def click_reply_annotation(self, problem):
|
|
"""
|
|
Mouse over on annotation selector and click on "Reply to Annotation".
|
|
"""
|
|
annotation_span_selector = '.annotatable-span[data-problem-id="{}"]'.format(problem)
|
|
self.mouse_hover(self.browser.find_element_by_css_selector(annotation_span_selector))
|
|
self.wait_for_element_visibility(annotation_span_selector, "Reply to Annotation link is visible")
|
|
|
|
annotation_reply_selector = '.annotatable-reply[data-problem-id="{}"]'.format(problem)
|
|
self.q(css=annotation_reply_selector).click()
|
|
|
|
self.active_problem = problem
|
|
|
|
def active_problem_selector(self, sub_selector):
|
|
"""
|
|
Return css selector for current active problem with sub_selector.
|
|
"""
|
|
return u'div[data-problem-id="{}"] {}'.format(
|
|
self.q(css='.vert-{}'.format(self.active_problem + 1)).map(
|
|
lambda el: el.get_attribute('data-id')).results[0],
|
|
sub_selector,
|
|
)
|
|
|
|
def mouse_hover(self, element):
|
|
"""
|
|
Mouse over on given element.
|
|
"""
|
|
mouse_hover_action = ActionChains(self.browser).move_to_element(element)
|
|
mouse_hover_action.perform()
|
|
|
|
def check_scroll_to_problem(self):
|
|
"""
|
|
Return visibility of active problem's input selector.
|
|
"""
|
|
annotation_input_selector = self.active_problem_selector('.annotation-input')
|
|
return self.q(css=annotation_input_selector).visible
|
|
|
|
def answer_problem(self):
|
|
"""
|
|
Submit correct answer for active problem.
|
|
"""
|
|
self.q(css=self.active_problem_selector('.comment')).fill('Test Response')
|
|
|
|
answer_css = self.active_problem_selector('.tag[data-id="{}"]'.format(self.active_problem))
|
|
# Selenium will first move the element into view then click on it.
|
|
self.q(css=answer_css).click()
|
|
# Wait for the click to take effect, which is after the class is applied.
|
|
self.wait_for(lambda: 'selected' in self.q(css=answer_css).attrs('class')[0], description='answer selected')
|
|
# Click the "Check" button.
|
|
self.q(css=self.active_problem_selector('.submit')).click()
|
|
# This will trigger a POST to problem_check so wait until the response is returned.
|
|
self.wait_for_ajax()
|
|
|
|
def check_feedback(self):
|
|
"""
|
|
Return visibility of active problem's feedback.
|
|
"""
|
|
self.wait_for_element_visibility(
|
|
self.active_problem_selector('.tag-status.correct'), "Correct is visible"
|
|
)
|
|
return self.q(css=self.active_problem_selector('.tag-status.correct')).visible
|
|
|
|
def click_return_to_annotation(self):
|
|
"""
|
|
Click on active problem's "Return to Annotation" link.
|
|
"""
|
|
self.q(css=self.active_problem_selector('.annotation-return')).click()
|
|
|
|
def check_scroll_to_annotation(self):
|
|
"""
|
|
Return visibility of active annotation component header.
|
|
"""
|
|
annotation_header_selector = '.annotation-header'
|
|
return self.q(css=annotation_header_selector).visible
|