[Python] Playwright unable to click Confirm button in OrangeHRM modal - both CSS selector and...

Discussão em 'Python' iniciado por Stack, Julho 10, 2025.

  1. Stack

    Stack Membro Participativo

    I'm automating the OrangeHRM demo website using Playwright with Python. After adding a leave entitlement, a modal dialog appears with a "Confirm" button that I need to click but I'm unable to do so

    import pytest
    from playwright.sync_api import expect
    from test_data.pim_data import get_last_created_employee

    @pytest.mark.usefixtures("init_driver")
    class TestLeaveEntitlementScenario1:
    def test_add_leave_entitlement_for_last_employee(self):
    """
    Test Case: Add Leave Entitlement for Last Created Employee
    Preconditions:
    - Admin is logged in (handled by fixture)
    - At least one employee exists and is persisted
    Steps:
    1. Navigate to Leave > Entitlements > Add Entitlements
    2. Enter/select last created employee
    3. Select leave type, period, and enter entitled days
    4. Save and confirm
    5. Verify success message and entitlement addition
    """
    from automation.pages.login_page import LoginPage
    from automation.pages.leave_page import LeavePage
    from test_data.pim_data import get_last_created_employee
    from test_data.leave_entitlement_data import get_leave_entitlement_data
    page = self.page
    # Manual admin login
    from test_data.login_data import LOGIN_USERS
    creds = LOGIN_USERS["valid"]
    login_page = LoginPage(page)
    login_page.do_login(creds["username"], creds["password"])
    employee = get_last_created_employee()
    assert employee, "No last created employee found."
    emp_name = f"{employee['first_name']} {employee['middle_name']} {employee['last_name']}"
    # Get leave entitlement data and override employee_name with the last created employee
    leave_data = get_leave_entitlement_data()
    leave_data["employee_name"] = emp_name
    leave_type = leave_data["leave_type"]
    period = leave_data.get("period")
    entitlement = leave_data["entitlement"]

    try:
    # Step 1: Navigate to Leave > Entitlements > Add Entitlements using POM
    leave_page = LeavePage(page)

    leave_page.go_to_leave()
    leave_page.go_to_add_entitlement()
    # Step 2-4: Add leave entitlement using robust POM method
    leave_page.add_leave_entitlement(emp_name, leave_type, period, entitlement)

    # Step 5: Robustly handle confirmation dialog after Save (use strict CSS selector for Confirm button)
    try:
    # Use strict document.querySelector for Confirm button in the modal
    page.evaluate('''() => {
    const btn = document.querySelector("#app > div.oxd-overlay.oxd-overlay--flex.oxd-overlay--flex-centered > div > div > div > div.orangehrm-modal-footer > button.oxd-button.oxd-button--medium.oxd-button--secondary.orangehrm-button-margin");
    if (btn) {
    btn.scrollIntoView({block: 'center'});
    btn.focus();
    btn.click();
    } else {
    throw new Error('Confirm button not found');
    }
    }''')
    page.screenshot(path="confirm_btn_after_click.png", full_page=True)
    except Exception as e:
    page.screenshot(path="confirm_dialog_debug.png", full_page=True)
    print(f"[DEBUG] Could not click Confirm (JS strict selector): {e}")
    pass # Dialog may not always appear

    # Step 6: Assert the appearance and content of the success toast (robust, allow for variations)
    try:
    toast = page.locator(".oxd-toast--success")
    expect(toast).to_be_visible(timeout=5000)
    toast_text = toast.inner_text().lower()
    assert ("success" in toast_text or "entitlement" in toast_text), f"Success toast did not appear or did not contain expected text. Actual: {toast_text}"
    except Exception as e:
    page.screenshot(path="toast_debug.png", full_page=True)
    raise AssertionError(f"Success toast not found or incorrect: {e}")

    # Step 7: Wait for the entitlements table and verify the new row exists (best practice)
    try:
    table = page.locator("table")
    expect(table).to_be_visible(timeout=10000)
    found = False
    rows = table.locator("tbody tr")
    row_count = rows.count()
    for i in range(row_count):
    row = rows.nth(i)
    row_text = row.inner_text().lower()
    if leave_type.strip().lower() in row_text and str(entitlement) in row_text:
    found = True
    break
    if not found:
    page.screenshot(path="table_row_debug.png", full_page=True)
    assert found, f"Entitlement row with leave type '{leave_type}' and entitlement '{entitlement}' not found in table."
    except Exception as e:
    page.screenshot(path="table_debug.png", full_page=True)
    raise AssertionError(f"Entitlements table check failed: {e}")
    finally:
    page.screenshot(path="leave_entitlement_debug.png", full_page=True)



    this is my entire test I've tried using

    document.querySelector("#app > div.oxd-overlay.oxd-overlay--flex.oxd-overlay--flex-centered > div > div > div > div.orangehrm-modal-footer > button.oxd-button.oxd-button--medium.oxd-button--secondary.orangehrm-button-margin")


    and

    button[class='oxd-button oxd-button--medium oxd-button--secondary orangehrm-button-margin']


    but nothing seems to work I'm using playwright mcp

    The modal is visible and the button exists.

    Continue reading...

Compartilhe esta Página