From a1d2522dd17cbca97a49ec7d70ff6ead354a11e6 Mon Sep 17 00:00:00 2001 From: Brady-Malott <55215446+Brady-Malott@users.noreply.github.com> Date: Tue, 7 Mar 2023 18:39:58 -0500 Subject: [PATCH 1/6] Update Jenkinsfile --- Jenkinsfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 19bf6f0..eb2bdb1 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -33,12 +33,12 @@ pipeline { post { success { echo 'Pipeline has completed' - discordSend description: '', footer: '', image: '', link: 'http://3.238.108.178:8080/', result: '', scmWebUrl: '', thumbnail: '', title: + discordSend description: '', footer: '', image: '', link: 'http://3.220.122.102:8080/', result: '', scmWebUrl: '', thumbnail: '', title: 'Pipeline has completed ✅', webhookURL: 'https://discord.com/api/webhooks/1075879011667955872/Nk0gmKZkrISEs-hru-HjtzzgezWweABCdPsOKGIzkmj5xMcqKC3m1-dx7GZSu0yURAOo' } failure { echo 'Something has failed!' - discordSend description: 'Pipeline has failed!', footer: '', image: '', link: 'http://3.238.108.178:8080/', result: '', scmWebUrl: '', thumbnail: '', title: + discordSend description: 'Pipeline has failed!', footer: '', image: '', link: 'http://3.220.122.102:8080/', result: '', scmWebUrl: '', thumbnail: '', title: 'Pipeline failure ❌', webhookURL: 'https://discord.com/api/webhooks/1075879011667955872/Nk0gmKZkrISEs-hru-HjtzzgezWweABCdPsOKGIzkmj5xMcqKC3m1-dx7GZSu0yURAOo' } } From 863ae3496a294c4b47c9276c991138a3dc58c669 Mon Sep 17 00:00:00 2001 From: Aleksa V Date: Tue, 7 Mar 2023 18:58:00 -0500 Subject: [PATCH 2/6] removed a testing file --- selenium.py | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 selenium.py diff --git a/selenium.py b/selenium.py deleted file mode 100644 index a363491..0000000 --- a/selenium.py +++ /dev/null @@ -1,4 +0,0 @@ -from selenium import webdriver - -driver = webdriver.chrome() -driver.get("http://www.python.org") From 1d0a0c1c17403e2873572850fbad52f2c79bec6e Mon Sep 17 00:00:00 2001 From: Aleksa V Date: Tue, 7 Mar 2023 21:49:09 -0500 Subject: [PATCH 3/6] Scaffolded and added readmes for testing work --- __init__.py | 0 requirements.txt | 2 ++ tests/features/add-task.feature | 17 ++++++++++++ tests/features/how-to-run-behave.md | 5 ++++ tests/features/steps/add-task-steps.py | 38 ++++++++++++++++++++++++++ tests/features/steps/check-ui-steps.py | 30 ++++++++++++++++++++ tests/unit/__init__.py | 0 tests/unit/how-to-run-tests.md | 11 ++++++++ tests.py => tests/unit/test_example.py | 3 ++ 9 files changed, 106 insertions(+) create mode 100644 __init__.py create mode 100644 tests/features/add-task.feature create mode 100644 tests/features/how-to-run-behave.md create mode 100644 tests/features/steps/add-task-steps.py create mode 100644 tests/features/steps/check-ui-steps.py create mode 100644 tests/unit/__init__.py create mode 100644 tests/unit/how-to-run-tests.md rename tests.py => tests/unit/test_example.py (99%) mode change 100755 => 100644 diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/requirements.txt b/requirements.txt index fbfd869..c9f1ec1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -38,6 +38,8 @@ requests==2.25.1 requests-toolbelt==0.9.1 rq==1.9.0 selenium +behave +webdriver_manager six==1.16.0 SQLAlchemy==1.4.20 urllib3==1.26.6 diff --git a/tests/features/add-task.feature b/tests/features/add-task.feature new file mode 100644 index 0000000..07b2634 --- /dev/null +++ b/tests/features/add-task.feature @@ -0,0 +1,17 @@ +Feature: Add tasks to todo list + As a user + I want to be able to add tasks to my todo list + So thats I can keep track of my work + + Scenario: User visits the todo list page + Given the user is on the todo list page + Then the page should have a text field to enter the title of the task + And the page should have a text field to enter the estimate of hours needed to complete the task + And the page should have a button to add the task + + Scenario: Add a new task to the todo list + Given I am on the todo list page + When I enter "Buy groceries" in the title field + And I enter "2" in the estimate field + And I click the "Add" button + Then the task "Buy groceries" with estimate "2" should be added to the todo list \ No newline at end of file diff --git a/tests/features/how-to-run-behave.md b/tests/features/how-to-run-behave.md new file mode 100644 index 0000000..e49a513 --- /dev/null +++ b/tests/features/how-to-run-behave.md @@ -0,0 +1,5 @@ +How to run behave tutorial + +1. Running all behave features + +run " behave tests/features/add-task.feature " \ No newline at end of file diff --git a/tests/features/steps/add-task-steps.py b/tests/features/steps/add-task-steps.py new file mode 100644 index 0000000..652025e --- /dev/null +++ b/tests/features/steps/add-task-steps.py @@ -0,0 +1,38 @@ +from behave import * +from webdriver_manager.chrome import ChromeDriverManager +from selenium import webdriver +from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.common.by import By + +@given(u'I am on the todo list page') +def open_browser(context): + context.driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) + context.driver.implicitly_wait(5) + context.driver.get("http://127.0.0.1:5000/") + + +@when('I enter "{title}" in the title field') +def step_impl(context, title): + title_field = context.driver.find_element(By.NAME, "title") + title_field.send_keys(title) + + +@when('I enter "{estimate}" in the estimate field') +def step_impl(context, estimate): + estimate_field = context.driver.find_element(By.NAME, "estimate") + estimate_field.send_keys(estimate) + + +@when(u'I click the "Add" button') +def step_impl(context): + add_button = context.driver.find_element(By.XPATH, "//button[contains(text(),'Add')]") + add_button.click() + context.driver.implicitly_wait(5) + + +@then('the task "{title}" with estimate "{estimate}" should be added to the todo list') +def step_impl(context, title, estimate): + dump_text = context.driver.page_source + print(dump_text) + assert ("Buy groceries | 2" in dump_text) is True + diff --git a/tests/features/steps/check-ui-steps.py b/tests/features/steps/check-ui-steps.py new file mode 100644 index 0000000..698df79 --- /dev/null +++ b/tests/features/steps/check-ui-steps.py @@ -0,0 +1,30 @@ +from behave import * +from webdriver_manager.chrome import ChromeDriverManager +from selenium import webdriver +from selenium.webdriver.chrome.service import Service as ChromeService +from selenium.webdriver.common.by import By + + +@given(u'the user is on the todo list page') +def open_browser(context): + context.driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) + context.driver.implicitly_wait(5) + context.driver.get("http://127.0.0.1:5000/") + + +@then(u'the page should have a text field to enter the title of the task') +def check_task_title_textbox(context): + status = context.driver.find_element(By.NAME, "title").is_displayed() + assert status is True + + +@then(u'the page should have a text field to enter the estimate of hours needed to complete the task') +def check_task_estimate_textbox(context): + status = context.driver.find_element(By.NAME, "estimate").is_displayed() + assert status is True + + +@then(u'the page should have a button to add the task') +def check_task_add_button(context): + status = context.driver.find_element(By.XPATH, "//button[contains(text(),'Add')]").is_displayed() + assert status is True diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/unit/how-to-run-tests.md b/tests/unit/how-to-run-tests.md new file mode 100644 index 0000000..c6e8720 --- /dev/null +++ b/tests/unit/how-to-run-tests.md @@ -0,0 +1,11 @@ +How to run unit tests + +unit tests must follow the "test*.py" regex to be picked up + +1. Individual tests + +run " python .\tests\unit\test_example.py " + +2. Run all unit tests + +run " python -m unittest discover -s ./tests/unit " \ No newline at end of file diff --git a/tests.py b/tests/unit/test_example.py old mode 100755 new mode 100644 similarity index 99% rename from tests.py rename to tests/unit/test_example.py index 52111b1..fb9827f --- a/tests.py +++ b/tests/unit/test_example.py @@ -1,4 +1,7 @@ #!/usr/bin/env python +import sys +sys.path.append('./') + from datetime import datetime, timedelta import unittest from app import create_app, db From 89dda8d505b79312d2d50dc2bffc300354a9fc35 Mon Sep 17 00:00:00 2001 From: Brady-Malott <55215446+Brady-Malott@users.noreply.github.com> Date: Wed, 8 Mar 2023 17:24:08 -0500 Subject: [PATCH 4/6] Ignored .idea folder --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 1e4f836..3d8d8c7 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ nosetests.xml venv app.db microblog.log* + +.idea/ From 71249f04abd91c74c4785de305b06c8a484062b9 Mon Sep 17 00:00:00 2001 From: Aleksa V Date: Wed, 8 Mar 2023 19:51:22 -0500 Subject: [PATCH 5/6] PR issues --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index 82e3e48..c0567b3 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,32 @@ # Welcome to Microblog! This is an example application featured in my [Flask Mega-Tutorial](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world). See the tutorial for instructions on how to work with it. + +# How to run behave tutorial + +*NOTE* behave steps in the .feature file MUST unicode match those in the 'steps' file + +e.g. in the *.feature file there is a Gherkin line like +'the task 'Buy groceries' with estimate '2' should be added to the todo list' + +then in the accompanying *step.py file it must follow the exact unicode in the behave decorator +Like this -> '@then("the task '{title}' with estimate '{estimate}' should be added to the todo list")' + + +Also step files must follow the regex *step.py + +1. Running all behave features + +run " behave tests/features/add-task.feature " + +# How to run unit tests + +unit tests must follow the "test*.py" regex to be picked up + +1. Individual tests + +run " python ./ests/unit/test_example.py " + +2. Run all unit tests + +run " python -m unittest discover -s ./tests/unit " \ No newline at end of file From 858f7cccdfa99eb4590921c98519863a285a369a Mon Sep 17 00:00:00 2001 From: Aleksa V Date: Wed, 8 Mar 2023 19:52:19 -0500 Subject: [PATCH 6/6] Missed a file --- tests/features/add-task.feature | 8 +++---- tests/features/how-to-run-behave.md | 5 ----- tests/features/steps/add-task-steps.py | 30 ++++++++++++++++++++------ tests/features/steps/check-ui-steps.py | 21 ++++++++++++------ tests/unit/how-to-run-tests.md | 11 ---------- 5 files changed, 42 insertions(+), 33 deletions(-) delete mode 100644 tests/features/how-to-run-behave.md delete mode 100644 tests/unit/how-to-run-tests.md diff --git a/tests/features/add-task.feature b/tests/features/add-task.feature index 07b2634..3e1c284 100644 --- a/tests/features/add-task.feature +++ b/tests/features/add-task.feature @@ -11,7 +11,7 @@ Feature: Add tasks to todo list Scenario: Add a new task to the todo list Given I am on the todo list page - When I enter "Buy groceries" in the title field - And I enter "2" in the estimate field - And I click the "Add" button - Then the task "Buy groceries" with estimate "2" should be added to the todo list \ No newline at end of file + When I enter 'Buy groceries' in the title field + And I enter '2' in the estimate field + And I click the 'Add' button + Then the task 'Buy groceries' with estimate '2' should be added to the todo list \ No newline at end of file diff --git a/tests/features/how-to-run-behave.md b/tests/features/how-to-run-behave.md deleted file mode 100644 index e49a513..0000000 --- a/tests/features/how-to-run-behave.md +++ /dev/null @@ -1,5 +0,0 @@ -How to run behave tutorial - -1. Running all behave features - -run " behave tests/features/add-task.feature " \ No newline at end of file diff --git a/tests/features/steps/add-task-steps.py b/tests/features/steps/add-task-steps.py index 652025e..4fa5cf2 100644 --- a/tests/features/steps/add-task-steps.py +++ b/tests/features/steps/add-task-steps.py @@ -1,38 +1,54 @@ -from behave import * +from behave import given, when, then from webdriver_manager.chrome import ChromeDriverManager from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.common.by import By +from selenium.webdriver.chrome.options import Options -@given(u'I am on the todo list page') +#THESE ARE EXAMPLES FILES. +#Todo delete these once we set a standard with our own tests + +@given("I am on the todo list page") def open_browser(context): - context.driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) + + # Implementation of headless from https://stackoverflow.com/questions/46920243/how-to-configure-chromedriver-to-initiate-chrome-browser-in-headless-mode-throug + # Stackoverflow post desribes what is goin on with options to enable headless chrome + + options = Options() + options.add_argument("--headless") # Runs Chrome in headless mode. + options.add_argument('--no-sandbox') # Bypass OS security model + options.add_argument('start-maximized') #to maximize viewport this should still be headless + options.add_argument('disable-infobars') + options.add_argument("--disable-extensions") + context.driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install())) context.driver.implicitly_wait(5) context.driver.get("http://127.0.0.1:5000/") -@when('I enter "{title}" in the title field') +@when("I enter '{title}' in the title field") def step_impl(context, title): title_field = context.driver.find_element(By.NAME, "title") title_field.send_keys(title) -@when('I enter "{estimate}" in the estimate field') +@when("I enter '{estimate}' in the estimate field") def step_impl(context, estimate): estimate_field = context.driver.find_element(By.NAME, "estimate") estimate_field.send_keys(estimate) -@when(u'I click the "Add" button') +@when("I click the 'Add' button") def step_impl(context): add_button = context.driver.find_element(By.XPATH, "//button[contains(text(),'Add')]") add_button.click() context.driver.implicitly_wait(5) -@then('the task "{title}" with estimate "{estimate}" should be added to the todo list') +@then("the task '{title}' with estimate '{estimate}' should be added to the todo list") def step_impl(context, title, estimate): dump_text = context.driver.page_source print(dump_text) assert ("Buy groceries | 2" in dump_text) is True + + diff --git a/tests/features/steps/check-ui-steps.py b/tests/features/steps/check-ui-steps.py index 698df79..1f07681 100644 --- a/tests/features/steps/check-ui-steps.py +++ b/tests/features/steps/check-ui-steps.py @@ -1,30 +1,39 @@ -from behave import * +from behave import given, when, then from webdriver_manager.chrome import ChromeDriverManager from selenium import webdriver from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.common.by import By +from selenium.webdriver.chrome.options import Options +#THESE ARE EXAMPLES FILES. +#Todo delete these once we set a standard with our own tests -@given(u'the user is on the todo list page') +@given("the user is on the todo list page") def open_browser(context): - context.driver = webdriver.Chrome(service=ChromeService(ChromeDriverManager().install())) + options = Options() + options.add_argument("--headless") # Runs Chrome in headless mode. + options.add_argument('--no-sandbox') # Bypass OS security model + options.add_argument('start-maximized') #to maximize viewport this should still be headless + options.add_argument('disable-infobars') + options.add_argument("--disable-extensions") + context.driver = webdriver.Chrome(options=options, service=ChromeService(ChromeDriverManager().install())) context.driver.implicitly_wait(5) context.driver.get("http://127.0.0.1:5000/") -@then(u'the page should have a text field to enter the title of the task') +@then("the page should have a text field to enter the title of the task") def check_task_title_textbox(context): status = context.driver.find_element(By.NAME, "title").is_displayed() assert status is True -@then(u'the page should have a text field to enter the estimate of hours needed to complete the task') +@then("the page should have a text field to enter the estimate of hours needed to complete the task") def check_task_estimate_textbox(context): status = context.driver.find_element(By.NAME, "estimate").is_displayed() assert status is True -@then(u'the page should have a button to add the task') +@then("the page should have a button to add the task") def check_task_add_button(context): status = context.driver.find_element(By.XPATH, "//button[contains(text(),'Add')]").is_displayed() assert status is True diff --git a/tests/unit/how-to-run-tests.md b/tests/unit/how-to-run-tests.md deleted file mode 100644 index c6e8720..0000000 --- a/tests/unit/how-to-run-tests.md +++ /dev/null @@ -1,11 +0,0 @@ -How to run unit tests - -unit tests must follow the "test*.py" regex to be picked up - -1. Individual tests - -run " python .\tests\unit\test_example.py " - -2. Run all unit tests - -run " python -m unittest discover -s ./tests/unit " \ No newline at end of file