Download tests/test_focus_browser.py from wzender/mathly: direct link, hf CLI and curl.
- Browser
- Download file 5.53 kB
-
https://huggingface.co/spaces/wzender/mathly/resolve/main/tests/test_focus_browser.py
- Command line
-
hf download hf://spaces/wzender/mathly/tests/test_focus_browser.py
-
curl -L -o test_focus_browser.py https://huggingface.co/spaces/wzender/mathly/resolve/main/tests/test_focus_browser.py
5.53 kB
| """Focus practice end to end: the class teacher gives skills to one student from the report; only that student sees | |
| it, marked as personal, and the report counts only them.""" | |
| import socket | |
| import threading | |
| import time | |
| import pytest | |
| from app.main import create_app | |
| from test_assignments import MemoryAssignments | |
| from test_worksheets import MemoryWorksheets | |
| from test_worksheets_browser import NoAnswers, uvicorn | |
| playwright = pytest.importorskip("playwright.sync_api") | |
| TEACHER, DANA, YOSSI = ("bbbbbbbb-0000-4000-8000-00000000000%d" % i for i in (1, 2, 3)) | |
| mail = {TEACHER: "teacher@test.invalid", DANA: "dana@test.invalid", YOSSI: "yossi@test.invalid"} | |
| class SchoolAuth: | |
| url, key, secret = "https://test.invalid", "public-test", "server-test" | |
| teachers = developers = frozenset() | |
| def user(self, token): | |
| return {"id": token, "email": mail[token]} if token in mail else None | |
| def classes(self, fresh=False): | |
| return [{"id": 3, "name": "讟壮1", "lessons": ["t", "k"], "teachers": [mail[TEACHER]], | |
| "emails": list(mail.values()), "nicknames": {}, "exams": []}] | |
| def access_for(self, _id, **kwargs): | |
| return None | |
| def user_accounts(self, emails): | |
| return {email: {"id": uid, "name": ""} for uid, email in mail.items() if email in emails} | |
| def _admin(self, path, method="GET", body=None, prefer=""): | |
| from app.auth import AuthUnavailable | |
| if path.startswith("/rest/v1/math_progress"): | |
| return [] | |
| raise AuthUnavailable("supabase answered 404: no other tables here") | |
| def session(browser, uid): | |
| ctx = browser.new_context(viewport={"width": 390, "height": 844}, is_mobile=True, has_touch=True) | |
| ctx.route("https://cdn.jsdelivr.net/**", lambda route: route.abort()) | |
| ctx.add_init_script('''window.supabase={createClient:()=>({auth:{ | |
| getSession:async()=>({data:{session:{access_token:"%s",user:{id:"%s"}}}}), | |
| onAuthStateChange:()=>({data:{subscription:{unsubscribe(){}}}}),signOut:async()=>{} | |
| }})};''' % (uid, uid)) | |
| page = ctx.new_page() | |
| errors = [] | |
| page.on("pageerror", lambda e: errors.append(str(e))) | |
| return page, errors | |
| def school(): | |
| app = create_app(auth=SchoolAuth()) | |
| app.state.assignments, app.state.worksheets, app.state.answers = MemoryAssignments(), MemoryWorksheets(), NoAnswers() | |
| with socket.socket() as sock: | |
| sock.bind(("127.0.0.1", 0)) | |
| server = uvicorn().Server(uvicorn().Config(app, log_level="error")) | |
| thread = threading.Thread(target=server.run, kwargs={"sockets": [sock]}, daemon=True) | |
| thread.start() | |
| try: | |
| while not server.started: | |
| time.sleep(.01) | |
| yield f"http://127.0.0.1:{sock.getsockname()[1]}", app | |
| finally: | |
| server.should_exit = True | |
| thread.join(timeout=5) | |
| def test_the_teacher_gives_focus_practice_to_one_student(school): | |
| url, app = school | |
| with playwright.sync_playwright() as p: | |
| browser = p.chromium.launch() | |
| try: | |
| teacher, t_errors = session(browser, TEACHER) | |
| teacher.goto(url) | |
| teacher.locator('[data-act="class-report"]').click() | |
| sheet = teacher.locator(".mx-report-sheet") | |
| sheet.locator("[data-report-tab=tasks]").click() | |
| sheet.locator("[data-asg-focus-new]").click() | |
| form = sheet.locator("[data-focus-form]") | |
| form.locator("button[type=submit]").click() | |
| playwright.expect(form.locator(".mx-row [role=status]")).to_have_text("讘讞专讜 诇驻讞讜转 转诇诪讬讚 讗讞讚.") | |
| form.locator('[name=student][value="dana@test.invalid"]').check() | |
| form.locator("details", has_text="讟讻谞讬拽讛 讗诇讙讘专讬转 1").locator("summary").click() | |
| form.locator('[name=skill][value="t_ext"]').check() | |
| form.locator("[name=title]").fill("讞讬讝讜拽 驻讬诇讜讙") | |
| form.locator("[name=due_on]").fill("2099-01-01") | |
| form.locator("button[type=submit]").click() | |
| card = sheet.locator(".mx-asg-t") | |
| playwright.expect(card).to_contain_text("讗讬砖讬") | |
| playwright.expect(card).to_contain_text("转专讙讜诇 诪诪讜拽讚 诇: dana") | |
| playwright.expect(card.locator(".mx-asg-count")).to_contain_text("0 诪转讜讱 1 转诇诪讬讚讬诐 住讬讬诪讜") # only Dana counts | |
| (row,) = app.state.assignments.rows.values() | |
| assert row["student_emails"] == ["dana@test.invalid"] and row["items"] == [{"kind": "skill", "id": "t_ext"}] | |
| dana, d_errors = session(browser, DANA) | |
| dana.goto(url) | |
| dana.locator('.mx-nav [data-view="home"]').click() | |
| asg = dana.locator(".mx-asgs .mx-asg") | |
| playwright.expect(asg).to_contain_text("讞讬讝讜拽 驻讬诇讜讙") | |
| playwright.expect(asg.locator(".mx-asg-personal")).to_have_text("馃幆 讗讬砖讬") | |
| yossi, y_errors = session(browser, YOSSI) | |
| with yossi.expect_response(lambda r: "/api/math/assignments" in r.url) as got: | |
| yossi.goto(url) | |
| assert got.value.json()["assignments"] == [] | |
| yossi.locator('.mx-nav [data-view="home"]').click() | |
| playwright.expect(yossi.locator(".mx-continue")).to_be_visible() | |
| playwright.expect(yossi.locator(".mx-asgs")).to_have_count(0) # not given to Yossi | |
| assert not (t_errors or d_errors or y_errors), (t_errors, d_errors, y_errors) | |
| finally: | |
| browser.close() | |