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
from selenium.webdriver.common.keys import Keys
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, 'loginBtn')
self.error_message = (By.ID, 'errorMsg')
def open(self, url):
self.driver.get(url)
def enter_email(self, email):
self.driver.find_element(*self.email_input).clear()
self.driver.find_element(*self.email_input).send_keys(email)
def enter_password(self, password):
self.driver.find_element(*self.password_input).clear()
self.driver.find_element(*self.password_input).send_keys(password)
def click_login(self):
self.driver.find_element(*self.login_button).click()
def get_error_message(self):
try:
return WebDriverWait(self.driver, 5).until(
EC.visibility_of_element_located(self.error_message)
).text
except:
return ''
class TestLoginExploratory(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.login_page = LoginPage(self.driver)
self.login_page.open('https://example.com/login')
def test_invalid_email_format(self):
self.login_page.enter_email('invalid-email')
self.login_page.enter_password('Password123')
self.login_page.click_login()
error = self.login_page.get_error_message()
self.assertIn('invalid email', error.lower())
def test_empty_fields(self):
self.login_page.enter_email('')
self.login_page.enter_password('')
self.login_page.click_login()
error = self.login_page.get_error_message()
self.assertIn('required', error.lower())
def test_long_input_strings(self):
long_string = 'a'*500
self.login_page.enter_email(long_string + '@test.com')
self.login_page.enter_password(long_string)
self.login_page.click_login()
error = self.login_page.get_error_message()
self.assertTrue(error != '' or True) # Accept error or no crash
def test_multiple_quick_clicks(self):
self.login_page.enter_email('user@test.com')
self.login_page.enter_password('Password123')
for _ in range(5):
self.login_page.click_login()
# Check page still responsive by checking login button enabled
login_btn = self.driver.find_element(*self.login_page.login_button)
self.assertTrue(login_btn.is_enabled())
def test_keyboard_navigation(self):
email_elem = self.driver.find_element(*self.login_page.email_input)
email_elem.send_keys('user@test.com')
email_elem.send_keys(Keys.TAB)
active = self.driver.switch_to.active_element
self.assertEqual(active.get_attribute('id'), 'password')
active.send_keys('Password123')
active.send_keys(Keys.TAB)
active = self.driver.switch_to.active_element
self.assertEqual(active.get_attribute('id'), 'loginBtn')
active.send_keys(Keys.ENTER)
# Wait for possible error or success
WebDriverWait(self.driver, 5).until(
EC.presence_of_element_located(self.login_page.error_message)
)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()This script uses Selenium with Python's unittest framework to automate exploratory testing of a login page.
The LoginPage class follows the Page Object Model pattern to keep locators and actions organized.
Each test method covers a different exploratory scenario from the manual test case steps:
- Invalid email format triggers an error message.
- Empty fields show required field errors.
- Long input strings do not crash the page.
- Clicking login multiple times quickly does not freeze or disable the button.
- Keyboard navigation works correctly through inputs and login button.
Explicit waits ensure the test waits for error messages to appear before asserting.
Assertions check for expected error messages or UI states to confirm correct behavior.
Finally, the browser is closed after tests to clean up.