{"id":20846517,"url":"https://github.com/ivpel/vigilant-pytest-example","last_synced_at":"2026-04-20T22:03:29.460Z","repository":{"id":133583492,"uuid":"568775662","full_name":"ivpel/vigilant-pytest-example","owner":"ivpel","description":"Example of how to use vigilant-kit and pytest.","archived":false,"fork":false,"pushed_at":"2022-11-21T13:34:35.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-28T11:07:26.545Z","etag":null,"topics":["pytest","python","selenium","tutorial","vigilant","webdriver"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ivpel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-21T11:39:02.000Z","updated_at":"2022-12-10T06:13:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"bfcddd5a-818d-4b39-a0d3-ce3130201c9d","html_url":"https://github.com/ivpel/vigilant-pytest-example","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ivpel/vigilant-pytest-example","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpel%2Fvigilant-pytest-example","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpel%2Fvigilant-pytest-example/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpel%2Fvigilant-pytest-example/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpel%2Fvigilant-pytest-example/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ivpel","download_url":"https://codeload.github.com/ivpel/vigilant-pytest-example/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ivpel%2Fvigilant-pytest-example/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32067626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pytest","python","selenium","tutorial","vigilant","webdriver"],"created_at":"2024-11-18T02:16:44.269Z","updated_at":"2026-04-20T22:03:29.454Z","avatar_url":"https://github.com/ivpel.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Testing ecommerce project with `vigilant-kit` and `pytest`\nIn this tutorial, we will learn how to use `vigilant-kit` with `pytest` in real-like project\nwith **POM** pattern and **fixtures**.\n\nThis is a simplified example, but it is enough to understand how it works and be able to apply and use it on your project!\n\nGood luck!\n\nSource code: [vigilant-kit and pytest](https://github.com/ivpel/vigilant-pytest)\n\nPytest docs: [pytest](https://docs.pytest.org/en/latest/getting-started.html)\n\n## Table of content:\n1. [Install `pytest`, `vigilant-kit` and `Selenium Webdriver` server.](#installation-part)\n2. [POM pattern.](#pom-pattern)\n3. [Writing tests.](#writing-tests)\n\n## Installation part\nTo install `vigilant-kit` in your project, run this command:\n```shell\npip install vigilant-kit\n```\nInstall `pytest`:\n```shell\npip install pytest\n```\nHow to install and run Selenium Server described here [Install Selenium Server](https://github.com/ivpel/vigilant-kit/blob/main/docs/selenium_install.md)\n\n## POM pattern\nWhat is POM pattern?\nPage Object Model (POM) is a design pattern, popularly used in test automation that creates Object Repository for web UI\nelements. The advantage of the model is that it reduces code duplication and improves test maintenance.\nUnder this model, for each web page in the application, there should be a corresponding Page Class. This Page class will\nidentify the WebElements of that web page and also contains Page methods which perform operations on those WebElements.\n\nFor our basic ecommerce project we want to have next POM objects:\n   1. Login Page\n   2. Category List page\n   3. Product Page\n   4. Cart Page\n   5. Checkout Page\n\n## Writing tests\nOur test target will be this project: https://www.saucedemo.com/\nIt is simple, yet perfect for our purposes' resource.\n\n### Tests \u0026 dirs structure\nDirectory - separation between tests type is a good way to manage your tests.\nFunctional in `functional/` directory, unit tests inside `unit/` directory, etc.\n\nInside `functional/` dir we need to create two more dirs: \n`fixtures/` - for our fixtures.\n`pom/` - for our Page Objects Model objects.\n\nLike this:\n```shell\n  tests/functional \n    - fixtures/\n    - pom/\n    - test_name.py\n```\n\nAlso, don't forget about our configuration file `.vigilant.env`. You can place it in root of your project,\nor as example - inside `tests/functional/` directory. \n\nExample of `.vigilant.env` configuration:\n```text\nSELENIUM_HOST=http://127.0.0.1:4444/wd/hub\nSELENIUM_BROWSER=firefox\nBASE_URL=https://www.saucedemo.com\nWAIT_TIMEOUT=10\nLOGGER_LEVEL=INFO\n```\n\n### POM objects\nI like to start testing from deciding and describing my Page Objects. So when I will write\nactual tests I will already use correct locators from correct Object Repository.\nSo for which pages we will create POM objects? Check below:\n   1. Login Page\n   2. Category List page\n   3. Product Page\n   4. Cart Page\n   5. Checkout Page\n   \n\nLet's start with Login Page, but first we need to do something else - create BasePage object.\nBasePage class will be parent class for all other pages.\n\n`functional/pom/base_page.py`\n```python\nfrom vigilant.driver.vigilant_driver import VigilantDriver\n\n\nclass BasePage:\n\n    def __init__(self, driver):\n        self.driver: VigilantDriver = driver\n\n```\n\nUsing `BasePage` class let's create `LoginPage`.\n\n1. Login page\n\n`functional/pom/login_page.py`\n```python\nfrom .base_page import BasePage\n\n\nclass LoginPage(BasePage):\n\n    USERNAME_INPUT = '//input[@id=\"user-name\"]'\n    PASSWORD_INPUT = '//input[@id=\"password\"]'\n    LOGIN_BUTTON = '//input[@id=\"login-button\"]'\n\n    USERNAME_DATA = 'standard_user'\n    PASSWORD_DATA = 'secret_sauce'\n\n    def __init__(self, driver):\n        super().__init__(driver)\n\n    def fill_in_and_login(self):\n        self.driver.fill_field(self.USERNAME_INPUT, self.USERNAME_DATA)\n        self.driver.fill_field(self.PASSWORD_INPUT, self.PASSWORD_DATA)\n        self.driver.click(self.LOGIN_BUTTON)\n```\n\n2. Category List page\n\n`functional/pom/category_list_page.py`\n```python\nfrom .base_page import BasePage\n\n\nclass CategoryListPage(BasePage):\n\n    PRODUCT_CARD = '//div[@class=\"inventory_item\"]'\n    PRODUCT_NAME = '//div[@class=\"inventory_item_name\"]'\n    ADD_TO_CART_BUTTON = '//button[text()=\"Add to cart\"]'\n    PRODUCT_PRICE = '//div[@class=\"inventory_item_price\"]'\n\n    def __init__(self, driver):\n        super().__init__(driver)\n```\n\n3. Product Detail page\n\n`functional/pom/product_detail_page.py`\n```python\nfrom .base_page import BasePage\n\n\nclass ProductDetailPage(BasePage):\n\n    PRODUCT_PRICE = '//div[@class=\"inventory_details_price\"]'\n    ADD_TO_CART_BUTTON = '//button[text()=\"Add to cart\"]'\n    BACK_TO_CLP_BUTTON = '//button[@id=\"back-to-products\"]'\n    \n    def __init__(self, driver):\n        super().__init__(driver)\n```\n\n4. Cart page\n\n`functional/pom/cart_page.py`\n```python\nfrom .base_page import BasePage\n\n\nclass CartPage(BasePage):\n    \n    CART_ICON_LINK = '//a[@class=\"shopping_cart_link\"]'\n    PRODUCT_PRICE = '//div[@class=\"inventory_item_price\"]'\n    PRODUCT_NAME = '//div[@class=\"inventory_item_name\"]'\n    REMOVE_PRODUCT = '//button[text()=\"Remove\"]'\n    CONTINUE_SHOPPING_BUTTON = '//button[@id=\"continue-shopping\"]'\n    CHECKOUT_BUTTON = '//button[@id=\"checkout\"]'\n    \n    \n    def __init__(self, driver):\n        super().__init__(driver)\n```\n\n5. Checkout page\n\n`functional/pom/cart_page.py`\n```python\nfrom .base_page import BasePage\n\n\nclass CheckoutPage(BasePage):\n\n    # First step checkout\n    FIRST_NAME = '//input[@id=\"first-name\"]'\n    LAST_NAME = '//input[@id=\"last-name\"]'\n    ZIP_CODE = '//input[@id=\"postal-code\"]'\n    CONTINUE_BUTTON = '//input[@id=\"continue\"]'\n    \n    # Second step checkout\n    FINISH_BUTTON = '//button[@id=\"finish\"]'\n    CANCEL_BUTTON = '//button[@id=\"cancel\"]'\n    \n    # Checkout complete\n    BACK_HOME_BUTTON = '//button[@id=\"back-to-products\"]'\n    \n    def __init__(self, driver):\n        super().__init__(driver)\n```\n\nNow let's create Login test.\n`functional/test_ecommerce.py`\n```python\nimport pytest\n\nfrom vigilant.driver.vigilant_driver import VigilantDriver\nfrom pom.login_page import LoginPage\n\n\n@pytest.fixture(scope=\"module\")\ndef driver():\n    vd = VigilantDriver()\n    yield vd\n    vd.quit()\n\n\ndef test_login(driver):\n    login_page = LoginPage(driver)\n    driver.get_page('/')\n    login_page.fill_in_and_login()\n\n```\nRun it:\n```shell\npytest tests/functional/test_ecommerce.py\n```\n\nIn the example above, we use data from `LoginPage` class, which allow us to use elements locators and\nmethod for login in. So if we will have more tests in the future which require login functionality - we will use\n`LoginPage` object, and if something in the project will change - we will need to refactor it only in one place, not in \nthe all tests that were affected by changes.\n\nGood! We are now logged in. Go next to the Category List Page and make sure that we can add projects from CLP.\n\n`functional/test_ecommerce.py`\n```python\n...\nfrom pom.category_list_page import CategoryListPage\n\n...\n\ndef test_add_product_from_clp(driver):\n    clp = CategoryListPage(driver)\n\n    driver.assertions.see(clp.PRODUCT_CARD + '[1]') # +[1] is Xpath trick to say that we looking for FIRST available element with this selector\n    driver.click(clp.ADD_TO_CART_BUTTON + '[1]')\n    driver.assertions.see_text('Remove')\n\n```\nGreat. Now let's add one more tests to check if customer is able to complete order. It will be more complicated test \nif compare to previous one, but also it will show how to use different object in one tests:\n`functional/test_ecommerce.py`\n```python\n...\nfrom pom.cart_page import CartPage\nfrom pom.checkout_page import CheckoutPage\n\n...\n\ndef test_complete_order(driver):\n    cart = CartPage(driver)\n    checkout = CheckoutPage(driver)\n\n    # Go to cart page and assert correct url\n    driver.click(cart.CART_ICON_LINK)\n    driver.assertions.see_in_url('/cart.html')\n\n    # From cart page go to checkout and complete it\n    driver.click(cart.CHECKOUT_BUTTON)\n    driver.assertions.see_in_url('/checkout-step-one.html')\n\n    # Fill personal info and go to Second step\n    checkout.fill_personal_info()\n    driver.click(checkout.CONTINUE_BUTTON)\n    driver.assertions.see_in_url('checkout-step-two.html')\n\n    # Place order\n    driver.click(checkout.FINISH_BUTTON)\n    driver.assertions.see_in_url('/checkout-complete.html')\n\n```\n\nFull result:\n```python\nimport pytest\n\nfrom vigilant.driver.vigilant_driver import VigilantDriver\nfrom pom.login_page import LoginPage\nfrom pom.category_list_page import CategoryListPage\nfrom pom.cart_page import CartPage\nfrom pom.checkout_page import CheckoutPage\n\n\n@pytest.fixture(scope=\"module\")\ndef driver():\n    vd = VigilantDriver()\n    yield vd\n    vd.quit()\n\n\ndef test_login(driver):\n    login_page = LoginPage(driver)\n\n    driver.get_page('/')\n    login_page.fill_in_and_login()\n    driver.assertions.see_in_url('/inventory.html')\n\n\ndef test_add_product_from_clp(driver):\n    clp = CategoryListPage(driver)\n\n    driver.assertions.see(\n        clp.PRODUCT_CARD + '[1]')  # +[1] is Xpath trick to say that we looking for FIRST available element with this selector\n    driver.click(clp.ADD_TO_CART_BUTTON + '[1]')\n    driver.assertions.see_text('Remove')\n\n\ndef test_complete_order(driver):\n    cart = CartPage(driver)\n    checkout = CheckoutPage(driver)\n\n    # Go to cart page and assert correct url\n    driver.click(cart.CART_ICON_LINK)\n    driver.assertions.see_in_url('/cart.html')\n\n    # From cart page go to checkout and complete it\n    driver.click(cart.CHECKOUT_BUTTON)\n    driver.assertions.see_in_url('/checkout-step-one.html')\n\n    # Fill personal info and go to Second step\n    checkout.fill_personal_info()\n    driver.click(checkout.CONTINUE_BUTTON)\n    driver.assertions.see_in_url('checkout-step-two.html')\n\n    # Place order\n    driver.click(checkout.FINISH_BUTTON)\n    driver.assertions.see_in_url('/checkout-complete.html')\n\n```\nLet's run it:\n```shell\npytest tests/functional/test_ecommerce.py\n```\nResult should be this:\n```text\n==================================================== test session starts ============================================\nplatform linux -- Python 3.10.6, pytest-7.2.0, pluggy-1.0.0\nrootdir: /home/ivan/projects/vigilant_lab\ncollected 3 items                                                                                                                                                                                                                         \n\ntests/functional/test_ecommerce.py ...                                                                                                                                                                                              [100%]\n\n===================================================== 3 passed in 3.62s =============================================\n```\n\nGreat! Everything work as expected.\n\nWhat's next?\n\nAs example, you can try to move fixture that setup our browser, in to the `fixture/` directory:\n```python\n@pytest.fixture(scope=\"module\")\ndef driver():\n    vd = VigilantDriver()\n    yield vd\n    vd.quit()\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivpel%2Fvigilant-pytest-example","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fivpel%2Fvigilant-pytest-example","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fivpel%2Fvigilant-pytest-example/lists"}