Something went wrong. Try again.
Paper Mario mod hosting site - AT Protocol appview starhaven.dev
appview
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178"""The Markdown editor that mod details, version notes, and bios are written in."""
import base64import re
from playwright.sync_api import expect
from helpers import PNG, Actor
LISTING_COLLECTION = "dev.starhaven.mod.listing"
def save_bio(actor: Actor) -> None: with actor.page.expect_navigation(): with actor.page.expect_response(lambda r: r.request.method == "PATCH") as resp: actor.page.get_by_role("button", name="Save").click() assert resp.value.ok
def test_a_bio_is_written_in_the_editor(actor: Actor): actor.login() actor.page.goto(f"{actor.app_url}/{actor.handle}") actor.page.locator("markdown-input .cm-content").click() actor.page.keyboard.type("I make **mods**") save_bio(actor) actor.page.context.clear_cookies()
actor.page.goto(f"{actor.app_url}/{actor.handle}") expect(actor.page.locator(".actor-bio strong")).to_have_text("mods")
def test_an_image_added_to_the_details_shows_on_the_mod(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/settings")
actor.page.locator("markdown-input input[type=file]").set_input_files( files=[{"name": "shot.png", "mimeType": "image/png", "buffer": PNG}] ) expect(actor.page.locator("#details")).to_have_value( re.compile(r"!\[\]\(baf[a-z0-9]+\)"), timeout=15000 ) actor.page.get_by_role("button", name="Save").click() expect(actor.page).to_have_url(f"{actor.app_url}/{actor.handle}/master-quest")
expect(actor.page.locator(".markdown img")).to_have_count(1) [listing] = actor.records(LISTING_COLLECTION) assert len(listing["value"]["detailsImages"]) == 1
def test_an_image_dropped_on_the_details_is_uploaded(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/settings")
content = actor.page.locator("markdown-input .cm-content").first content.evaluate( """(el, png) => { const bytes = Uint8Array.from(atob(png), (c) => c.charCodeAt(0)); const data = new DataTransfer(); data.items.add(new File([bytes], "dropped.png", { type: "image/png" })); const rect = el.getBoundingClientRect(); el.dispatchEvent(new DragEvent("drop", { bubbles: true, cancelable: true, dataTransfer: data, clientX: rect.left + 5, clientY: rect.top + 5, })); }""", base64.b64encode(PNG).decode(), ) expect(actor.page.locator("#details")).to_have_value( re.compile(r"!\[\]\(baf[a-z0-9]+\)"), timeout=15000 )
def test_the_toolbar_formats_the_details(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/settings")
actor.page.get_by_role("textbox", name="Details").click() actor.page.keyboard.type("Bosses") actor.page.keyboard.press("ControlOrMeta+a") actor.page.get_by_role("button", name="Bold").click() expect(actor.page.locator("#details")).to_have_value("**Bosses**") actor.page.get_by_role("button", name="Heading").click() expect(actor.page.locator("#details")).to_have_value("## **Bosses**")
def test_a_bio_has_only_bold_and_italics(actor: Actor): actor.login() actor.page.goto(f"{actor.app_url}/{actor.handle}")
toolbar = actor.page.get_by_role("toolbar", name="Formatting") expect(toolbar.get_by_role("button")).to_have_count(2) expect(toolbar.get_by_role("button", name="Bold")).to_be_visible() expect(toolbar.get_by_role("button", name="Italic")).to_be_visible()
def test_an_image_in_version_notes_shows_with_the_version(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/versions") actor.page.get_by_role("button", name="Upload a new version").click()
dialog = actor.page.locator("#version-dialog") dialog.locator("markdown-input input[type=file]").set_input_files( files=[{"name": "shot.png", "mimeType": "image/png", "buffer": PNG}] ) expect(actor.page.locator("#version-description")).to_have_value( re.compile(r"!\[\]\(baf[a-z0-9]+\)"), timeout=15000 ) actor.page.get_by_label("Version", exact=True).fill("v2") actor.page.get_by_label("Upload…").set_input_files( files=[{"name": "mod.bps", "mimeType": "application/octet-stream", "buffer": b"BPS1 x"}] ) actor.page.get_by_role("button", name="Publish version").click()
expect(actor.page.get_by_role("heading", name="v2")).to_be_visible() expect(actor.page.locator(".version .markdown img")).to_have_count(1) assert len(actor.version_record("v2")["value"]["descriptionImages"]) == 1
def test_editing_version_notes_keeps_their_images_and_adds_more(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/versions") actor.page.get_by_role("link", name="Edit").click()
def add_image(name: str, count: int) -> None: expect(actor.page.locator("markdown-input .cm-editor")).to_be_visible() actor.page.locator("markdown-input input[type=file]").set_input_files( files=[{"name": name, "mimeType": "image/png", "buffer": PNG + name.encode()}] ) expect(actor.page.locator("#description")).to_have_value( re.compile(r"(!\[\]\(baf[a-z0-9]+\)\s*){%d}" % count), timeout=15000 ) actor.page.get_by_role("button", name="Save").click() expect(actor.page.locator(".version .markdown img")).to_have_count(count) assert len(actor.version_record("1.0")["value"]["descriptionImages"]) == count
add_image("first.png", 1) actor.page.get_by_role("link", name="Edit").click() actor.page.get_by_role("textbox", name="What changed").press("ControlOrMeta+End") add_image("second.png", 2)
def test_the_table_button_inserts_a_table_to_fill_in(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/settings")
actor.page.get_by_role("textbox", name="Details").click() actor.page.get_by_role("button", name="Table").click() actor.page.keyboard.type("Button") expect(actor.page.locator("#details")).to_have_value( "| Button | Column |\n| --- | --- |\n| | |\n" )
def test_a_table_shows_its_source_only_while_the_cursor_is_in_it(actor: Actor): actor.login() actor.create_mod("master-quest", title="Master Quest") actor.page.goto(f"{actor.app_url}/{actor.handle}/master-quest/settings") editor = actor.page.locator("markdown-input").first
actor.page.get_by_role("textbox", name="Details").click() actor.page.get_by_role("button", name="Table").click() expect(editor.locator(".cm-table-source")).not_to_have_count(0) expect(editor.locator(".cm-table-widget")).to_have_count(0)
actor.page.keyboard.press("ControlOrMeta+End") expect(editor.locator(".cm-table-widget")).to_have_count(1) expect(editor.locator(".cm-table-source")).to_have_count(0)
editor.locator(".cm-table-widget").click() expect(editor.locator(".cm-table-widget")).to_have_count(0) expect(editor.locator(".cm-table-source")).not_to_have_count(0)