|
# retoor <retoor@molodetz.nl>
|
|
|
|
from tests.conftest import BASE_URL
|
|
|
|
KIND_PICKER = "select[data-quiz-kind-picker]"
|
|
DIALOG_MESSAGE = ".dialog-message"
|
|
DIALOG_CONFIRM = ".dialog-confirm"
|
|
DIALOG_CANCEL = ".dialog-cancel"
|
|
OPTION_FIELDS = "[data-quiz-kind-fields='options']"
|
|
FREE_TEXT_FIELDS = "[data-quiz-kind-fields='free_text']"
|
|
NUMERIC_FIELDS = "[data-quiz-kind-fields='numeric']"
|
|
BOOLEAN_FIELDS = "[data-quiz-kind-fields='true_false']"
|
|
PUBLISH_BUTTON = ".quiz-publish button:has-text('Publish quiz')"
|
|
|
|
|
|
def _draft(page, title):
|
|
page.goto(f"{BASE_URL}/quizzes/new", wait_until="domcontentloaded")
|
|
page.locator("form.quiz-form").wait_for(state="visible")
|
|
page.fill("input[name='title']", title)
|
|
page.fill("textarea[name='description']", "Built in the browser.")
|
|
page.click("form.quiz-form button[type='submit']")
|
|
page.wait_for_url("**/edit", wait_until="domcontentloaded")
|
|
return page.url.rsplit("/", 2)[-2]
|
|
|
|
|
|
def _add_choice(page, prompt="Which journal mode allows concurrent readers?"):
|
|
form = page.locator("form[data-quiz-question-form]")
|
|
form.wait_for(state="visible")
|
|
page.select_option(KIND_PICKER, "single_choice")
|
|
page.fill("form[data-quiz-question-form] textarea[name='prompt']", prompt)
|
|
page.fill("form[data-quiz-question-form] textarea[name='options']", "DELETE\nWAL")
|
|
page.fill("form[data-quiz-question-form] input[name='correct_indexes']", "1")
|
|
page.click("form[data-quiz-question-form] button[type='submit']")
|
|
page.locator(".quiz-question").first.wait_for(state="visible")
|
|
|
|
|
|
def test_the_builder_opens_after_creating_a_draft(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder opens quiz")
|
|
page.locator(".quiz-builder-page").wait_for(state="visible")
|
|
page.locator("form[data-quiz-question-form]").wait_for(state="visible")
|
|
|
|
|
|
def test_the_kind_picker_lists_all_eight_kinds(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder kinds quiz")
|
|
picker = page.locator(KIND_PICKER)
|
|
picker.wait_for(state="visible")
|
|
assert picker.locator("option").count() == 8
|
|
|
|
|
|
def test_the_kind_picker_swaps_the_visible_fields(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder field swap quiz")
|
|
page.locator(KIND_PICKER).wait_for(state="visible")
|
|
page.select_option(KIND_PICKER, "single_choice")
|
|
assert page.locator(OPTION_FIELDS).is_visible()
|
|
assert not page.locator(FREE_TEXT_FIELDS).is_visible()
|
|
page.select_option(KIND_PICKER, "free_text")
|
|
assert page.locator(FREE_TEXT_FIELDS).is_visible()
|
|
assert not page.locator(OPTION_FIELDS).is_visible()
|
|
page.select_option(KIND_PICKER, "numeric")
|
|
assert page.locator(NUMERIC_FIELDS).is_visible()
|
|
page.select_option(KIND_PICKER, "true_false")
|
|
assert page.locator(BOOLEAN_FIELDS).is_visible()
|
|
|
|
|
|
def test_adding_a_question_renders_it_in_the_list(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder add quiz")
|
|
_add_choice(page)
|
|
question = page.locator(".quiz-question").first
|
|
assert "Which journal mode" in question.inner_text()
|
|
assert "Single choice" in question.inner_text()
|
|
|
|
|
|
def test_the_preview_marks_the_correct_option(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder preview quiz")
|
|
_add_choice(page)
|
|
page.locator(".quiz-preview-correct").first.wait_for(state="visible")
|
|
assert page.locator(".quiz-preview-correct").first.inner_text().strip() == "WAL"
|
|
|
|
|
|
def test_the_checklist_blocks_publishing_an_empty_quiz(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder checklist quiz")
|
|
page.locator(".quiz-checklist").wait_for(state="visible")
|
|
assert page.locator(PUBLISH_BUTTON).is_disabled()
|
|
|
|
|
|
def test_the_checklist_clears_once_the_quiz_is_complete(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder ready quiz")
|
|
_add_choice(page)
|
|
page.locator(".quiz-publish-ready").wait_for(state="visible")
|
|
assert page.locator(PUBLISH_BUTTON).is_enabled()
|
|
|
|
|
|
def test_the_move_controls_reorder_the_questions(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder reorder quiz")
|
|
_add_choice(page, "First question")
|
|
_add_choice(page, "Second question")
|
|
before = page.locator(".quiz-question-prompt").first.inner_text()
|
|
page.locator("button[aria-label='Move question down']").first.click()
|
|
page.wait_for_url("**/edit", wait_until="domcontentloaded")
|
|
page.locator(".quiz-question").first.wait_for(state="visible")
|
|
after = page.locator(".quiz-question-prompt").first.inner_text()
|
|
assert after != before
|
|
|
|
|
|
def test_deleting_a_question_removes_it(alice):
|
|
page, _ = alice
|
|
_draft(page, "Builder delete quiz")
|
|
_add_choice(page, "Doomed question")
|
|
assert page.locator(".quiz-question").count() == 1
|
|
page.locator(".quiz-question-actions button:has-text('Delete')").first.click()
|
|
page.locator(DIALOG_CONFIRM).wait_for(state="visible")
|
|
page.locator(DIALOG_CONFIRM).click()
|
|
page.wait_for_url("**/edit", wait_until="domcontentloaded")
|
|
page.locator(".empty-state").wait_for(state="visible")
|
|
assert page.locator(".quiz-question").count() == 0
|
|
|
|
|
|
def test_publishing_asks_for_confirmation(alice):
|
|
page, _ = alice
|
|
slug = _draft(page, "Builder confirm quiz")
|
|
_add_choice(page)
|
|
page.locator(PUBLISH_BUTTON).click()
|
|
page.locator(DIALOG_MESSAGE).wait_for(state="visible")
|
|
assert "permanent" in page.locator(DIALOG_MESSAGE).inner_text().lower()
|
|
page.locator(DIALOG_CANCEL).click()
|
|
page.goto(f"{BASE_URL}/quizzes/{slug}/edit", wait_until="domcontentloaded")
|
|
page.locator(".quiz-publish").wait_for(state="visible")
|
|
assert page.locator(".quiz-banner-locked").count() == 0
|
|
|
|
|
|
def test_accepting_the_confirmation_publishes(alice):
|
|
page, _ = alice
|
|
slug = _draft(page, "Builder publish quiz")
|
|
_add_choice(page)
|
|
page.locator(PUBLISH_BUTTON).click()
|
|
page.locator(DIALOG_CONFIRM).wait_for(state="visible")
|
|
page.locator(DIALOG_CONFIRM).click()
|
|
page.wait_for_url(f"**/quizzes/{slug}", wait_until="domcontentloaded")
|
|
page.locator("h1.quiz-detail-title").wait_for(state="visible")
|
|
|
|
|
|
def test_the_builder_is_read_only_after_publishing(alice):
|
|
page, _ = alice
|
|
slug = _draft(page, "Builder frozen quiz")
|
|
_add_choice(page)
|
|
page.locator(PUBLISH_BUTTON).click()
|
|
page.locator(DIALOG_CONFIRM).wait_for(state="visible")
|
|
page.locator(DIALOG_CONFIRM).click()
|
|
page.wait_for_url(f"**/quizzes/{slug}", wait_until="domcontentloaded")
|
|
page.goto(f"{BASE_URL}/quizzes/{slug}/edit", wait_until="domcontentloaded")
|
|
page.locator(".quiz-banner-locked").wait_for(state="visible")
|
|
assert page.locator("form[data-quiz-question-form]").count() == 0
|
|
assert page.locator(PUBLISH_BUTTON).count() == 0
|
|
assert page.locator(".quiz-question-actions").count() == 0
|
|
|
|
|
|
def test_the_detail_page_hides_edit_after_publishing(alice):
|
|
page, _ = alice
|
|
slug = _draft(page, "Builder detail frozen quiz")
|
|
_add_choice(page)
|
|
page.locator(PUBLISH_BUTTON).click()
|
|
page.locator(DIALOG_CONFIRM).wait_for(state="visible")
|
|
page.locator(DIALOG_CONFIRM).click()
|
|
page.wait_for_url(f"**/quizzes/{slug}", wait_until="domcontentloaded")
|
|
page.locator(".quiz-detail-actions").wait_for(state="visible")
|
|
assert page.locator(".quiz-detail-actions a:has-text('Edit')").count() == 0
|