Skip to content
Snippets Groups Projects
Commit d5175ba7 authored by Mart van Santen's avatar Mart van Santen
Browse files

Removed behave, add dummy documentation

parent 8c6ef7a1
No related branches found
No related tags found
2 merge requests!68Merge loginpanel into main and release 0.5.0,!57Resolve "Add login panel CI/CD to create (docker) image"
Pipeline #10105 failed with stages
in 34 seconds
FROM alpine:3.9
LABEL name="Integration CI test image"
RUN apk --no-cache add \
chromium \
chromium-chromedriver \
python3-dev \
curl \
bash
RUN pip3 install behave behave_webdriver
"""Basic setup for behave and chromedriver."""
import behave_webdriver
import os
import re
import time
from behave_webdriver.driver import ChromeOptions
def save_screenshot(context, step):
"""Save a screenshot to ./screenshots."""
timestamp = time.strftime("%Y-%m-%dT%H:%M:%S")
filename = re.sub('\W', '-', '{} failed {}'.format(timestamp,
str(step.name)))
filepath = os.path.join('screenshots', filename + '.png')
if not os.path.exists('screenshots'):
os.mkdir('screenshots')
print('Saving screenshot to %s' % filepath)
context.behave_driver.save_screenshot(filepath)
def before_all(context):
"""Run at the very beginning."""
userdata = context.config.userdata
headless = userdata.get('headless', 'False')
chrome_options = ChromeOptions()
if headless == 'True':
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
context.behave_driver = behave_webdriver.Chrome(
chrome_options=chrome_options)
def before_tag(context, tag):
values = dict()
userdata = context.config.userdata
values['home'] = userdata.get('url')
values['logout'] = values['home'] + "/logout"
values['userinfo'] = values['home'] + "/userinfo"
values['single-sign-off'] = values['home'] + "/single-sign-off"
values['username'] = userdata.get('username')
values['username2'] = userdata.get('username2')
values['password'] = userdata.get('password')
values['email'] = userdata.get('email')
values['role'] = userdata.get('role')
assert values['home'], 'url variable missing in' \
'userdata. Provide it with "-D url".'
assert values['username'], 'username variable missing in' \
'userdata. Provide it with "-D username".'
assert values['password'], 'password variable missing in' \
'userdata. Provide it with "-D password".'
assert values['email'], 'email variable missing in' \
'userdata. Provide it with "-D email".'
assert values['role'], 'role variable missing in' \
'userdata. Provide it with "-D role".'
context.oauth = values
def after_all(context):
"""Cleanup after tests run."""
context.behave_driver.quit()
def after_step(context, step):
"""Save screeshot if step fails."""
if step.status == 'failed':
save_screenshot(context, step)
print("Console log output:")
for message in context.behave_driver.get_log('browser'):
print(" Level: {}".format(message['level']))
print(" Timestamp: {}".format(message['timestamp']))
print(" Source: {}".format(message['source']))
print(" Message: {}\n".format(message['message']))
@oauth
Feature: Test login-provider function
As a Stackspin user
I want to be able to login to a Stackspin App
And verify my userdata that is provided by OpenID Connect
Scenario: Open the oAuth application and Login witha valid user
Given the oauth client "home" URL was opened
And the element "input#username" is visible
When I enter the "username" in the inputfield "input#username"
And I enter the "password" in the inputfield "input#password"
And I click on the button "input#submit"
Then I wait on element "input#password" for 1000ms to not exist
And I expect that the path is "/"
And I expect that element "body" contains the text "access_token"
Scenario: Get OpenID Connect userdata for testuser
When I open the oauth client "userinfo" URL
Then I expect that the "preferred_username" in the json output is the same as oauth variable "username"
And I expect that the "email" in the json output is the same as oauth variable "email"
And I expect that the "stackspin_roles" in the json output contains the value of oauth variable "role"
And I expect that the "name" in the json output is the same as oauth variable "username"
Scenario: Logout
When I open the oauth client "logout" URL
Then I wait on element "input#username" for 1000ms to be visible
And I expect that element "input#password" is visible
And I expect that element "input#submit" is visible
@oauth
Feature: Test logout-provider function
As a Stackspin user
I want to be able to use single-sign off triggered by a
Stackspin APP. And verify that even though I selected remember me
my session was removed.
Scenario: Login with a valid user and remember session
Given the oauth client "home" URL was opened
And the element "input#remember" is visible
When I enter the "username" in the inputfield "input#username"
And I enter the "password" in the inputfield "input#password"
And I click on the element "input#remember"
And I click on the button "input#submit"
Then I wait on element "input#password" for 1000ms to not exist
Scenario: Logout using the single sign-off feature
Given the oauth client "single-sign-off" URL was opened
And I pause for 1000ms
Then I wait on element "input#username" for 1000ms to exist
@oauth
Feature: Test features that prohibit unauthorized access
As an attacker or unauthorized user
I want to to login to a Stackspin App
And the single sign-on will block my login attempts
Scenario: Login with a valid user without access to an application
Given the oauth client "home" URL was opened
And the element "input#username" is visible
When I enter the "username2" in the inputfield "input#username"
And I enter the "password" in the inputfield "input#password"
And I click on the button "input#submit"
Then I wait on element "input#password" for 1000ms to not exist
And I expect that element "input#username" does not exist
And I expect that element "body" contains the text "error"
And I expect that element "body" contains the text "Permission denied"
And I expect that element "body" contains the text "missing application permission"
Scenario: Login with an invalid user
Given the oauth client "home" URL was opened
And the element "input#username" is visible
When I set "not_a_valid_user" to the inputfield "input#username"
And I set "password" to the inputfield "input#password"
And I click on the button "input#submit"
Then I wait on element "input#password" for 1000ms to not exist
And I expect that element "input#username" does not exist
And I expect that element "body" contains the text "error"
And I expect that element "body" contains the text "Login denied"
And I expect that element "body" contains the text "Invalid username or password"
@oauth
Feature: Testing single sign-on sessions
As a Stackspin user
I want to login once to use an application
And I use my active single sign-on session to login again without providing credentials
Scenario: Login with a valid user and remember session
Given the oauth client "home" URL was opened
And the element "input#username" is visible
And the element "input#remember" is visible
When I enter the "username" in the inputfield "input#username"
And I enter the "password" in the inputfield "input#password"
And I click on the element "input#remember"
And I click on the button "input#submit"
Then I wait on element "input#password" for 1000ms to not exist
And I expect that element "input#username" does not exist
And I expect that the path is "/"
And I expect that element "body" contains the text "access_token"
Scenario: Login without providing credentials
Given the oauth client "logout" URL was opened
And I pause for 1000ms
And there is no element "input#username" on the page
And there is no element "input#password" on the page
And the element "button#continue" is visible
When I click on the element "button#continue"
Then I wait on element "button#continue" for 1000ms to not exist
And I expect that the path is "/"
And I expect that element "body" contains the text "access_token"
Scenario: Terminate single sign-on session
Given the oauth client "logout" URL was opened
And I pause for 1000ms
And the element "button#logout" is visible
When I click on the element "button#logout"
Then I expect that the "error" in the json output is "Login cancelled"
And I expect that the "error_description" in the json output is "Login was cancelled and user session was terminated"
"""Custom steps for tests that anaylize a website that returns a json object."""
import json
from behave import given, when, then
from behave_webdriver.steps import *
@then(u'I expect that the "{variable}" in the json output is the same as oauth variable "{value}"')
def step_impl(context, variable, value):
assert context.oauth[value] == get_value_from_json_body(context, variable)
@then(u'I expect that the "{variable}" in the json output is "{value}"')
def step_impl(context, variable, value):
assert value == get_value_from_json_body(context, variable)
@then(u'I expect that the "{variable}" in the json output contains the value of oauth variable "{value}"')
def step_impl(context, variable, value):
assert context.oauth[value] in get_value_from_json_body(context, variable)
@then(u'I expect that the "{variable}" in the json output contains "{value}"')
def step_impl(context, variable, value):
assert value in get_value_from_json_body(context, variable)
def get_value_from_json_body(context, key):
obj_serialized = context.behave_driver.get_element("body").text
return json.loads(obj_serialized)[key]
"""Custom steps for login tests that use oauth environment variables"""
from behave import given, when, then
from behave_webdriver.steps import *
def before_all(context):
pass # login and save cookies here
@when(u'I open the oauth client "{url}" URL')
@given(u'The oauth client "{url}" URL was opened')
def step_impl(context, url):
context.behave_driver.get(context.oauth[url])
@when(u'I enter the "{attribute}" in the inputfield "{element}"')
def step_impl(context, attribute, element):
"""Enter value into login inputfields."""
elem = context.behave_driver.get_element(element)
elem.clear()
value = context.oauth[attribute]
elem.send_keys(value)
@then(u'I expect that element "{element}" contains the value of var "{variable}"')
def step_impl(context, element, variable):
"""Check if value is in field"""
elem = context.behave_driver.get_element(element)
value = context.oauth[variable]
assert value in elem.text
"""
Stub app to check if SSO works in testing
"""
import json
from os import environ
from flask import Flask, url_for, redirect, jsonify, session, request
......@@ -32,6 +36,8 @@ sso.store_registration_info(sso_client_reg)
@app.route("/")
def index():
"""Index"""
if "state" not in session.keys():
state = rndstr()
session["state"] = state
......@@ -46,6 +52,7 @@ def index():
@app.route("/userinfo")
def info():
"""Show info"""
if "state" in session.keys() and sso.grant[session["state"]].is_valid:
token = sso.grant[session["state"]].get_token()
return jsonify(token.id_token.to_dict())
......@@ -53,12 +60,14 @@ def info():
@app.route("/logout")
def logout():
"""Logout"""
del sso.grant[session["state"]]
del session["state"]
return redirect("/")
@app.route("/single-sign-off")
def single_sign_off():
"""Single Sign Off Call"""
redir = sso.construct_CheckSessionRequest(state=session["state"])
answer = sso.do_end_session_request(state=session["state"], request_args={
"id_token_hint": redir["id_token"],
......@@ -69,6 +78,7 @@ def single_sign_off():
@app.route("/callback")
def callback():
"""Callback"""
if "error" in request.args:
return jsonify(request.args)
aresp = sso.parse_response(AuthorizationResponse, info=json.dumps(request.args))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment