Skip to content

web/flows: fix source icons being always inverted (cherry-pick #20419 to version-2026.2)#20607

Merged
BeryJu merged 1 commit intoversion-2026.2from
cherry-pick/20419-to-version-2026.2
Feb 26, 2026
Merged

web/flows: fix source icons being always inverted (cherry-pick #20419 to version-2026.2)#20607
BeryJu merged 1 commit intoversion-2026.2from
cherry-pick/20419-to-version-2026.2

Conversation

@authentik-automation
Copy link
Contributor

Cherry-pick of #20419 to version-2026.2 branch.

Original PR: #20419
Original Author: @BeryJu
Cherry-picked commit: 7c9bc2a

* web/flows: fix inverted source icons

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* fix actually

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

---------

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
@netlify
Copy link

netlify bot commented Feb 26, 2026

Deploy Preview for authentik-integrations ready!

Name Link
🔨 Latest commit 4017ee3
🔍 Latest deploy log https://app.netlify.com/projects/authentik-integrations/deploys/69a085d481dd85000862e658
😎 Deploy Preview https://deploy-preview-20607--authentik-integrations.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codecov
Copy link

codecov bot commented Feb 26, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
3026 1 3025 4
View the top 1 failed test(s) by shortest run time
tests.e2e.test_source_scim.TestSourceSCIM::test_scim_conformance
Stack Traces | 590s run time
self = <unittest.case._Outcome object at 0x7f682896cd70>
test_case = <tests.e2e.test_source_scim.TestSourceSCIM testMethod=test_scim_conformance>
subTest = False

    @contextlib.contextmanager
    def testPartExecutor(self, test_case, subTest=False):
        old_success = self.success
        self.success = True
        try:
>           yield

.../hostedtoolcache/Python/3.14.3........./x64/lib/python3.14/unittest/case.py:58: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <tests.e2e.test_source_scim.TestSourceSCIM testMethod=test_scim_conformance>
result = <TestCaseFunction test_scim_conformance>

    def run(self, result=None):
        if result is None:
            result = self.defaultTestResult()
            startTestRun = getattr(result, 'startTestRun', None)
            stopTestRun = getattr(result, 'stopTestRun', None)
            if startTestRun is not None:
                startTestRun()
        else:
            stopTestRun = None
    
        result.startTest(self)
        try:
            testMethod = getattr(self, self._testMethodName)
            if (getattr(self.__class__, "__unittest_skip__", False) or
                getattr(testMethod, "__unittest_skip__", False)):
                # If the class or method was skipped.
                skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')
                            or getattr(testMethod, '__unittest_skip_why__', ''))
                _addSkip(result, self, skip_why)
                return result
    
            expecting_failure = (
                getattr(self, "__unittest_expecting_failure__", False) or
                getattr(testMethod, "__unittest_expecting_failure__", False)
            )
            outcome = _Outcome(result)
            start_time = time.perf_counter()
            try:
                self._outcome = outcome
    
                with outcome.testPartExecutor(self):
                    self._callSetUp()
                if outcome.success:
                    outcome.expecting_failure = expecting_failure
                    with outcome.testPartExecutor(self):
                        self._callTestMethod(testMethod)
                    outcome.expecting_failure = False
                    with outcome.testPartExecutor(self):
>                       self._callTearDown()

.../hostedtoolcache/Python/3.14.3........./x64/lib/python3.14/unittest/case.py:672: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <tests.e2e.test_source_scim.TestSourceSCIM testMethod=test_scim_conformance>

    def _callTearDown(self):
>       self.tearDown()

.../hostedtoolcache/Python/3.14.3........./x64/lib/python3.14/unittest/case.py:629: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <tests.e2e.test_source_scim.TestSourceSCIM testMethod=test_scim_conformance>

    def tearDown(self):
        if IS_CI:
            print("::endgroup::", file=stderr)
        super().tearDown()
        if IS_CI:
            print("::group::Browser logs")
        # Very verbose way to get browser logs
        # https://github..../selenium/pull/15641
        # for some reason this removes the `get_log` API from Remote Webdriver
        # and only keeps it on the local Chrome web driver, even when using
        # a remote chrome driver...? (nvm the fact this was released as a minor version)
>       for line in self.driver.execute(Command.GET_LOG, {"type": "browser"})["value"]:
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/e2e/utils.py:158: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.remote.webdriver.WebDriver (session="2543525fc0ee776fd4b4615060cb7242")>
driver_command = 'getLog', params = {'type': 'browser'}

    def execute(self, driver_command: str, params: dict[str, Any] | None = None) -> dict[str, Any]:
        """Sends a command to be executed by a command.CommandExecutor.
    
        Args:
            driver_command: The name of the command to execute as a string.
            params: A dictionary of named parameters to send with the command.
    
        Returns:
            The command's JSON response loaded into a dictionary object.
        """
        params = self._wrap_value(params)
    
        if self.session_id:
            if not params:
                params = {"sessionId": self.session_id}
            elif "sessionId" not in params:
                params["sessionId"] = self.session_id
    
        response = cast(RemoteConnection, self.command_executor).execute(driver_command, params)
    
        if response:
>           self.error_handler.check_response(response)

.venv/lib/python3.14.../webdriver/remote/webdriver.py:432: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x7f682896c1a0>
response = {'status': 404, 'value': '{\n  "value": {\n    "message": "Unable to find session with ID: 2543525fc0ee776fd4b4615060c...a:642)\\n\\tat java.base\\u002fjava.lang.Thread.run(Thread.java:1583)\\n",\n    "error": "invalid session id"\n  }\n}'}

    def check_response(self, response: dict[str, Any]) -> None:
        """Check that a JSON response from the WebDriver does not have an error.
    
        Args:
            response: The JSON response from the WebDriver server as a dictionary
                object.
    
        Raises:
            WebDriverException: If the response contains an error message.
        """
        status = response.get("status", None)
        if not status or status == ErrorCode.SUCCESS:
            return
        value = None
        message = response.get("message", "")
        screen: str = response.get("screen", "")
        stacktrace = None
        if isinstance(status, int):
            value_json = response.get("value", None)
            if value_json and isinstance(value_json, str):
                try:
                    value = json.loads(value_json)
                    if isinstance(value, dict):
                        if len(value) == 1:
                            value = value["value"]
                        status = value.get("error", None)
                        if not status:
                            status = value.get("status", ErrorCode.UNKNOWN_ERROR)
                            message = value.get("value") or value.get("message")
                            if not isinstance(message, str):
                                value = message
                                message = message.get("message") if isinstance(message, dict) else None
                        else:
                            message = value.get("message", None)
                except ValueError:
                    pass
    
        exception_class: type[WebDriverException]
        e = ErrorCode()
        error_codes = [item for item in dir(e) if not item.startswith("__")]
        for error_code in error_codes:
            error_info = getattr(ErrorCode, error_code)
            if isinstance(error_info, list) and status in error_info:
                exception_class = getattr(ExceptionMapping, error_code, WebDriverException)
                break
        else:
            exception_class = WebDriverException
    
        if not value:
            value = response["value"]
        if isinstance(value, str):
            raise exception_class(value)
        if message == "" and "message" in value:
            message = value["message"]
    
        screen = None  # type: ignore[assignment]
        if "screen" in value:
            screen = value["screen"]
    
        stacktrace = None
        st_value = value.get("stackTrace") or value.get("stacktrace")
        if st_value:
            if isinstance(st_value, str):
                stacktrace = st_value.split("\n")
            else:
                stacktrace = []
                try:
                    for frame in st_value:
                        line = frame.get("lineNumber", "")
                        file = frame.get("fileName", "<anonymous>")
                        if line:
                            file = f"{file}:{line}"
                        meth = frame.get("methodName", "<anonymous>")
                        if "className" in frame:
                            meth = f"{frame['className']}.{meth}"
                        msg = "    at %s (%s)"
                        msg = msg % (meth, file)
                        stacktrace.append(msg)
                except TypeError:
                    pass
        if exception_class == UnexpectedAlertPresentException:
            alert_text = None
            if "data" in value:
                alert_text = value["data"].get("text")
            elif "alert" in value:
                alert_text = value["alert"].get("text")
            raise exception_class(message, screen, stacktrace, alert_text)  # type: ignore[call-arg]  # mypy is not smart enough here
>       raise exception_class(message, screen, stacktrace)
E       selenium.common.exceptions.InvalidSessionIdException: Message: Unable to find session with ID: 2543525fc0ee776fd4b4615060cb7242. Session was removed at 2026-02-26T17:54:07.947765492Z (130 seconds ago), reason: session timed out due to inactivity, node: http://10.1.0.143:4444
E       Build info: version: '4.40.0', revision: 'b3333f1'
E       System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.14.0-1017-azure', java.version: '21.0.10'
E       Driver info: driver.version: unknown; For documentation on this error, please visit: https://www.selenium..../webdriver/troubleshooting/errors#invalidsessionidexception
E       Stacktrace:
E       org.openqa.selenium.NoSuchSessionException: Unable to find session with ID: 2543525fc0ee776fd4b4615060cb7242. Session was removed at 2026-02-26T17:54:07.947765492Z (130 seconds ago), reason: session timed out due to inactivity, node: http://10.1.0.143:4444
E       Build info: version: '4.40.0', revision: 'b3333f1'
E       System info: os.name: 'Linux', os.arch: 'amd64', os.version: '6.14.0-1017-azure', java.version: '21.0.10'
E       Driver info: driver.version: unknown
E       	at org.openqa.selenium.grid.sessionmap.local.LocalSessionMap.get(LocalSessionMap.java:138)
E       	at org.openqa.selenium.grid.sessionmap.SessionMap.getUri(SessionMap.java:84)
E       	at org.openqa.selenium.grid.router.HandleSession.lambda$loadSessionId$5(HandleSession.java:231)
E       	at org.openqa.selenium.grid.router.HandleSession.execute(HandleSession.java:188)
E       	at org.openqa.selenium.remote.http.Route$PredicatedRoute.handle(Route.java:398)
E       	at org.openqa.selenium.remote.http.Route.execute(Route.java:69)
E       	at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:361)
E       	at org.openqa.selenium.remote.http.Route.execute(Route.java:69)
E       	at org.openqa.selenium.grid.router.Router.execute(Router.java:89)
E       	at org.openqa.selenium.grid.web.EnsureSpecCompliantResponseHeaders.lambda$apply$0(EnsureSpecCompliantResponseHeaders.java:34)
E       	at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:63)
E       	at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:361)
E       	at org.openqa.selenium.remote.http.Route.execute(Route.java:69)
E       	at org.openqa.selenium.remote.http.Route$NestedRoute.handle(Route.java:271)
E       	at org.openqa.selenium.remote.http.Route.execute(Route.java:69)
E       	at org.openqa.selenium.remote.http.Route$CombinedRoute.handle(Route.java:361)
E       	at org.openqa.selenium.remote.http.Route.execute(Route.java:69)
E       	at org.openqa.selenium.remote.AddWebDriverSpecHeaders.lambda$apply$0(AddWebDriverSpecHeaders.java:35)
E       	at org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)
E       	at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:63)
E       	at org.openqa.selenium.remote.ErrorFilter.lambda$apply$0(ErrorFilter.java:44)
E       	at org.openqa.selenium.remote.http.Filter$1.execute(Filter.java:63)
E       	at org.openqa.selenium.netty.server.SeleniumHandler.lambda$channelRead0$0(SeleniumHandler.java:49)
E       	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
E       	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
E       	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
E       	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
E       	at java.base/java.lang.Thread.run(Thread.java:1583)

.venv/lib/python3.14.../webdriver/remote/errorhandler.py:232: InvalidSessionIdException

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

@BeryJu BeryJu merged commit d686932 into version-2026.2 Feb 26, 2026
87 of 90 checks passed
@BeryJu BeryJu deleted the cherry-pick/20419-to-version-2026.2 branch February 26, 2026 20:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant