Compare commits
	
		
			10 Commits
		
	
	
		
			static-con
			...
			enterprise
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 60000812fd | |||
| 929e70669a | |||
| 36114284bf | |||
| a65ea0de94 | |||
| 2056b0cbee | |||
| af85ddf60b | |||
| e8e42261e3 | |||
| 9fda4e91ad | |||
| a11f1258e1 | |||
| a97578ac62 | 
							
								
								
									
										2
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/ci-main.yml
									
									
									
									
										vendored
									
									
								
							| @ -168,6 +168,8 @@ jobs: | |||||||
|             glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml* |             glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml* | ||||||
|           - name: ldap |           - name: ldap | ||||||
|             glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap* |             glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap* | ||||||
|  |           - name: rac | ||||||
|  |             glob: tests/e2e/test_provider_rac* | ||||||
|           - name: radius |           - name: radius | ||||||
|             glob: tests/e2e/test_provider_radius* |             glob: tests/e2e/test_provider_radius* | ||||||
|           - name: scim |           - name: scim | ||||||
|  | |||||||
| @ -31,6 +31,8 @@ class PytestTestRunner(DiscoverRunner):  # pragma: no cover | |||||||
|  |  | ||||||
|         if kwargs.get("randomly_seed", None): |         if kwargs.get("randomly_seed", None): | ||||||
|             self.args.append(f"--randomly-seed={kwargs['randomly_seed']}") |             self.args.append(f"--randomly-seed={kwargs['randomly_seed']}") | ||||||
|  |         if kwargs.get("no_capture"): | ||||||
|  |             self.args.append("-s") | ||||||
|  |  | ||||||
|         settings.TEST = True |         settings.TEST = True | ||||||
|         settings.CELERY["task_always_eager"] = True |         settings.CELERY["task_always_eager"] = True | ||||||
| @ -56,6 +58,10 @@ class PytestTestRunner(DiscoverRunner):  # pragma: no cover | |||||||
|     def add_arguments(cls, parser: ArgumentParser): |     def add_arguments(cls, parser: ArgumentParser): | ||||||
|         """Add more pytest-specific arguments""" |         """Add more pytest-specific arguments""" | ||||||
|         DiscoverRunner.add_arguments(parser) |         DiscoverRunner.add_arguments(parser) | ||||||
|  |         parser.add_argument( | ||||||
|  |             "--no-capture", | ||||||
|  |             action="store_true", | ||||||
|  |         ) | ||||||
|         parser.add_argument( |         parser.add_argument( | ||||||
|             "--randomly-seed", |             "--randomly-seed", | ||||||
|             type=int, |             type=int, | ||||||
|  | |||||||
							
								
								
									
										44
									
								
								tests/e2e/_process.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								tests/e2e/_process.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,44 @@ | |||||||
|  | """authentik e2e testing utilities""" | ||||||
|  |  | ||||||
|  | from datetime import timedelta | ||||||
|  | from time import mktime | ||||||
|  | from unittest.mock import MagicMock, patch | ||||||
|  |  | ||||||
|  | from daphne.testing import DaphneProcess | ||||||
|  | from django import setup as django_setup | ||||||
|  | from django.conf import settings | ||||||
|  | from django.utils.timezone import now | ||||||
|  |  | ||||||
|  | from authentik.lib.config import CONFIG | ||||||
|  | from authentik.lib.generators import generate_id | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestDatabaseProcess(DaphneProcess): | ||||||
|  |     """Channels does not correctly switch to the test database by default. | ||||||
|  |     https://github.com/django/channels/issues/2048""" | ||||||
|  |  | ||||||
|  |     def run(self): | ||||||
|  |         if not settings.configured:  # Fix For raise AppRegistryNotReady("Apps aren't loaded yet.") | ||||||
|  |             django_setup()  # Ensure Django is fully set up before using settings | ||||||
|  |         if not settings.DATABASES[list(settings.DATABASES.keys())[0]]["NAME"].startswith("test_"): | ||||||
|  |             for _, db_settings in settings.DATABASES.items(): | ||||||
|  |                 db_settings["NAME"] = f"test_{db_settings['NAME']}" | ||||||
|  |         settings.TEST = True | ||||||
|  |         from authentik.enterprise.license import LicenseKey | ||||||
|  |  | ||||||
|  |         with ( | ||||||
|  |             patch( | ||||||
|  |                 "authentik.enterprise.license.LicenseKey.validate", | ||||||
|  |                 MagicMock( | ||||||
|  |                     return_value=LicenseKey( | ||||||
|  |                         aud="", | ||||||
|  |                         exp=int(mktime((now() + timedelta(days=3000)).timetuple())), | ||||||
|  |                         name=generate_id(), | ||||||
|  |                         internal_users=100, | ||||||
|  |                         external_users=100, | ||||||
|  |                     ) | ||||||
|  |                 ), | ||||||
|  |             ), | ||||||
|  |             CONFIG.patch("email.port", 1025), | ||||||
|  |         ): | ||||||
|  |             return super().run() | ||||||
| @ -1,7 +1,6 @@ | |||||||
| """LDAP and Outpost e2e tests""" | """LDAP and Outpost e2e tests""" | ||||||
|  |  | ||||||
| from dataclasses import asdict | from dataclasses import asdict | ||||||
| from time import sleep |  | ||||||
|  |  | ||||||
| from guardian.shortcuts import assign_perm | from guardian.shortcuts import assign_perm | ||||||
| from ldap3 import ALL, ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, SUBTREE, Connection, Server | from ldap3 import ALL, ALL_ATTRIBUTES, ALL_OPERATIONAL_ATTRIBUTES, SUBTREE, Connection, Server | ||||||
| @ -56,17 +55,7 @@ class TestProviderLDAP(SeleniumTestCase): | |||||||
|         outpost.providers.add(ldap) |         outpost.providers.add(ldap) | ||||||
|  |  | ||||||
|         self.start_ldap(outpost) |         self.start_ldap(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|         sleep(5) |  | ||||||
|         return outpost |         return outpost | ||||||
|  |  | ||||||
|     @retry() |     @retry() | ||||||
|  | |||||||
| @ -7,7 +7,6 @@ from sys import platform | |||||||
| from time import sleep | from time import sleep | ||||||
| from unittest.case import skip, skipUnless | from unittest.case import skip, skipUnless | ||||||
|  |  | ||||||
| from channels.testing import ChannelsLiveServerTestCase |  | ||||||
| from jwt import decode | from jwt import decode | ||||||
| from selenium.webdriver.common.by import By | from selenium.webdriver.common.by import By | ||||||
|  |  | ||||||
| @ -87,17 +86,7 @@ class TestProviderProxy(SeleniumTestCase): | |||||||
|         outpost.build_user_permissions(outpost.user) |         outpost.build_user_permissions(outpost.user) | ||||||
|  |  | ||||||
|         self.start_proxy(outpost) |         self.start_proxy(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|         sleep(5) |  | ||||||
|  |  | ||||||
|         self.driver.get("http://localhost:9000/api") |         self.driver.get("http://localhost:9000/api") | ||||||
|         self.login() |         self.login() | ||||||
| @ -168,17 +157,7 @@ class TestProviderProxy(SeleniumTestCase): | |||||||
|         outpost.build_user_permissions(outpost.user) |         outpost.build_user_permissions(outpost.user) | ||||||
|  |  | ||||||
|         self.start_proxy(outpost) |         self.start_proxy(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|         sleep(5) |  | ||||||
|  |  | ||||||
|         self.driver.get("http://localhost:9000/api") |         self.driver.get("http://localhost:9000/api") | ||||||
|         self.login() |         self.login() | ||||||
| @ -202,7 +181,7 @@ class TestProviderProxy(SeleniumTestCase): | |||||||
| # TODO: Fix flaky test | # TODO: Fix flaky test | ||||||
| @skip("Flaky test") | @skip("Flaky test") | ||||||
| @skipUnless(platform.startswith("linux"), "requires local docker") | @skipUnless(platform.startswith("linux"), "requires local docker") | ||||||
| class TestProviderProxyConnect(ChannelsLiveServerTestCase): | class TestProviderProxyConnect(SeleniumTestCase): | ||||||
|     """Test Proxy connectivity over websockets""" |     """Test Proxy connectivity over websockets""" | ||||||
|  |  | ||||||
|     @retry(exceptions=[AssertionError]) |     @retry(exceptions=[AssertionError]) | ||||||
| @ -239,16 +218,7 @@ class TestProviderProxyConnect(ChannelsLiveServerTestCase): | |||||||
|         ) |         ) | ||||||
|         outpost.providers.add(proxy) |         outpost.providers.add(proxy) | ||||||
|         outpost.build_user_permissions(outpost.user) |         outpost.build_user_permissions(outpost.user) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen and state.version: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|  |  | ||||||
|         state = outpost.state |         state = outpost.state | ||||||
|         self.assertGreaterEqual(len(state), 1) |         self.assertGreaterEqual(len(state), 1) | ||||||
|  | |||||||
| @ -76,17 +76,7 @@ class TestProviderProxyForward(SeleniumTestCase): | |||||||
|         outpost.build_user_permissions(outpost.user) |         outpost.build_user_permissions(outpost.user) | ||||||
|  |  | ||||||
|         self.start_outpost(outpost) |         self.start_outpost(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|         sleep(5) |  | ||||||
|  |  | ||||||
|     @retry() |     @retry() | ||||||
|     def test_traefik(self): |     def test_traefik(self): | ||||||
|  | |||||||
							
								
								
									
										126
									
								
								tests/e2e/test_provider_rac.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								tests/e2e/test_provider_rac.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | |||||||
|  | """RAC e2e tests""" | ||||||
|  |  | ||||||
|  | from datetime import timedelta | ||||||
|  | from time import mktime, sleep | ||||||
|  | from unittest.mock import MagicMock, patch | ||||||
|  |  | ||||||
|  | from django.utils.timezone import now | ||||||
|  | from selenium.webdriver.common.by import By | ||||||
|  | from selenium.webdriver.common.keys import Keys | ||||||
|  |  | ||||||
|  | from authentik.blueprints.tests import apply_blueprint, reconcile_app | ||||||
|  | from authentik.core.models import Application | ||||||
|  | from authentik.enterprise.license import LicenseKey | ||||||
|  | from authentik.enterprise.models import License | ||||||
|  | from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider | ||||||
|  | from authentik.flows.models import Flow | ||||||
|  | from authentik.lib.generators import generate_id | ||||||
|  | from authentik.outposts.models import Outpost, OutpostType | ||||||
|  | from tests.e2e.utils import SeleniumTestCase, retry | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class TestProviderRAC(SeleniumTestCase): | ||||||
|  |     """RAC e2e tests""" | ||||||
|  |  | ||||||
|  |     def setUp(self): | ||||||
|  |         super().setUp() | ||||||
|  |         self.password = generate_id() | ||||||
|  |  | ||||||
|  |     def start_rac(self, outpost: Outpost): | ||||||
|  |         """Start rac container based on outpost created""" | ||||||
|  |         self.run_container( | ||||||
|  |             image=self.get_container_image("ghcr.io/goauthentik/dev-rac"), | ||||||
|  |             environment={ | ||||||
|  |                 "AUTHENTIK_TOKEN": outpost.token.key, | ||||||
|  |             }, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |     @patch( | ||||||
|  |         "authentik.enterprise.license.LicenseKey.validate", | ||||||
|  |         MagicMock( | ||||||
|  |             return_value=LicenseKey( | ||||||
|  |                 aud="", | ||||||
|  |                 exp=int(mktime((now() + timedelta(days=3000)).timetuple())), | ||||||
|  |                 name=generate_id(), | ||||||
|  |                 internal_users=100, | ||||||
|  |                 external_users=100, | ||||||
|  |             ) | ||||||
|  |         ), | ||||||
|  |     ) | ||||||
|  |     @retry() | ||||||
|  |     @apply_blueprint( | ||||||
|  |         "default/flow-default-authentication-flow.yaml", | ||||||
|  |         "default/flow-default-invalidation-flow.yaml", | ||||||
|  |     ) | ||||||
|  |     @apply_blueprint( | ||||||
|  |         "default/flow-default-provider-authorization-implicit-consent.yaml", | ||||||
|  |         "default/flow-default-provider-invalidation.yaml", | ||||||
|  |     ) | ||||||
|  |     @apply_blueprint( | ||||||
|  |         "system/providers-rac.yaml", | ||||||
|  |     ) | ||||||
|  |     @reconcile_app("authentik_crypto") | ||||||
|  |     def test_rac_ssh(self): | ||||||
|  |         """Test SSH RAC""" | ||||||
|  |         License.objects.create(key=generate_id()) | ||||||
|  |  | ||||||
|  |         test_ssh = self.run_container( | ||||||
|  |             image="lscr.io/linuxserver/openssh-server:latest", | ||||||
|  |             ports={ | ||||||
|  |                 "2222": "2222", | ||||||
|  |             }, | ||||||
|  |             environment={ | ||||||
|  |                 "USER_NAME": "authentik", | ||||||
|  |                 "USER_PASSWORD": self.password, | ||||||
|  |                 "PASSWORD_ACCESS": "true", | ||||||
|  |                 "SUDO_ACCESS": "true", | ||||||
|  |             }, | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         rac: RACProvider = RACProvider.objects.create( | ||||||
|  |             name=generate_id(), | ||||||
|  |             authorization_flow=Flow.objects.get( | ||||||
|  |                 slug="default-provider-authorization-implicit-consent" | ||||||
|  |             ), | ||||||
|  |         ) | ||||||
|  |         endpoint = Endpoint.objects.create( | ||||||
|  |             name=generate_id(), | ||||||
|  |             protocol=Protocols.SSH, | ||||||
|  |             host=f"{self.host}:2222", | ||||||
|  |             settings={ | ||||||
|  |                 "username": "authentik", | ||||||
|  |                 "password": self.password, | ||||||
|  |             }, | ||||||
|  |             provider=rac, | ||||||
|  |         ) | ||||||
|  |         app = Application.objects.create(name=generate_id(), slug=generate_id(), provider=rac) | ||||||
|  |         outpost: Outpost = Outpost.objects.create( | ||||||
|  |             name=generate_id(), | ||||||
|  |             type=OutpostType.RAC, | ||||||
|  |         ) | ||||||
|  |         outpost.providers.add(rac) | ||||||
|  |         outpost.build_user_permissions(outpost.user) | ||||||
|  |  | ||||||
|  |         self.start_rac(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|  |  | ||||||
|  |         self.driver.get( | ||||||
|  |             self.url("authentik_providers_rac:start", app=app.slug, endpoint=endpoint.pk) | ||||||
|  |         ) | ||||||
|  |         self.login() | ||||||
|  |         sleep(1) | ||||||
|  |  | ||||||
|  |         iface = self.driver.find_element(By.CSS_SELECTOR, "ak-rac") | ||||||
|  |         sleep(5) | ||||||
|  |         state = self.driver.execute_script("return arguments[0].clientState", iface) | ||||||
|  |         self.assertEqual(state, 3) | ||||||
|  |  | ||||||
|  |         uid = generate_id() | ||||||
|  |         self.driver.find_element(By.CSS_SELECTOR, "body").send_keys( | ||||||
|  |             f'echo "{uid}" > /tmp/test' + Keys.ENTER | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         sleep(2) | ||||||
|  |  | ||||||
|  |         _, output = test_ssh.exec_run("cat /tmp/test") | ||||||
|  |         self.assertEqual(output, f"{uid}\n".encode()) | ||||||
| @ -1,7 +1,6 @@ | |||||||
| """Radius e2e tests""" | """Radius e2e tests""" | ||||||
|  |  | ||||||
| from dataclasses import asdict | from dataclasses import asdict | ||||||
| from time import sleep |  | ||||||
|  |  | ||||||
| from pyrad.client import Client | from pyrad.client import Client | ||||||
| from pyrad.dictionary import Dictionary | from pyrad.dictionary import Dictionary | ||||||
| @ -50,17 +49,7 @@ class TestProviderRadius(SeleniumTestCase): | |||||||
|         outpost.providers.add(radius) |         outpost.providers.add(radius) | ||||||
|  |  | ||||||
|         self.start_radius(outpost) |         self.start_radius(outpost) | ||||||
|  |         self.wait_for_outpost(outpost) | ||||||
|         # Wait until outpost healthcheck succeeds |  | ||||||
|         healthcheck_retries = 0 |  | ||||||
|         while healthcheck_retries < 50:  # noqa: PLR2004 |  | ||||||
|             if len(outpost.state) > 0: |  | ||||||
|                 state = outpost.state[0] |  | ||||||
|                 if state.last_seen: |  | ||||||
|                     break |  | ||||||
|             healthcheck_retries += 1 |  | ||||||
|             sleep(0.5) |  | ||||||
|         sleep(5) |  | ||||||
|         return outpost |         return outpost | ||||||
|  |  | ||||||
|     @retry() |     @retry() | ||||||
|  | |||||||
| @ -419,7 +419,6 @@ class TestSourceSAML(SeleniumTestCase): | |||||||
|         # Wait until we're logged in |         # Wait until we're logged in | ||||||
|         self.wait_for_url(self.if_user_url()) |         self.wait_for_url(self.if_user_url()) | ||||||
|  |  | ||||||
|         # sleep(999999) |  | ||||||
|         self.assert_user( |         self.assert_user( | ||||||
|             User.objects.exclude(username="akadmin") |             User.objects.exclude(username="akadmin") | ||||||
|             .exclude(username__startswith="ak-outpost") |             .exclude(username__startswith="ak-outpost") | ||||||
|  | |||||||
| @ -12,8 +12,8 @@ from typing import Any | |||||||
| from unittest.case import TestCase | from unittest.case import TestCase | ||||||
| from urllib.parse import urlencode | from urllib.parse import urlencode | ||||||
|  |  | ||||||
|  | from channels.testing import ChannelsLiveServerTestCase | ||||||
| from django.apps import apps | from django.apps import apps | ||||||
| from django.contrib.staticfiles.testing import StaticLiveServerTestCase |  | ||||||
| from django.db import connection | from django.db import connection | ||||||
| from django.db.migrations.loader import MigrationLoader | from django.db.migrations.loader import MigrationLoader | ||||||
| from django.test.testcases import TransactionTestCase | from django.test.testcases import TransactionTestCase | ||||||
| @ -35,6 +35,8 @@ from authentik.core.api.users import UserSerializer | |||||||
| from authentik.core.models import User | from authentik.core.models import User | ||||||
| from authentik.core.tests.utils import create_test_admin_user | from authentik.core.tests.utils import create_test_admin_user | ||||||
| from authentik.lib.generators import generate_id | from authentik.lib.generators import generate_id | ||||||
|  | from authentik.outposts.models import Outpost | ||||||
|  | from tests.e2e._process import TestDatabaseProcess | ||||||
|  |  | ||||||
| RETRIES = int(environ.get("RETRIES", "3")) | RETRIES = int(environ.get("RETRIES", "3")) | ||||||
| IS_CI = "CI" in environ | IS_CI = "CI" in environ | ||||||
| @ -58,10 +60,13 @@ def get_local_ip() -> str: | |||||||
|     return ip_addr |     return ip_addr | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class ContainerException(Exception): ... | ||||||
|  |  | ||||||
|  |  | ||||||
| class DockerTestCase(TestCase): | class DockerTestCase(TestCase): | ||||||
|     """Mixin for dealing with containers""" |     """Mixin for dealing with containers""" | ||||||
|  |  | ||||||
|     max_healthcheck_attempts = 30 |     max_healthcheck_attempts = 50 | ||||||
|  |  | ||||||
|     __client: DockerClient |     __client: DockerClient | ||||||
|     __network: Network |     __network: Network | ||||||
| @ -95,7 +100,7 @@ class DockerTestCase(TestCase): | |||||||
|             sleep(1) |             sleep(1) | ||||||
|             attempt += 1 |             attempt += 1 | ||||||
|             if attempt >= self.max_healthcheck_attempts: |             if attempt >= self.max_healthcheck_attempts: | ||||||
|                 self.failureException("Container failed to start") |                 raise ContainerException("Container failed to start") | ||||||
|  |  | ||||||
|     def get_container_image(self, base: str) -> str: |     def get_container_image(self, base: str) -> str: | ||||||
|         """Try to pull docker image based on git branch, fallback to main if not found.""" |         """Try to pull docker image based on git branch, fallback to main if not found.""" | ||||||
| @ -152,13 +157,17 @@ class DockerTestCase(TestCase): | |||||||
|         self.__network.remove() |         self.__network.remove() | ||||||
|  |  | ||||||
|  |  | ||||||
| class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase): | class SeleniumTestCase(DockerTestCase, ChannelsLiveServerTestCase): | ||||||
|     """StaticLiveServerTestCase which automatically creates a Webdriver instance""" |     """ChannelsLiveServerTestCase which automatically creates a Webdriver instance""" | ||||||
|  |  | ||||||
|  |     ProtocolServerProcess = TestDatabaseProcess | ||||||
|  |  | ||||||
|     host = get_local_ip() |     host = get_local_ip() | ||||||
|     wait_timeout: int |     wait_timeout: int | ||||||
|     user: User |     user: User | ||||||
|  |  | ||||||
|  |     serve_static = True | ||||||
|  |  | ||||||
|     def setUp(self): |     def setUp(self): | ||||||
|         if IS_CI: |         if IS_CI: | ||||||
|             print("::group::authentik Logs", file=stderr) |             print("::group::authentik Logs", file=stderr) | ||||||
| @ -265,6 +274,18 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase): | |||||||
|         self.assertEqual(user["name"].value, expected_user.name) |         self.assertEqual(user["name"].value, expected_user.name) | ||||||
|         self.assertEqual(user["email"].value, expected_user.email) |         self.assertEqual(user["email"].value, expected_user.email) | ||||||
|  |  | ||||||
|  |     def wait_for_outpost(self, outpost: Outpost, tries=50): | ||||||
|  |         """Wait until outpost healthcheck succeeds""" | ||||||
|  |         healthcheck_retries = 0 | ||||||
|  |         while healthcheck_retries < tries: | ||||||
|  |             if len(outpost.state) > 0: | ||||||
|  |                 state = outpost.state[0] | ||||||
|  |                 if state.last_seen: | ||||||
|  |                     return | ||||||
|  |             healthcheck_retries += 1 | ||||||
|  |             sleep(0.5) | ||||||
|  |         raise ContainerException("Outpost failed to become healthy") | ||||||
|  |  | ||||||
|  |  | ||||||
| @lru_cache | @lru_cache | ||||||
| def get_loader(): | def get_loader(): | ||||||
| @ -277,7 +298,12 @@ def retry(max_retires=RETRIES, exceptions=None): | |||||||
|     """Retry test multiple times. Default to catching Selenium Timeout Exception""" |     """Retry test multiple times. Default to catching Selenium Timeout Exception""" | ||||||
|  |  | ||||||
|     if not exceptions: |     if not exceptions: | ||||||
|         exceptions = [WebDriverException, TimeoutException, NoSuchElementException] |         exceptions = [ | ||||||
|  |             WebDriverException, | ||||||
|  |             TimeoutException, | ||||||
|  |             NoSuchElementException, | ||||||
|  |             ContainerException, | ||||||
|  |         ] | ||||||
|  |  | ||||||
|     logger = get_logger() |     logger = get_logger() | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	