├── .idea
├── .gitignore
├── PytestTutorials.iml
├── inspectionProfiles
│ ├── Project_Default.xml
│ └── profiles_settings.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── DemoFirstTest
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-311.pyc
│ ├── first_run_test.cpython-311-pytest-7.2.0.pyc
│ ├── test_assertions.cpython-311-pytest-7.2.0.pyc
│ └── test_first_run.cpython-311-pytest-7.2.0.pyc
└── first_run_test.py
├── DemoPytest
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-311.pyc
│ ├── test_assertions_hard.cpython-311-pytest-7.2.0.pyc
│ ├── test_assertions_soft.cpython-311-pytest-7.2.0.pyc
│ ├── test_fixtures.cpython-311-pytest-7.2.0.pyc
│ ├── test_fixtures_2.cpython-311-pytest-7.2.0.pyc
│ ├── test_markers_group.cpython-311-pytest-7.2.0.pyc
│ ├── test_multiple_subset_form.cpython-311-pytest-7.2.0.pyc
│ ├── test_multiple_subset_iphone.cpython-311-pytest-7.2.0.pyc
│ ├── test_parameters.cpython-311-pytest-7.2.0.pyc
│ └── test_parameters_2.cpython-311-pytest-7.2.0.pyc
├── geckodriver.log
├── test_assertions_hard.py
├── test_assertions_soft.py
├── test_cross_browser.py
├── test_fail.py
├── test_fixtures_1.py
├── test_fixtures_2.py
├── test_markers_group.py
├── test_multiple_subset_form.py
├── test_multiple_subset_iphone.py
├── test_parameters_1.py
├── test_parameters_2.py
├── test_skip.py
└── test_stop.py
├── __pycache__
└── conftest.cpython-311-pytest-7.2.0.pyc
├── conftest.py
├── main.py
├── pages
├── __init__.py
├── base_page.py
├── change_password_page.py
├── login_page.py
└── my_account_page.py
├── pytest.ini
├── tests
├── __init__.py
├── base_test.py
├── test_change_password.py
└── test_login.py
└── utilities
├── __init__.py
├── locators.py
└── test_data.py
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/PytestTutorials.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DemoFirstTest/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoFirstTest/__init__.py
--------------------------------------------------------------------------------
/DemoFirstTest/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoFirstTest/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/DemoFirstTest/__pycache__/first_run_test.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoFirstTest/__pycache__/first_run_test.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoFirstTest/__pycache__/test_assertions.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoFirstTest/__pycache__/test_assertions.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoFirstTest/__pycache__/test_first_run.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoFirstTest/__pycache__/test_first_run.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoFirstTest/first_run_test.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 |
3 | def test_lambdatest_playground():
4 | driver = webdriver.Chrome()
5 | driver.maximize_window()
6 | driver.get("https://www.lambdatest.com/selenium-playground/")
7 | print("Title: ", driver.title)
8 |
9 | def test2_lambdatest_ecommerce():
10 | driver = webdriver.Chrome()
11 | driver.maximize_window()
12 | driver.get("https://ecommerce-playground.lambdatest.io/")
13 | print("Title: ", driver.title)
14 |
15 | def testRexWebsite():
16 | driver = webdriver.Chrome()
17 | driver.maximize_window()
18 | driver.get("https://rexjones2.com")
19 | print("Title: ", driver.title)
20 |
21 | def google_test():
22 | driver = webdriver.Chrome()
23 | driver.maximize_window()
24 | driver.get("https://google.com")
25 | print("Title: ", driver.title)
26 |
--------------------------------------------------------------------------------
/DemoPytest/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__init__.py
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/__init__.cpython-311.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/__init__.cpython-311.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_assertions_hard.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_assertions_hard.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_assertions_soft.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_assertions_soft.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_fixtures.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_fixtures.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_fixtures_2.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_fixtures_2.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_markers_group.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_markers_group.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_multiple_subset_form.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_multiple_subset_form.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_multiple_subset_iphone.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_multiple_subset_iphone.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_parameters.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_parameters.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/__pycache__/test_parameters_2.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/DemoPytest/__pycache__/test_parameters_2.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/DemoPytest/geckodriver.log:
--------------------------------------------------------------------------------
1 | 1673230054863 geckodriver INFO Listening on 127.0.0.1:55664
2 | 1673230057910 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--remote-debugging-port" "55665" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileaxyYDz"
3 | 1673230058588 Marionette INFO Marionette enabled
4 | 1673230058594 Marionette INFO Listening on port 55677
5 | Read port: 55677
6 | WebDriver BiDi listening on ws://127.0.0.1:55665
7 | 1673230058874 RemoteAgent WARN TLS certificate errors will be ignored for this session
8 | console.warn: SearchSettings: "get: No settings file exists, new profile?" (new NotFoundError("Could not open the file at C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileaxyYDz\\search.json.mozlz4", (void 0)))
9 | DevTools listening on ws://127.0.0.1:55665/devtools/browser/0f9b8816-2fd8-4a1d-a4bf-f54a4ff33090
10 | 1673230063661 Marionette INFO Stopped listening on port 55677
11 | 1673230258599 geckodriver INFO Listening on 127.0.0.1:55979
12 | 1673230261633 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--remote-debugging-port" "55980" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileg1pPLK"
13 | 1673230262165 Marionette INFO Marionette enabled
14 | 1673230262171 Marionette INFO Listening on port 55992
15 | Read port: 55992
16 | WebDriver BiDi listening on ws://127.0.0.1:55980
17 | 1673230262448 RemoteAgent WARN TLS certificate errors will be ignored for this session
18 | console.warn: SearchSettings: "get: No settings file exists, new profile?" (new NotFoundError("Could not open the file at C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileg1pPLK\\search.json.mozlz4", (void 0)))
19 | DevTools listening on ws://127.0.0.1:55980/devtools/browser/316aef71-1e41-4c57-a282-c587485ecb93
20 | 1673230267011 Marionette INFO Stopped listening on port 55992
21 | 1678243550011 geckodriver INFO Listening on 127.0.0.1:61598
22 | 1678243553051 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--remote-debugging-port" "61599" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileHQ0tS9"
23 | console.warn: services.settings: Ignoring preference override of remote settings server
24 | console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment
25 | 1678243553480 Marionette INFO Marionette enabled
26 | Dynamically enable window occlusion 0
27 | 1678243553486 Marionette INFO Listening on port 61608
28 | Read port: 61608
29 | WebDriver BiDi listening on ws://127.0.0.1:61599
30 | 1678243553609 RemoteAgent WARN TLS certificate errors will be ignored for this session
31 | console.warn: SearchSettings: "get: No settings file exists, new profile?" (new NotFoundError("Could not open the file at C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileHQ0tS9\\search.json.mozlz4", (void 0)))
32 | DevTools listening on ws://127.0.0.1:61599/devtools/browser/9093b034-1ed1-4352-858d-3f0e566256d2
33 | 1678243558848 Marionette INFO Stopped listening on port 61608
34 | Dynamically enable window occlusion 1
35 | 1678243672818 geckodriver INFO Listening on 127.0.0.1:61800
36 | 1678243675863 mozrunner::runner INFO Running command: "C:\\Program Files\\Mozilla Firefox\\firefox.exe" "--marionette" "--remote-debugging-port" "61801" "--remote-allow-hosts" "localhost" "-no-remote" "-profile" "C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileT6hAf2"
37 | console.warn: services.settings: Ignoring preference override of remote settings server
38 | console.warn: services.settings: Allow by setting MOZ_REMOTE_SETTINGS_DEVTOOLS=1 in the environment
39 | 1678243676181 Marionette INFO Marionette enabled
40 | Dynamically enable window occlusion 0
41 | 1678243676186 Marionette INFO Listening on port 61809
42 | Read port: 61809
43 | WebDriver BiDi listening on ws://127.0.0.1:61801
44 | 1678243676305 RemoteAgent WARN TLS certificate errors will be ignored for this session
45 | console.warn: SearchSettings: "get: No settings file exists, new profile?" (new NotFoundError("Could not open the file at C:\\Users\\RexJo\\AppData\\Local\\Temp\\rust_mozprofileT6hAf2\\search.json.mozlz4", (void 0)))
46 | DevTools listening on ws://127.0.0.1:61801/devtools/browser/2bd75a89-c83d-4516-ad04-3848c9f88115
47 | 1678243681757 Marionette INFO Stopped listening on port 61809
48 | Dynamically enable window occlusion 1
49 |
--------------------------------------------------------------------------------
/DemoPytest/test_assertions_hard.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 | from selenium.webdriver.common.by import By
3 |
4 | class AssertionsTest():
5 | pass
6 |
7 | def test_lambdatest_radio_button_demo_value():
8 | driver = webdriver.Chrome()
9 | driver.maximize_window()
10 | driver.get("https://www.lambdatest.com/selenium-playground/radiobutton-demo")
11 | driver.find_element(By.XPATH,
12 | "//h4[contains(text(),'Gender')]"
13 | "//following::input[@value='Male']").click()
14 | driver.find_element(By.XPATH,
15 | "//h4[contains(text(),'Age Group')]"
16 | "//following::input[@value='15 - 50']").click()
17 | driver.find_element(By.XPATH,
18 | "//button[text()='Get values']").click()
19 | gender = driver.find_element(By.CSS_SELECTOR,
20 | ".genderbutton").text
21 | age_group = driver.find_element(By.CSS_SELECTOR,
22 | ".groupradiobutton").text
23 | print("Gender Object: \t", id(gender))
24 | print("Male Object: \t", id("Male"))
25 | assert gender is "Male", "Gender Is Not Correct"
26 | assert driver.title.__contains__("Selenium Grid Online")
27 | assert "51" in age_group, "Age Group Is Not Correct"
28 |
--------------------------------------------------------------------------------
/DemoPytest/test_assertions_soft.py:
--------------------------------------------------------------------------------
1 | import softest
2 | from selenium import webdriver
3 | from selenium.webdriver.common.by import By
4 |
5 | class AssertionsTest(softest.TestCase):
6 | pass
7 |
8 | def test_lambdatest_radio_button_demo_value(self):
9 | driver = webdriver.Chrome()
10 | driver.maximize_window()
11 | driver.get("https://www.lambdatest.com/selenium-playground/radiobutton-demo")
12 | driver.find_element(By.XPATH,
13 | "//h4[contains(text(),'Gender')]"
14 | "//following::input[@value='Male']").click()
15 | driver.find_element(By.XPATH,
16 | "//h4[contains(text(),'Age Group')]"
17 | "//following::input[@value='15 - 50']").click()
18 | driver.find_element(By.XPATH,
19 | "//button[text()='Get values']").click()
20 | gender = driver.find_element(By.CSS_SELECTOR,
21 | ".genderbutton").text
22 | age_group = driver.find_element(By.CSS_SELECTOR,
23 | ".groupradiobutton").text
24 | print("Gender Object: \t", id(gender))
25 | print("Male Object: \t", id("Male"))
26 | self.soft_assert(self.assertIs,
27 | "Male", gender, "Gender Is Not Correct")
28 | self.soft_assert(self.assertTrue,
29 | driver.title.__contains__("Selenium Grid Online"))
30 | self.soft_assert(self.assertIn,
31 | "51", age_group, "Age Group Is Not Correct")
32 | self.assert_all("Verify Gender, Title, & Age Group")
33 |
--------------------------------------------------------------------------------
/DemoPytest/test_cross_browser.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 | from selenium.webdriver.common.by import By
3 | import pytest
4 |
5 | @pytest.mark.usefixtures("driver_initialization")
6 | class BaseClass:
7 | pass
8 |
9 | class TestSeleniumGrid(BaseClass):
10 | def test_lambdatest_remaining_checkboxes(self):
11 | driver = webdriver.Chrome()
12 | driver.get("https://lambdatest.github.io/sample-todo-app/")
13 | driver.find_element(By.XPATH, "//input[@name='li3']").click()
14 | remaining_checkboxes = driver.find_element\
15 | (By.CSS_SELECTOR, "span.ng-binding").text
16 | assert remaining_checkboxes == "4 of 5 remaining"
17 |
--------------------------------------------------------------------------------
/DemoPytest/test_fail.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | class Test_Math:
4 | def test_divide_number(self):
5 | pytest.xfail("Need To Investigate")
6 | num = 10
7 | result = num + num
8 | assert result == num / num
9 |
10 | @pytest.mark.xfail(reason="Result Add Numbers & Not Multiply Numbers")
11 | def test_square_number(self):
12 | num = 10
13 | result = num + num # 10 * 10 = 100
14 | assert result == num ** 2
15 |
16 | @pytest.mark.xfail(reason="Result & Assert Are Correct")
17 | def test_cube_number(self):
18 | num = 10
19 | result = num * num * num # 10 * 10 * 10 = 1000
20 | assert result == num ** 3
21 |
22 | @pytest.mark.xfail(run=False)
23 | def test_number_square(self):
24 | num = 10
25 | result = num * num # 10 * 10 = 100
26 | assert result == num ** 2
27 |
--------------------------------------------------------------------------------
/DemoPytest/test_fixtures_1.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from selenium import webdriver
3 | from selenium.webdriver.common.by import By
4 |
5 | driver = webdriver.Chrome()
6 |
7 | @pytest.fixture(autouse=True)
8 | def start_automatic_fixture():
9 | print("Start Test With Automatic Fixture")
10 |
11 | @pytest.fixture()
12 | def setup_teardown():
13 | driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=account/login")
14 | driver.find_element(By.ID, "input-email")\
15 | .send_keys("PytestSelenium@Gmail.com")
16 | driver.find_element(By.ID, "input-password")\
17 | .send_keys("@1234PytestSelenium")
18 | driver.find_element(By.XPATH,
19 | "//input[@value='Login']").click()
20 | print("Log In")
21 | yield
22 | driver.find_element(By.PARTIAL_LINK_TEXT,
23 | "Logout").click()
24 | print("Log Out")
25 |
26 | def test1_order_history_title(setup_teardown):
27 | driver.find_element(By.PARTIAL_LINK_TEXT,
28 | "Order").click()
29 | assert driver.title == "Order History"
30 | print("Test 1 Is Complete")
31 |
32 | def test2_change_password_title(setup_teardown):
33 | driver.find_element(By.PARTIAL_LINK_TEXT,
34 | "Password").click()
35 | assert driver.title == "Change Password"
36 | print("Test 2 Is Complete")
37 |
--------------------------------------------------------------------------------
/DemoPytest/test_fixtures_2.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from selenium import webdriver
3 | from selenium.webdriver.common.by import By
4 |
5 | driver = webdriver.Chrome()
6 |
7 | @pytest.fixture(autouse=True)
8 | def start_automatic_fixture():
9 | print("Start Test With Automatic Fixture")
10 |
11 | @pytest.fixture(scope="function")
12 | def setup_teardown():
13 | driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=account/login")
14 | driver.find_element(By.ID, "input-email")\
15 | .send_keys("PytestSelenium@Gmail.com")
16 | driver.find_element(By.ID, "input-password")\
17 | .send_keys("@1234PytestSelenium")
18 | driver.find_element(By.XPATH,
19 | "//input[@value='Login']").click()
20 | print("Log In")
21 | yield
22 | driver.find_element(By.PARTIAL_LINK_TEXT,
23 | "Logout").click()
24 | print("Log Out")
25 |
26 | @pytest.mark.usefixtures("setup_teardown")
27 | def test1_order_history_title():
28 | driver.find_element(By.PARTIAL_LINK_TEXT,
29 | "Order").click()
30 | assert driver.title == "Order History"
31 | print("Test 1 Is Complete")
32 |
33 | @pytest.mark.usefixtures("setup_teardown")
34 | def test2_change_password_title():
35 | driver.find_element(By.PARTIAL_LINK_TEXT,
36 | "Password").click()
37 | assert driver.title == "Change Password"
38 | print("Test 2 Is Complete")
39 |
--------------------------------------------------------------------------------
/DemoPytest/test_markers_group.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from selenium import webdriver
3 | from selenium.webdriver.common.by import By
4 |
5 | pytestmark = [pytest.mark.regression, pytest.mark.sanity]
6 | # pytestmark = pytest.mark.regression
7 |
8 | @pytest.mark.integration
9 | @pytest.mark.smoke
10 | def test_lambdatest_ajax_form():
11 | driver = webdriver.Chrome()
12 | driver.maximize_window()
13 | driver.get("https://www.lambdatest.com/selenium-playground/ajax-form-submit-demo")
14 | driver.find_element(By.ID, "title")\
15 | .send_keys("Pytest Tutorial")
16 | driver.find_element(By.ID, "description")\
17 | .send_keys("LambdaTest Selenium Playground")
18 | driver.find_element(By.ID, "btn-submit").click()
19 | request = driver.find_element(By.ID,
20 | "submit-control").text
21 | assert request.__contains__("Processing")
22 |
23 | def test_e2e():
24 | print("End To End Test")
25 |
26 | @pytest.mark.smoke
27 | def test_login():
28 | print("Log Into Application")
29 |
30 | @pytest.mark.smoke
31 | def test_logout():
32 | print("Log Out Application")
33 |
--------------------------------------------------------------------------------
/DemoPytest/test_multiple_subset_form.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 | from selenium.webdriver.common.by import By
3 |
4 | def test_lambdatest_simple_form_demo():
5 | driver = webdriver.Chrome()
6 | driver.maximize_window()
7 | driver.get("https://www.lambdatest.com/selenium-playground/simple-form-demo")
8 | driver.find_element(By.XPATH,
9 | "//input[@id='user-message']")\
10 | .send_keys("Pytest Is A Test Framework")
11 | driver.find_element(By.ID, "showInput").click()
12 | message = driver.find_element(By.ID, "message").text
13 | assert message == "Pytest Is A Test Framework"
14 |
--------------------------------------------------------------------------------
/DemoPytest/test_multiple_subset_iphone.py:
--------------------------------------------------------------------------------
1 | from selenium import webdriver
2 | from selenium.webdriver.common.by import By
3 |
4 | def test_search_lambdatest_ecommerce():
5 | driver = webdriver.Chrome()
6 | driver.maximize_window()
7 | driver.get("https://ecommerce-playground.lambdatest.io/")
8 | driver.find_element(By.XPATH,
9 | "//input[@placeholder='Search For Products']")\
10 | .send_keys("iPhone")
11 | driver.find_element(By.XPATH,
12 | "//button[text()='Search']").click()
13 | search_value = driver.find_element(By.XPATH,
14 | "//h1[contains(text(),'Search')]").text
15 | assert "iPhone" in search_value
16 |
17 | def test_add_to_cart():
18 | result = 1
19 | print("Add To Cart")
20 | assert result == 3
21 |
--------------------------------------------------------------------------------
/DemoPytest/test_parameters_1.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | from selenium import webdriver
4 | from selenium.webdriver.common.by import By
5 | import pytest
6 |
7 | @pytest.mark.parametrize("num1, num2, expected_total",
8 | [
9 | ("25", "25", "50"),
10 | ("10", "10", "30"),
11 | ("30", "40", "70")
12 | ])
13 | def test_lambdatest_two_input_fields(num1, num2, expected_total):
14 | driver = webdriver.Chrome()
15 | driver.maximize_window()
16 | driver.get("https://www.lambdatest.com/selenium-playground/simple-form-demo")
17 | driver.find_element(By.ID, "sum1").send_keys(num1)
18 | driver.find_element(By.ID, "sum2").send_keys(num2)
19 | driver.find_element(By.XPATH,
20 | "//button[text()='Get values']").click()
21 | actual_total = driver.find_element(By.ID, "addmessage").text
22 | assert actual_total == expected_total, \
23 | "Actual & Expected Totals Do Not Match"
24 |
25 | @pytest.mark.parametrize("base", [1, 2, 3])
26 | @pytest.mark.parametrize("exponent", [4, 5, 6])
27 | def test_raising_base_to_power(base, exponent):
28 | result = base ** exponent
29 | assert result == math.pow(base, exponent)
30 |
--------------------------------------------------------------------------------
/DemoPytest/test_parameters_2.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from selenium.webdriver.common.by import By
3 |
4 | @pytest.mark.usefixtures("initialize_driver")
5 | class BaseClass:
6 | pass
7 |
8 | class Test_Drivers(BaseClass):
9 | def test_multiple_browsers(self):
10 | self.driver.get("https://www.lambdatest.com/selenium-playground/")
11 | header = self.driver.find_element(By.CSS_SELECTOR,
12 | "div#__next h1").text
13 | print("Header: ", header)
14 | assert header == "Selenium Playground"
15 |
--------------------------------------------------------------------------------
/DemoPytest/test_skip.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | import pytest
4 | from selenium import webdriver
5 |
6 |
7 | class TestLambdaTest:
8 | def test_sample_app_title(self):
9 | driver = webdriver.Chrome()
10 | driver.get("https://lambdatest.github.io/sample-todo-app/")
11 | pytest.skip()
12 | expected_title = "Sample page - lambdatest.com"
13 | assert expected_title == driver.title
14 |
15 | @pytest.mark.skip(reason="Code Has Not Been Deployed")
16 | def test_ecommerce_title(self):
17 | driver = webdriver.Chrome()
18 | driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=product/category&path=17")
19 | expected_title = "Software"
20 | assert expected_title == driver.title
21 |
22 | @pytest.mark.skip()
23 | def test_special_offers(self):
24 | driver = webdriver.Chrome()
25 | driver.get("https://ecommerce-playground.lambdatest.io/index.php?route=product/special")
26 | expected_title = "Special Offers"
27 | assert expected_title == driver.title
28 |
29 | @pytest.mark.skipif(
30 | datetime.now() <= datetime(2099, 12, 31),
31 | reason="Repo Is Not Complete Until After Finishing Tutorial")
32 | def test_pytest_github_repo(self):
33 | driver = webdriver.Chrome()
34 | driver.get("https://github.com/RexJonesII/PytestTutorials")
35 | expected_title = "RexJonesII"
36 | print("Title: ", expected_title)
37 | assert driver.title.__contains__(expected_title)
38 |
--------------------------------------------------------------------------------
/DemoPytest/test_stop.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | # @pytest.mark.skip(reason="Demonstrate How To Skip A Class")
4 | # @pytest.mark.xfail (reason="Demonstrate How To XFAIL/XPASS A Class")
5 | class Test_Math:
6 | # Pass
7 | def test_number_square(self):
8 | num = 10
9 | result = num * num # 10 * 10 = 100
10 | assert result == num ** 2
11 |
12 | def test_divide_number(self):
13 | # Fail
14 | num = 10
15 | result = num + num
16 | assert result == num / num
17 |
18 | # Fail
19 | def test_square_number(self):
20 | num = 10
21 | result = num + num # 10 * 10 = 100
22 | assert result == num ** 2
23 |
24 | # Pass
25 | def test_cube_number(self):
26 | num = 10
27 | result = num * num * num # 10 * 10 * 10 = 1000
28 | assert result == num ** 3
29 |
--------------------------------------------------------------------------------
/__pycache__/conftest.cpython-311-pytest-7.2.0.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/__pycache__/conftest.cpython-311-pytest-7.2.0.pyc
--------------------------------------------------------------------------------
/conftest.py:
--------------------------------------------------------------------------------
1 | import pytest
2 | from selenium import webdriver
3 | from selenium.webdriver.remote.remote_connection import RemoteConnection
4 |
5 | from utilities.test_data import TestData
6 |
7 | @pytest.fixture(params=["chrome", "firefox", "edge"])
8 | def initialize_driver(request):
9 | if request.param == "chrome":
10 | driver = webdriver.Chrome()
11 | elif request.param == "firefox":
12 | driver = webdriver.Firefox()
13 | elif request.param == "edge":
14 | driver = webdriver.Edge()
15 | request.cls.driver = driver
16 | print("Browser: ", request.param)
17 | driver.get(TestData.url)
18 | driver.maximize_window()
19 | yield
20 | print("Close Driver")
21 | driver.close()
22 |
23 | # 1st Step: Declare Variables For Setting Up LambdaTest
24 | user_name = "Rex.Jones"
25 | access_token = "YxU1eSK0Cx3WkN7d2FouJ4agNhPUiw8yOrXWAF8TN19LvOueVB"
26 | remote_url = "https://" + user_name + ":" + access_token + "@hub.lambdatest.com/wd/hub"
27 |
28 | # 2nd Step: Define The Desired Capabilities (3 Caps)
29 | chrome_caps = {
30 | "build" : "1.0",
31 | "name" : "LambdaTest Grid On Chrome",
32 | "platform" : "Windows 10",
33 | "browserName" : "Chrome",
34 | "version" : "latest"
35 | }
36 |
37 | firefox_caps = {
38 | "build" : "2.0",
39 | "name" : "LambdaTest Grid On Firefox",
40 | "platform" : "Windows 10",
41 | "browserName" : "Firefox",
42 | "version" : "latest"
43 | }
44 |
45 | edge_caps = {
46 | "build" : "3.0",
47 | "name" : "LambdaTest Grid On Edge",
48 | "platform" : "Windows 10",
49 | "browserName" : "Edge",
50 | "version" : "latest"
51 | }
52 |
53 | #3rd Step: Connect To LambdaTest Using A Fixture & RemoteConnection
54 | @pytest.fixture(params=["chrome", "firefox", "edge"])
55 | def driver_initialization(request):
56 | """
57 | Initialize Driver For Selenium Grid On LambdaTest
58 | :param request:
59 | """
60 | desired_caps = {}
61 |
62 | if request.param == "chrome":
63 | desired_caps.update(chrome_caps)
64 | driver = webdriver.Remote(
65 | command_executor=RemoteConnection(remote_url),
66 | desired_capabilities={"LT:Options":desired_caps})
67 | elif request.param == "firefox":
68 | desired_caps.update(firefox_caps)
69 | driver = webdriver.Remote(
70 | command_executor=RemoteConnection(remote_url),
71 | desired_capabilities={"LT:Options": desired_caps})
72 | elif request.param == "edge":
73 | desired_caps.update(edge_caps)
74 | driver = webdriver.Remote(
75 | command_executor=RemoteConnection(remote_url),
76 | desired_capabilities={"LT:Options": desired_caps})
77 | request.cls.driver = driver
78 | yield
79 | driver.close()
80 |
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | # This is a sample Python script.
2 |
3 | # Press Shift+F10 to execute it or replace it with your code.
4 | # Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.
5 |
6 |
7 | def print_hi(name):
8 | # Use a breakpoint in the code line below to debug your script.
9 | print(f'Hi, {name}') # Press Ctrl+F8 to toggle the breakpoint.
10 |
11 |
12 | # Press the green button in the gutter to run the script.
13 | if __name__ == '__main__':
14 | print_hi('PyCharm')
15 |
16 | # See PyCharm help at https://www.jetbrains.com/help/pycharm/
17 |
--------------------------------------------------------------------------------
/pages/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/pages/__init__.py
--------------------------------------------------------------------------------
/pages/base_page.py:
--------------------------------------------------------------------------------
1 | from selenium.webdriver.common.by import By
2 |
3 |
4 | class BasePage:
5 | """
6 | The Purpose Of A BasePage Is To Contain Methods Common To All Page Objects
7 | """
8 | def __init__(self, driver):
9 | self.driver = driver
10 |
11 | def find(self, *locator):
12 | return self.driver.find_element(*locator)
13 |
14 | def click(self, locator):
15 | self.find(*locator).click()
16 | # self.driver.find_element(*locator).click()
17 |
18 | def set(self, locator, value):
19 | self.find(*locator).clear()
20 | self.find(*locator).send_keys(value)
21 |
22 | def get_text(self, locator):
23 | return self.find(*locator).text
24 |
25 | def get_title(self):
26 | return self.driver.title
27 |
28 | def click_right_menu_page(self, page_name):
29 | # self.click(self.page(page_name))
30 | page = By.XPATH, "//aside[@id='column-right']//a[text()=' "+ page_name +"']"
31 | self.click(page)
32 |
33 | # Below Method Allows Us To Click Page, Check If Page Is Visible, & More Actions
34 | def page(self, page_name):
35 | return By.XPATH, "//aside[@id='column-right']//a[text()=' "+ page_name +"']"
36 |
--------------------------------------------------------------------------------
/pages/change_password_page.py:
--------------------------------------------------------------------------------
1 | from pages.base_page import BasePage
2 | from pages.my_account_page import MyAccountPage
3 | from utilities.locators import ChangePasswordLocatorFields
4 |
5 |
6 | class ChangePasswordPage(BasePage):
7 |
8 | def __init__(self, driver):
9 | self.locate = ChangePasswordLocatorFields
10 | super().__init__(driver)
11 |
12 | def change_password(self, password, confirm_password):
13 | self.set(self.locate.password_field, password)
14 | self.set(self.locate.confirm_password_field, confirm_password)
15 | self.click(self.locate.continue_button)
16 | return MyAccountPage(self.driver)
17 |
18 | def get_confirmation_error_message(self):
19 | return self.get_text(self.locate.confirmation_error_message)
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/pages/login_page.py:
--------------------------------------------------------------------------------
1 | from selenium.webdriver.common.by import By
2 |
3 | from pages.base_page import BasePage
4 | from pages.my_account_page import MyAccountPage
5 |
6 |
7 | class LoginPage(BasePage):
8 | email_address_field = (By.ID, "input-email")
9 | password_field = (By.ID, "input-password")
10 | login_button = (By.XPATH, "//div[@id='content']//input[@value='Login']")
11 | warning_message = (By.CSS_SELECTOR, "#account-login .alert-danger")
12 |
13 | def __init__(self, driver):
14 | super().__init__(driver)
15 |
16 | def set_email_address(self, email_address):
17 | self.set(self.email_address_field, email_address)
18 | # self.driver.find_element(self.email_address_field).send_keys(email_address)
19 |
20 | def set_password(self, password):
21 | self.set(self.password_field, password)
22 |
23 | def click_login_button(self):
24 | self.click(self.login_button)
25 | return MyAccountPage(self.driver)
26 |
27 | def log_into_application(self, email, password):
28 | self.set_email_address(email)
29 | self.set_password(password)
30 | self.click_login_button()
31 |
32 | def get_warning_message(self):
33 | return self.get_text(self.warning_message)
34 |
--------------------------------------------------------------------------------
/pages/my_account_page.py:
--------------------------------------------------------------------------------
1 | from pages.base_page import BasePage
2 |
3 | class MyAccountPage(BasePage):
4 | pass
5 |
--------------------------------------------------------------------------------
/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | markers =
3 | smoke: Smoke Test
4 | regression: Regression Test
5 | sanity
6 | integration:
7 | addopts = -rA -v --html=AutomatonPytestReport.html
8 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/tests/__init__.py
--------------------------------------------------------------------------------
/tests/base_test.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | @pytest.mark.usefixtures("initialize_driver")
4 | class BaseTest:
5 | pass
--------------------------------------------------------------------------------
/tests/test_change_password.py:
--------------------------------------------------------------------------------
1 | from pages.change_password_page import ChangePasswordPage
2 | from pages.login_page import LoginPage
3 | from tests.base_test import BaseTest
4 | from utilities.test_data import TestData
5 |
6 | class TestChangePassword(BaseTest):
7 |
8 | def test_changing_password(self):
9 | login_page = LoginPage(self.driver)
10 | change_password_page = ChangePasswordPage(self.driver)
11 | expected_message = "Password confirmation does not match password!"
12 | login_page.set_email_address(TestData.email)
13 | login_page.set_password(TestData.password)
14 | my_account_page = login_page.click_login_button()
15 | my_account_page.click_right_menu_page("Password")
16 | change_password_page.change_password(
17 | "InvalidPassword", "InvalidConfirmPassword")
18 | actual_message = change_password_page.get_confirmation_error_message()
19 | assert actual_message == expected_message
20 |
--------------------------------------------------------------------------------
/tests/test_login.py:
--------------------------------------------------------------------------------
1 | from pages.login_page import LoginPage
2 | from tests.base_test import BaseTest
3 | from utilities.test_data import TestData
4 |
5 |
6 | class TestLogin(BaseTest):
7 |
8 | def test_valid_credentials(self):
9 | login_page = LoginPage(self.driver)
10 | login_page.set_email_address(TestData.email)
11 | login_page.set_password(TestData.password)
12 | login_page.click_login_button()
13 | actual_title = login_page.get_title()
14 | assert actual_title == "My Account"
15 |
16 | def test_invalid_credentials(self):
17 | login_page = LoginPage(self.driver)
18 | login_page.log_into_application(
19 | "Invalid Email", "Invalid Password")
20 | actual_message = login_page.get_warning_message()
21 | assert actual_message.__contains__("Warning")
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/utilities/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RexJonesII/PytestTutorials/565fa3045533b57823c8946d2137b1e2ca7318fb/utilities/__init__.py
--------------------------------------------------------------------------------
/utilities/locators.py:
--------------------------------------------------------------------------------
1 | from selenium.webdriver.common.by import By
2 |
3 | class ChangePasswordLocatorFields:
4 | password_field = (By.ID, "input-password")
5 | confirm_password_field = (By.ID, "input-confirm")
6 | continue_button = (By.XPATH, "//div[@id='content']//input[@value='Continue']")
7 | confirmation_error_message = (By.CSS_SELECTOR, "#content .text-danger")
8 |
--------------------------------------------------------------------------------
/utilities/test_data.py:
--------------------------------------------------------------------------------
1 |
2 | class TestData:
3 | url = "https://ecommerce-playground.lambdatest.io/index.php?route=account/login"
4 | email = "PytestSelenium@GMail.com"
5 | password = "@1234PytestSelenium"
6 |
--------------------------------------------------------------------------------