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
import unittest
class LoginPage:
def __init__(self, driver):
self.driver = driver
self.email_input = (By.ID, 'email')
self.password_input = (By.ID, 'password')
self.login_button = (By.ID, 'login-btn')
def enter_email(self, email):
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.email_input)).clear()
self.driver.find_element(*self.email_input).send_keys(email)
def enter_password(self, password):
WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.password_input)).clear()
self.driver.find_element(*self.password_input).send_keys(password)
def click_login(self):
WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable(self.login_button)).click()
class DashboardPage:
def __init__(self, driver):
self.driver = driver
self.welcome_message = (By.ID, 'welcome-msg')
def is_welcome_message_displayed(self):
return WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.welcome_message)) is not None
class TestLogin(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.get('https://example.com/login')
def test_valid_login(self):
login_page = LoginPage(self.driver)
login_page.enter_email('user@example.com')
login_page.enter_password('Password123!')
login_page.click_login()
# Wait for URL to contain '/dashboard'
WebDriverWait(self.driver, 10).until(EC.url_contains('/dashboard'))
self.assertIn('/dashboard', self.driver.current_url, 'URL does not contain /dashboard after login')
dashboard_page = DashboardPage(self.driver)
self.assertTrue(dashboard_page.is_welcome_message_displayed(), 'Welcome message not displayed on dashboard')
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()This test script uses Selenium with Python and unittest framework to automate the user story test case.
We define two page classes: LoginPage and DashboardPage to keep locators and actions organized (Page Object Model).
In test_valid_login, we enter the email and password, click login, then wait explicitly for the URL to contain '/dashboard'.
We assert the URL contains '/dashboard' and that the welcome message is visible on the dashboard page.
Explicit waits ensure the test waits for elements or URL changes properly, avoiding flaky tests.
The setUp and tearDown methods handle browser start and close for clean test runs.