Merge branch 'main' into Issue-#5-Add-2FA
This commit is contained in:
commit
8f962bcfd4
|
@ -39,3 +39,4 @@ venv
|
||||||
app.db
|
app.db
|
||||||
microblog.log*
|
microblog.log*
|
||||||
.env
|
.env
|
||||||
|
.idea/
|
|
@ -33,12 +33,12 @@ pipeline {
|
||||||
post {
|
post {
|
||||||
success {
|
success {
|
||||||
echo 'Pipeline has completed'
|
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'
|
'Pipeline has completed ✅', webhookURL: 'https://discord.com/api/webhooks/1075879011667955872/Nk0gmKZkrISEs-hru-HjtzzgezWweABCdPsOKGIzkmj5xMcqKC3m1-dx7GZSu0yURAOo'
|
||||||
}
|
}
|
||||||
failure {
|
failure {
|
||||||
echo 'Something has failed!'
|
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'
|
'Pipeline failure ❌', webhookURL: 'https://discord.com/api/webhooks/1075879011667955872/Nk0gmKZkrISEs-hru-HjtzzgezWweABCdPsOKGIzkmj5xMcqKC3m1-dx7GZSu0yURAOo'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
29
README.md
29
README.md
|
@ -1,3 +1,32 @@
|
||||||
# Welcome to Microblog!
|
# 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.
|
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 "
|
|
@ -44,6 +44,9 @@ requests==2.25.1
|
||||||
requests-toolbelt==0.9.1
|
requests-toolbelt==0.9.1
|
||||||
rq==1.9.0
|
rq==1.9.0
|
||||||
selenium==4.4.1
|
selenium==4.4.1
|
||||||
|
selenium
|
||||||
|
behave
|
||||||
|
webdriver_manager
|
||||||
six==1.16.0
|
six==1.16.0
|
||||||
sniffio==1.3.0
|
sniffio==1.3.0
|
||||||
sortedcontainers==2.4.0
|
sortedcontainers==2.4.0
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
from selenium import webdriver
|
|
||||||
|
|
||||||
driver = webdriver.chrome()
|
|
||||||
driver.get("http://www.python.org")
|
|
|
@ -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
|
|
@ -0,0 +1,54 @@
|
||||||
|
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("I am on the todo list page")
|
||||||
|
def open_browser(context):
|
||||||
|
|
||||||
|
# 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")
|
||||||
|
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("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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
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("the user is on the todo list page")
|
||||||
|
def open_browser(context):
|
||||||
|
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("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("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("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
|
|
@ -1,4 +1,7 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
import sys
|
||||||
|
sys.path.append('./')
|
||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import unittest
|
import unittest
|
||||||
from app import create_app, db
|
from app import create_app, db
|
Loading…
Reference in New Issue