fix and add som usecases
This commit is contained in:
@@ -10,8 +10,17 @@ def driver():
|
||||
Initializes and returns a Chrome WebDriver instance for each test function.
|
||||
Automatically quits the driver after the test function completes.
|
||||
"""
|
||||
# Initialize the Chrome WebDriver
|
||||
driver = webdriver.Chrome()
|
||||
# Configure Chrome options to disable the password manager and related pop-ups
|
||||
chrome_options = webdriver.ChromeOptions()
|
||||
prefs = {
|
||||
"credentials_enable_service": False,
|
||||
"profile.password_manager_enabled": False
|
||||
}
|
||||
chrome_options.add_experimental_option("prefs", prefs)
|
||||
chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
|
||||
|
||||
# Initialize the Chrome WebDriver with the specified options
|
||||
driver = webdriver.Chrome(options=chrome_options)
|
||||
|
||||
# Maximize the browser window
|
||||
driver.maximize_window()
|
||||
|
||||
1
tests/test_dynamic_content/__init__.py
Normal file
1
tests/test_dynamic_content/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -9,12 +9,12 @@ class TestDynamicContent:
|
||||
and dynamic elements.
|
||||
"""
|
||||
|
||||
def test_delayed_text_appears(self, driver):
|
||||
def test_delayed_text_appears(self, driver, base_url):
|
||||
"""
|
||||
Tests that the delayed text appears after a few seconds.
|
||||
"""
|
||||
dynamic_page = DynamicContentPage(driver)
|
||||
dynamic_page.open()
|
||||
dynamic_page.open(base_url)
|
||||
|
||||
# The waiting logic is inside the get_delayed_text method
|
||||
text = dynamic_page.get_delayed_text()
|
||||
@@ -24,12 +24,12 @@ class TestDynamicContent:
|
||||
"The delayed text did not appear or has incorrect content."
|
||||
|
||||
@pytest.mark.smoke
|
||||
def test_button_enables_after_click(self, driver):
|
||||
def test_button_enables_after_click(self, driver, base_url):
|
||||
"""
|
||||
Tests that a disabled button becomes enabled after an action.
|
||||
"""
|
||||
dynamic_page = DynamicContentPage(driver)
|
||||
dynamic_page.open()
|
||||
dynamic_page.open(base_url)
|
||||
|
||||
# Verify the button is initially disabled
|
||||
assert not dynamic_page.is_initially_disabled_button_enabled(), \
|
||||
@@ -44,12 +44,12 @@ class TestDynamicContent:
|
||||
assert dynamic_page.is_initially_disabled_button_enabled(), \
|
||||
"Button should be enabled after clicking the 'Enable' button."
|
||||
|
||||
def test_tabs_content_switching(self, driver):
|
||||
def test_tabs_content_switching(self, driver, base_url):
|
||||
"""
|
||||
Tests that content switches correctly when different tabs are clicked.
|
||||
"""
|
||||
dynamic_page = DynamicContentPage(driver)
|
||||
dynamic_page.open()
|
||||
dynamic_page.open(base_url)
|
||||
|
||||
# Switch to Password tab and verify content
|
||||
dynamic_page.switch_to_tab('password')
|
||||
@@ -62,12 +62,12 @@ class TestDynamicContent:
|
||||
assert "Account tab" in content, "Account tab content is not visible after switching back."
|
||||
|
||||
@pytest.mark.smoke
|
||||
def test_alert_handling(self, driver):
|
||||
def test_alert_handling(self, driver, base_url):
|
||||
"""
|
||||
Tests the triggering and handling of a browser alert.
|
||||
"""
|
||||
dynamic_page = DynamicContentPage(driver)
|
||||
dynamic_page.open()
|
||||
dynamic_page.open(base_url)
|
||||
|
||||
dynamic_page.trigger_alert()
|
||||
|
||||
@@ -75,12 +75,12 @@ class TestDynamicContent:
|
||||
|
||||
assert alert_text == "This is a browser alert!", "The alert text is incorrect."
|
||||
|
||||
def test_modal_dialog(self, driver):
|
||||
def test_modal_dialog(self, driver, base_url):
|
||||
"""
|
||||
Tests the opening of a modal dialog and verifies its content.
|
||||
"""
|
||||
dynamic_page = DynamicContentPage(driver)
|
||||
dynamic_page.open()
|
||||
dynamic_page.open(base_url)
|
||||
|
||||
dynamic_page.open_modal()
|
||||
|
||||
1
tests/test_form_elements/__init__.py
Normal file
1
tests/test_form_elements/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -7,12 +7,12 @@ class TestFormElements:
|
||||
Test suite for the Form Elements page.
|
||||
"""
|
||||
|
||||
def test_text_input(self, driver):
|
||||
def test_text_input(self, driver, base_url):
|
||||
"""
|
||||
Tests text entry and retrieval from the text input field.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
test_text = "Hello, Selenium!"
|
||||
form_page.enter_text_in_input(test_text)
|
||||
@@ -21,12 +21,12 @@ class TestFormElements:
|
||||
assert retrieved_text == test_text, f"Expected '{test_text}', but got '{retrieved_text}'"
|
||||
|
||||
@pytest.mark.smoke
|
||||
def test_checkbox_selection(self, driver):
|
||||
def test_checkbox_selection(self, driver, base_url):
|
||||
"""
|
||||
Tests the selection and deselection of a checkbox.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
assert not form_page.is_checkbox_selected(), "Checkbox should be deselected initially"
|
||||
|
||||
@@ -36,12 +36,12 @@ class TestFormElements:
|
||||
form_page.select_checkbox()
|
||||
assert not form_page.is_checkbox_selected(), "Checkbox should be deselected after clicking again"
|
||||
|
||||
def test_radio_button_selection(self, driver):
|
||||
def test_radio_button_selection(self, driver, base_url):
|
||||
"""
|
||||
Tests that only one radio button can be selected at a time.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
form_page.choose_radio_option(2)
|
||||
assert form_page.is_radio_option_selected(2), "Radio option 2 should be selected"
|
||||
@@ -51,12 +51,12 @@ class TestFormElements:
|
||||
assert form_page.is_radio_option_selected(3), "Radio option 3 should be selected"
|
||||
assert not form_page.is_radio_option_selected(2), "Radio option 2 should not be selected"
|
||||
|
||||
def test_dropdown_selection(self, driver):
|
||||
def test_dropdown_selection(self, driver, base_url):
|
||||
"""
|
||||
Tests selecting an option from the custom dropdown.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
fruit_to_select = "Banana"
|
||||
form_page.select_fruit_by_visible_text(fruit_to_select)
|
||||
@@ -65,22 +65,22 @@ class TestFormElements:
|
||||
assert selected_fruit == fruit_to_select, \
|
||||
f"Expected '{fruit_to_select}' to be selected, but got '{selected_fruit}'"
|
||||
|
||||
def test_disabled_button_state(self, driver):
|
||||
def test_disabled_button_state(self, driver, base_url):
|
||||
"""
|
||||
Verifies that the 'Disabled' button is indeed disabled.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
assert not form_page.is_disabled_button_enabled(), "The disabled button should not be enabled"
|
||||
|
||||
@pytest.mark.smoke
|
||||
def test_form_submission(self, driver):
|
||||
def test_form_submission(self, driver, base_url):
|
||||
"""
|
||||
A simple test to fill a field and click the submit button.
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
form_page.open(base_url)
|
||||
|
||||
form_page.enter_text_in_input("Test submission")
|
||||
form_page.click_submit_button()
|
||||
@@ -93,10 +93,10 @@ class TestFormElements:
|
||||
|
||||
|
||||
|
||||
def test_filure_case(self,driver):
|
||||
"""
|
||||
"""
|
||||
form_page = FormElementsPage(driver)
|
||||
form_page.open()
|
||||
print("case1")
|
||||
assert "" == "a", "error"
|
||||
# def test_filure_case(self,driver, base_url):
|
||||
# """
|
||||
# """
|
||||
# form_page = FormElementsPage(driver)
|
||||
# form_page.open(base_url)
|
||||
# print("case1")
|
||||
# assert "" == "a", "error"
|
||||
34
tests/test_home/conftest.py
Normal file
34
tests/test_home/conftest.py
Normal file
@@ -0,0 +1,34 @@
|
||||
import pytest
|
||||
import pandas as pd
|
||||
from page_objects.login_page import LoginPage
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def logged_in_driver(driver, base_url):
|
||||
"""
|
||||
A fixture that provides a logged-in WebDriver instance.
|
||||
|
||||
It performs the following steps:
|
||||
1. Reads valid login credentials from 'data/login_data.csv'.
|
||||
2. Navigates to the login page.
|
||||
3. Performs the login action.
|
||||
4. Yields the driver to the test function.
|
||||
|
||||
The test function then runs on a page that requires authentication.
|
||||
"""
|
||||
# 1. 读取有效的登录凭据 (假设第一行为有效数据)
|
||||
df = pd.read_csv('data/login_data.csv')
|
||||
valid_user = df[df['test_case'] == 'valid_credentials'].iloc[0]
|
||||
email = valid_user['email']
|
||||
password = valid_user['password']
|
||||
|
||||
# 2. 初始化登录页面并打开
|
||||
login_page = LoginPage(driver)
|
||||
login_page.open(base_url)
|
||||
|
||||
# 3. 执行登录
|
||||
login_page.login(email, password)
|
||||
|
||||
# 4. 将已登录的 driver 提供给测试用例
|
||||
yield driver
|
||||
|
||||
# 测试结束后,driver fixture 会自动关闭浏览器
|
||||
102
tests/test_home/test_dashboard.py
Normal file
102
tests/test_home/test_dashboard.py
Normal file
@@ -0,0 +1,102 @@
|
||||
import time
|
||||
import pytest
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from page_objects.home_dashboard_page import HomeDashboardPage
|
||||
from page_objects.profile_editor_page import ProfileEditorPage
|
||||
from page_objects.settings_panel_page import SettingsPanelPage
|
||||
from page_objects.danger_zone_page import DangerZonePage
|
||||
|
||||
@pytest.mark.regression
|
||||
@pytest.mark.usefixtures("logged_in_driver")
|
||||
class TestDashboard:
|
||||
"""
|
||||
Test suite for the Home page and its nested pages (Dashboard).
|
||||
Requires user to be logged in.
|
||||
"""
|
||||
|
||||
def test_navigation_between_pages(self, logged_in_driver):
|
||||
"""
|
||||
Tests that the user can successfully navigate between the Profile,
|
||||
Settings, and Danger Zone pages.
|
||||
"""
|
||||
# Arrange
|
||||
dashboard_page = HomeDashboardPage(logged_in_driver)
|
||||
settings_page = SettingsPanelPage(logged_in_driver)
|
||||
danger_zone_page = DangerZonePage(logged_in_driver)
|
||||
profile_page = ProfileEditorPage(logged_in_driver)
|
||||
|
||||
# Act & Assert: Navigate back to dashborade and verify
|
||||
text = dashboard_page.verify_title_is_dashboarde()
|
||||
assert text == 'Test Cases' , 'error switch to dashhoard tab'
|
||||
|
||||
# Act & Assert: Navigate to Settings tab and verify
|
||||
dashboard_page.navigate_to_settings()
|
||||
text = settings_page.verify_title_is_settings()
|
||||
assert text == 'Application Settings' , 'error switch to settings tab'
|
||||
|
||||
# Act & Assert: Danger Zone and verify
|
||||
|
||||
text = danger_zone_page.verify_danger_zone_exist()
|
||||
assert text == 'Danger Zone' , 'no exists Danger Zone '
|
||||
|
||||
# Act & Assert: Navigate back to Profile and verify
|
||||
dashboard_page.navigate_to_profile()
|
||||
print(text)
|
||||
text = profile_page.verify_title_is_profile()
|
||||
assert text == 'Personal Information' , 'error switch to profile tab'
|
||||
|
||||
def test_profile_editor_interaction(self, logged_in_driver):
|
||||
"""
|
||||
Tests basic interaction with the profile editor form.
|
||||
"""
|
||||
# Arrange
|
||||
dashboard_page = HomeDashboardPage(logged_in_driver)
|
||||
profile_page = ProfileEditorPage(logged_in_driver)
|
||||
|
||||
# Act: Ensure we are on the profile page and update username
|
||||
dashboard_page.navigate_to_profile()
|
||||
new_username = "Automation Tester"
|
||||
profile_page.set_username(new_username)
|
||||
# self.profile_page.click_save_changes() # This action is commented out as it might not have a real backend effect
|
||||
|
||||
# Assert: Check if the value was updated in the input field
|
||||
updated_value = profile_page.find_element(profile_page.USERNAME_INPUT).get_attribute("value")
|
||||
assert updated_value == new_username
|
||||
|
||||
def test_danger_zone_dialog_flow(self, logged_in_driver):
|
||||
"""
|
||||
Tests that the 'Delete Account' button shows a confirmation dialog
|
||||
and that the cancel button closes it.
|
||||
"""
|
||||
# Arrange
|
||||
danger_zone_page = DangerZonePage(logged_in_driver)
|
||||
|
||||
# Act: Click the delete button
|
||||
danger_zone_page.click_delete_account()
|
||||
|
||||
# # Assert: The confirmation dialog is visible
|
||||
# assert danger_zone_page.verify_confirmation_dialog_exist(), \
|
||||
# "Confirmation dialog should be visible after clicking 'Delete Account'."
|
||||
|
||||
# Act: Click the cancel button
|
||||
time.sleep(1)
|
||||
danger_zone_page.click_cancel_in_dialog()
|
||||
text = danger_zone_page.verify_confirmation_dialog_exist()
|
||||
# Assert: The dialog is no longer visible
|
||||
assert text == 'Are you absolutely sure?', \
|
||||
"Confirmation dialog should not be visible after clicking 'Cancel'."
|
||||
|
||||
# Act: Click the delete button
|
||||
time.sleep(1)
|
||||
danger_zone_page.click_delete_account()
|
||||
danger_zone_page.set_dialog_input()
|
||||
danger_zone_page.click_confirm_in_dialog()
|
||||
# 等待跳转到登录页
|
||||
WebDriverWait(logged_in_driver, 5).until(
|
||||
lambda driver: '/login' in driver.current_url
|
||||
)
|
||||
|
||||
# 断言当前 URL
|
||||
current_url = logged_in_driver.current_url
|
||||
assert current_url.endswith('/login'), f"Expected to be on /login, but got {current_url}"
|
||||
|
||||
44
tests/test_home/test_home.py
Normal file
44
tests/test_home/test_home.py
Normal file
@@ -0,0 +1,44 @@
|
||||
import pytest
|
||||
from page_objects.home_page import HomePage
|
||||
from page_objects.login_page import LoginPage
|
||||
|
||||
@pytest.mark.usefixtures("logged_in_driver")
|
||||
class TestHomePage:
|
||||
"""
|
||||
Test suite for the Home page, which requires user authentication.
|
||||
"""
|
||||
|
||||
def test_welcome_message_is_displayed(self, logged_in_driver):
|
||||
"""
|
||||
Verifies that the correct welcome message is displayed after login.
|
||||
"""
|
||||
home_page = HomePage(logged_in_driver)
|
||||
welcome_text = home_page.get_welcome_message()
|
||||
# Assert against the hardcoded user name from auth.tsx
|
||||
assert "Welcome, Test User!" in welcome_text, "Welcome message is not correct or not found."
|
||||
|
||||
def test_dashboard_is_visible_on_load(self, logged_in_driver):
|
||||
"""
|
||||
Verifies that the dashboard tab content is visible by default.
|
||||
"""
|
||||
home_page = HomePage(logged_in_driver)
|
||||
assert home_page.is_dashboard_content_visible(), "Dashboard content should be visible by default."
|
||||
|
||||
def test_switch_to_profile_tab(self, logged_in_driver):
|
||||
"""
|
||||
Verifies that the user can switch to the Profile tab.
|
||||
"""
|
||||
home_page = HomePage(logged_in_driver)
|
||||
home_page.switch_to_profile_tab()
|
||||
# A proper test would assert that profile-specific elements are visible.
|
||||
|
||||
def test_logout_functionality(self, logged_in_driver):
|
||||
"""
|
||||
Verifies that clicking the logout button logs the user out and redirects to the login page.
|
||||
"""
|
||||
home_page = HomePage(logged_in_driver)
|
||||
home_page.click_logout_button()
|
||||
|
||||
# Verify redirection to the login page
|
||||
login_page = LoginPage(logged_in_driver)
|
||||
assert login_page.is_login_form_visible(), "After logout, the login form should be visible."
|
||||
61
tests/test_login/test_login.py
Normal file
61
tests/test_login/test_login.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import pytest
|
||||
from page_objects.login_page import LoginPage
|
||||
from page_objects.home_page import HomePage
|
||||
|
||||
@pytest.mark.regression
|
||||
class TestLogin:
|
||||
"""
|
||||
Test suite for the Login page, covering authentication scenarios.
|
||||
"""
|
||||
|
||||
def test_successful_login(self, driver, base_url):
|
||||
"""
|
||||
Tests that a user can successfully log in with valid credentials
|
||||
and is redirected to the home page.
|
||||
"""
|
||||
login_page = LoginPage(driver)
|
||||
home_page = HomePage(driver)
|
||||
|
||||
login_page.open(base_url)
|
||||
|
||||
# Use the hardcoded credentials from auth.tsx
|
||||
login_page.login("poop@shenjianl.cn", "shenjianZ")
|
||||
|
||||
# Explicitly wait for the URL to change to '/home'
|
||||
login_page.wait_for_url_contains("/home")
|
||||
|
||||
# Assert against the hardcoded user name
|
||||
welcome_message = home_page.get_welcome_message()
|
||||
assert "Welcome, Test User!" in welcome_message, \
|
||||
f"Welcome message was '{welcome_message}', but expected it to contain 'Welcome, Test User!'."
|
||||
|
||||
@pytest.mark.smoke
|
||||
@pytest.mark.parametrize("email, password, expected_error", [
|
||||
("user@example.com", "wrongpassword", "Invalid email or password"),
|
||||
("wronguser@example.com", "password123", "Invalid email or password"),
|
||||
])
|
||||
def test_login_with_invalid_credentials(self, driver, base_url, email, password, expected_error):
|
||||
"""
|
||||
Tests that login fails with various invalid credentials and the correct
|
||||
error message is displayed.
|
||||
"""
|
||||
login_page = LoginPage(driver)
|
||||
login_page.open(base_url)
|
||||
|
||||
login_page.login(email, password)
|
||||
|
||||
assert expected_error in login_page.get_error_message()
|
||||
assert "login" in driver.current_url
|
||||
|
||||
def test_accessing_protected_route_redirects_to_login(self, driver, base_url):
|
||||
"""
|
||||
Tests that attempting to access a protected page (e.g., /home) without
|
||||
being logged in redirects the user to the login page.
|
||||
"""
|
||||
login_page = LoginPage(driver)
|
||||
|
||||
home_url = base_url.rstrip('/') + "/home"
|
||||
driver.get(home_url)
|
||||
|
||||
assert "login" in driver.current_url
|
||||
assert login_page.is_login_form_visible(), "Login form should be visible after redirect"
|
||||
Reference in New Issue
Block a user