diff --git a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/IDFProjectLaunchTargetEditorFunctionalityTest.java b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/IDFProjectLaunchTargetEditorFunctionalityTest.java new file mode 100644 index 000000000..4d40ef4ce --- /dev/null +++ b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/executable/cases/project/IDFProjectLaunchTargetEditorFunctionalityTest.java @@ -0,0 +1,225 @@ +/******************************************************************************* + * Copyright 2025 Espressif Systems (Shanghai) PTE LTD. All rights reserved. + * Use is subject to license terms. + *******************************************************************************/ +package com.espressif.idf.ui.test.executable.cases.project; + +import static org.eclipse.swtbot.swt.finder.waits.Conditions.widgetIsEnabled; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.eclipse.swtbot.eclipse.finder.SWTWorkbenchBot; +import org.eclipse.swtbot.swt.finder.junit.SWTBotJunit4ClassRunner; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.MethodSorters; + +import com.espressif.idf.ui.handlers.Messages; +import com.espressif.idf.ui.test.common.WorkBenchSWTBot; +import com.espressif.idf.ui.test.common.utility.TestWidgetWaitUtility; +import com.espressif.idf.ui.test.operations.EnvSetupOperations; +import com.espressif.idf.ui.test.operations.ProjectTestOperations; +import com.espressif.idf.ui.test.operations.selectors.LaunchBarTargetSelector; + +/** + * Test class to test the Launch Target Editor + * + * @author Andrii Filippov + * + */ +@SuppressWarnings("restriction") +@RunWith(SWTBotJunit4ClassRunner.class) +@FixMethodOrder(MethodSorters.NAME_ASCENDING) + +public class IDFProjectLaunchTargetEditorFunctionalityTest { + @BeforeClass + public static void beforeTestClass() throws Exception + { + Fixture.loadEnv(); + Fixture.givenNewEspressifIDFProjectIsSelected("EspressIf", "Espressif IDF Project"); + Fixture.givenProjectNameIs("LaunchTargetEditorTest"); + Fixture.whenNewProjectIsSelected(); + } + + @AfterClass + public static void afterEachTest() + { + try + { + Fixture.cleanTestEnv(); + } + catch (Exception e) + { + System.err.println("Error during cleanup: " + e.getMessage()); + } + } + + @Test + public void givenANewProjectCreatedBuiltWhenSelectNewTargetWhenPopUpAppearsThenBuildFolderDeletedSuccessfully() + throws Exception + { + Fixture.whenProjectIsBuiltUsingContextMenu(); + Fixture.whenChangeLaunchTarget(); + Fixture.whenRefreshProject(); + Fixture.thenBuildFolderDeletedSuccessfully(); + } + + @Test + public void givenBNewProjectCreatedWhenCreateNewLaunchTargetThenProjectBuiltSuccessfully() + throws Exception + { + Fixture.whenCreateNewLaunchTarget(); + Fixture.whenProjectIsBuiltUsingContextMenu(); + } + + @Test + public void givenCNewProjectCreatedWhenDeleteSelectedLaunchTargetThenDeletedSuccessfully() + throws Exception + { + Fixture.whenProjectFullCleanUsingContextMenu(); + Fixture.whenDeleteSelectedLaunchTarget(); + Fixture.thenLaunchTargetDeletedSuccessfully(); + } + + private static class Fixture + { + private static SWTWorkbenchBot bot; + private static String category; + private static String subCategory; + private static String projectName; + + private static void loadEnv() throws Exception + { + bot = WorkBenchSWTBot.getBot(); + EnvSetupOperations.setupEspressifEnv(bot); + bot.sleep(1000); + ProjectTestOperations.deleteAllProjects(bot); + } + + private static void givenNewEspressifIDFProjectIsSelected(String category, String subCategory) + { + Fixture.category = category; + Fixture.subCategory = subCategory; + } + + private static void givenProjectNameIs(String projectName) + { + Fixture.projectName = projectName; + } + + private static void whenNewProjectIsSelected() throws Exception + { + ProjectTestOperations.setupProject(projectName, category, subCategory, bot); + } + + private static void whenProjectIsBuiltUsingContextMenu() throws IOException + { + ProjectTestOperations.buildProjectUsingContextMenu(projectName, bot); + ProjectTestOperations.waitForProjectBuild(bot); + TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); + } + + private static void whenChangeLaunchTarget() throws Exception + { + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + targetSelector.selectTarget("esp32c2"); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "IDF Launch Target Changed", 20000); + SWTBotShell shell = bot.shell("IDF Launch Target Changed"); + shell.setFocus(); + bot.button("Yes").click(); + } + + private static void whenSelectLaunchTarget() throws Exception + { + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + targetSelector.selectTarget("target"); + } + + private static void whenDeleteLaunchTarget() throws Exception + { + bot.sleep(500); + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + targetSelector.clickEdit(); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "New ESP Target", 20000); + SWTBotShell shell = bot.shell("New ESP Target"); + shell.setFocus(); + bot.button("Delete").click(); + } + + private static void whenDeleteSelectedLaunchTarget() throws Exception + { + whenSelectLaunchTarget(); + whenDeleteLaunchTarget(); + } + + private static void thenLaunchTargetDeletedSuccessfully() throws Exception + { + bot.sleep(500); + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + assertTrue("Launch Target was not deleted successfully!", !targetSelector.isTargetPresent("target")); + } + + private static void selectNewLaunchTarget() + { + LaunchBarTargetSelector targetSelector = new LaunchBarTargetSelector(bot); + targetSelector.select("New Launch Target..."); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "New Launch Target", 20000); + assertTrue("'New Launch Target' dialog did not appear", bot.shell("New Launch Target").isActive()); + } + + private static void handleNewLaunchTargetDialog() throws Exception + { + SWTBotShell shell = bot.shell("New Launch Target"); + bot.table().select("ESP Target"); + shell.setFocus(); + bot.waitUntil(widgetIsEnabled(bot.button("Next >")), 5000); + bot.button("Next >").click(); + TestWidgetWaitUtility.waitForDialogToAppear(bot, "New ESP Target",10000); + } + + private static void handleNewEspTargetDialog() throws Exception + { + bot.textWithLabel("Name:").setText("target"); + bot.button("Finish").click(); + TestWidgetWaitUtility.waitForOperationsInProgressToFinishSync(bot); + } + + private static void whenCreateNewLaunchTarget() throws Exception + { + selectNewLaunchTarget(); + handleNewLaunchTargetDialog(); + handleNewEspTargetDialog(); + } + + private static void whenRefreshProject() throws IOException + { + ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Refresh"); + } + + private static void thenBuildFolderDeletedSuccessfully() throws Exception + { + assertTrue("Build folder was not deleted successfully!", ProjectTestOperations.findProjectFullCleanedFilesInBuildFolder(projectName, bot)); + } + + private static void whenProjectFullCleanUsingContextMenu() throws IOException + { + ProjectTestOperations.launchCommandUsingContextMenu(projectName, bot, "Project Full Clean"); + ProjectTestOperations.joinJobByName(Messages.ProjectFullCleanCommandHandler_RunningFullcleanJobName); + ProjectTestOperations.findInConsole(bot, "Espressif IDF Tools Console", "Done"); + TestWidgetWaitUtility.waitForOperationsInProgressToFinishSync(bot); + } + + private static void cleanTestEnv() + { + TestWidgetWaitUtility.waitForOperationsInProgressToFinishAsync(bot); + ProjectTestOperations.closeAllProjects(bot); + ProjectTestOperations.deleteAllProjects(bot); + } + } +} + diff --git a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/ProjectTestOperations.java b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/ProjectTestOperations.java index 6ae4172d6..2e4cff321 100644 --- a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/ProjectTestOperations.java +++ b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/ProjectTestOperations.java @@ -88,8 +88,12 @@ public static void waitForProjectBuild(SWTWorkbenchBot bot) throws IOException SWTBotView consoleView = viewConsole("CDT Build Console", bot); consoleView.show(); consoleView.setFocus(); + try { TestWidgetWaitUtility.waitUntilViewContains(bot, "Build complete", consoleView, DefaultPropertyFetcher.getLongPropertyValue(DEFAULT_PROJECT_BUILD_WAIT_PROPERTY, 300000)); + } catch (Exception e) { + throw new AssertionError("Project Build failed", e); + } } public static void waitForProjectFlash(SWTWorkbenchBot bot) throws IOException diff --git a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java index d3b1fc65c..6bc2938ab 100644 --- a/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java +++ b/tests/com.espressif.idf.ui.test/src/com/espressif/idf/ui/test/operations/selectors/LaunchBarTargetSelector.java @@ -8,6 +8,8 @@ import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.widgetOfType; import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.withText; +import java.util.List; + import org.eclipse.launchbar.ui.controls.internal.CSelector; import org.eclipse.launchbar.ui.controls.internal.LaunchBarWidgetIds; import org.eclipse.launchbar.ui.controls.internal.TargetSelector; @@ -23,7 +25,9 @@ import org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory; import org.eclipse.swtbot.swt.finder.results.Result; import org.eclipse.swtbot.swt.finder.widgets.AbstractSWTBotControl; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotLabel; import org.eclipse.swtbot.swt.finder.widgets.SWTBotShell; +import static org.eclipse.swtbot.swt.finder.matchers.WidgetMatcherFactory.allOf; /** * Launchbar CDT helper class to select items from launch targets @@ -98,27 +102,80 @@ public LaunchBarTargetSelector select(String text) public LaunchBarTargetSelector selectTarget(String text) { - click(); - SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); - ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); - int numberOfItemsInScrolledComp = syncExec( - () -> ((Composite) scrolledComposite.getChildren()[0]).getChildren().length); - Label itemToSelect; - - // Set the text in the not visible text field - // when the target list is too big, swtbot cannot select a target label, so we filter the list - if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) - { - swtBotShell.bot().text().setText(text); - itemToSelect = swtBotShell.bot().label(0).widget; - } - else - { - itemToSelect = swtBotShell.bot().widget(withText(text)); - } - - Point itemToSelectLocation = syncExec((Result) itemToSelect::getLocation); - clickOnInternalWidget(itemToSelectLocation.x, itemToSelectLocation.y, itemToSelect); - return this; + click(); + SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); + ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); + int numberOfItemsInScrolledComp = syncExec( + () -> ((Composite) scrolledComposite.getChildren()[0]).getChildren().length); + Label itemToSelect; + + if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) + { + swtBotShell.bot().text().setText(text); + itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); + } + else + { + itemToSelect = swtBotShell.bot().widget(allOf(widgetOfType(Label.class), withText(text))); + } + + Point itemToSelectLocation = syncExec((Result) itemToSelect::getLocation); + clickOnInternalWidget(itemToSelectLocation.x, itemToSelectLocation.y, itemToSelect); + return this; + } + + public void scrollToBottom(ScrolledComposite scrolledComposite) + { + syncExec(() -> { + scrolledComposite.setOrigin(0, scrolledComposite.getClientArea().height); + }); + } + + public boolean isTargetPresent(String text) + { + click(); + + try + { + SWTBotShell swtBotShell = bot().shellWithId(LaunchBarWidgetIds.POPUP); + ScrolledComposite scrolledComposite = swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class)); + + int numberOfItemsInScrolledComp = syncExec(() -> + ((Composite) scrolledComposite.getChildren()[0]).getChildren().length + ); + + // Scroll to the bottom if there are many items + if (numberOfItemsInScrolledComp > NUM_FOR_FILTER_POPUP) + { + scrollToBottom(swtBotShell.bot().widget(widgetOfType(ScrolledComposite.class))); + swtBotShell.bot().text().setText(text); + + List labels = swtBotShell.bot().widgets(widgetOfType(Label.class)); + for (Label label : labels) + { + String labelText = syncExec(label::getText); + if (labelText.equals(text)) + { + return true; + } + } + return false; + } + else + { + Widget itemToCheck = swtBotShell.bot().widget(withText(text)); + String labelText = syncExec(() -> ((Label) itemToCheck).getText()); + return labelText.equals(text); + } + } + catch (WidgetNotFoundException e) + { + return false; + } + catch (Exception e) + { + e.printStackTrace(); + return false; + } } }