issues/153/user_tool.py (209 lines of code) (raw):
import os
import random
import re
import string
import pytest
from playwright.async_api import Page, TimeoutError, async_playwright, expect
from utils.trace_cleaner import trace_cleaner
<<<<<<< HEAD
# Utility function to generate a unique random email for testing
def generate_random_email():
timestamp = int(time.time())
return f"t1533148+{timestamp}@gmail.com"
EMAIL = "t1533148@gmail.com" # for example test+1234@gmail.com
PASSWORD = "" # it will be something like "sdib pxop ovyl uawy"
=======
EMAIL_USERNAME = "xecuycismfsga"
EMAIL_ALIAS = "kypqxmbx"
USER_EMAIL = f"{EMAIL_USERNAME}+{EMAIL_ALIAS}@gmail.com"
PASSWORD = "uwgb zzoc cofa kaaq"
SLOW_MO: int | None = 500
PROXY_URL = os.getenv("PROXY_URL")
WORKSPACE_NAME = "BltGot0t"
>>>>>>> main
async def create_workspace(page: Page, workspace_name: str = WORKSPACE_NAME):
"""
Create a workspace if it does not already exist
"""
await page.get_by_label("My settings").click()
await page.get_by_test_id("InitialSettingsPage").get_by_label("Workspaces").click()
try:
await (
page.locator('button[aria-label="row"]')
.filter(has_text=workspace_name)
.last.wait_for(timeout=3000)
)
except TimeoutError:
await page.get_by_label("New workspace").last.click()
await page.get_by_text("Name", exact=True).click()
name_input = page.get_by_role("textbox", name="Name")
await name_input.clear()
await name_input.type(workspace_name, delay=200)
await page.get_by_role("button", name="Save").click()
await (
page.get_by_test_id("WorkspaceInitialPage")
.get_by_label("Back")
.first.click()
)
await page.get_by_label("Inbox").click()
def generate_random_string(length=6, case="mixed"):
if case == "lower":
characters = string.ascii_lowercase
elif case == "upper":
characters = string.ascii_uppercase
elif case == "mixed":
characters = string.ascii_letters
else:
raise ValueError("Case must be 'lower', 'upper', or 'mixed'")
random_string = "".join(random.choice(characters) for _ in range(length))
return random_string
async def get_magic_code(
page: Page, user_email: str = USER_EMAIL, password: str = PASSWORD
):
return "123456"
async def create_user(page: Page, firstname: str = "User", lastname: str = EMAIL_ALIAS):
await page.get_by_role("button", name="Join").click()
# Update profile
await page.get_by_text("Track and budget expenses").click()
await page.get_by_role("textbox", name="First name").fill(firstname)
await page.get_by_role("textbox", name="Last name").fill(lastname)
await page.get_by_role("button", name="Continue").click()
async def login(page: Page):
# get current timestamp
magic_code = await get_magic_code(page)
if magic_code is None:
raise ValueError("Failed to retrieve magic code")
await page.get_by_role("textbox").fill(magic_code)
async def login_or_create_user(
page: Page,
firstname: str = "User",
lastname: str = EMAIL_ALIAS,
user_email: str = USER_EMAIL,
):
await page.goto("https://dev.new.expensify.com:8082/")
await page.get_by_test_id("username").fill(user_email)
await page.get_by_role("button", name="Continue").click()
try:
await page.get_by_role("button", name="Join").wait_for(
state="visible", timeout=2000
)
await create_user(page, firstname=firstname, lastname=lastname)
except TimeoutError:
await login(page)
await page.get_by_label("Inbox").wait_for(state="visible", timeout=10000)
async def submit_expense(page: Page):
expense_preview = (
page.get_by_role("button", name="View details")
.filter(has_text=f"{WORKSPACE_NAME} owes:")
.last
)
try:
await expense_preview.wait_for(state="visible", timeout=3000)
except TimeoutError:
await page.get_by_label("Create").last.click()
await page.get_by_text("Submit expense", exact=True).click()
await page.get_by_label("Manual").click()
await page.get_by_placeholder("0").fill("100")
await (
page.locator("#numPadContainerView")
.get_by_role("button", name="Next")
.click()
)
await page.get_by_text("Merchant").click()
await page.get_by_role("textbox", name="Merchant").fill("test")
await page.get_by_role("button", name="Save").click()
await page.get_by_role("button", name="Submit").click()
return expense_preview
async def enable_custom_fields_and_rules(page: Page):
await page.get_by_label("My settings").click()
await page.get_by_role("menuitem", name="Workspaces").click()
await (
page.locator('button[aria-label="row"]')
.filter(has_text=WORKSPACE_NAME)
.last.click(timeout=3000)
)
await page.get_by_label("More features").click()
custom_fields = page.get_by_label("Set up custom fields for spend.")
if not await custom_fields.is_checked():
await custom_fields.click()
try:
await page.get_by_role("button", name="Upgrade").click(timeout=3000)
await page.get_by_role("button", name="Got it, thanks").click()
except TimeoutError:
pass
rules = page.get_by_label("Require receipts, flag high spend, and more.")
if not await rules.is_checked():
await rules.click()
<<<<<<< HEAD
# Test to verify opening distance receipt from another workspace opens without issue
def test_open_receipt_different_workspace():
with sync_playwright() as p:
browser, context, page, user_email1 = login_user(p)
# Start tracing with screenshots, snapshots, and sources
context.tracing.start(screenshots=True, snapshots=True, sources=True)
trace_file = "/app/expensify/user_tool/output_browser1.zip"
=======
async def add_custom_report_name(page: Page):
await page.get_by_role("menuitem", name="Rules").click()
custom_report_names = page.get_by_role(
"switch", name="Custom report names", exact=True
)
if not await custom_report_names.is_checked():
await custom_report_names.click()
await page.get_by_role("menuitem", name="report", exact=True).click()
await page.locator('input[aria-label="Name"]').fill("report")
await page.get_by_role("button", name="Save").click()
@pytest.mark.asyncio
async def test_search_bar_spacing():
async with async_playwright() as p:
browser = await p.chromium.launch(
proxy={"server": PROXY_URL} if PROXY_URL else None,
headless=False,
args=[
"--no-sandbox",
"--disable-dev-shm-usage",
"--ignore-certificate-errors",
"--disable-web-security",
"--disable-features=IsolateOrigins,site-per-process",
],
slow_mo=SLOW_MO,
)
context = await browser.new_context()
await context.tracing.start(screenshots=True, snapshots=True, sources=True)
page = await context.new_page()
>>>>>>> main
try:
await login_or_create_user(page)
await create_workspace(page)
workspace_chat = (
page.locator(
'button[aria-label="Navigates to a chat"]',
has_text=WORKSPACE_NAME,
)
.filter(has_not_text="#admins")
.first
)
await workspace_chat.click()
expense_preview = await submit_expense(page)
await expense_preview.click()
await enable_custom_fields_and_rules(page)
await add_custom_report_name(page)
await (
page.get_by_test_id("WorkspaceInitialPage")
.get_by_label("Back")
.first.click()
)
await page.get_by_label("Inbox").click()
report_details = (
page.locator('div[data-testid="DisplayNamesWithTooltip"]')
.filter(has_text=re.compile(r"Expense Report #\d+"))
.last
)
report_title = await report_details.inner_text(timeout=5000)
await page.get_by_text("Title").last.click()
await page.locator('input[aria-label="Title"]').fill(generate_random_string())
await page.get_by_role("button", name="Save").click()
await expect(
page.locator('div[data-testid="DisplayNamesWithTooltip"]')
.filter(has_text=report_title)
.last
).to_be_visible()
# Close all tabs gracefully
await page.close()
await context.close()
finally:
# Ensure tracing is stopped and trace is exported even if an error occurs
trace_path = "/app/expensify/user_tool/output_browser1.zip"
await context.tracing.stop(path=trace_path)
trace_cleaner(trace_path)
await browser.close()