diff --git a/pom.xml b/pom.xml
index bb03a56..bd76b05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -14,6 +14,8 @@
1.16.2
3.26.0
3.2.0
+ 3.3.0
+ 4.22.0
3.3.0
0.0.0-SNAPSHOT
NodePort
@@ -98,6 +100,12 @@
${version.assertj}
test
+
+ org.seleniumhq.selenium
+ selenium-java
+ ${version.selenium}
+ test
+
@@ -120,6 +128,15 @@
+
+ maven-failsafe-plugin
+ ${version.failsafe-maven-plugin}
+
+
+ org.jboss.logmanager.LogManager
+
+
+
@@ -135,6 +152,17 @@
+
+ maven-failsafe-plugin
+
+
+
+ integration-test
+ verify
+
+
+
+
diff --git a/src/test/java/com/marcnuri/yakd/selenium/HomeIT.java b/src/test/java/com/marcnuri/yakd/selenium/HomeIT.java
new file mode 100644
index 0000000..18149df
--- /dev/null
+++ b/src/test/java/com/marcnuri/yakd/selenium/HomeIT.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2024 Marc Nuri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 2024-06-26, 17:20
+ */
+package com.marcnuri.yakd.selenium;
+
+import io.quarkus.test.common.http.TestHTTPResource;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.TestProfile;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.support.ui.Wait;
+import org.openqa.selenium.support.ui.WebDriverWait;
+
+import java.net.URL;
+import java.time.Duration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@QuarkusTest
+@TestProfile(IntegrationTestProfile.class)
+public class HomeIT {
+
+ @TestHTTPResource
+ URL url;
+ WebDriver driver;
+
+ @BeforeEach
+ void loadHomePage() {
+ driver.get(url.toString());
+ final Wait wait = new WebDriverWait(driver, Duration.ofSeconds(1));
+ wait.until(d -> d.findElement(By.cssSelector(".dashboard-page")).isDisplayed());
+ }
+
+ @Test
+ void hasDocumentTitle() {
+ assertThat(driver.getTitle())
+ .isEqualTo("YAKD - Kubernetes Dashboard");
+ }
+
+ @Test
+ void hasFooter() {
+ assertThat(driver.findElement(By.cssSelector(".dashboard-page footer")).getText())
+ .matches("Copyright © \\d{4} - Marc Nuri - Licensed under the Apache License 2.0");
+ }
+}
diff --git a/src/test/java/com/marcnuri/yakd/selenium/IntegrationTestProfile.java b/src/test/java/com/marcnuri/yakd/selenium/IntegrationTestProfile.java
new file mode 100644
index 0000000..ed7f5b4
--- /dev/null
+++ b/src/test/java/com/marcnuri/yakd/selenium/IntegrationTestProfile.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2024 Marc Nuri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 2024-06-26, 17:30
+ */
+package com.marcnuri.yakd.selenium;
+
+import io.quarkus.test.junit.QuarkusTestProfile;
+import io.quarkus.test.kubernetes.client.WithKubernetesTestServer;
+
+import java.util.Map;
+
+@WithSelenium
+@WithKubernetesTestServer
+public class IntegrationTestProfile implements QuarkusTestProfile {
+
+ @Override
+ public Map getConfigOverrides() {
+ return Map.of(
+ "yakd.frontend.root", "/frontend",
+ "quarkus.kubernetes-client.devservices.enabled", "false"
+ );
+ }
+
+}
diff --git a/src/test/java/com/marcnuri/yakd/selenium/SeleniumTestResource.java b/src/test/java/com/marcnuri/yakd/selenium/SeleniumTestResource.java
new file mode 100644
index 0000000..fb02481
--- /dev/null
+++ b/src/test/java/com/marcnuri/yakd/selenium/SeleniumTestResource.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2024 Marc Nuri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 2024-06-26, 17:30
+ */
+package com.marcnuri.yakd.selenium;
+
+import io.quarkus.test.common.QuarkusTestResourceConfigurableLifecycleManager;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.chrome.ChromeDriver;
+import org.openqa.selenium.chrome.ChromeDriverService;
+import org.openqa.selenium.chrome.ChromeOptions;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Map;
+
+public class SeleniumTestResource implements QuarkusTestResourceConfigurableLifecycleManager {
+
+ private boolean headless;
+ private ChromeDriverService chromeDriverService;
+ private ChromeDriver chromeDriver;
+
+ @Override
+ public void init(WithSelenium annotation) {
+ headless = annotation.headless();
+ }
+
+ @Override
+ public Map start() {
+ chromeDriverService = new ChromeDriverService.Builder()
+ .usingAnyFreePort()
+ .build();
+ try {
+ chromeDriverService.start();
+ } catch (IOException exception) {
+ throw new IllegalStateException("Unable to start ChromeDriverService", exception);
+ }
+ final ChromeOptions chromeOptions = new ChromeOptions();
+ if (headless) {
+ chromeOptions.addArguments("--headless=new");
+ }
+ chromeDriver = new ChromeDriver(chromeDriverService, chromeOptions);
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public void stop() {
+ if (chromeDriver != null) {
+ chromeDriver.close();
+ }
+ if (chromeDriverService != null) {
+ chromeDriverService.stop();
+ }
+ }
+
+ @Override
+ public void inject(TestInjector testInjector) {
+ testInjector.injectIntoFields(chromeDriver, new TestInjector.MatchesType(WebDriver.class));
+ }
+}
diff --git a/src/test/java/com/marcnuri/yakd/selenium/WithSelenium.java b/src/test/java/com/marcnuri/yakd/selenium/WithSelenium.java
new file mode 100644
index 0000000..67c8347
--- /dev/null
+++ b/src/test/java/com/marcnuri/yakd/selenium/WithSelenium.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2024 Marc Nuri
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Created on 2024-06-26, 17:30
+ */
+package com.marcnuri.yakd.selenium;
+
+import io.quarkus.test.common.QuarkusTestResource;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@QuarkusTestResource(SeleniumTestResource.class)
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface WithSelenium {
+
+ boolean headless() default true;
+
+}