issues/152/user_tool.py [21:163]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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()
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



issues/153/user_tool.py [30:172]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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()
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



