"""Message corrections (XEP-0308), in clear and in OMEMO chats.""" import asyncio from playwright.async_api import async_playwright from browser import login, BASE, OUT async def send(page, text): await page.fill("#chat_textarea", text) await page.press("#chat_textarea", "Enter") await page.wait_for_timeout(2500) async def edit_last(page, text): """↑ in the empty textarea, then replace the text""" await page.fill("#chat_textarea", "") await page.press("#chat_textarea", "ArrowUp") await page.wait_for_timeout(1500) print(" textarea after ↑:", repr(await page.input_value("#chat_textarea"))) await send(page, text) async def bubbles(page, n=4): return (await page.locator("#chat_widget .bubble p").all_inner_texts())[-n:] async def open_chat(page, jid): await page.goto(BASE + "/chat/" + jid) await page.wait_for_selector("#chat_textarea", timeout=15000) await page.wait_for_timeout(5000) async def main(): async with async_playwright() as p: browser = await p.chromium.launch() actx, alice, aerr = await login(browser, "alice@localhost", "alicepass", "editalice") bctx, bob, berr = await login(browser, "bob@localhost", "bobpass", "editbob") await alice.wait_for_timeout(4000) await open_chat(alice, "bob@localhost") await open_chat(bob, "alice@localhost") # Clear text await alice.evaluate("ChatOmemo.disableContactState('bob@localhost')") await alice.wait_for_timeout(2000) await send(alice, "Hẹn gặp lúc 9h") await edit_last(alice, "Hẹn gặp lúc 10h") print("clear, alice:", await bubbles(alice, 2)) print("clear, bob:", await bubbles(bob, 2)) print("edited marks on bob:", await bob.locator("#chat_widget .edited").count()) # OMEMO await alice.evaluate("ChatOmemo.enableContactState('bob@localhost', false)") await alice.wait_for_timeout(5000) print("alice omemo:", await alice.evaluate("Chat.getOmemoState()")) await send(alice, "Bí mật: mật khẩu wifi là 1234") await edit_last(alice, "Bí mật: mật khẩu wifi là 5678") await alice.screenshot(path=f"{OUT}/edit_1_alice.png") print("omemo, alice:", await bubbles(alice, 3)) print("omemo, bob:", await bubbles(bob, 3)) # Second edit, from the message menu mid = await alice.evaluate("[...document.querySelectorAll('#chat_widget .bubble [data-mid]')].pop().dataset.mid") await alice.evaluate(f"Chat_ajaxEdit({mid})") await alice.wait_for_timeout(1500) print(" textarea from menu:", repr(await alice.input_value("#chat_textarea"))) await send(alice, "Bí mật: mật khẩu wifi là 9999") await bob.wait_for_timeout(2000) await bob.screenshot(path=f"{OUT}/edit_2_bob.png") print("omemo 2nd edit, bob:", await bubbles(bob, 3)) # After a reload only the last versions are shown await open_chat(bob, "alice@localhost") await open_chat(alice, "bob@localhost") print("reload, bob:", await bubbles(bob, 3)) print("reload, alice:", await bubbles(alice, 3)) await bob.screenshot(path=f"{OUT}/edit_3_bob_reload.png") # Search finds the new text, not the old one await bob.evaluate("ChatActions_ajaxShowSearchDialog('alice@localhost', false)") await bob.wait_for_selector("form[name=search] input", timeout=10000) await bob.wait_for_timeout(1000) for q in ("wifi", "1234", "9h", "10h"): await bob.fill("form[name=search] input", q) await bob.wait_for_timeout(2500) print(f"search {q!r}:", await bob.locator("#chat_search #message_preview li p").all_inner_texts()) for e in aerr + berr: print(e) await browser.close() asyncio.run(main())