diff --git a/.github/workflows/automation-tests.yml b/.github/workflows/automation-tests.yml
index 434d0c1..7a02472 100644
--- a/.github/workflows/automation-tests.yml
+++ b/.github/workflows/automation-tests.yml
@@ -1,4 +1,4 @@
-name: CI with 🐋 & Selenide
+name: automation tests
on:
push:
@@ -24,5 +24,5 @@ jobs:
- name: Build test docker container
run: docker-compose build
- - name: Run Selenide tests
- run: mvn -B -ntp test -P automation-tests -D headless=true
+ - name: Run automation tests
+ run: mvn -B -ntp test -P automation-tests -D selenide.headless=true
diff --git a/.github/workflows/release-github-tag.yml b/.github/workflows/release-github-tag.yml
index 38d6089..0aede50 100644
--- a/.github/workflows/release-github-tag.yml
+++ b/.github/workflows/release-github-tag.yml
@@ -38,7 +38,7 @@ jobs:
mvn \
--no-transfer-progress \
--batch-mode \
- -Dgpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} \
+ -D gpg.passphrase=${{ secrets.OSSRH_GPG_SECRET_KEY_PASSWORD }} \
-P ossrh \
clean deploy
env:
@@ -56,7 +56,6 @@ jobs:
- name: Build docker init container
run: |
- echo "Building docker image = kilmajster/keycloak-username-password-attribute-authenticator:$TAG" && \
docker build \
--build-arg VERSION="$TAG" \
-f src/main/docker/initContainer.Dockerfile \
diff --git a/pom.xml b/pom.xml
index fd08d53..4e2dc21 100644
--- a/pom.xml
+++ b/pom.xml
@@ -62,15 +62,16 @@
11
11
- 13.0.0
+ 13.0.1
3.19.0
+ 6.10.4
4.13.2
+ 3.141.59
+ 5.21.0
1.15.3
1.7.0
- 5.21.0
- 3.141.59
3.8.1
@@ -96,23 +97,24 @@
org.keycloak
- keycloak-server-spi
+ keycloak-services
${keycloak.version}
provided
org.keycloak
- keycloak-server-spi-private
+ keycloak-server-spi
${keycloak.version}
provided
org.keycloak
- keycloak-services
+ keycloak-server-spi-private
${keycloak.version}
provided
+
junit
@@ -154,6 +156,19 @@
org.seleniumhq.selenium
selenium-chrome-driver
${selenium-chrome-driver.version}
+ test
+
+
+ io.cucumber
+ cucumber-java
+ ${cucumber.version}
+ test
+
+
+ io.cucumber
+ cucumber-junit
+ ${cucumber.version}
+ test
@@ -184,7 +199,7 @@
maven-surefire-plugin
${maven-surefire-plugin.version}
- **/*AT
+ **/CucumberConfig.java
@@ -237,7 +252,6 @@
maven-gpg-plugin
${maven-gpg-plugin.version}
-
--pinentry-mode
loopback
diff --git a/src/test/java/io.github.kilmajster.keycloak/CucumberConfig.java b/src/test/java/io.github.kilmajster.keycloak/CucumberConfig.java
new file mode 100644
index 0000000..4b2cc87
--- /dev/null
+++ b/src/test/java/io.github.kilmajster.keycloak/CucumberConfig.java
@@ -0,0 +1,10 @@
+package io.github.kilmajster.keycloak;
+
+import io.cucumber.junit.Cucumber;
+import io.cucumber.junit.CucumberOptions;
+import org.junit.runner.RunWith;
+
+@RunWith(Cucumber.class)
+@CucumberOptions(features = "src/test/resources/cucumber")
+public class CucumberConfig {
+}
\ No newline at end of file
diff --git a/src/test/java/io.github.kilmajster.keycloak/KeycloakSteps.java b/src/test/java/io.github.kilmajster.keycloak/KeycloakSteps.java
new file mode 100644
index 0000000..4b479ea
--- /dev/null
+++ b/src/test/java/io.github.kilmajster.keycloak/KeycloakSteps.java
@@ -0,0 +1,93 @@
+package io.github.kilmajster.keycloak;
+
+import com.codeborne.selenide.SelenideElement;
+import dasniko.testcontainers.keycloak.KeycloakContainer;
+import io.cucumber.java.en.And;
+import io.cucumber.java.en.Given;
+import io.cucumber.java.en.Then;
+import io.cucumber.java.en.When;
+import org.junit.Before;
+import org.openqa.selenium.By;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+
+import static com.codeborne.selenide.Condition.text;
+import static com.codeborne.selenide.Selenide.$;
+import static com.codeborne.selenide.Selenide.open;
+import static io.github.kilmajster.keycloak.TestConstants.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public final class KeycloakSteps {
+
+ private static final Logger log = LoggerFactory.getLogger(KeycloakSteps.class);
+
+ private final KeycloakContainer keycloak = new KeycloakContainer(KEYCLOAK_DEV_DOCKER_IMAGE)
+ .withRealmImportFile("dev-realm.json")
+ .withLogConsumer(new Slf4jLogConsumer(log));
+
+ @Given("keycloak is running with default setup")
+ public void keycloak_is_running_with_default_setup() {
+ if (!keycloak.isRunning()) {
+ log.info("Starting keycloak container...");
+ keycloak.start();
+ }
+ }
+
+ @Given("keycloak is running with LOGIN_FORM_ATTRIBUTE_LABEL = {string}")
+ public void keycloak_is_running_with_login_form_attribute_label_env(final String envLoginFormAttributeLabel) {
+ keycloak.addEnv("LOGIN_FORM_ATTRIBUTE_LABEL", envLoginFormAttributeLabel);
+ if (!keycloak.isRunning()) {
+ log.info("Starting keycloak container with LOGIN_FORM_ATTRIBUTE_LABEL = " + envLoginFormAttributeLabel);
+ keycloak.start();
+ }
+ }
+
+ @When("user goes to the account console page")
+ public void go_to_keycloak_account_page() {
+ final String keycloakUrl = TestConstants.KEYCLOAK_LOCAL_URL_PREFIX + keycloak.getFirstMappedPort();
+ open(keycloakUrl + "/auth/realms/dev-realm/account");
+ }
+
+ @Then("user should be not logged in")
+ public void user_should_be_not_logged_in() {
+ final String loggedInUser = $(By.id("landingLoggedInUser")).val();
+ assertThat(loggedInUser).isNullOrEmpty();
+ }
+
+ @When("user clicks a sign in button")
+ public static void click_sign_in_button() {
+ log.info("click_sign_in_button()");
+
+ $(By.id("landingSignInButton")).click();
+ }
+
+ @Then("login form with attribute input labeled as {string} should be shown")
+ public static void verify_login_form_is_displayed_with_user_attribute_label(final String label) {
+ log.info("verify_login_form_is_displayed_with_user_attribute_label( label = " + label + " )");
+
+ assertThat($(By.id("kc-form-login")).isDisplayed()).isTrue();
+ userAttributeFormLabel().shouldHave(text(label));
+ }
+
+ @When("user log into account console with a valid credentials and user attribute equal {string}")
+ public static void log_into_account_console(final String attribute) {
+ log.info("log_into_account_console()");
+
+ $(By.id("username")).val(TEST_USERNAME);
+ $(By.id("password")).val(TEST_PASSWORD);
+ $(By.id("login_form_user_attribute")).val(attribute);
+ $(By.id("kc-login")).click();
+ }
+
+ @Then("user should be logged into account console")
+ public static void verify_that_user_is_logged_in() {
+ log.info("verify_that_user_is_logged_in()");
+
+ $(By.id("landingLoggedInUser")).shouldHave(text("test"));
+ }
+
+ private static SelenideElement userAttributeFormLabel() {
+ return $(By.xpath("//input[@id='login_form_user_attribute']/preceding-sibling::label"));
+ }
+}
diff --git a/src/test/java/io.github.kilmajster.keycloak/TestConstants.java b/src/test/java/io.github.kilmajster.keycloak/TestConstants.java
new file mode 100644
index 0000000..6d0c7ba
--- /dev/null
+++ b/src/test/java/io.github.kilmajster.keycloak/TestConstants.java
@@ -0,0 +1,9 @@
+package io.github.kilmajster.keycloak;
+
+public interface TestConstants {
+ String KEYCLOAK_DEV_DOCKER_IMAGE = "kilmajster/keycloak-with-authenticator:test";
+ String KEYCLOAK_LOCAL_URL_PREFIX = "http://localhost:";
+
+ String TEST_USERNAME = "test";
+ String TEST_PASSWORD = "test";
+}
\ No newline at end of file
diff --git a/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormAT.java b/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormAT.java
deleted file mode 100644
index cfc6808..0000000
--- a/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormAT.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.github.kilmajster.keycloak;
-
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-import io.github.kilmajster.keycloak.base.BaseKeycloakInDockerAT;
-import org.junit.Rule;
-import org.junit.Test;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
-
-import static io.github.kilmajster.keycloak.base.Steps.*;
-
-
-public class UsernamePasswordAttributeFormAT extends BaseKeycloakInDockerAT {
-
- @Rule
- public KeycloakContainer keycloak = new KeycloakContainer(KEYCLOAK_DEV_DOCKER_IMAGE)
- .withRealmImportFile("dev-realm.json")
- .withNetwork(testNetwork)
- .withNetworkAliases(KEYCLOAK_NETWORK_ALIAS)
- .withLogConsumer(new Slf4jLogConsumer(log));
-
- @Test
- public void shouldLogIntoAccountConsole() {
- final String keycloakBaseUrl = getKeycloakBaseUrl(keycloak);
-
- go_to_keycloak_account_page(keycloakBaseUrl);
- click_sign_in_button();
- verify_login_form_is_displayed_with_user_attribute_label("Test attr");
- log_into_account_console();
- verify_that_user_is_logged_in();
- }
-}
\ No newline at end of file
diff --git a/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormEnvVarConfigAT.java b/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormEnvVarConfigAT.java
deleted file mode 100644
index 05ffc96..0000000
--- a/src/test/java/io.github.kilmajster.keycloak/UsernamePasswordAttributeFormEnvVarConfigAT.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package io.github.kilmajster.keycloak;
-
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-import io.github.kilmajster.keycloak.base.BaseKeycloakInDockerAT;
-import org.junit.Rule;
-import org.junit.Test;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
-
-import static io.github.kilmajster.keycloak.base.Steps.*;
-
-
-public class UsernamePasswordAttributeFormEnvVarConfigAT extends BaseKeycloakInDockerAT {
-
- @Rule
- public KeycloakContainer keycloak = new KeycloakContainer(KEYCLOAK_DEV_DOCKER_IMAGE)
- .withRealmImportFile("dev-realm.json")
- .withEnv("LOGIN_FORM_ATTRIBUTE_LABEL", "Custom label")
- .withNetwork(testNetwork)
- .withNetworkAliases(KEYCLOAK_NETWORK_ALIAS)
- .withLogConsumer(new Slf4jLogConsumer(log));
-
- @Test
- public void shouldTakeAttributeLabelFromEnvVariable() {
- final String keycloakBaseUrl = getKeycloakBaseUrl(keycloak);
-
- go_to_keycloak_account_page(keycloakBaseUrl);
- click_sign_in_button();
- verify_login_form_is_displayed_with_user_attribute_label("Custom label");
- log_into_account_console();
- verify_that_user_is_logged_in();
- }
-}
\ No newline at end of file
diff --git a/src/test/java/io.github.kilmajster.keycloak/base/BaseKeycloakInDockerAT.java b/src/test/java/io.github.kilmajster.keycloak/base/BaseKeycloakInDockerAT.java
deleted file mode 100644
index 53947f9..0000000
--- a/src/test/java/io.github.kilmajster.keycloak/base/BaseKeycloakInDockerAT.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package io.github.kilmajster.keycloak.base;
-
-import com.codeborne.selenide.WebDriverRunner;
-import dasniko.testcontainers.keycloak.KeycloakContainer;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Rule;
-import org.openqa.selenium.chrome.ChromeOptions;
-import org.openqa.selenium.remote.RemoteWebDriver;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testcontainers.containers.BrowserWebDriverContainer;
-import org.testcontainers.containers.Container;
-import org.testcontainers.containers.Network;
-import org.testcontainers.containers.output.Slf4jLogConsumer;
-
-public abstract class BaseKeycloakInDockerAT {
-
- protected static final Logger log = LoggerFactory.getLogger(BaseKeycloakInDockerAT.class);
-
- protected static final String KEYCLOAK_DEV_DOCKER_IMAGE = "kilmajster/keycloak-with-authenticator:test";
- protected static final String KEYCLOAK_NETWORK_ALIAS = "keycloak-host";
- protected static final int KEYCLOAK_DEFAULT_PORT = 8080;
- protected static final String KEYCLOAK_DOCKER_URL = "http://" + KEYCLOAK_NETWORK_ALIAS + ":" + KEYCLOAK_DEFAULT_PORT;
- protected static final String KEYCLOAK_LOCAL_URL_PREFIX = "http://localhost:";
-
- @Rule
- public Network testNetwork = isHeadless() ? Network.newNetwork() : null;
-
- @Rule
- public BrowserWebDriverContainer chrome = isHeadless() ? (BrowserWebDriverContainer) new BrowserWebDriverContainer()
- .withCapabilities(new ChromeOptions())
- .withNetwork(testNetwork)
- .withLogConsumer(new Slf4jLogConsumer(log)) : null;
-
- @Before
- public void setUp() {
- if (isHeadless()) {
- log.info("Headless mode is enabled!");
- RemoteWebDriver driver = chrome.getWebDriver();
- WebDriverRunner.setWebDriver(driver);
- }
- }
-
- @After
- public void tearDown() {
- if (isHeadless()) {
- WebDriverRunner.closeWebDriver();
- }
- }
-
- protected static boolean isHeadless() {
- return Boolean.parseBoolean(System.getProperty("headless"));
- }
-
- protected String getKeycloakBaseUrl(final KeycloakContainer keycloakContainer) {
- return isHeadless() ? KEYCLOAK_DOCKER_URL : KEYCLOAK_LOCAL_URL_PREFIX + keycloakContainer.getFirstMappedPort();
- }
-}
\ No newline at end of file
diff --git a/src/test/java/io.github.kilmajster.keycloak/base/Steps.java b/src/test/java/io.github.kilmajster.keycloak/base/Steps.java
deleted file mode 100644
index 707723f..0000000
--- a/src/test/java/io.github.kilmajster.keycloak/base/Steps.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package io.github.kilmajster.keycloak.base;
-
-import com.codeborne.selenide.SelenideElement;
-import org.openqa.selenium.By;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static com.codeborne.selenide.Condition.text;
-import static com.codeborne.selenide.Selenide.$;
-import static com.codeborne.selenide.Selenide.open;
-import static org.assertj.core.api.Assertions.assertThat;
-
-public final class Steps {
-
- protected static final Logger log = LoggerFactory.getLogger(Steps.class);
-
-
- public static void go_to_keycloak_account_page(final String keycloakUrl) {
- log.info("go_to_keycloak_account_page( keycloakUrl = " + keycloakUrl + " )");
-
- open(keycloakUrl + "/auth/realms/dev-realm/account");
- }
-
- public static void click_sign_in_button() {
- log.info("click_sign_in_button()");
-
- $(By.id("landingSignInButton")).click();
- }
-
- public static void verify_login_form_is_displayed_with_user_attribute_label(final String label) {
- log.info("verify_login_form_is_displayed_with_user_attribute_label( label = " + label + " )");
-
- assertThat($(By.id("kc-form-login")).isDisplayed()).isTrue();
- userAttributeFormLabel().shouldHave(text(label));
- }
-
- public static void log_into_account_console() {
- log.info("log_into_account_console()");
-
- $(By.id("username")).val("test");
- $(By.id("password")).val("test");
- $(By.id("login_form_user_attribute")).val("test");
- $(By.id("kc-login")).click();
- }
-
- public static void verify_that_user_is_logged_in() {
- log.info("verify_that_user_is_logged_in()");
-
- $(By.id("landingLoggedInUser")).shouldHave(text("test"));
- }
-
- private static SelenideElement userAttributeFormLabel() {
- return $(By.xpath("//input[@id='login_form_user_attribute']/preceding-sibling::label"));
- }
-}
diff --git a/src/test/resources/cucumber.properties b/src/test/resources/cucumber.properties
new file mode 100644
index 0000000..aa51b35
--- /dev/null
+++ b/src/test/resources/cucumber.properties
@@ -0,0 +1 @@
+cucumber.publish.quiet=true
\ No newline at end of file
diff --git a/src/test/resources/cucumber/login-form-env-var-config.feature b/src/test/resources/cucumber/login-form-env-var-config.feature
new file mode 100644
index 0000000..e100c1d
--- /dev/null
+++ b/src/test/resources/cucumber/login-form-env-var-config.feature
@@ -0,0 +1,8 @@
+Feature: Login form with user attribute with environment variable based configuration
+
+ Scenario: label is taken from environment variable
+ Given keycloak is running with LOGIN_FORM_ATTRIBUTE_LABEL = "Custom label"
+ When user goes to the account console page
+ Then user should be not logged in
+ When user clicks a sign in button
+ Then login form with attribute input labeled as "Custom label" should be shown
\ No newline at end of file
diff --git a/src/test/resources/cucumber/login-form.feature b/src/test/resources/cucumber/login-form.feature
new file mode 100644
index 0000000..5a294d8
--- /dev/null
+++ b/src/test/resources/cucumber/login-form.feature
@@ -0,0 +1,10 @@
+Feature: Login form with user attribute
+
+ Scenario: user can log into account console
+ Given keycloak is running with default setup
+ When user goes to the account console page
+ Then user should be not logged in
+ When user clicks a sign in button
+ Then login form with attribute input labeled as "Test attr" should be shown
+ When user log into account console with a valid credentials and user attribute equal "test"
+ Then user should be logged into account console
\ No newline at end of file