diff --git a/nextcloud_create_doc_and_share.py b/nextcloud_create_doc_and_share.py index c9ed6adb..d4ec37ff 100644 --- a/nextcloud_create_doc_and_share.py +++ b/nextcloud_create_doc_and_share.py @@ -1,16 +1,24 @@ +from time import time_ns + from playwright.sync_api import Playwright, sync_playwright +def log_note(message: str) -> None: + timestamp = round(time_ns() * 1000) + print(f"{timestamp} {message}") def run(playwright: Playwright) -> None: + log_note("Launch browser") browser = playwright.chromium.launch(headless=True) context = browser.new_context() page = context.new_page() + log_note("Login") page.goto("http://nc/") page.get_by_label("Account name or email").click() page.get_by_label("Account name or email").fill("Crash") page.get_by_label("Account name or email").press("Tab") page.get_by_label("Password", exact=True).fill("Override") page.get_by_label("Password", exact=True).press("Enter") + log_note("Create new text file") page.get_by_role("link", name="Files").click() page.get_by_role("link", name="New file/folder menu").click() page.get_by_role("link", name="New text file").click() @@ -18,10 +26,12 @@ def run(playwright: Playwright) -> None: page.locator("#view9-input-file").press("Enter") page.get_by_role("button", name="Create a new file with the selected template").click() page.get_by_role("button", name="Close modal").click() + log_note("Share file with other user") page.get_by_role("link", name="colab_meeting .md").get_by_role("link", name="Share").click() page.get_by_placeholder("Name, email, or Federated Cloud ID …").click() page.get_by_placeholder("Name, email, or Federated Cloud ID …").fill("docs") page.get_by_text("docs_dude").first.click() + log_note("Close browser") page.close() # --------------------- diff --git a/nextcloud_create_user.py b/nextcloud_create_user.py index a37636a2..98e181ad 100644 --- a/nextcloud_create_user.py +++ b/nextcloud_create_user.py @@ -1,11 +1,18 @@ import contextlib +from time import time_ns + from playwright.sync_api import Playwright, sync_playwright +def log_note(message: str) -> None: + timestamp = round(time_ns() * 1000) + print(f"{timestamp} {message}") def create_user(playwright: Playwright, username: str, password: str) -> None: + log_note("Launch browser") browser = playwright.chromium.launch(headless=True) context = browser.new_context() page = context.new_page() + log_note("Login") page.goto("http://nc/") page.get_by_label("Account name or email").click() page.get_by_label("Account name or email").fill("Crash") @@ -14,6 +21,7 @@ def create_user(playwright: Playwright, username: str, password: str) -> None: page.get_by_label("Password", exact=True).press("Enter") with contextlib.suppress(Exception): page.get_by_role("button", name="Close modal").click(timeout=15_000) + log_note("Create user") page.get_by_role("link", name="Open settings menu").click() page.get_by_role("link", name="Users").click() page.get_by_role("button", name="New user").click() @@ -23,6 +31,7 @@ def create_user(playwright: Playwright, username: str, password: str) -> None: page.get_by_placeholder("Display name").press("Tab") page.get_by_placeholder("Password", exact=True).fill(password) page.get_by_role("button", name="Add a new user").click() + log_note("Close browser") # --------------------- page.close() diff --git a/nextcloud_install.py b/nextcloud_install.py index 4e709179..c97d511e 100644 --- a/nextcloud_install.py +++ b/nextcloud_install.py @@ -1,7 +1,14 @@ +from time import time_ns + from playwright.sync_api import sync_playwright +def log_note(message: str) -> None: + timestamp = round(time_ns() * 1000) + print(f"{timestamp} {message}") + def main(): with sync_playwright() as playwright: + log_note("Launch browser") browser_type = playwright.chromium browser = browser_type.launch( headless=True, @@ -12,17 +19,20 @@ def main(): page.set_default_timeout(180_000) # 1. Create User + log_note("Create admin user") page.type('#adminlogin', 'Crash') page.type('#adminpass', 'Override') page.click('.primary') # 2. Install all Apps + log_note("Install recommended apps") install_selector = '.button-vue--vue-primary' page.wait_for_selector(install_selector) page.click(install_selector) # 3. Dashboard page.wait_for_selector('.app-dashboard') + log_note("Installation complete") browser.close() diff --git a/nextcloud_talk.py b/nextcloud_talk.py index 3fb4d45c..e63e4bdd 100644 --- a/nextcloud_talk.py +++ b/nextcloud_talk.py @@ -1,8 +1,12 @@ import random import string +from time import time_ns from playwright.sync_api import Playwright, sync_playwright, expect +def log_note(message: str) -> None: + timestamp = round(time_ns() * 1000) + print(f"{timestamp} {message}") def get_random_text() -> str: size_in_bytes = 20 * 1024 @@ -10,15 +14,18 @@ def get_random_text() -> str: return ''.join(random.choice(characters) for _ in range(size_in_bytes)) def send_message(sender, message): + log_note("Sending message") sender.get_by_role("textbox", name="Write message, @ to mention someone …").click() sender.get_by_role("textbox", name="Write message, @ to mention someone …").fill(message) sender.get_by_role("textbox", name="Write message, @ to mention someone …").press("Enter") def create_conversation(playwright: Playwright) -> str: headless = True + log_note("Launch browser") browser = playwright.chromium.launch(headless=headless) context = browser.new_context() page = context.new_page() + log_note("Login as admin") page.goto("http://nc/") page.get_by_label("Account name or email").click() page.get_by_label("Account name or email").fill("Crash") @@ -27,24 +34,29 @@ def create_conversation(playwright: Playwright) -> str: page.get_by_role("button", name="Log in").click() # Wait for the modal to load. As it seems you can't close it while it is showing the opening animation. + log_note("Close first-time run popup") page.get_by_role("button", name="Close modal").click(timeout=15_000) + log_note("Open Talk app") page.get_by_role("link", name="Talk", exact=True).click() page.wait_for_url("**/apps/spreed/") # Headless browsers trigger a warning in Nextcloud, however they actually work fine if headless: + log_note("Close headless warning") page.wait_for_selector('.toast-close') page.click('.toast-close') page.wait_for_selector('.toast-close') page.click('.toast-close') + log_note("Create conversation") page.get_by_role("button", name="Create a new group conversation").click() page.get_by_placeholder("Conversation name").fill("Random talk") page.locator("label").filter(has_text="Allow guests to join via link").locator("svg").click() page.get_by_role("button", name="Create conversation").click() page.get_by_role("button", name="Copy conversation link").click() + log_note("Close browser") # --------------------- page.close() @@ -59,33 +71,40 @@ def talk(playwright: Playwright, url: str) -> None: browser_count = 5 # Launch browsers + log_note(f"Launching {browser_count} browsers") browsers = [playwright.chromium.launch(headless=headless, slow_mo=action_delay_ms) for _ in range(browser_count)] contexts = [browser.new_context() for browser in browsers] pages = [context.new_page() for context in contexts] # Go to URL for all users + log_note("Navigating to Talk conversation") for page in pages: page.goto(url) # Close toast messages for headless browsers if headless: + log_note("Close headless warning") for page in pages: page.wait_for_selector('.toast-close').click() # Perform actions for all users + log_note("Set guest usernames") for page in pages: page.get_by_role("button", name="Edit").click() page.get_by_placeholder("Guest").fill(f"Dude#{pages.index(page) + 1}") page.get_by_role("button", name="Save name").click() # Send first message and check for visibility + log_note("Send the first validation message") sender = pages[0] message = "Let's send some random text!" send_message(sender, message) + log_note("Validate the first message got received") for page in pages[1:]: expect(page.get_by_text(message, exact=True)).to_be_visible() # Send random text and validate it was received by other users + log_note("Start sending random messages") for i, sender in enumerate(pages): receivers = pages[:i] + pages[i + 1:] random_text = get_random_text() @@ -93,9 +112,11 @@ def talk(playwright: Playwright, url: str) -> None: send_message(sender, random_text) for receiver in receivers: expect(receiver.get_by_text(random_text, exact=True)).to_be_visible() + log_note("Message received by all users") # -------------------- # Close all users + log_note("Close all browsers") for page in pages: page.close()