testRealmReps;
+
+ private boolean resetTimeOffset;
+
+ //protected KeycloakTestingClient testingClient;
+
+ @BeforeAll
+ static void launchBrowser() throws Throwable {
+ playwright = Playwright.create();
+ BrowserType.LaunchOptions launchOptions = new BrowserType.LaunchOptions().setHeadless(true);
+ browser = playwright.chromium().launch(launchOptions);
+
+ keycloak = EmbeddedKeycloakLifecycle.getInstance();
+ if (!keycloak.isRunning()) {
+ keycloak.start();
+ }
+
+ adminClient = Keycloak.getInstance(keycloak.getBaseUrl(), "master", "admin", "admin", "admin-cli");
+ }
+
+ @AfterAll
+ static void closeBrowser() {
+ playwright.close();
+ adminClient.close();
+ }
+
+ @BeforeEach
+ void createContextAndPage() throws Exception {
+ context = browser.newContext();
+ page = context.newPage();
+
+ //adminClient = testContext.getAdminClient();
+ if (adminClient == null || adminClient.isClosed()) {
+ adminClient = Keycloak.getInstance(keycloak.getBaseUrl(), "master", "admin", "admin", "admin-cli");
+ }
+
+ //getTestingClient();
+
+ //setDefaultPageUriParameters();
+
+ //TestEventsLogger.setDriver(driver);
+
+ // The backend cluster nodes may not be yet started. Password will be updated later for cluster setup.
+ /*if (!AuthServerTestEnricher.AUTH_SERVER_CLUSTER) {
+ updateMasterAdminPassword();
+ }*/
+
+ beforeAbstractKeycloakTestRealmImport();
+
+ importTestRealms();
+
+ /*if (testContext.getTestRealmReps().isEmpty()) {
+ importTestRealms();
+
+ if (!isImportAfterEachMethod()) {
+ testContext.setTestRealmReps(testRealmReps);
+ }
+
+ afterAbstractKeycloakTestRealmImport();
+ }*/
+
+ //oauth.init(driver);
+ }
+
+ @AfterEach
+ void closeContext() throws IOException {
+ context.close();
+ //adminClient.realms().realm("test").remove();
+ }
+
+
+ private boolean importTestRealm(String realmJsonPath) throws IOException {
+
+ ObjectMapper mapper = new ObjectMapper();
+ try (InputStream fis = getClass().getResourceAsStream(realmJsonPath)) {
+ RealmRepresentation realmRepresentation = mapper.readValue(fis, RealmRepresentation.class);
+ adminClient.realms().create(realmRepresentation);
+ return true;
+ }
+
+ }
+
+ public static UPConfig setUserProfileConfiguration(RealmResource testRealm, String configuration) {
+ try {
+ UPConfig config = configuration == null ? null : JsonSerialization.readValue(configuration, UPConfig.class);
+
+ if (config != null) {
+ UPAttribute username = config.getAttribute(UserModel.USERNAME);
+
+ if (username == null) {
+ config.addOrReplaceAttribute(new UPAttribute(UserModel.USERNAME));
+ }
+
+ UPAttribute email = config.getAttribute(UserModel.EMAIL);
+
+ if (email == null) {
+ config.addOrReplaceAttribute(new UPAttribute(UserModel.EMAIL, new UPAttributePermissions(new HashSet<>(Arrays.asList(ROLE_USER, ROLE_ADMIN)), new HashSet<>(Arrays.asList(ROLE_USER, ROLE_ADMIN))), new UPAttributeRequired(new HashSet<>(Collections.singletonList(ROLE_USER)), new HashSet<>())));
+ }
+ }
+
+ testRealm.users().userProfile().update(config);
+
+ return config;
+ } catch (IOException ioe) {
+ throw new RuntimeException("Failed to read configuration", ioe);
+ }
+ }
+
+ /*public void reconnectAdminClient() throws Exception {
+ testContext.reconnectAdminClient();
+ adminClient = testContext.getAdminClient();
+ }*/
+
+ /**
+ * Executed before test realms import
+ *
+ * In @Before block
+ */
+ protected void beforeAbstractKeycloakTestRealmImport() throws Exception {
+ }
+
+ /**
+ * Executed after test realms import
+ *
+ * In @Before block
+ */
+ protected void afterAbstractKeycloakTestRealmImport() {
+ }
+
+ /**
+ * Executed as the last task of each test case
+ *
+ * In @After block
+ */
+ protected void postAfterAbstractKeycloak() throws Exception {
+ }
+
+ @AfterEach
+ public void afterAbstractKeycloakTest() throws Exception {
+ /*if (resetTimeOffset) {
+ resetTimeOffset();
+ }*/
+
+ if (isImportAfterEachMethod()) {
+ log.info("removing test realms after test method");
+ for (RealmRepresentation testRealm : testRealmReps) {
+ removeRealm(testRealm.getRealm());
+ }
+ } else {
+ /*log.info("calling all TestCleanup");
+ // Remove all sessions
+ testContext.getTestRealmReps().stream().forEach((r)->testingClient.testing().removeUserSessions(r.getRealm()));
+
+ // Cleanup objects
+ for (TestCleanup cleanup : testContext.getCleanups().values()) {
+ try {
+ if (cleanup != null) cleanup.executeCleanup();
+ } catch (Exception e) {
+ log.error("failed cleanup!", e);
+ throw new RuntimeException(e);
+ }
+ }
+ testContext.getCleanups().clear();*/
+ }
+
+ postAfterAbstractKeycloak();
+
+ // Remove all browsers from queue
+ DroneUtils.resetQueue();
+ }
+
+ /*protected TestCleanup getCleanup(String realmName) {
+ return testContext.getOrCreateCleanup(realmName);
+ }
+
+ protected TestCleanup getCleanup() {
+ return getCleanup("test");
+ }*/
+
+ protected boolean isImportAfterEachMethod() {
+ return false;
+ }
+
+ /*protected void updateMasterAdminPassword() {
+ if (!suiteContext.isAdminPasswordUpdated()) {
+ log.debug("updating admin password");
+
+ welcomePage.navigateTo();
+ if (!welcomePage.isPasswordSet()) {
+ welcomePage.setPassword("admin", "admin");
+ }
+
+ suiteContext.setAdminPasswordUpdated(true);
+ }
+ }
+
+ public void deleteAllCookiesForMasterRealm() {
+ deleteAllCookiesForRealm(MASTER);
+ }
+
+ protected void deleteAllCookiesForRealm(String realmName) {
+ navigateToUri(oauth.SERVER_ROOT + "/auth/realms/" + realmName + "/testing/blank");
+ log.info("deleting cookies in '" + realmName + "' realm");
+ driver.manage().deleteAllCookies();
+ }*/
+
+ // this is useful mainly for smartphones as cookies deletion doesn't work there
+ protected void deleteAllSessionsInRealm(String realmName) {
+ log.info("removing all sessions from '" + realmName + "' realm...");
+ try {
+ adminClient.realm(realmName).logoutAll();
+ log.info("sessions successfully deleted");
+ }
+ catch (NotFoundException e) {
+ log.warn("realm not found");
+ }
+ }
+
+ /*protected void resetRealmSession(String realmName) {
+ deleteAllCookiesForRealm(realmName);
+
+ if (driver instanceof AppiumDriver) { // smartphone drivers don't support cookies deletion
+ try {
+ log.info("resetting realm session");
+
+ final RealmRepresentation realmRep = adminClient.realm(realmName).toRepresentation();
+
+ deleteAllSessionsInRealm(realmName); // logout users
+
+ if (realmRep.isInternationalizationEnabled()) { // reset the locale
+ String locale = getDefaultLocaleName(realmRep.getRealm());
+ loginPage.localeDropdown().selectByText(locale);
+ log.info("locale reset to " + locale);
+ }
+ } catch (NotFoundException e) {
+ log.warn("realm not found");
+ }
+ }
+ }
+
+ protected String getDefaultLocaleName(String realmName) {
+ return ENGLISH_LOCALE_NAME;
+ }
+
+ public void setDefaultPageUriParameters() {
+ masterRealmPage.setAuthRealm(MASTER);
+ loginPage.setAuthRealm(MASTER);
+ }
+
+ public KeycloakTestingClient getTestingClient() {
+ if (testingClient == null) {
+ testingClient = testContext.getTestingClient();
+ }
+ return testingClient;
+ }
+
+ public TestContext getTestContext() {
+ return testContext;
+ }*/
+
+ public Keycloak getAdminClient() {
+ return adminClient;
+ }
+
+ public abstract void addTestRealms(List testRealms);
+
+ private void addTestRealms() {
+ log.debug("loading test realms");
+ if (testRealmReps == null) {
+ testRealmReps = new ArrayList<>();
+ }
+ if (testRealmReps.isEmpty()) {
+ addTestRealms(testRealmReps);
+ }
+ }
+
+ public void fixAuthServerHostAndPortForClientRepresentation(ClientRepresentation cr) {
+ cr.setBaseUrl(removeDefaultPorts(replaceAuthHostWithRealHost(cr.getBaseUrl())));
+ cr.setAdminUrl(removeDefaultPorts(replaceAuthHostWithRealHost(cr.getAdminUrl())));
+
+ if (cr.getRedirectUris() != null && !cr.getRedirectUris().isEmpty()) {
+ List fixedUrls = new ArrayList<>(cr.getRedirectUris().size());
+ for (String url : cr.getRedirectUris()) {
+ fixedUrls.add(removeDefaultPorts(replaceAuthHostWithRealHost(url)));
+ }
+
+ cr.setRedirectUris(fixedUrls);
+ }
+ }
+
+ public String replaceAuthHostWithRealHost(String url) {
+ if (url != null && (url.contains("localhost:8180") || url.contains("localhost:8543"))) {
+ return url.replaceFirst("localhost:(\\d)+", AUTH_SERVER_HOST + ":" + AUTH_SERVER_PORT);
+ }
+
+ return url;
+ }
+
+ public void importTestRealms() {
+ addTestRealms();
+ log.info("importing test realms");
+ for (RealmRepresentation testRealm : testRealmReps) {
+ importRealm(testRealm);
+ }
+ }
+
+ private void modifySamlAttributes(ClientRepresentation cr) {
+ if (cr.getProtocol() != null && cr.getProtocol().equals("saml")) {
+ log.debug("Modifying attributes of SAML client: " + cr.getClientId());
+ for (Map.Entry entry : cr.getAttributes().entrySet()) {
+ cr.getAttributes().put(entry.getKey(), replaceHttpValuesWithHttps(entry.getValue()));
+ }
+ }
+ }
+
+ private void modifyRedirectUrls(ClientRepresentation cr) {
+ if (cr.getRedirectUris() != null && cr.getRedirectUris().size() > 0) {
+ List redirectUrls = cr.getRedirectUris();
+ List fixedRedirectUrls = new ArrayList<>(redirectUrls.size());
+ for (String url : redirectUrls) {
+ fixedRedirectUrls.add(replaceHttpValuesWithHttps(url));
+ }
+ cr.setRedirectUris(fixedRedirectUrls);
+ }
+ }
+
+ private void modifyMainUrls(ClientRepresentation cr) {
+ cr.setBaseUrl(replaceHttpValuesWithHttps(cr.getBaseUrl()));
+ cr.setAdminUrl(replaceHttpValuesWithHttps(cr.getAdminUrl()));
+ }
+
+ private String replaceHttpValuesWithHttps(String input) {
+ if (input == null) {
+ return null;
+ }
+ if ("".equals(input)) {
+ return "";
+ }
+ return input
+ .replace("http", "https")
+ .replace("8080", "8543")
+ .replace("8180", "8543");
+ }
+
+ protected interface ExecutableTestMethod {
+ void execute() throws Exception;
+ }
+
+ protected void runTestWithTimeout(long timeout, ExecutableTestMethod executableTestMethod) throws Exception {
+ ExecutorService service = Executors.newSingleThreadExecutor();
+ Callable