import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.url = "http://localhost:5000/login"
self.username_input = (By.ID, "username")
self.password_input = (By.ID, "password")
self.login_button = (By.ID, "login-btn")
def load(self):
self.driver.get(self.url)
def login(self, username, password):
WebDriverWait(self.driver, 10).until(
EC.visibility_of_element_located(self.username_input)
)
self.driver.find_element(*self.username_input).send_keys(username)
self.driver.find_element(*self.password_input).send_keys(password)
self.driver.find_element(*self.login_button).click()
class DashboardPage:
def __init__(self, driver):
self.driver = driver
self.welcome_text_locator = (By.XPATH, "//h1[contains(text(), 'Welcome,')]")
def is_loaded(self):
return WebDriverWait(self.driver, 10).until(
EC.url_contains("/dashboard")
)
def get_welcome_text(self):
return self.driver.find_element(*self.welcome_text_locator).text
@pytest.fixture
def driver():
driver = webdriver.Chrome()
driver.implicitly_wait(5)
yield driver
driver.quit()
@pytest.mark.usefixtures("driver")
def test_user_can_login(driver):
login_page = LoginPage(driver)
dashboard_page = DashboardPage(driver)
login_page.load()
login_page.login("testuser", "Test@1234")
assert dashboard_page.is_loaded(), "Dashboard page did not load"
welcome_text = dashboard_page.get_welcome_text()
assert welcome_text == "Welcome, testuser!", f"Unexpected welcome text: {welcome_text}"This test script uses pytest and Selenium WebDriver to automate the login test.
We use the Page Object Model to keep page details separate from test logic. LoginPage handles login page actions, and DashboardPage handles dashboard checks.
Explicit waits ensure elements are ready before interacting, avoiding flaky tests.
The driver fixture sets up and tears down the browser cleanly.
The test test_user_can_login loads the login page, performs login, then asserts the dashboard URL and welcome message.
This organized structure helps tests stay clear and easy to maintain as the project grows.