commit 8749d7ab3769bc2165427b1930a37605ed88a4c9 Author: Greg Gauthier Date: Wed Jul 24 21:25:00 2024 +0100 initial commit diff --git a/.gitea/workflows/pylint.yml b/.gitea/workflows/pylint.yml new file mode 100644 index 0000000..415a6c2 --- /dev/null +++ b/.gitea/workflows/pylint.yml @@ -0,0 +1,24 @@ +name: Pylint + +on: [ push ] + +jobs: + build: + runs-on: ubuntu-gitea + strategy: + matrix: + python-version: [ "3.12" ] + steps: + - uses: actions/checkout@v4 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v3 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pylint + python -m pip install -r requirements.txt + - name: Analysing the code with pylint + run: | + pylint $(git ls-files '*.py') diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3a3635 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea/ +.venv/ +**/.env* +reports/ +**/__pycache__/ +screenshots/ \ No newline at end of file diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..c22f04b --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[MASTER] +disable=C0114, C0115, C0116 diff --git a/behave.ini b/behave.ini new file mode 100644 index 0000000..26d22b0 --- /dev/null +++ b/behave.ini @@ -0,0 +1,17 @@ +# Define ALIAS for PrettyHTMLFormatter. +[behave.formatters] +html-pretty = behave_html_pretty_formatter:PrettyHTMLFormatter + +[behave.userdata] +behave.formatter.html-pretty.title_string = Test Automation Report +behave.formatter.html-pretty.pseudo_steps = false +behave.formatter.html-pretty.pretty_output = true + +# The '%' must be escaped in ini format. +behave.formatter.html-pretty.date_format = %%d-%%m-%%Y %%H:%%M:%%S +behave.formatter.html-pretty.show_summary = true +behave.formatter.html-pretty.show_unexecuted_steps = true + +# Following will be formatted in summary section: +behave.additional-info.Tester=Jimminy Cricket +behave.additional-info.Location=The Moon \ No newline at end of file diff --git a/behave_runner.py b/behave_runner.py new file mode 100644 index 0000000..70667f7 --- /dev/null +++ b/behave_runner.py @@ -0,0 +1,26 @@ +import os +import subprocess +from datetime import datetime + + +def execute_features(): + """ + Method helps to run the feature files and generate the BDD report + :return: + """ + report_directory = "reports" + current_directory = os.getcwd() + new_folder_path = os.path.join(current_directory, report_directory) + if not os.path.exists(new_folder_path): + os.mkdir(new_folder_path) + htmlpath = os.path.join(report_directory, 'Test_Automation_Report_'\ + + datetime.now().strftime("%d-%m-%Y %H-%M-%S") + ".html") + + command = ["behave", "-f", "html-pretty", "-o", htmlpath] + + subprocess.run(command, check=True) + print("Test cases are executed successfully. The report will be available at " + htmlpath) + + +if __name__ == '__main__': + execute_features() diff --git a/features/__init__.py b/features/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/features/environment.py b/features/environment.py new file mode 100644 index 0000000..84e5b16 --- /dev/null +++ b/features/environment.py @@ -0,0 +1,65 @@ +# pylint: disable=no-name-in-module,unused-argument,comparison-of-constants +import os +from datetime import datetime +import logging +from playwright.sync_api import sync_playwright + + +def before_all(context): + p = sync_playwright().start() + browser = p.chromium.launch(headless=True, slow_mo=1000, channel="chrome") + context.page = browser.new_page() + + +def get_page(context): + return context.page + + +def after_all(context): + context.page.close() + + +def before_feature(context, feature): + """ + Method will execute prior to each feature + :param context: + :param feature: + :return: + """ + # Create logger + context.logger = logging.getLogger('automation_tests') + context.logger.setLevel(logging.DEBUG) + + +def after_feature(context, feature): + """ + Method will execute after each feature + :param context: + :param feature: + :return: + """ + + +def before_scenario(context, scenario): + """ + :param context: + :param scenario: + :return: + """ + + +def after_scenario(context, scenario): + if scenario.status == 'failed': + timestamp = datetime.now().strftime('%Y%m%d%H%M%S') + screenshot_path = os.path.join('screenshots', f'{scenario.name}_{timestamp}', '.png') + context.page.screenshot(path=screenshot_path) + + +def before_step(context, step): + # run before each step + pass + + +def after_step(context, step): + # run after each step + pass diff --git a/features/example.feature b/features/example.feature new file mode 100644 index 0000000..79a6e88 --- /dev/null +++ b/features/example.feature @@ -0,0 +1,7 @@ +# Created by gregg at 24/07/2024 +Feature: showing off behave + + Scenario: run a simple test + Given we have behave installed + When we implement a test + Then behave will test it for us! \ No newline at end of file diff --git a/features/playwright_example.feature b/features/playwright_example.feature new file mode 100644 index 0000000..54d12ec --- /dev/null +++ b/features/playwright_example.feature @@ -0,0 +1,10 @@ +# Created by gregg at 24/07/2024 +Feature: Example Login Page + As a registered user of the site + I would like to be able to login to the site + So that I can do my things on the site + + Scenario: A registered user logs into the site + Given the browser is at the login page + When the user enters his login details + Then the user is presented with the landing page \ No newline at end of file diff --git a/features/steps/__init__.py b/features/steps/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/features/steps/example.py b/features/steps/example.py new file mode 100644 index 0000000..762a8e5 --- /dev/null +++ b/features/steps/example.py @@ -0,0 +1,19 @@ +# pylint: disable=no-name-in-module,unused-argument,comparison-of-constants +from behave import given, when, then + + +@given('we have behave installed') +def we_have_behave_installed(context): + # it is implied in the capacity to + # run this! + pass + + +@when('we implement a test') +def we_implement_a_test(context): + assert True is not False + + +@then('behave will test it for us!') +def behave_will_test_it(context): + assert context.failed is False diff --git a/features/steps/playwright_example.py b/features/steps/playwright_example.py new file mode 100644 index 0000000..e30d212 --- /dev/null +++ b/features/steps/playwright_example.py @@ -0,0 +1,26 @@ +# pylint: disable=no-name-in-module,unused-argument,comparison-of-constants +from behave import given, when, then + +from features import environment + + +@given("the browser is at the login page") +def the_browser_is_at_the_login_page(context): + """ + :type context: behave.runner.Context + """ + page = environment.get_page(context) + page.goto("https://www.saucedemo.com/") + + +@when("the user enters his login details") +def user_enters_details(context): + context.page.fill('#user-name', 'standard_user') + context.page.fill('#password', 'secret_sauce') + context.page.click('#login-button') + + +@then("the user is presented with the landing page") +def user_presented_with_landing_page(context): + header = context.page.get_by_text('Swag Labs') + assert "Swag Labs" in header.text_content(), "Login failed!" diff --git a/page_objects/__init__.py b/page_objects/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..7408838 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +addopts = -s -v --durations=0 --numprocesses auto +testpaths = pytests diff --git a/pytests/__init__.py b/pytests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pytests/test_example.py b/pytests/test_example.py new file mode 100644 index 0000000..d114c9b --- /dev/null +++ b/pytests/test_example.py @@ -0,0 +1,19 @@ +import re +from playwright.sync_api import Page, expect + + +def test_has_title(page: Page): + page.goto("https://playwright.dev/") + + # Expect a title "to contain" a substring. + expect(page).to_have_title(re.compile("Playwright")) + + +def test_get_started_link(page: Page): + page.goto("https://playwright.dev/") + + # Click the get started link. + page.get_by_role("link", name="Get started").click() + + # Expects page to have a heading with the name of Installation. + expect(page.get_by_role("heading", name="Installation")).to_be_visible() diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..592043f --- /dev/null +++ b/requirements.txt @@ -0,0 +1,14 @@ +pylint~=3.2.6 +pytest~=8.2.2 +pytest-xdist~=3.6.1 +pytest-pylint~=0.21.0 +pytest-playwright +pytest-playwright-snapshot +python-dotenv~=1.0.1 +playwright~=1.45.1 +behave~=1.2.6 +behave-cucumber-formatter~=1.0.1 +behave-cucumber-matcher~=0.4.0 +behave-html-pretty-formatter~=1.11.2 + +