package shogun.task; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import shogun.sdk.SDK; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; import java.util.List; import static org.junit.jupiter.api.Assertions.*; class TaskTrayTest { private TaskTray taskTray; private Path dummyJDK; private List<String> toBeUninstalled = new ArrayList<>(); private String candidateStr; @Test void showTray() throws InterruptedException, IOException { String dummyJDKVersion = "15.1"; String dummyJDKVendor = "AdoptOpenJDK"; dummyJDK = createDummyJDK(dummyJDKVendor, dummyJDKVersion); taskTray = new TaskTray(); taskTray.skipConfirmation = true; taskTray.show(); taskTray.waitForActionToFinish(); Element rootMenu = $(taskTray.popup); Element availableCandidates = $(taskTray.availableCandidatesMenu); SDK sdk = new SDK(); List<String> installedCandidates = sdk.getInstalledCandidates(); // number of installed candidates + Other candidates + SDKMAN version + Shogun version + Quit int menuCount = 4; assertEquals(installedCandidates.size() + menuCount, rootMenu.getItemCount(), "showing all installed candidates"); List<String> strings = sdk.listCandidates(); int numberOfAvailableCandidates = strings.size() - installedCandidates.size(); assertEquals(numberOfAvailableCandidates, availableCandidates.getItemCount(), "showing all available candidates"); System.out.println("Initialization finished"); rootMenu.dumpLabels(); int numberOfAvailableVersions = rootMenu.getItem(0).getItemCount(); Element javaMenu; javaMenu = rootMenu.findMenuContains("java"); if (javaMenu == null) { availableCandidates.findMenuContains("java"); } assertNotNull(javaMenu); long numberOfUnregisteredJDKs = javaMenu.countMenuContains(taskTray.getMessage(Messages.notRegistered)); if (0 < numberOfUnregisteredJDKs) { Element dummyJDKMenu = javaMenu.findMenuContains(dummyJDKVersion); // not registered java menu has "copy to clipboard", "reveal in finder", "register" menuItems assertEquals(3, dummyJDKMenu.getItemCount()); // register the JDK dummyJDKMenu.getLast().click(); taskTray.waitForActionToFinish(); Element javaMenu2; javaMenu2 = rootMenu.findMenuContains("java"); if (javaMenu2 == null) { availableCandidates.findMenuContains("java"); } assertNotNull(javaMenu2); // number of unregistered java decreased assertEquals(numberOfUnregisteredJDKs - 1, javaMenu.countMenuContains(taskTray.getMessage(Messages.notRegistered))); Element dummyJDKMenu2 = javaMenu.findMenuContains(dummyJDKVersion); // uninstall the jdk dummyJDKMenu2.getLast().click(); taskTray.waitForActionToFinish(); } int popupItemCount = rootMenu.getItemCount(); int availableItemCount = availableCandidates.getItemCount(); // install 1 available candidate Element firstAvailable = availableCandidates.getItem(0); candidateStr = firstAvailable.getLabel(); Element firstAvailableVersionMenu = firstAvailable.getItem(0); String candidateVersion = firstAvailableVersionMenu.getLabel().trim(); toBeUninstalled.add(candidateVersion); Element installMenu = firstAvailableVersionMenu.getLast(); // install the version assertEquals(taskTray.getMessage(Messages.install), installMenu.getLabel()); System.out.printf("Installing %s:%s%n", candidateStr, candidateVersion); rootMenu.dumpLabels(); installMenu.click(); taskTray.waitForActionToFinish(); System.out.printf("Finished %s:%s installation%n", candidateStr, candidateVersion); rootMenu.dumpLabels(); assertEquals(popupItemCount + 1, rootMenu.getItemCount()); assertEquals(availableItemCount - 1, availableCandidates.getItemCount()); Element installedCandidate = rootMenu.findMenuContains(candidateStr); // ensure that the installed version is marked as default Element makeDefaultMenu = rootMenu.findMenuContains(candidateStr).findMenuContains(candidateVersion).findMenu(Messages.makeDefault); if (makeDefaultMenu != null) { makeDefaultMenu.click(); taskTray.waitForActionToFinish(); } Element secondVersion = installedCandidate.getLast(); assertNotNull(installedCandidate); String thirdVersionLabel = secondVersion.getLabel().trim(); toBeUninstalled.add(thirdVersionLabel); Element thirdVersionInstallMenu = secondVersion.findMenu(Messages.install); thirdVersionInstallMenu.click(); taskTray.waitForActionToFinish(); // make the third version default rootMenu.findMenuContains(candidateStr).findMenuContains(thirdVersionLabel).findMenu(Messages.makeDefault).click(); taskTray.waitForActionToFinish(); List<String> labels = rootMenu.findMenuContains(candidateStr).labels(); // only 1 version is marked as default assertEquals(1, labels.stream().filter(e -> e.contains(">")).count()); // test all installed versions are listed on top boolean installed = true; for (String label : labels) { System.out.println(label); if (installed && label.contains("installed")) { continue; } if (installed && !label.contains("installed")) { installed = false; } if (!installed && label.contains("installed")) { fail("version that is marked as installed it not listed on top"); } } Element candidateVersionToBeUninstalledMenu = installedCandidate.getItem(0); Element uninstallMenu = candidateVersionToBeUninstalledMenu.getLast(); assertEquals(taskTray.getMessage(Messages.uninstall), uninstallMenu.getLabel()); System.out.printf("Uninstalling %s%n", candidateVersionToBeUninstalledMenu.getLabel()); rootMenu.dumpLabels(); uninstallMenu.click(); taskTray.waitForActionToFinish(); // wait for EventQueue to update menu items System.out.printf("Uninstalled %s%n", candidateVersionToBeUninstalledMenu.getLabel()); rootMenu.dumpLabels(); assertEquals(popupItemCount + 1, rootMenu.getItemCount()); assertEquals(availableItemCount - 1, availableCandidates.getItemCount()); rootMenu.findMenuContains(candidateStr).findMenuContains(thirdVersionLabel).findMenu(Messages.uninstall).click(); taskTray.waitForActionToFinish(); assertEquals(popupItemCount, rootMenu.getItemCount()); assertEquals(availableItemCount, availableCandidates.getItemCount()); // uninstalled version is archived Element uninstalledVersionMenu = availableCandidates.getItem(0).getItem(0); // menu has install menu item assertNotNull(uninstalledVersionMenu.findMenu(Messages.install)); // click refresh menu $(taskTray.versionMenu).findMenu(Messages.refresh).click(); taskTray.waitForActionToFinish(); assertEquals(installedCandidates.size() + menuCount, rootMenu.getItemCount(), "showing all installed candidates"); assertEquals(numberOfAvailableCandidates, availableCandidates.getItemCount(), "showing all available candidates"); assertEquals(numberOfAvailableVersions, rootMenu.getItem(0).getItemCount()); } @AfterEach void finish() throws IOException { for (String versionStr : toBeUninstalled) { System.out.printf("Uninstalling %s:%s in finally block%n", candidateStr, versionStr); // ensure the version is uninstalled SDK.runSDK("uninstall " + candidateStr + " " + versionStr); } //noinspection ResultOfMethodCallIgnored Files.walk(dummyJDK) .sorted(Comparator.reverseOrder()) .map(Path::toFile) .forEach(File::delete); } Element $(Menu menu) { return new Element(menu); } Element $(MenuItem menuItem) { return new Element((Menu) menuItem); } class Element { private MenuItem menu; Element(Menu menu) { this.menu = menu; } void dumpLabels() { for (int i = 0; i < getMenu().getItemCount(); i++) { System.out.println(i + ":" + getMenu().getItem(i).getLabel()); } } long countMenuContains(String label) { return labels().stream().filter(e -> e.contains(label)).count(); } Element(MenuItem item) { this.menu = item; } int getItemCount() { return getMenu().getItemCount(); } Element getItem(@SuppressWarnings("SameParameterValue") int i) { try { return new Element(getMenu().getItem(i)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("index:" + i + " not found."); labels().forEach(System.out::println); throw e; } } Element getLast() { return new Element(getMenu().getItem(getMenu().getItemCount() - 1)); } private Menu getMenu() { return (Menu) menu; } Element findMenuContains(String label) { for (int i = 0; i < getMenu().getItemCount(); i++) { MenuItem menuItem = getMenu().getItem(i); if (menuItem.getLabel().contains(label)) { return new Element(menuItem); } } System.out.println("label:" + label + " not found."); labels().forEach(System.out::println); return null; } Element findMenu(Messages message) { return findMenuContains(taskTray.getMessage(message).replaceAll("\\{[0-9]+}", "")); } String getLabel() { return menu.getLabel(); } void click() { for (ActionListener actionListener : menu.getActionListeners()) { actionListener.actionPerformed(new ActionEvent(TaskTrayTest.class, 0, "dummy")); } } List<String> labels() { List<String> labels = new ArrayList<>(); for (int i = 0; i < getMenu().getItemCount(); i++) { labels.add(getMenu().getItem(i).getLabel()); } return labels; } } @NotNull private static Path createDummyJDK(String dummyVendor, String version) throws IOException { String home = System.getProperty("user.home"); long time = System.currentTimeMillis(); Path dummyJDKHome = Path.of(home + "/Downloads/shogun_dummyJDK" + time); Path bin = Path.of(home + "/Downloads/shogun_dummyJDK" + time + "/Contents/Home/bin"); Path dummyJava = Path.of(home + "/Downloads/shogun_dummyJDK" + time + "/Contents/Home/bin/java"); List<String> strings = Arrays.asList("#!/bin/sh", "echo openjdk version \\\"11.0.3\\\" 2019-04-16", String.format("echo OpenJDK Runtime Environment %s \\(build %s\\)", dummyVendor, version), String.format("echo OpenJDK 64-Bit Server VM %s \\(build %s, mixed mode\\)", dummyVendor, version)); if (bin.toFile().mkdirs()) { Files.write(dummyJava, strings); } else { System.out.println("failed" + bin.toFile()); } //noinspection ResultOfMethodCallIgnored dummyJava.toFile().setExecutable(true); return dummyJDKHome; } }