e2e: start implementing e2e tests
This commit is contained in:
parent
467b95cf02
commit
27728abe99
|
@ -0,0 +1,14 @@
|
||||||
|
version: '3.7'
|
||||||
|
|
||||||
|
services:
|
||||||
|
hub:
|
||||||
|
image: dosel/zalenium
|
||||||
|
command: start
|
||||||
|
ports:
|
||||||
|
- 4444:4444
|
||||||
|
environment:
|
||||||
|
PULL_SELENIUM_IMAGE: 'true'
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
- /tmp/videos:/home/seluser/videos
|
||||||
|
privileged: true
|
|
@ -0,0 +1,109 @@
|
||||||
|
"""Test 2-step enroll flow"""
|
||||||
|
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||||
|
|
||||||
|
from passbook.flows.models import Flow, FlowDesignation, FlowStageBinding
|
||||||
|
from passbook.policies.expression.models import ExpressionPolicy
|
||||||
|
from passbook.policies.models import PolicyBinding
|
||||||
|
from passbook.stages.prompt.models import FieldTypes, Prompt, PromptStage
|
||||||
|
from passbook.stages.user_login.models import UserLoginStage
|
||||||
|
from passbook.stages.user_write.models import UserWriteStage
|
||||||
|
|
||||||
|
|
||||||
|
class TestEnroll2Step(StaticLiveServerTestCase):
|
||||||
|
"""Test 2-step enroll flow"""
|
||||||
|
|
||||||
|
host = "0.0.0.0"
|
||||||
|
port = 8001
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.driver = webdriver.Remote(
|
||||||
|
command_executor="http://localhost:4444/wd/hub",
|
||||||
|
desired_capabilities=DesiredCapabilities.CHROME,
|
||||||
|
)
|
||||||
|
self.driver.implicitly_wait(2)
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super().tearDown()
|
||||||
|
self.driver.quit()
|
||||||
|
|
||||||
|
def test_enroll_2_step(self):
|
||||||
|
"""Test 2-step enroll flow"""
|
||||||
|
# First stage fields
|
||||||
|
username_prompt = Prompt.objects.create(
|
||||||
|
field_key="username", label="Username", order=0, type=FieldTypes.TEXT
|
||||||
|
)
|
||||||
|
password = Prompt.objects.create(
|
||||||
|
field_key="password", label="Password", order=1, type=FieldTypes.PASSWORD
|
||||||
|
)
|
||||||
|
password_repeat = Prompt.objects.create(
|
||||||
|
field_key="password_repeat",
|
||||||
|
label="Password (repeat)",
|
||||||
|
order=2,
|
||||||
|
type=FieldTypes.PASSWORD,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Second stage fields
|
||||||
|
name_field = Prompt.objects.create(
|
||||||
|
field_key="name", label="Name", order=0, type=FieldTypes.TEXT
|
||||||
|
)
|
||||||
|
email = Prompt.objects.create(
|
||||||
|
field_key="email", label="E-Mail", order=1, type=FieldTypes.EMAIL
|
||||||
|
)
|
||||||
|
|
||||||
|
# Stages
|
||||||
|
first_stage = PromptStage.objects.create(name="prompt-stage-first")
|
||||||
|
first_stage.fields.set([username_prompt, password, password_repeat])
|
||||||
|
first_stage.save()
|
||||||
|
second_stage = PromptStage.objects.create(name="prompt-stage-second")
|
||||||
|
second_stage.fields.set([name_field, email])
|
||||||
|
second_stage.save()
|
||||||
|
user_write = UserWriteStage.objects.create(name="enroll-user-write")
|
||||||
|
user_login = UserLoginStage.objects.create(name="enroll-user-login")
|
||||||
|
|
||||||
|
# Password checking policy
|
||||||
|
password_policy = ExpressionPolicy.objects.create(
|
||||||
|
name="policy-enrollment-password-equals",
|
||||||
|
expression="{{ request.context.password == request.context.password_repeat }}",
|
||||||
|
)
|
||||||
|
PolicyBinding.objects.create(
|
||||||
|
target=first_stage, policy=password_policy, order=0
|
||||||
|
)
|
||||||
|
|
||||||
|
flow = Flow.objects.create(
|
||||||
|
name="default-enrollment-flow",
|
||||||
|
slug="default-enrollment-flow",
|
||||||
|
designation=FlowDesignation.ENROLLMENT,
|
||||||
|
)
|
||||||
|
|
||||||
|
FlowStageBinding.objects.create(flow=flow, stage=first_stage, order=0)
|
||||||
|
FlowStageBinding.objects.create(flow=flow, stage=second_stage, order=1)
|
||||||
|
FlowStageBinding.objects.create(flow=flow, stage=user_write, order=2)
|
||||||
|
FlowStageBinding.objects.create(flow=flow, stage=user_login, order=3)
|
||||||
|
self.driver.get(f"http://host.docker.internal:{self.port}")
|
||||||
|
self.driver.find_element(By.CSS_SELECTOR, "[role=enroll]").click()
|
||||||
|
self.driver.find_element(By.ID, "id_username").send_keys("foo")
|
||||||
|
self.driver.find_element(By.ID, "id_password").send_keys("pbadmin")
|
||||||
|
self.driver.find_element(By.ID, "id_password_repeat").send_keys("pbadmin")
|
||||||
|
self.driver.find_element(By.CSS_SELECTOR, ".pf-c-button").click()
|
||||||
|
self.driver.find_element(By.ID, "id_name").send_keys("some name")
|
||||||
|
self.driver.find_element(By.ID, "id_email").send_keys("foo@bar.baz")
|
||||||
|
self.driver.find_element(By.CSS_SELECTOR, ".pf-c-button").click()
|
||||||
|
self.driver.find_element(By.LINK_TEXT, "foo").click()
|
||||||
|
self.assertEqual(
|
||||||
|
self.driver.find_element(By.XPATH, "//a[contains(@href, '/-/user/')]").text,
|
||||||
|
"foo",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.driver.find_element(By.ID, "id_username").get_attribute("value"), "foo"
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.driver.find_element(By.ID, "id_name").get_attribute("value"),
|
||||||
|
"some name",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
self.driver.find_element(By.ID, "id_email").get_attribute("value"),
|
||||||
|
"foo@bar.baz",
|
||||||
|
)
|
|
@ -0,0 +1,54 @@
|
||||||
|
"""test default login flow"""
|
||||||
|
import string
|
||||||
|
from random import SystemRandom
|
||||||
|
|
||||||
|
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
|
||||||
|
from django.core.management import call_command
|
||||||
|
from selenium import webdriver
|
||||||
|
from selenium.webdriver.common.by import By
|
||||||
|
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
|
||||||
|
from selenium.webdriver.common.keys import Keys
|
||||||
|
|
||||||
|
from passbook.core.models import User
|
||||||
|
|
||||||
|
|
||||||
|
class TestLogin(StaticLiveServerTestCase):
|
||||||
|
"""test default login flow"""
|
||||||
|
|
||||||
|
host = "0.0.0.0"
|
||||||
|
port = 8000
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.driver = webdriver.Remote(
|
||||||
|
command_executor="http://localhost:4444/wd/hub",
|
||||||
|
desired_capabilities=DesiredCapabilities.CHROME,
|
||||||
|
)
|
||||||
|
self.driver.implicitly_wait(2)
|
||||||
|
self.password = "".join(
|
||||||
|
SystemRandom().choice(string.ascii_uppercase + string.digits)
|
||||||
|
for _ in range(8)
|
||||||
|
)
|
||||||
|
User.objects.create_superuser(
|
||||||
|
username="pbadmin", email="admin@example.tld", password=self.password
|
||||||
|
)
|
||||||
|
call_command("migrate", "--fake", "passbook_flows", "0001_initial")
|
||||||
|
call_command("migrate", "passbook_flows", "0002_default_flows")
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
super().tearDown()
|
||||||
|
self.driver.quit()
|
||||||
|
|
||||||
|
def test_login(self):
|
||||||
|
"""test default login flow"""
|
||||||
|
self.driver.get(
|
||||||
|
f"http://host.docker.internal:{self.port}/flows/default-authentication-flow/?next=%2F"
|
||||||
|
)
|
||||||
|
self.driver.find_element(By.ID, "id_uid_field").click()
|
||||||
|
self.driver.find_element(By.ID, "id_uid_field").send_keys("admin@example.tld")
|
||||||
|
self.driver.find_element(By.ID, "id_uid_field").send_keys(Keys.ENTER)
|
||||||
|
self.driver.find_element(By.ID, "id_password").send_keys(self.password)
|
||||||
|
self.driver.find_element(By.ID, "id_password").send_keys(Keys.ENTER)
|
||||||
|
self.assertEqual(
|
||||||
|
self.driver.find_element(By.XPATH, "//a[contains(@href, '/-/user/')]").text,
|
||||||
|
"pbadmin",
|
||||||
|
)
|
|
@ -43,12 +43,12 @@
|
||||||
{% if enroll_url %}
|
{% if enroll_url %}
|
||||||
<p class="pf-c-login__main-footer-band-item">
|
<p class="pf-c-login__main-footer-band-item">
|
||||||
{% trans 'Need an account?' %}
|
{% trans 'Need an account?' %}
|
||||||
<a href="{{ enroll_url }}">{% trans 'Sign up.' %}</a>
|
<a role="enroll" href="{{ enroll_url }}">{% trans 'Sign up.' %}</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if recovery_url %}
|
{% if recovery_url %}
|
||||||
<p class="pf-c-login__main-footer-band-item">
|
<p class="pf-c-login__main-footer-band-item">
|
||||||
<a href="{{ recovery_url }}">{% trans 'Forgot username or password?' %}</a>
|
<a role="recovery" href="{{ recovery_url }}">{% trans 'Forgot username or password?' %}</a>
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
Reference in New Issue