|
import pytest
|
|
import asyncio
|
|
from playwright.async_api import expect
|
|
|
|
@pytest.mark.asyncio
|
|
class TestBillingAdminFlow:
|
|
|
|
async def test_01_admin_login(self, page, base_url):
|
|
await page.goto(f"{base_url}/")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('input[name="username"]', 'adminuser')
|
|
await page.fill('input[name="password"]', 'adminpassword123')
|
|
await page.click('button[type="submit"]')
|
|
|
|
await page.wait_for_load_state("networkidle")
|
|
await expect(page.locator('text=Dashboard')).to_be_visible()
|
|
|
|
async def test_02_navigate_to_admin_billing(self, page, base_url):
|
|
await page.goto(f"{base_url}/")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('input[name="username"]', 'adminuser')
|
|
await page.fill('input[name="password"]', 'adminpassword123')
|
|
await page.click('button[type="submit"]')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.click('text=Admin')
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.click('text=Billing')
|
|
await page.wait_for_url("**/admin/billing")
|
|
|
|
await expect(page.locator('h2:has-text("Billing Administration")')).to_be_visible()
|
|
|
|
async def test_03_view_revenue_statistics(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('.stats-cards')).to_be_visible()
|
|
await expect(page.locator('.stat-card:has-text("Total Revenue")')).to_be_visible()
|
|
await expect(page.locator('.stat-card:has-text("Total Invoices")')).to_be_visible()
|
|
await expect(page.locator('.stat-card:has-text("Pending Invoices")')).to_be_visible()
|
|
|
|
async def test_04_verify_revenue_value_display(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
revenue_stat = page.locator('.stat-card:has-text("Total Revenue") .stat-value')
|
|
await expect(revenue_stat).to_be_visible()
|
|
|
|
revenue_text = await revenue_stat.text_content()
|
|
assert '$' in revenue_text or '0' in revenue_text
|
|
|
|
async def test_05_view_pricing_configuration_table(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('.pricing-config-section')).to_be_visible()
|
|
await expect(page.locator('h3:has-text("Pricing Configuration")')).to_be_visible()
|
|
await expect(page.locator('.pricing-table')).to_be_visible()
|
|
|
|
async def test_06_verify_pricing_config_rows(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('.pricing-table tbody tr')).to_have_count(6, timeout=5000)
|
|
|
|
await expect(page.locator('td:has-text("Storage cost per GB per month")')).to_be_visible()
|
|
await expect(page.locator('td:has-text("Bandwidth egress cost per GB")')).to_be_visible()
|
|
await expect(page.locator('td:has-text("Free tier storage")')).to_be_visible()
|
|
|
|
async def test_07_click_edit_pricing_button(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
edit_buttons = page.locator('.btn-edit')
|
|
await expect(edit_buttons.first).to_be_visible()
|
|
|
|
page.on('dialog', lambda dialog: dialog.dismiss())
|
|
await edit_buttons.first.click()
|
|
await page.wait_for_timeout(1000)
|
|
|
|
async def test_08_edit_pricing_value(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
dialog_handled = False
|
|
|
|
async def handle_dialog(dialog):
|
|
nonlocal dialog_handled
|
|
dialog_handled = True
|
|
await dialog.accept(text="0.005")
|
|
|
|
page.on('dialog', handle_dialog)
|
|
|
|
edit_button = page.locator('.btn-edit').first
|
|
await edit_button.click()
|
|
await page.wait_for_timeout(1000)
|
|
|
|
if dialog_handled:
|
|
await page.wait_for_timeout(2000)
|
|
|
|
async def test_09_view_invoice_generation_section(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('.invoice-generation-section')).to_be_visible()
|
|
await expect(page.locator('h3:has-text("Generate Invoices")')).to_be_visible()
|
|
|
|
async def test_10_verify_invoice_generation_form(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('#invoiceYear')).to_be_visible()
|
|
await expect(page.locator('#invoiceMonth')).to_be_visible()
|
|
await expect(page.locator('#generateInvoices')).to_be_visible()
|
|
|
|
async def test_11_set_invoice_generation_date(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('#invoiceYear', '2024')
|
|
await page.fill('#invoiceMonth', '11')
|
|
|
|
year_value = await page.input_value('#invoiceYear')
|
|
month_value = await page.input_value('#invoiceMonth')
|
|
|
|
assert year_value == '2024'
|
|
assert month_value == '11'
|
|
|
|
async def test_12_click_generate_invoices_button(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.fill('#invoiceYear', '2024')
|
|
await page.fill('#invoiceMonth', '10')
|
|
|
|
page.on('dialog', lambda dialog: dialog.dismiss())
|
|
|
|
await page.click('#generateInvoices')
|
|
await page.wait_for_timeout(1000)
|
|
|
|
async def test_13_verify_all_stat_cards_present(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
stat_cards = page.locator('.stat-card')
|
|
await expect(stat_cards).to_have_count(3)
|
|
|
|
async def test_14_verify_pricing_table_headers(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('th:has-text("Configuration")')).to_be_visible()
|
|
await expect(page.locator('th:has-text("Current Value")')).to_be_visible()
|
|
await expect(page.locator('th:has-text("Unit")')).to_be_visible()
|
|
await expect(page.locator('th:has-text("Actions")')).to_be_visible()
|
|
|
|
async def test_15_verify_all_edit_buttons_present(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
edit_buttons = page.locator('.btn-edit')
|
|
count = await edit_buttons.count()
|
|
assert count == 6
|
|
|
|
async def test_16_scroll_through_admin_dashboard(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await page.evaluate("window.scrollTo(0, 0)")
|
|
await page.wait_for_timeout(500)
|
|
|
|
await page.evaluate("window.scrollTo(0, document.body.scrollHeight / 2)")
|
|
await page.wait_for_timeout(500)
|
|
|
|
await page.evaluate("window.scrollTo(0, document.body.scrollHeight)")
|
|
await page.wait_for_timeout(500)
|
|
|
|
await page.evaluate("window.scrollTo(0, 0)")
|
|
await page.wait_for_timeout(500)
|
|
|
|
async def test_17_verify_responsive_layout(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
await expect(page.locator('.admin-billing')).to_be_visible()
|
|
|
|
bounding_box = await page.locator('.admin-billing').bounding_box()
|
|
assert bounding_box['width'] > 0
|
|
assert bounding_box['height'] > 0
|
|
|
|
async def test_18_verify_page_title(self, page, base_url):
|
|
await page.goto(f"{base_url}/admin/billing")
|
|
await page.wait_for_load_state("networkidle")
|
|
|
|
title = await page.title()
|
|
assert title is not None
|